create the goose-agent crate with the unrolled agent loop state machine (#11216)

Co-authored-by: Alex Hancock <alexhancock@block.xyz>
This commit is contained in:
Jack Amadeo
2026-08-14 13:33:16 +00:00
committed by GitHub
parent 0d0d130d96
commit 5f4b7cc100
20 changed files with 91 additions and 45 deletions
Generated
+22 -7
View File
@@ -4967,6 +4967,7 @@ dependencies = [
"futures",
"gethostname",
"goose-acp-macros",
"goose-agent",
"goose-context-management",
"goose-download-manager",
"goose-mcp",
@@ -5073,6 +5074,20 @@ dependencies = [
"syn 2.0.118",
]
[[package]]
name = "goose-agent"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"async-trait",
"goose-provider-types",
"rmcp 3.0.0",
"serde_json",
"tokio",
"tokio-util",
"uuid",
]
[[package]]
name = "goose-cli"
version = "1.46.0"
@@ -5133,7 +5148,7 @@ dependencies = [
[[package]]
name = "goose-context-management"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"async-trait",
@@ -5149,7 +5164,7 @@ dependencies = [
[[package]]
name = "goose-download-manager"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"once_cell",
@@ -5161,7 +5176,7 @@ dependencies = [
[[package]]
name = "goose-local-inference"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"async-stream",
@@ -5225,7 +5240,7 @@ dependencies = [
[[package]]
name = "goose-provider-types"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"async-stream",
@@ -5254,7 +5269,7 @@ dependencies = [
[[package]]
name = "goose-providers"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"anyhow",
"async-stream",
@@ -5286,7 +5301,7 @@ dependencies = [
[[package]]
name = "goose-sdk"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"agent-client-protocol",
"agent-client-protocol-schema",
@@ -5306,7 +5321,7 @@ dependencies = [
[[package]]
name = "goose-sdk-types"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"agent-client-protocol",
"agent-client-protocol-schema",
+22
View File
@@ -0,0 +1,22 @@
[package]
name = "goose-agent"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
description = "The GDK's Agent Loop"
[lints]
workspace = true
[dependencies]
anyhow = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync", "time", "fs", "process", "net", "signal", "io-std", "io-util"] }
tokio-util = { workspace = true, features = ["compat"] }
async-trait = { workspace = true }
goose-provider-types = { version = "0.1.0-alpha.6", path = "../goose-provider-types", default-features = false }
rmcp = { workspace = true }
uuid = { workspace = true }
serde_json = { workspace = true }
@@ -1,12 +1,14 @@
use goose_provider_types::conversation::{
message::{Message, MessageUsage},
token_usage::ProviderUsage,
Conversation,
};
use rmcp::model::ServerNotification;
use crate::conversation::message::{Message, MessageUsage};
use crate::conversation::Conversation;
#[derive(Clone, Debug)]
pub enum AgentEvent {
Message(Message),
Usage(crate::providers::base::ProviderUsage),
Usage(ProviderUsage),
MessageUsage {
message_id: Option<String>,
usage: MessageUsage,
+3
View File
@@ -0,0 +1,3 @@
pub mod events;
pub mod machine;
pub mod operation;
@@ -4,11 +4,11 @@ use anyhow::{anyhow, Result};
use async_trait::async_trait;
use tokio_util::sync::CancellationToken;
use crate::agents::state_machine::operation::{
use crate::operation::{
ConversationEffect, Emitter, Inference, InferenceInput, MachineEffect, Operation,
OperationFuture, OperationResult, StepResult,
};
use crate::conversation::Conversation;
use goose_provider_types::conversation::Conversation;
pub trait MachineSession: Send + Sync {
fn id(&self) -> &str;
@@ -26,7 +26,7 @@ pub trait EffectHandler<S, E>: Send + Sync {
}
pub trait EffectUsage<E>: Send + Sync {
fn usage(&self, _effect: &E) -> Option<goose_providers::conversation::token_usage::Usage> {
fn usage(&self, _effect: &E) -> Option<goose_provider_types::conversation::token_usage::Usage> {
None
}
}
@@ -5,9 +5,9 @@ use std::pin::Pin;
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;
use crate::agents::AgentEvent;
use crate::conversation::message::{Message, MessageContent, MessageErrorKind};
use crate::conversation::{effective_role, Conversation, EffectiveRole};
use crate::events::AgentEvent;
use goose_provider_types::conversation::message::{Message, MessageContent, MessageErrorKind};
use goose_provider_types::conversation::{effective_role, Conversation, EffectiveRole};
use rmcp::model::Tool;
pub type OperationFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-context-management"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
@@ -12,7 +12,7 @@ description = "Conversation compaction for Goose"
workspace = true
[dependencies]
goose-providers = { version = "0.1.0-alpha.5", path = "../goose-providers", features = ["rustls-tls"] }
goose-providers = { version = "0.1.0-alpha.6", path = "../goose-providers", features = ["rustls-tls"] }
anyhow = { workspace = true }
async-trait = { workspace = true }
include_dir = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-download-manager"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-local-inference"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
@@ -27,9 +27,9 @@ etcetera = { workspace = true }
encoding_rs = { version = "0.8.35", default-features = false }
fs2 = { workspace = true }
futures = { workspace = true }
goose-download-manager = { version = "0.1.0-alpha.5", path = "../goose-download-manager" }
goose-provider-types = { version = "0.1.0-alpha.5", path = "../goose-provider-types", default-features = false }
goose-sdk-types = { version = "0.1.0-alpha.5", path = "../goose-sdk-types", default-features = false }
goose-download-manager = { version = "0.1.0-alpha.6", path = "../goose-download-manager" }
goose-provider-types = { version = "0.1.0-alpha.6", path = "../goose-provider-types", default-features = false }
goose-sdk-types = { version = "0.1.0-alpha.6", path = "../goose-sdk-types", default-features = false }
hf-hub = { version = "1.0.0-rc.1", default-features = false }
include_dir = { workspace = true }
llama-cpp-2 = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-provider-types"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-providers"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
@@ -35,8 +35,8 @@ anyhow = { workspace = true }
async-stream = { workspace = true }
chrono = { workspace = true }
futures = { workspace = true }
goose-provider-types = { version = "0.1.0-alpha.5", path = "../goose-provider-types", default-features = false }
goose-local-inference = { version = "0.1.0-alpha.5", path = "../goose-local-inference", default-features = false, optional = true }
goose-provider-types = { version = "0.1.0-alpha.6", path = "../goose-provider-types", default-features = false }
goose-local-inference = { version = "0.1.0-alpha.6", path = "../goose-local-inference", default-features = false, optional = true }
reqwest = { workspace = true }
rmcp = { workspace = true, features = ["server", "macros"] }
serde = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-sdk-types"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "goose-sdk"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
@@ -33,14 +33,14 @@ uniffi = [
]
[dependencies]
goose-sdk-types = { version = "0.1.0-alpha.5", path = "../goose-sdk-types" }
goose-sdk-types = { version = "0.1.0-alpha.6", path = "../goose-sdk-types" }
agent-client-protocol = { workspace = true, features = ["unstable"] }
agent-client-protocol-schema = { workspace = true }
uniffi = { version = "0.32", features = ["cli"], optional = true }
thiserror = { version = "2", optional = true }
goose-providers = { version = "0.1.0-alpha.5", path = "../goose-providers", features = ["rustls-tls"], optional = true }
goose-context-management = { version = "0.1.0-alpha.5", path = "../goose-context-management", optional = true }
goose-providers = { version = "0.1.0-alpha.6", path = "../goose-providers", features = ["rustls-tls"], optional = true }
goose-context-management = { version = "0.1.0-alpha.6", path = "../goose-context-management", optional = true }
futures = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
tokio = { workspace = true, features = ["rt-multi-thread", "sync"], optional = true }
+6
View File
@@ -104,6 +104,8 @@ crates-publish dry_run="true":
goose-download-manager \
goose-local-inference \
goose-providers \
goose-agent \
goose-context-management \
goose-sdk; do \
cargo publish -p "$crate" $dry_run_flag --allow-dirty; \
done
@@ -130,6 +132,8 @@ bump-version rust_version:
"goose-download-manager",
"goose-local-inference",
"goose-providers",
"goose-agent",
"goose-context-management",
"goose-sdk",
]
crate_paths = {name: Path("crates") / name / "Cargo.toml" for name in crate_names}
@@ -150,6 +154,8 @@ bump-version rust_version:
"goose-download-manager",
"goose-local-inference",
"goose-providers",
"goose-agent",
"goose-context-management",
]
for path in crate_paths.values():
text = path.read_text()
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "goose-sdk"
version = "0.1.0a5"
version = "0.1.0a6"
description = "Python bindings for the Goose SDK"
readme = "README.md"
requires-python = ">=3.9"
+1
View File
@@ -139,6 +139,7 @@ goose-context-management = { path = "../goose-context-management" }
goose-providers = { path = "../goose-providers", default-features = false }
goose-download-manager = { path = "../goose-download-manager" }
goose-sdk-types = { path = "../goose-sdk-types" }
goose-agent = { path = "../goose-agent" }
rand = { workspace = true }
tokio-cron-scheduler = { version = "0.15", default-features = false }
urlencoding = { workspace = true }
+1 -2
View File
@@ -1,6 +1,5 @@
mod agent;
pub mod container;
mod events;
pub mod execute_commands;
pub mod extension;
pub mod extension_malware_check;
@@ -28,10 +27,10 @@ pub mod validate_extensions;
pub use agent::{Agent, AgentConfig, ExtensionLoadResult, GoosePlatform};
pub use container::Container;
pub use events::AgentEvent;
pub use execute_commands::COMPACT_TRIGGERS;
pub use extension::{ExtensionConfig, ExtensionError};
pub use extension_manager::ExtensionManager;
pub use goose_agent::events::AgentEvent;
pub use prompt_manager::PromptManager;
pub use schedule_tool::ScheduleTool;
pub use subagent_handler::SUBAGENT_TOOL_REQUEST_TYPE;
@@ -1,9 +1,9 @@
use crate::agents::state_machine::operation::{ConversationEffect, MachineEffect};
use crate::conversation::message::Message;
use crate::conversation::Conversation;
use crate::providers::base::ProviderUsage;
use crate::recipe::Recipe;
use crate::session::ExtensionData;
use goose_agent::operation::{ConversationEffect, MachineEffect};
pub enum GooseEffect {
Conversation(ConversationEffect),
+4 -4
View File
@@ -6,8 +6,6 @@
//! configuration is part of `Agent::reply`, not the state-machine protocol.
mod effects;
mod machine;
mod operation;
mod ops_bang_shell;
mod ops_compaction;
mod ops_doctor;
@@ -34,8 +32,10 @@ mod usage;
mod tests;
pub use effects::GooseEffect;
pub use machine::{EffectHandler, EffectUsage, MachineSession, SessionLoader, StateMachine, Step};
pub use operation::{
pub use goose_agent::machine::{
EffectHandler, EffectUsage, MachineSession, SessionLoader, StateMachine, Step,
};
pub use goose_agent::operation::{
applied, assistant_turn_count, ends_turn, last_effective_role, messages_since_kickoff,
not_applicable, trailing_error, yielded, yielded_with, ConversationEffect, Emitter, Inference,
InferenceInput, MachineEffect, Operation, OperationResult, SlashCommand, StepResult,
@@ -2,14 +2,12 @@ use anyhow::Result;
use async_trait::async_trait;
use crate::agents::state_machine::effects::GooseEffect;
use crate::agents::state_machine::machine::{
EffectHandler, EffectUsage, MachineSession, SessionLoader,
};
use crate::agents::state_machine::operation::{ConversationEffect, Emitter, MachineEffect};
use crate::agents::state_machine::usage;
use crate::agents::AgentEvent;
use crate::conversation::Conversation;
use crate::session::{Session, SessionManager};
use goose_agent::machine::{EffectHandler, EffectUsage, MachineSession, SessionLoader};
use goose_agent::operation::{ConversationEffect, Emitter, MachineEffect};
impl MachineSession for Session {
fn id(&self) -> &str {