Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9f08b8b
chore: bump workspace dependencies
jh-block Mar 4, 2026
ae79c39
chore: disable default features for image crate to reduce dep tree
jh-block Mar 4, 2026
82c4cb1
chore: bump tiktoken-rs, hf-hub, dirs, cliclack to reduce duplicate deps
jh-block Mar 4, 2026
d20ec2a
style: cargo fmt
jh-block Mar 4, 2026
6c1dfa1
fix: use distinct names for OpenAPI proxy schemas
jh-block Mar 4, 2026
c707fc9
fix: bind Message.role to Role schema instead of String
jh-block Mar 5, 2026
cafe477
fix: restore OpenAPI discriminator metadata for tagged enums
jh-block Mar 5, 2026
9c635f2
fix: restore binary schema for diagnostics ZIP response
jh-block Mar 5, 2026
6b6faf5
fix: resolve ErrorResponse schema-name collision between tunnel and s…
jh-block Mar 5, 2026
85d53e2
refactor: remove SchemaFixups post-processing modifier
jh-block Mar 5, 2026
940ea78
fix: restore binary schema for diagnostics response to fix TS typecheck
jh-block Mar 5, 2026
d456c23
fix: re-enable PNG codec for goose-mcp image handling
jh-block Mar 5, 2026
ff7b8b2
Merge remote-tracking branch 'origin/main' into jhugo/bump-workspace-…
jh-block Mar 9, 2026
7e213d5
chore: cargo update (105 semver-compatible bumps)
jh-block Mar 9, 2026
78a6ae6
fix: restore all image format codecs for docx add_image
jh-block Mar 9, 2026
e1706c2
chore: use image default features (rayon already in dep tree)
jh-block Mar 9, 2026
604bc66
Merge remote-tracking branch 'origin/main' into jhugo/bump-workspace-…
jh-block Mar 10, 2026
84b045a
chore: remove no-op schema collision test
jh-block Mar 10, 2026
cd458c2
style: cargo fmt
jh-block Mar 10, 2026
9406b8e
Merge remote-tracking branch 'origin/main' into jhugo/bump-workspace-…
jh-block Mar 11, 2026
5080cd9
fix: use distinct schema name for ContentBlock proxy
jh-block Mar 11, 2026
2a41b22
fix: restore OpenAPI discriminators and fix self-referential schemas
Mar 26, 2026
159512f
Merge origin/main into jhugo/bump-workspace-deps
Mar 26, 2026
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
318 changes: 30 additions & 288 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ include_dir = "0.7.4"
indoc = "2.0"
lru = "0.16"
once_cell = "1.20"
rand = "0.8"
rand = "0.10"
regex = "1.12"
reqwest = { version = "0.13", default-features = false, features = ["multipart", "form"] }
schemars = { default-features = false, version = "1.0" }
Expand All @@ -45,7 +45,7 @@ serde_json = "1.0"
serde_yaml = "0.9"
shellexpand = "3.1"
tempfile = "3"
thiserror = "1.0"
thiserror = "2.0"
tokio = { version = "1.49", features = ["full"] }
tokio-stream = "0.1"
tokio-util = "0.7"
Expand All @@ -54,10 +54,11 @@ tracing = "0.1"
tracing-appender = "0.2"
tracing-subscriber = "0.3"
urlencoding = "2.1"
utoipa = "4.1"
utoipa = "5"
uuid = { version = "1.11", features = ["v4"] }
webbrowser = "1.0"
which = "8.0.0"
zip = { version = "8", default-features = false }
wiremock = "0.6"
serial_test = "3.2.0"
test-case = "3.3.1"
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ base64 = { workspace = true }
regex = { workspace = true }
tar = "0.4"
reqwest = { workspace = true, features = ["blocking", "rustls"], default-features = false }
zip = { version = "^8.0", default-features = false, features = ["deflate"] }
zip = { workspace = true, features = ["deflate"] }
bzip2 = "0.5"
# Web server dependencies
axum = { workspace = true, features = ["ws", "macros"] }
Expand Down
4 changes: 2 additions & 2 deletions crates/goose-cli/src/session/thinking.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rand::seq::SliceRandom;
use rand::seq::IndexedRandom;

/// Extended list of playful thinking messages including both goose and general AI actions
const THINKING_MESSAGES: &[&str] = &[
Expand Down Expand Up @@ -215,6 +215,6 @@ const THINKING_MESSAGES: &[&str] = &[
/// Returns a random thinking message from the extended list
pub fn get_random_thinking_message() -> &'static str {
THINKING_MESSAGES
.choose(&mut rand::thread_rng())
.choose(&mut rand::rng())
.unwrap_or(&THINKING_MESSAGES[0])
}
2 changes: 1 addition & 1 deletion crates/goose-mcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ once_cell = { workspace = true }
ignore = { workspace = true }
lopdf = "0.36.0"
docx-rs = "0.4.7"
image = { version = "0.24.9", features = ["jpeg"] }
image = { version = "0.25", default-features = false, features = ["jpeg"] }
Comment thread
jh-block marked this conversation as resolved.
Outdated
umya-spreadsheet = "2.2.3"
which = {workspace = true}
lru = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ tokio-util = { workspace = true }
serde_path_to_error = "0.1.20"
tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] }
url = { workspace = true }
rand = "0.9.2"
rand = { workspace = true }
hex = "0.4.3"
socket2 = "0.6.1"
fs2 = { workspace = true }
Expand Down
25 changes: 13 additions & 12 deletions crates/goose-server/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,26 @@
use crate::routes::reply::MessageEvent;
use utoipa::openapi::schema::{
AdditionalProperties, AnyOfBuilder, ArrayBuilder, ObjectBuilder, OneOfBuilder, Schema,
SchemaFormat, SchemaType,
SchemaFormat, SchemaType, Type,
};
use utoipa::openapi::{AllOfBuilder, Ref, RefOr};

macro_rules! derive_utoipa {
($inner_type:ident as $schema_name:ident) => {
struct $schema_name {}

impl<'__s> ToSchema<'__s> for $schema_name {
fn schema() -> (&'__s str, utoipa::openapi::RefOr<utoipa::openapi::Schema>) {
impl utoipa::PartialSchema for $schema_name {
fn schema() -> utoipa::openapi::RefOr<utoipa::openapi::Schema> {
let settings = rmcp::schemars::generate::SchemaSettings::openapi3();
let generator = settings.into_generator();
let schema = generator.into_root_schema_for::<$inner_type>();
let schema = convert_schemars_to_utoipa(schema);
(stringify!($inner_type), schema)
convert_schemars_to_utoipa(schema)
}
}

fn aliases() -> Vec<(&'__s str, utoipa::openapi::schema::Schema)> {
Vec::new()
impl ToSchema for $schema_name {
fn name() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed(stringify!($inner_type))
}
}
};
Expand Down Expand Up @@ -210,10 +211,10 @@
}
}

RefOr::T(Schema::Array(array_builder.build()))

Check warning on line 214 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs

Check warning on line 214 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs
}
"string" => {
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::String);
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::Type(Type::String));

if let Some(Value::Number(min_length)) = obj.get("minLength") {
if let Some(min) = min_length.as_u64() {
Expand All @@ -232,10 +233,10 @@
object_builder = object_builder.format(Some(SchemaFormat::Custom(format.clone())));
}

RefOr::T(Schema::Object(object_builder.build()))

Check warning on line 236 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs

Check warning on line 236 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs
}
"number" => {
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::Number);
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::Type(Type::Number));

if let Some(Value::Number(minimum)) = obj.get("minimum") {
if let Some(min) = minimum.as_f64() {
Expand Down Expand Up @@ -263,10 +264,10 @@
}
}

RefOr::T(Schema::Object(object_builder.build()))

Check warning on line 267 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs

Check warning on line 267 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs
}
"integer" => {
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::Integer);
let mut object_builder = ObjectBuilder::new().schema_type(SchemaType::Type(Type::Integer));

if let Some(Value::Number(minimum)) = obj.get("minimum") {
if let Some(min) = minimum.as_f64() {
Expand Down Expand Up @@ -298,11 +299,11 @@
}
"boolean" => RefOr::T(Schema::Object(
ObjectBuilder::new()
.schema_type(SchemaType::Boolean)
.schema_type(SchemaType::Type(Type::Boolean))
.build(),

Check warning on line 303 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs

Check warning on line 303 in crates/goose-server/src/openapi.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose-server/src/openapi.rs
)),
"null" => RefOr::T(Schema::Object(
ObjectBuilder::new().schema_type(SchemaType::String).build(),
ObjectBuilder::new().schema_type(SchemaType::Type(Type::String)).build(),
)),
_ => RefOr::T(Schema::Object(ObjectBuilder::new().build())),
}
Expand Down
7 changes: 7 additions & 0 deletions crates/goose-server/src/routes/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ use std::sync::Arc;
use tokio_util::sync::CancellationToken;
use tracing::{error, warn};

fn content_schema() -> utoipa::openapi::schema::Array {
utoipa::openapi::schema::ArrayBuilder::new()
.items(utoipa::openapi::Ref::from_schema_name("Content"))
.build()
}

#[derive(Deserialize, utoipa::ToSchema)]
pub struct UpdateFromSessionRequest {
session_id: String,
Expand Down Expand Up @@ -136,6 +142,7 @@ pub struct CallToolRequest {

#[derive(Serialize, utoipa::ToSchema)]
pub struct CallToolResponse {
#[schema(schema_with = content_schema)]
content: Vec<Content>,
#[serde(skip_serializing_if = "Option::is_none")]
structured_content: Option<Value>,
Expand Down
1 change: 1 addition & 0 deletions crates/goose-server/src/routes/tunnel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::state::AppState;
use crate::tunnel::TunnelInfo;
use axum::{
extract::State,
http::StatusCode,
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-test-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repository.workspace = true
description.workspace = true

[dependencies]
axum = "0.7"
axum = "0.8"
rmcp = { workspace = true, features = ["server", "macros", "transport-streamable-http-server"] }
serde_json.workspace = true
tokio.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/goose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ tokenizers = { version = "0.21.0", default-features = false, features = ["onig"]
hf-hub = { version = "0.4.3", default-features = false, features = ["tokio"] }
symphonia = { version = "0.5", features = ["all"] }
rubato = "0.16"
zip = "0.6"
zip = { workspace = true, features = ["deflate"] }
sys-info = "0.9"

schemars = { workspace = true, features = [
Expand Down
7 changes: 7 additions & 0 deletions crates/goose/src/agents/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ use thiserror::Error;
use tracing::warn;
use utoipa::ToSchema;

fn tool_vec_schema() -> utoipa::openapi::schema::Array {
utoipa::openapi::schema::ArrayBuilder::new()
.items(utoipa::openapi::Ref::from_schema_name("Tool"))
.build()
}

pub use crate::agents::platform_extensions::{
PlatformExtensionContext, PlatformExtensionDef, PLATFORM_EXTENSIONS,
};
Expand Down Expand Up @@ -247,6 +253,7 @@ pub enum ExtensionConfig {
#[schema(required)]
description: String,
/// The tools provided by the frontend
#[schema(schema_with = tool_vec_schema)]
tools: Vec<Tool>,
/// Instructions for how to use these tools
instructions: Option<String>,
Expand Down
5 changes: 3 additions & 2 deletions crates/goose/src/config/signup_openrouter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ mod tests;

use anyhow::{anyhow, Result};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use rand::{distributions::Alphanumeric, Rng};
use rand::distr::Alphanumeric;
use rand::RngExt;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -42,7 +43,7 @@ struct TokenRequest {

impl PkceAuthFlow {
pub fn new() -> Result<Self> {
let code_verifier: String = rand::thread_rng()
let code_verifier: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(128)
.map(char::from)
Expand Down
5 changes: 3 additions & 2 deletions crates/goose/src/config/signup_tetrate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ mod tests;

use anyhow::{anyhow, Result};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use rand::{distributions::Alphanumeric, Rng};
use rand::distr::Alphanumeric;
use rand::RngExt;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -42,7 +43,7 @@ struct TokenRequest {

impl PkceAuthFlow {
pub fn new() -> Result<Self> {
let code_verifier: String = rand::thread_rng()
let code_verifier: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(128)
.map(char::from)
Expand Down
36 changes: 36 additions & 0 deletions crates/goose/src/conversation/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,40 @@ use rmcp::model::{
use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashSet;
use std::fmt;
use utoipa::openapi::RefOr;
use utoipa::ToSchema;
use uuid::Uuid;

fn json_object_schema() -> RefOr<utoipa::openapi::Schema> {
RefOr::Ref(utoipa::openapi::Ref::from_schema_name("JsonObject"))
}

/// Schema-only proxy for rmcp's TextContent (which lacks ToSchema in utoipa 5).
struct TextContentSchemaRef;
impl utoipa::PartialSchema for TextContentSchemaRef {
fn schema() -> RefOr<utoipa::openapi::Schema> {
RefOr::Ref(utoipa::openapi::Ref::from_schema_name("TextContent"))
}
}
impl utoipa::ToSchema for TextContentSchemaRef {
fn name() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed("TextContent")
Comment thread
jh-block marked this conversation as resolved.
Comment thread
jh-block marked this conversation as resolved.
Comment thread
jh-block marked this conversation as resolved.
}
}

/// Schema-only proxy for rmcp's ImageContent (which lacks ToSchema in utoipa 5).
struct ImageContentSchemaRef;
impl utoipa::PartialSchema for ImageContentSchemaRef {
fn schema() -> RefOr<utoipa::openapi::Schema> {
RefOr::Ref(utoipa::openapi::Ref::from_schema_name("ImageContent"))
}
}
impl utoipa::ToSchema for ImageContentSchemaRef {
fn name() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed("ImageContent")
}
}

#[derive(ToSchema)]
pub enum ToolCallResult<T> {
Success { value: T },
Expand Down Expand Up @@ -108,6 +139,7 @@ pub struct ToolResponse {
pub struct ToolConfirmationRequest {
pub id: String,
pub tool_name: String,
#[schema(schema_with = json_object_schema)]
pub arguments: JsonObject,
pub prompt: Option<String>,
}
Expand All @@ -119,6 +151,7 @@ pub enum ActionRequiredData {
ToolConfirmation {
id: String,
tool_name: String,
#[schema(schema_with = json_object_schema)]
arguments: JsonObject,
prompt: Option<String>,
},
Expand Down Expand Up @@ -185,7 +218,9 @@ pub struct ReasoningContent {
/// Content passed inside a message, which can be both simple content and tool content
#[serde(tag = "type", rename_all = "camelCase")]
pub enum MessageContent {
#[schema(value_type = TextContentSchemaRef)]
Text(TextContent),
#[schema(value_type = ImageContentSchemaRef)]
Image(ImageContent),
ToolRequest(ToolRequest),
ToolResponse(ToolResponse),
Expand Down Expand Up @@ -662,6 +697,7 @@ impl MessageMetadata {
#[serde(rename_all = "camelCase")]
pub struct Message {
pub id: Option<String>,
#[schema(value_type = String)]
Comment thread
jh-block marked this conversation as resolved.
Outdated
pub role: Role,
pub created: i64,
#[serde(deserialize_with = "deserialize_sanitized_content")]
Expand Down
6 changes: 3 additions & 3 deletions crates/goose/src/gateway/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ impl PairingStore {
}

pub fn generate_code() -> String {
use rand::Rng;
use rand::RngExt;
let chars: &[u8] = b"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
(0..6)
.map(|_| chars[rng.gen_range(0..chars.len())] as char)
.map(|_| chars[rng.random_range(0..chars.len())] as char)
.collect()
}

Expand Down
4 changes: 2 additions & 2 deletions crates/goose/src/session/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use std::io::Cursor;
use std::io::Write;
use utoipa::ToSchema;
use zip::write::FileOptions;
use zip::write::SimpleFileOptions;
use zip::ZipWriter;

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
Expand Down Expand Up @@ -81,10 +81,10 @@

let system_info = SystemInfo::collect();

let mut buffer = Vec::new();

Check warning on line 84 in crates/goose/src/session/diagnostics.rs

View workflow job for this annotation

GitHub Actions / Check Rust Code Format

Diff in /home/runner/work/goose/goose/crates/goose/src/session/diagnostics.rs
{
let mut zip = ZipWriter::new(Cursor::new(&mut buffer));
let options = FileOptions::default().compression_method(zip::CompressionMethod::Deflated);
let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Deflated);

let mut log_files: Vec<_> = fs::read_dir(&logs_dir)?
.filter_map(|e| e.ok())
Expand Down
Loading
Loading