Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,16 @@ jobs:
id-token: write # Required for Sigstore OIDC signing
attestations: write # Required for SLSA build provenance attestations
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Download all artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
merge-multiple: true

- name: Generate macOS update manifest
run: node ui/desktop/scripts/generate-mac-update-manifest.js --version "${GITHUB_REF_NAME}" --directory .

- name: Attest build provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
Expand All @@ -125,6 +130,7 @@ jobs:
*.deb
*.rpm
*.flatpak
latest-mac.yml
download_cli.sh

# Create/update the versioned release
Expand All @@ -141,6 +147,7 @@ jobs:
*.deb
*.rpm
*.flatpak
latest-mac.yml
download_cli.sh
allowUpdates: true
omitBody: true
Expand All @@ -162,6 +169,7 @@ jobs:
*.deb
*.rpm
*.flatpak
latest-mac.yml
download_cli.sh
allowUpdates: true
omitBody: true
Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
version = "1.38.0"
version = "1.39.0"
rust-version = "1.91.1"
authors = ["AAIF <ai-oss-tools@block.xyz>"]
license = "Apache-2.0"
Expand Down
4 changes: 4 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ release-intel:
copy-binary BUILD_MODE="release":
@if [ -f ./target/{{BUILD_MODE}}/goosed ]; then \
echo "Copying goosed binary from target/{{BUILD_MODE}}..."; \
rm -f ./ui/desktop/src/bin/goosed; \
cp -p ./target/{{BUILD_MODE}}/goosed ./ui/desktop/src/bin/; \
else \
echo "Binary not found in target/{{BUILD_MODE}}"; \
exit 1; \
fi
@if [ -f ./target/{{BUILD_MODE}}/goose ]; then \
echo "Copying goose CLI binary from target/{{BUILD_MODE}}..."; \
rm -f ./ui/desktop/src/bin/goose; \
cp -p ./target/{{BUILD_MODE}}/goose ./ui/desktop/src/bin/; \
else \
echo "goose CLI binary not found in target/{{BUILD_MODE}}"; \
Expand All @@ -62,13 +64,15 @@ copy-binary BUILD_MODE="release":
copy-binary-intel:
@if [ -f ./target/x86_64-apple-darwin/release/goosed ]; then \
echo "Copying Intel goosed binary to ui/desktop/src/bin with permissions preserved..."; \
rm -f ./ui/desktop/src/bin/goosed; \
cp -p ./target/x86_64-apple-darwin/release/goosed ./ui/desktop/src/bin/; \
else \
echo "Intel release binary not found."; \
exit 1; \
fi
@if [ -f ./target/x86_64-apple-darwin/release/goose ]; then \
echo "Copying Intel goose CLI binary to ui/desktop/src/bin..."; \
rm -f ./ui/desktop/src/bin/goose; \
cp -p ./target/x86_64-apple-darwin/release/goose ./ui/desktop/src/bin/; \
else \
echo "Intel goose CLI binary not found."; \
Expand Down
3 changes: 1 addition & 2 deletions crates/goose-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,11 +580,9 @@ enum SessionCommand {
},
#[command(name = "diagnostics")]
Diagnostics {
/// Session identifier for generating diagnostics
#[command(flatten)]
identifier: Option<Identifier>,

/// Output path for the diagnostics zip file (optional, defaults to current directory)
#[arg(short = 'o', long)]
output: Option<PathBuf>,
},
Expand Down Expand Up @@ -1358,6 +1356,7 @@ async fn handle_serve_command(host: String, port: u16, builtins: Vec<String>) ->
config_dir: Paths::config_dir(),
goose_platform: GoosePlatform::GooseCli,
additional_source_roots,
scheduler: None,
}));
let env_secret = std::env::var(GOOSE_SERVER_SECRET_KEY_ENV)
.ok()
Expand Down
45 changes: 19 additions & 26 deletions crates/goose-cli/src/commands/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,7 @@ async fn handle_oauth_configuration(provider_name: &str, key_name: &str) -> anyh
));

// Create a temporary provider instance to handle OAuth
let temp_model = goose::model_config::model_config_from_user_config(provider_name, "temp")?;
match create(provider_name, temp_model, Vec::new()).await {
match create(provider_name, Vec::new()).await {
Ok(provider) => match provider.configure_oauth().await {
Ok(_) => {
let _ = cliclack::log::success("OAuth authentication completed successfully!");
Expand Down Expand Up @@ -761,13 +760,11 @@ pub async fn configure_provider_dialog() -> anyhow::Result<bool> {

let spin = spinner();
spin.start("Attempting to fetch supported models...");
let temp_model_config = goose::model_config::model_config_from_user_config(
provider_name,
&provider_meta.default_model,
)?;
let temp_provider = create(provider_name, temp_model_config, Vec::new()).await?;
let temp_provider = create(provider_name, Vec::new()).await?;
let models_res = retry_operation(&RetryConfig::default(), || async {
temp_provider.fetch_recommended_models().await
temp_provider
.fetch_recommended_models(goose::model_config::global_toolshim())
.await
})
.await;
spin.stop(style("Model fetch complete").green());
Expand All @@ -792,9 +789,7 @@ pub async fn configure_provider_dialog() -> anyhow::Result<bool> {
{
let supports_thinking = match temp_provider.fetch_model_info(&model).await {
Ok(model_info) => model_info.reasoning,
Err(_) => goose_providers::model::ModelConfig::new(&model)
.map(|c| c.is_reasoning_model())
.unwrap_or(false),
Err(_) => goose_providers::model::ModelConfig::new(&model).is_reasoning_model(),
};

if supports_thinking {
Expand Down Expand Up @@ -1618,8 +1613,10 @@ pub async fn configure_tool_permissions_dialog() -> anyhow::Result<()> {
}

let extensions = extension_config.into_iter().collect::<Vec<_>>();
let new_provider = create(&provider_name, model_config, extensions).await?;
agent.update_provider(new_provider, &session.id).await?;
let new_provider = create(&provider_name, extensions).await?;
agent
.update_provider(new_provider, model_config, &session.id)
.await?;

let permission_manager = PermissionManager::instance();
let selected_tools = agent
Expand Down Expand Up @@ -1811,12 +1808,11 @@ pub async fn handle_openrouter_auth() -> anyhow::Result<()> {
}
};

match create("openrouter", model_config, Vec::new()).await {
match create("openrouter", Vec::new()).await {
Ok(provider) => {
let provider_model_config = provider.get_model_config();
let test_result = provider
.complete(
&provider_model_config,
&model_config,
"",
"You are goose, an AI assistant.",
&[Message::user().with_text("Say 'Configuration test successful!'")],
Expand Down Expand Up @@ -1883,17 +1879,14 @@ pub async fn handle_tetrate_auth() -> anyhow::Result<()> {
// Test configuration
println!("\nTesting configuration...");
let configured_model: String = config.get_goose_model()?;
let model_config =
match goose::model_config::model_config_from_user_config("tetrate", &configured_model) {
Ok(config) => config,
Err(e) => {
eprintln!("⚠️ Invalid model configuration: {}", e);
eprintln!("Your settings have been saved. Please check your model configuration.");
return Ok(());
}
};
if let Err(e) = goose::model_config::model_config_from_user_config("tetrate", &configured_model)
{
eprintln!("⚠️ Invalid model configuration: {}", e);
eprintln!("Your settings have been saved. Please check your model configuration.");
return Ok(());
}

match create("tetrate", model_config, Vec::new()).await {
match create("tetrate", Vec::new()).await {
Ok(provider) => {
let test_result = provider.fetch_supported_models().await;

Expand Down
3 changes: 1 addition & 2 deletions crates/goose-cli/src/commands/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ async fn check_provider(
let model_config = goose::model_config::model_config_from_user_config(&provider, &model)
.map_err(|e| ProviderCheckError::InvalidModel(e.to_string()))?;

let provider_client = goose::providers::create(&provider, model_config, Vec::new())
let provider_client = goose::providers::create(&provider, Vec::new())
.await
.map_err(|e| {
let error = e.to_string();
Expand All @@ -87,7 +87,6 @@ async fn check_provider(
})?;

let test_msg = Message::user().with_text("Say 'ok'");
let model_config = provider_client.get_model_config();
let start = std::time::Instant::now();
provider_client
.complete(&model_config, "check", "", &[test_msg], &[])
Expand Down
29 changes: 17 additions & 12 deletions crates/goose-cli/src/commands/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use etcetera::home_dir;
use goose::config::Config;
#[cfg(feature = "nostr")]
use goose::session::nostr_share;
use goose::session::{generate_diagnostics, Session, SessionManager, SessionType};
use goose::session::{
generate_diagnostics, DiagnosticsLevel, Session, SessionManager, SessionType,
};
use goose::utils::safe_truncate;
use regex::Regex;
use std::fs;
Expand Down Expand Up @@ -322,24 +324,27 @@ pub async fn handle_session_import(input: String, nostr: bool) -> Result<()> {

pub async fn handle_diagnostics(session_id: &str, output_path: Option<PathBuf>) -> Result<()> {
println!(
"Generating diagnostics bundle for session '{}'...",
"Generating diagnostics report for session '{}'...",
session_id
);

let session_manager = SessionManager::instance();
let diagnostics_data = generate_diagnostics(&session_manager, session_id)
.await
.with_context(|| {
format!(
"Failed to write to generate diagnostics bundle for session '{}'",
session_id
)
})?;
let diagnostics_report =
generate_diagnostics(&session_manager, session_id, DiagnosticsLevel::Full)
.await
.with_context(|| {
format!(
"Failed to generate diagnostics report for session '{}'",
session_id
)
})?;
let diagnostics_data = serde_json::to_vec_pretty(&diagnostics_report)
.context("Failed to serialize diagnostics report")?;

let output_file = if let Some(path) = output_path {
path.clone()
} else {
PathBuf::from(format!("diagnostics_{}.zip", session_id))
PathBuf::from(format!("diagnostics_{}.json", session_id))
};

let mut file = fs::File::create(&output_file).context(format!(
Expand All @@ -350,7 +355,7 @@ pub async fn handle_diagnostics(session_id: &str, output_path: Option<PathBuf>)
file.write_all(&diagnostics_data)
.context("Failed to write diagnostics data")?;

println!("Diagnostics bundle saved to: {}", output_file.display());
println!("Diagnostics report saved to: {}", output_file.display());

Ok(())
}
Expand Down
12 changes: 9 additions & 3 deletions crates/goose-cli/src/commands/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,15 @@ pub async fn handle_term_run(prompt: Vec<String>) -> Result<()> {
};

if let Some(oldest_user) = user_messages_after_last_assistant.last() {
session_manager
.truncate_conversation(&session_id, oldest_user.created)
.await?;
if let Some(message_id) = oldest_user.id.as_deref() {
session_manager
.truncate_conversation_from_message(&session_id, message_id)
.await?;
} else {
session_manager
.truncate_conversation(&session_id, oldest_user.created)
.await?;
}
}

let prompt_with_context = if user_messages_after_last_assistant.is_empty() {
Expand Down
Loading
Loading