Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 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
407 changes: 48 additions & 359 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ base64 = "0.22.1"
bytes = "1"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4", features = ["derive"] }
dirs = "5.0"
dirs = "6.0"
dotenvy = "0.15"
env-lock = "1.0.1"
etcetera = "0.11.0"
Expand All @@ -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
4 changes: 2 additions & 2 deletions crates/goose-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ goose-acp = { path = "../goose-acp", default-features = false }
goose-mcp = { path = "../goose-mcp" }
rmcp = { workspace = true }
clap = { workspace = true }
cliclack = "0.3.5"
cliclack = "0.4.0"
console = "0.16.1"
uuid = { workspace = true }
dotenvy = { workspace = true }
Expand All @@ -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
65 changes: 52 additions & 13 deletions crates/goose-server/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rmcp::model::{
RawEmbeddedResource, RawImageContent, RawResource, RawTextContent, ResourceContents, Role,
TaskSupport, TextContent, Tool, ToolAnnotations, ToolExecution,
};
use utoipa::{OpenApi, ToSchema};
use utoipa::{Modify, OpenApi, ToSchema};

use goose::config::declarative_providers::{
DeclarativeProviderConfig, LoadedProvider, ProviderEngine,
Expand All @@ -30,25 +30,26 @@ use crate::routes::recipe_utils::RecipeManifest;
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 @@ -213,7 +214,8 @@ fn convert_typed_schema(
RefOr::T(Schema::Array(array_builder.build()))
}
"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 @@ -235,7 +237,8 @@ fn convert_typed_schema(
RefOr::T(Schema::Object(object_builder.build()))
}
"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 @@ -266,7 +269,8 @@ fn convert_typed_schema(
RefOr::T(Schema::Object(object_builder.build()))
}
"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 +302,13 @@ fn convert_typed_schema(
}
"boolean" => RefOr::T(Schema::Object(
ObjectBuilder::new()
.schema_type(SchemaType::Boolean)
.schema_type(SchemaType::Type(Type::Boolean))
.build(),
)),
"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 All @@ -327,8 +333,41 @@ derive_utoipa!(ResourceContents as ResourceContentsSchema);
derive_utoipa!(JsonObject as JsonObjectSchema);
derive_utoipa!(Icon as IconSchema);

/// Post-processing modifier that adds OpenAPI discriminators to internally-tagged enums.
///
/// utoipa 5 does not automatically emit `discriminator` for `#[serde(tag = "...")]`
/// internally-tagged enums. This modifier restores the discriminator metadata that
/// clients depend on for deserialization.
struct DiscriminatorAddon;

impl Modify for DiscriminatorAddon {
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
use utoipa::openapi::schema::{Discriminator, Schema};
use utoipa::openapi::RefOr;

let Some(components) = openapi.components.as_mut() else {
return;
};

let discriminators: &[(&str, &str)] = &[
("MessageContent", "type"),
("ExtensionConfig", "type"),
("MessageEvent", "type"),
("ActionRequiredData", "actionType"),
];

for &(schema_name, property_name) in discriminators {
if let Some(RefOr::T(Schema::OneOf(one_of))) = components.schemas.get_mut(schema_name)
{
one_of.discriminator = Some(Discriminator::new(property_name));
}
}
}
}

#[derive(OpenApi)]
#[openapi(
modifiers(&DiscriminatorAddon),
paths(
super::routes::status::status,
super::routes::status::system_info,
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
6 changes: 3 additions & 3 deletions crates/goose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async-trait = { workspace = true }
async-stream = { workspace = true }
minijinja = { version = "2.12.0", features = ["loader"] }
include_dir = { workspace = true }
tiktoken-rs = "0.6.0"
tiktoken-rs = "0.9.1"
chrono = { workspace = true }
clap = { workspace = true }
indoc = { workspace = true }
Expand Down Expand Up @@ -108,10 +108,10 @@ candle-nn = { version = "0.9", default-features = false }
candle-transformers = { version = "0.9", default-features = false }
byteorder = "1.5.0"
tokenizers = { version = "0.21.0", default-features = false, features = ["onig"] }
hf-hub = { version = "0.4.3", default-features = false, features = ["tokio"] }
hf-hub = { version = "0.5.0", 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
Loading