Skip to content
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 {
Comment thread
michaelneale marked this conversation as resolved.
Outdated
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");

Copilot AI Dec 30, 2024

Copy link

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 uses AI. Check for mistakes.
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 {
Comment thread
michaelneale marked this conversation as resolved.
Outdated
dbg!("Adding NonDeveloperSystem");

Copilot AI Dec 30, 2024

Copy link

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 uses AI. Check for mistakes.
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");

Copilot AI Dec 30, 2024

Copy link

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 uses AI. Check for mistakes.
agent.add_system(Box::new(MemorySystem::new()));
} else {
dbg!("Skipping MemorySystem (GOOSE_SERVER__MEMORY not 'true')");

Copilot AI Dec 30, 2024

Copy link

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 uses AI. Check for mistakes.
}
} else {
dbg!("Skipping MemorySystem (GOOSE_SERVER__MEMORY not set)");
}

dbg!("Adding GooseHintsSystem");

Copilot AI Dec 30, 2024

Copy link

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 uses AI. Check for mistakes.
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