Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: a system for non developers to augment developer system #524

Merged
merged 23 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/desktop-app-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,19 @@ jobs:
working-directory: ui/desktop

- name: Make default Goose App
run: npm run bundle:default
run: |
attempt=0
max_attempts=2
until [ $attempt -ge $max_attempts ]; do
npm run bundle:default && break
attempt=$((attempt + 1))
echo "Attempt $attempt failed. Retrying..."
sleep 5
done
if [ $attempt -ge $max_attempts ]; then
echo "Action failed after $max_attempts attempts."
exit 1
fi
working-directory: ui/desktop
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
Expand Down
38 changes: 36 additions & 2 deletions crates/goose-server/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,26 @@ use goose::{
developer::DeveloperSystem,
memory::MemorySystem,
providers::{configs::ProviderConfig, factory},
systems::goose_hints::GooseHintsSystem,
systems::{goose_hints::GooseHintsSystem, non_developer::NonDeveloperSystem},
};
use std::{env, sync::Arc};
use std::{env, path::Path, process::Command, sync::Arc};
use tokio::sync::Mutex;

/// Check if the current directory or any parent directory contains a .git folder
fn is_in_git_repository() -> bool {
michaelneale marked this conversation as resolved.
Show resolved Hide resolved
let output = Command::new("git")
.arg("rev-parse")
.arg("--git-dir")
.output();

matches!(output, Ok(output) if output.status.success())
}

/// Check if a .goosehints file exists in the current directory
fn has_goosehints_file() -> bool {
Path::new(".goosehints").exists()
}

/// Shared application state
pub struct AppState {
pub provider_config: ProviderConfig,
Expand All @@ -21,15 +36,34 @@ impl AppState {
pub fn new(provider_config: ProviderConfig, secret_key: String) -> Result<Self> {
let provider = factory::get_provider(provider_config.clone())?;
let mut agent = Agent::new(provider);

dbg!("Adding DeveloperSystem");
Copy link
Preview

Copilot AI Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is used for debugging and should not be in production code.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
agent.add_system(Box::new(DeveloperSystem::new()));

// Only add NonDeveloperSystem if we're not in a git repository and don't have a .goosehints file
let in_git = is_in_git_repository();
let has_hints = has_goosehints_file();

if !in_git && !has_hints {
michaelneale marked this conversation as resolved.
Show resolved Hide resolved
dbg!("Adding NonDeveloperSystem");
Copy link
Preview

Copilot AI Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is used for debugging and should not be in production code.

Suggested change
dbg!("Adding NonDeveloperSystem");
agent.add_system(Box::new(NonDeveloperSystem::new()));

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
agent.add_system(Box::new(NonDeveloperSystem::new()));
} else {
dbg!("Skipping NonDeveloperSystem");
}

// Add memory system only if GOOSE_SERVER__MEMORY is set to "true"
if let Ok(memory_enabled) = env::var("GOOSE_SERVER__MEMORY") {
if memory_enabled.to_lowercase() == "true" {
dbg!("Adding MemorySystem");
Copy link
Preview

Copilot AI Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is used for debugging and should not be in production code.

Suggested change
dbg!("Adding MemorySystem");
agent.add_system(Box::new(MemorySystem::new()));

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
agent.add_system(Box::new(MemorySystem::new()));
} else {
dbg!("Skipping MemorySystem (GOOSE_SERVER__MEMORY not 'true')");
Copy link
Preview

Copilot AI Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is used for debugging and should not be in production code.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
}
} else {
dbg!("Skipping MemorySystem (GOOSE_SERVER__MEMORY not set)");
}

dbg!("Adding GooseHintsSystem");
Copy link
Preview

Copilot AI Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is used for debugging and should not be in production code.

Suggested change
dbg!("Adding GooseHintsSystem");
// dbg!("Adding GooseHintsSystem");

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
let goosehints_system = Box::new(GooseHintsSystem::new());
agent.add_system(goosehints_system);

Expand Down
1 change: 1 addition & 0 deletions crates/goose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ keyring = { version = "3.6.1", features = [
shellexpand = "3.1.0"
rust_decimal = "1.36.0"
rust_decimal_macros = "1.36.0"
tempfile = "3.8"

[dev-dependencies]
sysinfo = "0.32.1"
Expand Down
49 changes: 37 additions & 12 deletions crates/goose/src/providers/groq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ mod tests {
#[tokio::test]
async fn test_complete_basic() -> anyhow::Result<()> {
let model_name = "gpt-4o";
let expected_response = "Hello! How can I assist you today?";
// Mock response for normal completion
let response_body =
create_mock_open_ai_response(model_name, "Hello! How can I assist you today?");
let response_body = create_mock_open_ai_response(model_name, expected_response);

let (_, provider) = _setup_mock_server(response_body).await;
let (mock_server, provider) = _setup_mock_server(response_body).await;

// Prepare input messages
let messages = vec![Message::user().with_text("Hello?")];
Expand All @@ -120,16 +120,41 @@ mod tests {
.await?;

// Assert the response
if let MessageContent::Text(text) = &message.content[0] {
assert_eq!(text.text, "Hello! How can I assist you today?");
} else {
panic!("Expected Text content");
assert!(
!message.content.is_empty(),
"Message content should not be empty"
);
match &message.content[0] {
MessageContent::Text(text) => {
assert_eq!(
text.text, expected_response,
"Response text does not match expected"
);
}
other => panic!("Expected Text content, got {:?}", other),
}
assert_eq!(usage.usage.input_tokens, Some(TEST_INPUT_TOKENS));
assert_eq!(usage.usage.output_tokens, Some(TEST_OUTPUT_TOKENS));
assert_eq!(usage.usage.total_tokens, Some(TEST_TOTAL_TOKENS));
assert_eq!(usage.model, model_name);
assert_eq!(usage.cost, None);

// Verify usage metrics
assert_eq!(
usage.usage.input_tokens,
Some(TEST_INPUT_TOKENS),
"Input tokens mismatch"
);
assert_eq!(
usage.usage.output_tokens,
Some(TEST_OUTPUT_TOKENS),
"Output tokens mismatch"
);
assert_eq!(
usage.usage.total_tokens,
Some(TEST_TOTAL_TOKENS),
"Total tokens mismatch"
);
assert_eq!(usage.model, model_name, "Model name mismatch");
assert_eq!(usage.cost, None, "Cost should be None");

// Ensure mock server handled the request
mock_server.verify().await;

Ok(())
}
Expand Down
49 changes: 37 additions & 12 deletions crates/goose/src/providers/ollama.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ mod tests {
#[tokio::test]
async fn test_complete_basic() -> Result<()> {
let model_name = "gpt-4o";
let expected_response = "Hello! How can I assist you today?";
// Mock response for normal completion
let response_body =
create_mock_open_ai_response(model_name, "Hello! How can I assist you today?");
let response_body = create_mock_open_ai_response(model_name, expected_response);

let (_, provider) = _setup_mock_server(response_body).await;
let (mock_server, provider) = _setup_mock_server(response_body).await;

// Prepare input messages
let messages = vec![Message::user().with_text("Hello?")];
Expand All @@ -113,16 +113,41 @@ mod tests {
.await?;

// Assert the response
if let MessageContent::Text(text) = &message.content[0] {
assert_eq!(text.text, "Hello! How can I assist you today?");
} else {
panic!("Expected Text content");
assert!(
!message.content.is_empty(),
"Message content should not be empty"
);
match &message.content[0] {
MessageContent::Text(text) => {
assert_eq!(
text.text, expected_response,
"Response text does not match expected"
);
}
other => panic!("Expected Text content, got {:?}", other),
}
assert_eq!(usage.usage.input_tokens, Some(TEST_INPUT_TOKENS));
assert_eq!(usage.usage.output_tokens, Some(TEST_OUTPUT_TOKENS));
assert_eq!(usage.usage.total_tokens, Some(TEST_TOTAL_TOKENS));
assert_eq!(usage.model, model_name);
assert_eq!(usage.cost, None);

// Verify usage metrics
assert_eq!(
usage.usage.input_tokens,
Some(TEST_INPUT_TOKENS),
"Input tokens mismatch"
);
assert_eq!(
usage.usage.output_tokens,
Some(TEST_OUTPUT_TOKENS),
"Output tokens mismatch"
);
assert_eq!(
usage.usage.total_tokens,
Some(TEST_TOTAL_TOKENS),
"Total tokens mismatch"
);
assert_eq!(usage.model, model_name, "Model name mismatch");
assert_eq!(usage.cost, None, "Cost should be None");

// Ensure mock server handled the request
mock_server.verify().await;

Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions crates/goose/src/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ mod system;
pub use system::System;

pub mod goose_hints;
pub mod non_developer;
Loading
Loading