mirror of
https://github.com/block/goose.git
synced 2026-04-28 03:29:36 +00:00
merge goose-acp crate into goose (#8726)
This commit is contained in:
parent
05af51f18f
commit
38941b1d26
48 changed files with 196 additions and 286 deletions
|
|
@ -47,7 +47,6 @@ git commit -s # required for DCO sign-off
|
||||||
```
|
```
|
||||||
crates/
|
crates/
|
||||||
├── goose # core logic
|
├── goose # core logic
|
||||||
├── goose-acp # Agent Client Protocol
|
|
||||||
├── goose-acp-macros # ACP proc macros
|
├── goose-acp-macros # ACP proc macros
|
||||||
├── goose-cli # CLI entry
|
├── goose-cli # CLI entry
|
||||||
├── goose-server # backend (binary: goosed)
|
├── goose-server # backend (binary: goosed)
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,7 @@ For the full ACP specification, see the [Agent Client Protocol documentation](ht
|
||||||
- API client example: `ui/desktop/src/api/` (generated TypeScript client)
|
- API client example: `ui/desktop/src/api/` (generated TypeScript client)
|
||||||
|
|
||||||
**ACP**:
|
**ACP**:
|
||||||
- ACP server implementation: `crates/goose-acp/src/server.rs`
|
- ACP server implementation: `crates/goose/src/acp/server.rs`
|
||||||
- CLI integration: `crates/goose-cli/src/cli.rs` (Command::Acp)
|
- CLI integration: `crates/goose-cli/src/cli.rs` (Command::Acp)
|
||||||
- Protocol library: `sacp` crate (Rust implementation of ACP)
|
- Protocol library: `sacp` crate (Rust implementation of ACP)
|
||||||
- Test client example: `test_acp_client.py`
|
- Test client example: `test_acp_client.py`
|
||||||
|
|
|
||||||
42
Cargo.lock
generated
42
Cargo.lock
generated
|
|
@ -4358,9 +4358,12 @@ dependencies = [
|
||||||
"fs-err",
|
"fs-err",
|
||||||
"fs2",
|
"fs2",
|
||||||
"futures",
|
"futures",
|
||||||
|
"goose-acp-macros",
|
||||||
|
"goose-mcp",
|
||||||
"goose-sdk",
|
"goose-sdk",
|
||||||
"goose-test-support",
|
"goose-test-support",
|
||||||
"http 1.4.0",
|
"http 1.4.0",
|
||||||
|
"http-body-util",
|
||||||
"ignore",
|
"ignore",
|
||||||
"include_dir",
|
"include_dir",
|
||||||
"indexmap 2.13.0",
|
"indexmap 2.13.0",
|
||||||
|
|
@ -4419,6 +4422,7 @@ dependencies = [
|
||||||
"tokio-cron-scheduler",
|
"tokio-cron-scheduler",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-futures",
|
"tracing-futures",
|
||||||
"tracing-opentelemetry",
|
"tracing-opentelemetry",
|
||||||
|
|
@ -4446,43 +4450,6 @@ dependencies = [
|
||||||
"zip 8.4.0",
|
"zip 8.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "goose-acp"
|
|
||||||
version = "1.31.0"
|
|
||||||
dependencies = [
|
|
||||||
"agent-client-protocol-schema",
|
|
||||||
"anyhow",
|
|
||||||
"async-stream",
|
|
||||||
"async-trait",
|
|
||||||
"axum",
|
|
||||||
"base64 0.22.1",
|
|
||||||
"fs-err",
|
|
||||||
"futures",
|
|
||||||
"goose",
|
|
||||||
"goose-acp-macros",
|
|
||||||
"goose-mcp",
|
|
||||||
"goose-sdk",
|
|
||||||
"goose-test-support",
|
|
||||||
"http-body-util",
|
|
||||||
"regex",
|
|
||||||
"rmcp",
|
|
||||||
"sacp",
|
|
||||||
"schemars 1.2.1",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sqlx",
|
|
||||||
"strum 0.27.2",
|
|
||||||
"tempfile",
|
|
||||||
"test-case",
|
|
||||||
"tokio",
|
|
||||||
"tokio-util",
|
|
||||||
"tower-http",
|
|
||||||
"tracing",
|
|
||||||
"url",
|
|
||||||
"uuid",
|
|
||||||
"wiremock",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "goose-acp-macros"
|
name = "goose-acp-macros"
|
||||||
version = "1.31.0"
|
version = "1.31.0"
|
||||||
|
|
@ -4513,7 +4480,6 @@ dependencies = [
|
||||||
"etcetera 0.11.0",
|
"etcetera 0.11.0",
|
||||||
"futures",
|
"futures",
|
||||||
"goose",
|
"goose",
|
||||||
"goose-acp",
|
|
||||||
"goose-mcp",
|
"goose-mcp",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"open",
|
"open",
|
||||||
|
|
|
||||||
6
Justfile
6
Justfile
|
|
@ -205,7 +205,7 @@ check-acp-schema: generate-acp-types
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
echo "🔍 Checking ACP schema and generated types are up-to-date..."
|
echo "🔍 Checking ACP schema and generated types are up-to-date..."
|
||||||
if ! git diff --exit-code crates/goose-acp/acp-schema.json crates/goose-acp/acp-meta.json ui/sdk/src/generated/; then
|
if ! git diff --exit-code crates/goose/acp-schema.json crates/goose/acp-meta.json ui/sdk/src/generated/; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ACP generated files are out of date!"
|
echo "❌ ACP generated files are out of date!"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -217,8 +217,8 @@ check-acp-schema: generate-acp-types
|
||||||
# Generate ACP JSON schema from Rust types
|
# Generate ACP JSON schema from Rust types
|
||||||
generate-acp-schema:
|
generate-acp-schema:
|
||||||
@echo "Generating ACP schema..."
|
@echo "Generating ACP schema..."
|
||||||
cd crates/goose-acp && cargo run --bin generate-acp-schema
|
cd crates/goose && cargo run --bin generate-acp-schema
|
||||||
@echo "ACP schema generated: crates/goose-acp/acp-schema.json, crates/goose-acp/acp-meta.json"
|
@echo "ACP schema generated: crates/goose/acp-schema.json, crates/goose/acp-meta.json"
|
||||||
|
|
||||||
# Generate ACP TypeScript types from JSON schema (requires generate-acp-schema first)
|
# Generate ACP TypeScript types from JSON schema (requires generate-acp-schema first)
|
||||||
generate-acp-types: generate-acp-schema
|
generate-acp-types: generate-acp-schema
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "goose-acp"
|
|
||||||
version.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
rust-version.workspace = true
|
|
||||||
authors.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
description.workspace = true
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "generate-acp-schema"
|
|
||||||
path = "src/bin/generate_acp_schema.rs"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["code-mode", "rustls-tls"]
|
|
||||||
code-mode = ["goose/code-mode"]
|
|
||||||
local-inference = ["goose/local-inference"]
|
|
||||||
rustls-tls = ["goose/rustls-tls", "goose-mcp/rustls-tls"]
|
|
||||||
native-tls = ["goose/native-tls", "goose-mcp/native-tls"]
|
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
goose = { path = "../goose", default-features = false }
|
|
||||||
goose-mcp = { path = "../goose-mcp", default-features = false }
|
|
||||||
rmcp = { workspace = true }
|
|
||||||
sacp = { workspace = true, features = ["unstable"] }
|
|
||||||
agent-client-protocol-schema = { workspace = true }
|
|
||||||
async-trait = { workspace = true }
|
|
||||||
anyhow = { workspace = true }
|
|
||||||
tokio = { workspace = true }
|
|
||||||
tokio-util = { workspace = true, features = ["compat", "rt"] }
|
|
||||||
tracing = { workspace = true }
|
|
||||||
serde_json = { workspace = true }
|
|
||||||
futures = { workspace = true }
|
|
||||||
regex = { workspace = true }
|
|
||||||
fs-err = "3"
|
|
||||||
strum = { workspace = true }
|
|
||||||
url = { workspace = true }
|
|
||||||
|
|
||||||
# HTTP server dependencies
|
|
||||||
axum = { workspace = true, features = ["ws"] }
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
|
||||||
tower-http = { workspace = true, features = ["cors"] }
|
|
||||||
async-stream = { workspace = true }
|
|
||||||
http-body-util = "0.1.3"
|
|
||||||
uuid = { workspace = true, features = ["v7"] }
|
|
||||||
schemars = { workspace = true, features = ["derive"] }
|
|
||||||
goose-acp-macros = { path = "../goose-acp-macros" }
|
|
||||||
goose-sdk = { path = "../goose-sdk" }
|
|
||||||
base64 = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
async-trait = { workspace = true }
|
|
||||||
goose-test-support = { path = "../goose-test-support" }
|
|
||||||
wiremock = { workspace = true }
|
|
||||||
tempfile = { workspace = true }
|
|
||||||
test-case = { workspace = true }
|
|
||||||
axum = { workspace = true }
|
|
||||||
rmcp = { workspace = true, features = ["transport-streamable-http-server"] }
|
|
||||||
sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio-rustls", "sqlite"] }
|
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
|
||||||
# Used to provide extras imports for sacp
|
|
||||||
ignored = ["agent-client-protocol-schema"]
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#![recursion_limit = "256"]
|
|
||||||
|
|
||||||
mod adapters;
|
|
||||||
pub use goose_sdk::custom_requests;
|
|
||||||
mod fs;
|
|
||||||
pub mod server;
|
|
||||||
pub mod server_factory;
|
|
||||||
pub(crate) mod tools;
|
|
||||||
pub mod transport;
|
|
||||||
|
|
@ -22,7 +22,6 @@ path = "src/bin/generate_manpages.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap_mangen = "0.2.31"
|
clap_mangen = "0.2.31"
|
||||||
goose = { path = "../goose", default-features = false }
|
goose = { path = "../goose", default-features = false }
|
||||||
goose-acp = { path = "../goose-acp", default-features = false }
|
|
||||||
goose-mcp = { path = "../goose-mcp" }
|
goose-mcp = { path = "../goose-mcp" }
|
||||||
rmcp = { workspace = true }
|
rmcp = { workspace = true }
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
|
@ -71,8 +70,8 @@ winapi = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
|
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
|
||||||
code-mode = ["goose/code-mode", "goose-acp/code-mode"]
|
code-mode = ["goose/code-mode"]
|
||||||
local-inference = ["goose/local-inference", "goose-acp/local-inference"]
|
local-inference = ["goose/local-inference"]
|
||||||
aws-providers = ["goose/aws-providers"]
|
aws-providers = ["goose/aws-providers"]
|
||||||
cuda = ["goose/cuda", "local-inference"]
|
cuda = ["goose/cuda", "local-inference"]
|
||||||
telemetry = ["goose/telemetry"]
|
telemetry = ["goose/telemetry"]
|
||||||
|
|
|
||||||
|
|
@ -1064,8 +1064,9 @@ async fn handle_mcp_command(server: McpCommand) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_serve_command(host: String, port: u16, builtins: Vec<String>) -> Result<()> {
|
async fn handle_serve_command(host: String, port: u16, builtins: Vec<String>) -> Result<()> {
|
||||||
|
use goose::acp::server_factory::{AcpServer, AcpServerFactoryConfig};
|
||||||
|
use goose::acp::transport::create_router;
|
||||||
use goose::config::paths::Paths;
|
use goose::config::paths::Paths;
|
||||||
use goose_acp::server_factory::{AcpServer, AcpServerFactoryConfig};
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
@ -1081,7 +1082,7 @@ async fn handle_serve_command(host: String, port: u16, builtins: Vec<String>) ->
|
||||||
data_dir: Paths::data_dir(),
|
data_dir: Paths::data_dir(),
|
||||||
config_dir: Paths::config_dir(),
|
config_dir: Paths::config_dir(),
|
||||||
}));
|
}));
|
||||||
let router = goose_acp::transport::create_router(server);
|
let router = create_router(server);
|
||||||
|
|
||||||
let addr: SocketAddr = format!("{}:{}", host, port).parse()?;
|
let addr: SocketAddr = format!("{}:{}", host, port).parse()?;
|
||||||
info!("Starting ACP server on {}", addr);
|
info!("Starting ACP server on {}", addr);
|
||||||
|
|
@ -1766,7 +1767,7 @@ pub async fn cli() -> anyhow::Result<()> {
|
||||||
Some(Command::Doctor {}) => crate::commands::doctor::handle_doctor().await,
|
Some(Command::Doctor {}) => crate::commands::doctor::handle_doctor().await,
|
||||||
Some(Command::Info { verbose }) => handle_info(verbose),
|
Some(Command::Info { verbose }) => handle_info(verbose),
|
||||||
Some(Command::Mcp { server }) => handle_mcp_command(server).await,
|
Some(Command::Mcp { server }) => handle_mcp_command(server).await,
|
||||||
Some(Command::Acp { builtins }) => goose_acp::server::run(builtins).await,
|
Some(Command::Acp { builtins }) => goose::acp::server::run(builtins).await,
|
||||||
Some(Command::Serve {
|
Some(Command::Serve {
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
serde_urlencoded = "0.7"
|
serde_urlencoded = "0.7"
|
||||||
jsonschema = "0.30.0"
|
jsonschema = "0.30.0"
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true, features = ["v7"] }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
async-stream = { workspace = true }
|
async-stream = { workspace = true }
|
||||||
|
|
@ -96,7 +96,7 @@ nanoid = "0.4"
|
||||||
sha2 = { workspace = true }
|
sha2 = { workspace = true }
|
||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
axum = { workspace = true }
|
axum = { workspace = true, features = ["ws"] }
|
||||||
webbrowser = { workspace = true }
|
webbrowser = { workspace = true }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
@ -190,6 +190,9 @@ pem = { version = "3", optional = true }
|
||||||
pkcs1 = { version = "0.7", default-features = false, features = ["pkcs8"], optional = true }
|
pkcs1 = { version = "0.7", default-features = false, features = ["pkcs8"], optional = true }
|
||||||
pkcs8 = { version = "0.10", default-features = false, features = ["alloc"], optional = true }
|
pkcs8 = { version = "0.10", default-features = false, features = ["alloc"], optional = true }
|
||||||
sec1 = { version = "0.7", default-features = false, features = ["der", "pkcs8"], optional = true }
|
sec1 = { version = "0.7", default-features = false, features = ["der", "pkcs8"], optional = true }
|
||||||
|
goose-acp-macros = { version = "1.31.0", path = "../goose-acp-macros" }
|
||||||
|
tower-http = { workspace = true, features = ["cors"] }
|
||||||
|
http-body-util = "0.1.3"
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
|
@ -222,6 +225,7 @@ opentelemetry_sdk = { workspace = true, features = ["testing"] }
|
||||||
goose-test-support = { path = "../goose-test-support" }
|
goose-test-support = { path = "../goose-test-support" }
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
http.workspace = true
|
http.workspace = true
|
||||||
|
goose-mcp = { path = "../goose-mcp" }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "agent"
|
name = "agent"
|
||||||
|
|
@ -244,6 +248,10 @@ path = "src/bin/analyze_cli.rs"
|
||||||
name = "build_canonical_models"
|
name = "build_canonical_models"
|
||||||
path = "src/providers/canonical/build_canonical_models.rs"
|
path = "src/providers/canonical/build_canonical_models.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "generate-acp-schema"
|
||||||
|
path = "src/bin/generate_acp_schema.rs"
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
|
|
||||||
ignored = [
|
ignored = [
|
||||||
|
|
@ -251,4 +259,6 @@ ignored = [
|
||||||
"winapi",
|
"winapi",
|
||||||
# Used to provide extras imports for sacp
|
# Used to provide extras imports for sacp
|
||||||
"agent-client-protocol-schema",
|
"agent-client-protocol-schema",
|
||||||
|
# Used via http transport
|
||||||
|
"http-body-util",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::tools::AcpAwareToolMeta;
|
use crate::acp::tools::AcpAwareToolMeta;
|
||||||
|
use crate::agents::mcp_client::{Error as McpError, McpClientTrait};
|
||||||
|
use crate::agents::platform_extensions::developer::edit::{
|
||||||
|
resolve_path, string_replace, FileEditParams, FileReadParams, FileWriteParams,
|
||||||
|
};
|
||||||
|
use crate::agents::platform_extensions::developer::shell::{ShellParams, OUTPUT_LIMIT_BYTES};
|
||||||
|
use crate::agents::platform_extensions::developer::DeveloperClient;
|
||||||
use agent_client_protocol_schema::TerminalId;
|
use agent_client_protocol_schema::TerminalId;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
use goose::agents::mcp_client::{Error as McpError, McpClientTrait};
|
|
||||||
use goose::agents::platform_extensions::developer::edit::{
|
|
||||||
resolve_path, string_replace, FileEditParams, FileReadParams, FileWriteParams,
|
|
||||||
};
|
|
||||||
use goose::agents::platform_extensions::developer::shell::{ShellParams, OUTPUT_LIMIT_BYTES};
|
|
||||||
use goose::agents::platform_extensions::developer::DeveloperClient;
|
|
||||||
use rmcp::model::{CallToolResult, Content as RmcpContent, Tool, ToolAnnotations};
|
use rmcp::model::{CallToolResult, Content as RmcpContent, Tool, ToolAnnotations};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
CreateTerminalRequest, Diff, KillTerminalRequest, ReadTextFileRequest, ReleaseTerminalRequest,
|
CreateTerminalRequest, Diff, KillTerminalRequest, ReadTextFileRequest, ReleaseTerminalRequest,
|
||||||
|
|
@ -93,7 +93,7 @@ fn read_tool() -> Tool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcpTools {
|
impl AcpTools {
|
||||||
fn update_tool_call(&self, ctx: &goose::agents::ToolCallContext, fields: ToolCallUpdateFields) {
|
fn update_tool_call(&self, ctx: &crate::agents::ToolCallContext, fields: ToolCallUpdateFields) {
|
||||||
if let Some(ref req_id) = ctx.tool_call_request_id {
|
if let Some(ref req_id) = ctx.tool_call_request_id {
|
||||||
let _ = self
|
let _ = self
|
||||||
.cx
|
.cx
|
||||||
|
|
@ -125,7 +125,7 @@ impl AcpTools {
|
||||||
async fn acp_read(
|
async fn acp_read(
|
||||||
&self,
|
&self,
|
||||||
arguments: Option<rmcp::model::JsonObject>,
|
arguments: Option<rmcp::model::JsonObject>,
|
||||||
ctx: &goose::agents::ToolCallContext,
|
ctx: &crate::agents::ToolCallContext,
|
||||||
) -> Result<CallToolResult, McpError> {
|
) -> Result<CallToolResult, McpError> {
|
||||||
let params: FileReadParams = match Self::parse_args(arguments) {
|
let params: FileReadParams = match Self::parse_args(arguments) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
|
@ -150,7 +150,7 @@ impl AcpTools {
|
||||||
async fn acp_write(
|
async fn acp_write(
|
||||||
&self,
|
&self,
|
||||||
arguments: Option<rmcp::model::JsonObject>,
|
arguments: Option<rmcp::model::JsonObject>,
|
||||||
ctx: &goose::agents::ToolCallContext,
|
ctx: &crate::agents::ToolCallContext,
|
||||||
) -> Result<CallToolResult, McpError> {
|
) -> Result<CallToolResult, McpError> {
|
||||||
let params: FileWriteParams = match Self::parse_args(arguments) {
|
let params: FileWriteParams = match Self::parse_args(arguments) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
|
@ -187,7 +187,7 @@ impl AcpTools {
|
||||||
async fn acp_edit(
|
async fn acp_edit(
|
||||||
&self,
|
&self,
|
||||||
arguments: Option<rmcp::model::JsonObject>,
|
arguments: Option<rmcp::model::JsonObject>,
|
||||||
ctx: &goose::agents::ToolCallContext,
|
ctx: &crate::agents::ToolCallContext,
|
||||||
) -> Result<CallToolResult, McpError> {
|
) -> Result<CallToolResult, McpError> {
|
||||||
let params: FileEditParams = match Self::parse_args(arguments) {
|
let params: FileEditParams = match Self::parse_args(arguments) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
|
@ -240,7 +240,7 @@ impl AcpTools {
|
||||||
async fn acp_shell(
|
async fn acp_shell(
|
||||||
&self,
|
&self,
|
||||||
arguments: Option<rmcp::model::JsonObject>,
|
arguments: Option<rmcp::model::JsonObject>,
|
||||||
ctx: &goose::agents::ToolCallContext,
|
ctx: &crate::agents::ToolCallContext,
|
||||||
) -> Result<CallToolResult, McpError> {
|
) -> Result<CallToolResult, McpError> {
|
||||||
let params: ShellParams = match Self::parse_args(arguments) {
|
let params: ShellParams = match Self::parse_args(arguments) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
|
@ -404,7 +404,7 @@ impl McpClientTrait for AcpTools {
|
||||||
|
|
||||||
async fn call_tool(
|
async fn call_tool(
|
||||||
&self,
|
&self,
|
||||||
ctx: &goose::agents::ToolCallContext,
|
ctx: &crate::agents::ToolCallContext,
|
||||||
name: &str,
|
name: &str,
|
||||||
arguments: Option<rmcp::model::JsonObject>,
|
arguments: Option<rmcp::model::JsonObject>,
|
||||||
cancellation_token: CancellationToken,
|
cancellation_token: CancellationToken,
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
|
mod adapters;
|
||||||
mod common;
|
mod common;
|
||||||
|
pub(crate) mod fs;
|
||||||
mod provider;
|
mod provider;
|
||||||
|
pub mod server;
|
||||||
|
pub mod server_factory;
|
||||||
|
pub(crate) mod tools;
|
||||||
|
pub mod transport;
|
||||||
|
|
||||||
pub use common::{map_permission_response, PermissionDecision};
|
pub use common::{map_permission_response, PermissionDecision};
|
||||||
|
pub use goose_sdk::custom_requests;
|
||||||
pub use provider::{
|
pub use provider::{
|
||||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,36 @@
|
||||||
use crate::custom_requests::*;
|
use crate::acp::custom_requests::*;
|
||||||
use crate::fs::AcpTools;
|
use crate::acp::fs::AcpTools;
|
||||||
use crate::tools::AcpAwareToolMeta;
|
use crate::acp::tools::AcpAwareToolMeta;
|
||||||
use anyhow::Result;
|
use crate::acp::{PermissionDecision, ACP_CURRENT_MODEL};
|
||||||
use fs_err as fs;
|
use crate::agents::extension::{Envs, PLATFORM_EXTENSIONS};
|
||||||
use futures::future::BoxFuture;
|
use crate::agents::mcp_client::McpClientTrait;
|
||||||
use goose::acp::{PermissionDecision, ACP_CURRENT_MODEL};
|
use crate::agents::platform_extensions::developer::DeveloperClient;
|
||||||
use goose::agents::extension::{Envs, PLATFORM_EXTENSIONS};
|
use crate::agents::{Agent, AgentConfig, ExtensionConfig, GoosePlatform, SessionConfig};
|
||||||
use goose::agents::mcp_client::McpClientTrait;
|
use crate::config::base::CONFIG_YAML_NAME;
|
||||||
use goose::agents::platform_extensions::developer::DeveloperClient;
|
use crate::config::extensions::get_enabled_extensions_with_config;
|
||||||
use goose::agents::{Agent, AgentConfig, ExtensionConfig, GoosePlatform, SessionConfig};
|
use crate::config::paths::Paths;
|
||||||
use goose::builtin_extension::register_builtin_extensions;
|
use crate::config::permission::PermissionManager;
|
||||||
use goose::config::base::CONFIG_YAML_NAME;
|
use crate::config::{Config, GooseMode};
|
||||||
use goose::config::extensions::get_enabled_extensions_with_config;
|
use crate::conversation::message::{ActionRequiredData, Message, MessageContent};
|
||||||
use goose::config::paths::Paths;
|
|
||||||
use goose::config::permission::PermissionManager;
|
|
||||||
use goose::config::{Config, GooseMode};
|
|
||||||
use goose::conversation::message::{ActionRequiredData, Message, MessageContent};
|
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
use goose::dictation::providers::transcribe_local;
|
use crate::dictation::providers::transcribe_local;
|
||||||
use goose::dictation::providers::{
|
use crate::dictation::providers::{
|
||||||
all_providers, is_configured, transcribe_with_provider, DictationProvider,
|
all_providers, is_configured, transcribe_with_provider, DictationProvider,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
use goose::dictation::whisper;
|
use crate::dictation::whisper;
|
||||||
use goose::mcp_utils::ToolResult;
|
use crate::mcp_utils::ToolResult;
|
||||||
use goose::permission::permission_confirmation::PrincipalType;
|
use crate::permission::permission_confirmation::PrincipalType;
|
||||||
use goose::permission::{Permission, PermissionConfirmation};
|
use crate::permission::{Permission, PermissionConfirmation};
|
||||||
use goose::providers::base::Provider;
|
use crate::providers::base::Provider;
|
||||||
use goose::providers::inventory::{
|
use crate::providers::inventory::{
|
||||||
ProviderInventoryEntry, ProviderInventoryService, RefreshSkipReason,
|
ProviderInventoryEntry, ProviderInventoryService, RefreshSkipReason,
|
||||||
};
|
};
|
||||||
use goose::session::session_manager::SessionType;
|
use crate::session::session_manager::SessionType;
|
||||||
use goose::session::{EnabledExtensionsState, Session, SessionManager};
|
use crate::session::{EnabledExtensionsState, Session, SessionManager};
|
||||||
|
use anyhow::Result;
|
||||||
|
use fs_err as fs;
|
||||||
|
use futures::future::BoxFuture;
|
||||||
use goose_acp_macros::custom_methods;
|
use goose_acp_macros::custom_methods;
|
||||||
use rmcp::model::{CallToolResult, RawContent, ResourceContents, Role};
|
use rmcp::model::{CallToolResult, RawContent, ResourceContents, Role};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
|
|
@ -69,7 +68,7 @@ use url::Url;
|
||||||
pub type AcpProviderFactory = Arc<
|
pub type AcpProviderFactory = Arc<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
String,
|
String,
|
||||||
goose::model::ModelConfig,
|
crate::model::ModelConfig,
|
||||||
Vec<ExtensionConfig>,
|
Vec<ExtensionConfig>,
|
||||||
) -> BoxFuture<'static, Result<Arc<dyn Provider>>>
|
) -> BoxFuture<'static, Result<Arc<dyn Provider>>>
|
||||||
+ Send
|
+ Send
|
||||||
|
|
@ -106,7 +105,7 @@ const ELEVENLABS_TRANSCRIPTION_MODEL: &str = "scribe_v1";
|
||||||
struct GooseAcpSession {
|
struct GooseAcpSession {
|
||||||
agent: AgentHandle,
|
agent: AgentHandle,
|
||||||
internal_session_id: String,
|
internal_session_id: String,
|
||||||
tool_requests: HashMap<String, goose::conversation::message::ToolRequest>,
|
tool_requests: HashMap<String, crate::conversation::message::ToolRequest>,
|
||||||
cancel_token: Option<CancellationToken>,
|
cancel_token: Option<CancellationToken>,
|
||||||
/// Working directory set while the agent was still loading.
|
/// Working directory set while the agent was still loading.
|
||||||
/// Applied once the agent becomes ready.
|
/// Applied once the agent becomes ready.
|
||||||
|
|
@ -127,7 +126,7 @@ struct AgentSetupRequest {
|
||||||
mcp_servers: Vec<McpServer>,
|
mcp_servers: Vec<McpServer>,
|
||||||
/// Pre-resolved provider name + model config (from config, no network).
|
/// Pre-resolved provider name + model config (from config, no network).
|
||||||
/// When present the spawn skips re-deriving these from config.
|
/// When present the spawn skips re-deriving these from config.
|
||||||
resolved_provider: Option<(String, goose::model::ModelConfig)>,
|
resolved_provider: Option<(String, crate::model::ModelConfig)>,
|
||||||
/// Pre-instantiated provider reused from synchronous session initialization.
|
/// Pre-instantiated provider reused from synchronous session initialization.
|
||||||
prebuilt_provider: Option<Arc<dyn Provider>>,
|
prebuilt_provider: Option<Arc<dyn Provider>>,
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +139,7 @@ pub struct GooseAcpAgent {
|
||||||
client_terminal: OnceCell<bool>,
|
client_terminal: OnceCell<bool>,
|
||||||
config_dir: std::path::PathBuf,
|
config_dir: std::path::PathBuf,
|
||||||
session_manager: Arc<SessionManager>,
|
session_manager: Arc<SessionManager>,
|
||||||
thread_manager: Arc<goose::session::ThreadManager>,
|
thread_manager: Arc<crate::session::ThreadManager>,
|
||||||
permission_manager: Arc<PermissionManager>,
|
permission_manager: Arc<PermissionManager>,
|
||||||
goose_mode: GooseMode,
|
goose_mode: GooseMode,
|
||||||
disable_session_naming: bool,
|
disable_session_naming: bool,
|
||||||
|
|
@ -220,7 +219,7 @@ fn is_developer_file_tool(tool_name: &str) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_locations_from_meta(
|
fn extract_locations_from_meta(
|
||||||
tool_response: &goose::conversation::message::ToolResponse,
|
tool_response: &crate::conversation::message::ToolResponse,
|
||||||
) -> Option<Vec<ToolCallLocation>> {
|
) -> Option<Vec<ToolCallLocation>> {
|
||||||
let result = tool_response.tool_result.as_ref().ok()?;
|
let result = tool_response.tool_result.as_ref().ok()?;
|
||||||
let meta = result.meta.as_ref()?;
|
let meta = result.meta.as_ref()?;
|
||||||
|
|
@ -242,8 +241,8 @@ fn extract_locations_from_meta(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_tool_locations(
|
fn extract_tool_locations(
|
||||||
tool_request: &goose::conversation::message::ToolRequest,
|
tool_request: &crate::conversation::message::ToolRequest,
|
||||||
tool_response: &goose::conversation::message::ToolResponse,
|
tool_response: &crate::conversation::message::ToolResponse,
|
||||||
) -> Vec<ToolCallLocation> {
|
) -> Vec<ToolCallLocation> {
|
||||||
let mut locations = Vec::new();
|
let mut locations = Vec::new();
|
||||||
|
|
||||||
|
|
@ -385,7 +384,7 @@ fn summarize_tool_call(tool_name: &str, arguments: Option<&serde_json::Value>) -
|
||||||
if !s.is_empty() {
|
if !s.is_empty() {
|
||||||
let first_line = s.lines().next().unwrap_or(&s);
|
let first_line = s.lines().next().unwrap_or(&s);
|
||||||
if first_line.len() > 60 {
|
if first_line.len() > 60 {
|
||||||
return Some(format!("{}…", goose::utils::safe_truncate(first_line, 57)));
|
return Some(format!("{}…", crate::utils::safe_truncate(first_line, 57)));
|
||||||
}
|
}
|
||||||
return Some(first_line.to_string());
|
return Some(first_line.to_string());
|
||||||
}
|
}
|
||||||
|
|
@ -458,7 +457,7 @@ fn inventory_entry_to_dto(entry: ProviderInventoryEntry) -> ProviderInventoryEnt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provider_config_key_to_dto(key: goose::providers::base::ConfigKey) -> ProviderConfigKey {
|
fn provider_config_key_to_dto(key: crate::providers::base::ConfigKey) -> ProviderConfigKey {
|
||||||
ProviderConfigKey {
|
ProviderConfigKey {
|
||||||
name: key.name,
|
name: key.name,
|
||||||
required: key.required,
|
required: key.required,
|
||||||
|
|
@ -494,7 +493,7 @@ struct ProviderOptionEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn list_provider_entries(current_provider: Option<&str>) -> Vec<ProviderOptionEntry> {
|
async fn list_provider_entries(current_provider: Option<&str>) -> Vec<ProviderOptionEntry> {
|
||||||
let mut providers = goose::providers::providers()
|
let mut providers = crate::providers::providers()
|
||||||
.await
|
.await
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(metadata, _)| ProviderOptionEntry {
|
.map(|(metadata, _)| ProviderOptionEntry {
|
||||||
|
|
@ -548,7 +547,7 @@ fn session_provider_selection(session: &Session) -> &str {
|
||||||
async fn resolve_provider_and_model_from_config(
|
async fn resolve_provider_and_model_from_config(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
goose_session: &Session,
|
goose_session: &Session,
|
||||||
) -> Result<(String, goose::model::ModelConfig), String> {
|
) -> Result<(String, crate::model::ModelConfig), String> {
|
||||||
let global_provider = config.get_goose_provider().ok();
|
let global_provider = config.get_goose_provider().ok();
|
||||||
let provider_override = goose_session
|
let provider_override = goose_session
|
||||||
.provider_name
|
.provider_name
|
||||||
|
|
@ -563,17 +562,17 @@ async fn resolve_provider_and_model_from_config(
|
||||||
let model_config = match &goose_session.model_config {
|
let model_config = match &goose_session.model_config {
|
||||||
Some(mc) => mc.clone(),
|
Some(mc) => mc.clone(),
|
||||||
None if explicitly_switched => {
|
None if explicitly_switched => {
|
||||||
let entry = goose::providers::get_from_registry(&provider_name)
|
let entry = crate::providers::get_from_registry(&provider_name)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let default_model = &entry.metadata().default_model;
|
let default_model = &entry.metadata().default_model;
|
||||||
goose::model::ModelConfig::new(default_model)
|
crate::model::ModelConfig::new(default_model)
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.with_canonical_limits(&provider_name)
|
.with_canonical_limits(&provider_name)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let model_id = config.get_goose_model().map_err(|e| e.to_string())?;
|
let model_id = config.get_goose_model().map_err(|e| e.to_string())?;
|
||||||
goose::model::ModelConfig::new(&model_id)
|
crate::model::ModelConfig::new(&model_id)
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.with_canonical_limits(&provider_name)
|
.with_canonical_limits(&provider_name)
|
||||||
}
|
}
|
||||||
|
|
@ -586,7 +585,7 @@ async fn resolve_provider_and_model_from_config(
|
||||||
async fn resolve_provider_and_model(
|
async fn resolve_provider_and_model(
|
||||||
config_dir: &std::path::Path,
|
config_dir: &std::path::Path,
|
||||||
goose_session: &Session,
|
goose_session: &Session,
|
||||||
) -> Result<(String, goose::model::ModelConfig), String> {
|
) -> Result<(String, crate::model::ModelConfig), String> {
|
||||||
let config =
|
let config =
|
||||||
Config::new(config_dir.join(CONFIG_YAML_NAME), "goose").map_err(|e| e.to_string())?;
|
Config::new(config_dir.join(CONFIG_YAML_NAME), "goose").map_err(|e| e.to_string())?;
|
||||||
resolve_provider_and_model_from_config(&config, goose_session).await
|
resolve_provider_and_model_from_config(&config, goose_session).await
|
||||||
|
|
@ -704,7 +703,7 @@ impl GooseAcpAgent {
|
||||||
disable_session_naming: bool,
|
disable_session_naming: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let session_manager = Arc::new(SessionManager::new(data_dir));
|
let session_manager = Arc::new(SessionManager::new(data_dir));
|
||||||
let thread_manager = Arc::new(goose::session::ThreadManager::new(
|
let thread_manager = Arc::new(crate::session::ThreadManager::new(
|
||||||
session_manager.storage().clone(),
|
session_manager.storage().clone(),
|
||||||
));
|
));
|
||||||
let permission_manager = Arc::new(PermissionManager::new(config_dir.clone()));
|
let permission_manager = Arc::new(PermissionManager::new(config_dir.clone()));
|
||||||
|
|
@ -733,7 +732,7 @@ impl GooseAcpAgent {
|
||||||
async fn create_provider(
|
async fn create_provider(
|
||||||
&self,
|
&self,
|
||||||
provider_name: &str,
|
provider_name: &str,
|
||||||
model_config: goose::model::ModelConfig,
|
model_config: crate::model::ModelConfig,
|
||||||
extensions: Vec<ExtensionConfig>,
|
extensions: Vec<ExtensionConfig>,
|
||||||
) -> Result<Arc<dyn Provider>> {
|
) -> Result<Arc<dyn Provider>> {
|
||||||
(self.provider_factory)(provider_name.to_string(), model_config, extensions).await
|
(self.provider_factory)(provider_name.to_string(), model_config, extensions).await
|
||||||
|
|
@ -741,7 +740,7 @@ impl GooseAcpAgent {
|
||||||
|
|
||||||
async fn prepare_session_init_config(
|
async fn prepare_session_init_config(
|
||||||
&self,
|
&self,
|
||||||
resolved: &Result<(String, goose::model::ModelConfig), String>,
|
resolved: &Result<(String, crate::model::ModelConfig), String>,
|
||||||
mode_state: &SessionModeState,
|
mode_state: &SessionModeState,
|
||||||
goose_session: &Session,
|
goose_session: &Session,
|
||||||
) -> (
|
) -> (
|
||||||
|
|
@ -1187,7 +1186,7 @@ impl GooseAcpAgent {
|
||||||
|
|
||||||
async fn handle_tool_request(
|
async fn handle_tool_request(
|
||||||
&self,
|
&self,
|
||||||
tool_request: &goose::conversation::message::ToolRequest,
|
tool_request: &crate::conversation::message::ToolRequest,
|
||||||
session_id: &SessionId,
|
session_id: &SessionId,
|
||||||
session: &mut GooseAcpSession,
|
session: &mut GooseAcpSession,
|
||||||
cx: &ConnectionTo<Client>,
|
cx: &ConnectionTo<Client>,
|
||||||
|
|
@ -1235,7 +1234,7 @@ impl GooseAcpAgent {
|
||||||
.map(|a| {
|
.map(|a| {
|
||||||
let s = serde_json::to_string(a).unwrap_or_default();
|
let s = serde_json::to_string(a).unwrap_or_default();
|
||||||
if s.len() > 300 {
|
if s.len() > 300 {
|
||||||
format!("{}…", goose::utils::safe_truncate(&s, 300))
|
format!("{}…", crate::utils::safe_truncate(&s, 300))
|
||||||
} else {
|
} else {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
@ -1316,7 +1315,7 @@ impl GooseAcpAgent {
|
||||||
|
|
||||||
async fn handle_tool_response(
|
async fn handle_tool_response(
|
||||||
&self,
|
&self,
|
||||||
tool_response: &goose::conversation::message::ToolResponse,
|
tool_response: &crate::conversation::message::ToolResponse,
|
||||||
session_id: &SessionId,
|
session_id: &SessionId,
|
||||||
session: &mut GooseAcpSession,
|
session: &mut GooseAcpSession,
|
||||||
cx: &ConnectionTo<Client>,
|
cx: &ConnectionTo<Client>,
|
||||||
|
|
@ -1539,7 +1538,7 @@ impl GooseAcpAgent {
|
||||||
.map(|s| s.to_string());
|
.map(|s| s.to_string());
|
||||||
|
|
||||||
// Create the Thread — this IS the ACP session from the client's perspective.
|
// Create the Thread — this IS the ACP session from the client's perspective.
|
||||||
let thread_metadata = goose::session::ThreadMetadata {
|
let thread_metadata = crate::session::ThreadMetadata {
|
||||||
provider_id: requested_provider.clone(),
|
provider_id: requested_provider.clone(),
|
||||||
mode: Some(self.goose_mode.to_string()),
|
mode: Some(self.goose_mode.to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -1665,7 +1664,7 @@ impl GooseAcpAgent {
|
||||||
builder = builder.provider_name(provider);
|
builder = builder.provider_name(provider);
|
||||||
}
|
}
|
||||||
if let Some(model) = model_name {
|
if let Some(model) = model_name {
|
||||||
if let Ok(mc) = goose::model::ModelConfig::new(model) {
|
if let Ok(mc) = crate::model::ModelConfig::new(model) {
|
||||||
builder = builder.model_config(mc);
|
builder = builder.model_config(mc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1820,7 +1819,7 @@ impl GooseAcpAgent {
|
||||||
// so that handle_tool_response can extract file locations from the
|
// so that handle_tool_response can extract file locations from the
|
||||||
// matching request. No GooseAcpSession required.
|
// matching request. No GooseAcpSession required.
|
||||||
let mut replay_tool_requests =
|
let mut replay_tool_requests =
|
||||||
HashMap::<String, goose::conversation::message::ToolRequest>::new();
|
HashMap::<String, crate::conversation::message::ToolRequest>::new();
|
||||||
|
|
||||||
let t_replay = std::time::Instant::now();
|
let t_replay = std::time::Instant::now();
|
||||||
let mut replay_notifications: u32 = 0;
|
let mut replay_notifications: u32 = 0;
|
||||||
|
|
@ -2090,7 +2089,7 @@ impl GooseAcpAgent {
|
||||||
}
|
}
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Ok(goose::agents::AgentEvent::Message(message)) => {
|
Ok(crate::agents::AgentEvent::Message(message)) => {
|
||||||
self.thread_manager
|
self.thread_manager
|
||||||
.append_message(&thread_id, Some(&internal_session_id), &message)
|
.append_message(&thread_id, Some(&internal_session_id), &message)
|
||||||
.await
|
.await
|
||||||
|
|
@ -2217,7 +2216,7 @@ impl GooseAcpAgent {
|
||||||
let provider_name = current_provider.get_name().to_string();
|
let provider_name = current_provider.get_name().to_string();
|
||||||
let extensions =
|
let extensions =
|
||||||
EnabledExtensionsState::for_session(&self.session_manager, &internal_id, &config).await;
|
EnabledExtensionsState::for_session(&self.session_manager, &internal_id, &config).await;
|
||||||
let model_config = goose::model::ModelConfig::new(model_id)
|
let model_config = crate::model::ModelConfig::new(model_id)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
sacp::Error::invalid_params().data(format!("Invalid model config: {}", e))
|
sacp::Error::invalid_params().data(format!("Invalid model config: {}", e))
|
||||||
})?
|
})?
|
||||||
|
|
@ -2279,7 +2278,7 @@ impl GooseAcpAgent {
|
||||||
async fn update_thread_metadata(
|
async fn update_thread_metadata(
|
||||||
&self,
|
&self,
|
||||||
thread_id: &str,
|
thread_id: &str,
|
||||||
f: impl FnOnce(&mut goose::session::ThreadMetadata),
|
f: impl FnOnce(&mut crate::session::ThreadMetadata),
|
||||||
) -> Result<(), sacp::Error> {
|
) -> Result<(), sacp::Error> {
|
||||||
self.thread_manager
|
self.thread_manager
|
||||||
.update_metadata(thread_id, f)
|
.update_metadata(thread_id, f)
|
||||||
|
|
@ -2418,7 +2417,7 @@ impl GooseAcpAgent {
|
||||||
current_model
|
current_model
|
||||||
};
|
};
|
||||||
let model = model_name.unwrap_or(&default_model);
|
let model = model_name.unwrap_or(&default_model);
|
||||||
let model_config = goose::model::ModelConfig::new(model)
|
let model_config = crate::model::ModelConfig::new(model)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
sacp::Error::invalid_params().data(format!("Invalid model config: {}", e))
|
sacp::Error::invalid_params().data(format!("Invalid model config: {}", e))
|
||||||
})?
|
})?
|
||||||
|
|
@ -2765,8 +2764,8 @@ impl GooseAcpAgent {
|
||||||
|
|
||||||
#[custom_method(GetExtensionsRequest)]
|
#[custom_method(GetExtensionsRequest)]
|
||||||
async fn on_get_extensions(&self) -> Result<GetExtensionsResponse, sacp::Error> {
|
async fn on_get_extensions(&self) -> Result<GetExtensionsResponse, sacp::Error> {
|
||||||
let extensions = goose::config::extensions::get_all_extensions();
|
let extensions = crate::config::extensions::get_all_extensions();
|
||||||
let warnings = goose::config::extensions::get_warnings();
|
let warnings = crate::config::extensions::get_warnings();
|
||||||
let extensions_json = extensions
|
let extensions_json = extensions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| serde_json::to_value(&e))
|
.map(|e| serde_json::to_value(&e))
|
||||||
|
|
@ -2792,7 +2791,7 @@ impl GooseAcpAgent {
|
||||||
|
|
||||||
let extensions = EnabledExtensionsState::extensions_or_default(
|
let extensions = EnabledExtensionsState::extensions_or_default(
|
||||||
Some(&session.extension_data),
|
Some(&session.extension_data),
|
||||||
goose::config::Config::global(),
|
crate::config::Config::global(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let extensions_json = extensions
|
let extensions_json = extensions
|
||||||
|
|
@ -2838,9 +2837,9 @@ impl GooseAcpAgent {
|
||||||
let provider_id = provider_id.clone();
|
let provider_id = provider_id.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let result = async {
|
let result = async {
|
||||||
let metadata = goose::providers::get_from_registry(&provider_id).await?;
|
let metadata = crate::providers::get_from_registry(&provider_id).await?;
|
||||||
let model_config =
|
let model_config =
|
||||||
goose::model::ModelConfig::new(&metadata.metadata().default_model)?
|
crate::model::ModelConfig::new(&metadata.metadata().default_model)?
|
||||||
.with_canonical_limits(&provider_id);
|
.with_canonical_limits(&provider_id);
|
||||||
let provider =
|
let provider =
|
||||||
provider_factory(provider_id.clone(), model_config, Vec::new()).await?;
|
provider_factory(provider_id.clone(), model_config, Vec::new()).await?;
|
||||||
|
|
@ -2894,7 +2893,7 @@ impl GooseAcpAgent {
|
||||||
})?;
|
})?;
|
||||||
let response = match config.get_param::<serde_json::Value>(&req.key) {
|
let response = match config.get_param::<serde_json::Value>(&req.key) {
|
||||||
Ok(value) => ReadConfigResponse { value },
|
Ok(value) => ReadConfigResponse { value },
|
||||||
Err(goose::config::ConfigError::NotFound(_)) => ReadConfigResponse {
|
Err(crate::config::ConfigError::NotFound(_)) => ReadConfigResponse {
|
||||||
value: serde_json::Value::Null,
|
value: serde_json::Value::Null,
|
||||||
},
|
},
|
||||||
Err(e) => return Err(sacp::Error::internal_error().data(e.to_string())),
|
Err(e) => return Err(sacp::Error::internal_error().data(e.to_string())),
|
||||||
|
|
@ -3076,7 +3075,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
req: CreateSourceRequest,
|
req: CreateSourceRequest,
|
||||||
) -> Result<CreateSourceResponse, sacp::Error> {
|
) -> Result<CreateSourceResponse, sacp::Error> {
|
||||||
let source = goose::sources::create_source(
|
let source = crate::sources::create_source(
|
||||||
req.source_type,
|
req.source_type,
|
||||||
&req.name,
|
&req.name,
|
||||||
&req.description,
|
&req.description,
|
||||||
|
|
@ -3092,7 +3091,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
req: ListSourcesRequest,
|
req: ListSourcesRequest,
|
||||||
) -> Result<ListSourcesResponse, sacp::Error> {
|
) -> Result<ListSourcesResponse, sacp::Error> {
|
||||||
let sources = goose::sources::list_sources(req.source_type, req.project_dir.as_deref())?;
|
let sources = crate::sources::list_sources(req.source_type, req.project_dir.as_deref())?;
|
||||||
Ok(ListSourcesResponse { sources })
|
Ok(ListSourcesResponse { sources })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3101,7 +3100,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
req: UpdateSourceRequest,
|
req: UpdateSourceRequest,
|
||||||
) -> Result<UpdateSourceResponse, sacp::Error> {
|
) -> Result<UpdateSourceResponse, sacp::Error> {
|
||||||
let source = goose::sources::update_source(
|
let source = crate::sources::update_source(
|
||||||
req.source_type,
|
req.source_type,
|
||||||
&req.name,
|
&req.name,
|
||||||
&req.description,
|
&req.description,
|
||||||
|
|
@ -3117,7 +3116,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
req: DeleteSourceRequest,
|
req: DeleteSourceRequest,
|
||||||
) -> Result<EmptyResponse, sacp::Error> {
|
) -> Result<EmptyResponse, sacp::Error> {
|
||||||
goose::sources::delete_source(
|
crate::sources::delete_source(
|
||||||
req.source_type,
|
req.source_type,
|
||||||
&req.name,
|
&req.name,
|
||||||
req.global,
|
req.global,
|
||||||
|
|
@ -3131,7 +3130,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
req: ExportSourceRequest,
|
req: ExportSourceRequest,
|
||||||
) -> Result<ExportSourceResponse, sacp::Error> {
|
) -> Result<ExportSourceResponse, sacp::Error> {
|
||||||
let (json, filename) = goose::sources::export_source(
|
let (json, filename) = crate::sources::export_source(
|
||||||
req.source_type,
|
req.source_type,
|
||||||
&req.name,
|
&req.name,
|
||||||
req.global,
|
req.global,
|
||||||
|
|
@ -3146,7 +3145,7 @@ impl GooseAcpAgent {
|
||||||
req: ImportSourcesRequest,
|
req: ImportSourcesRequest,
|
||||||
) -> Result<ImportSourcesResponse, sacp::Error> {
|
) -> Result<ImportSourcesResponse, sacp::Error> {
|
||||||
let sources =
|
let sources =
|
||||||
goose::sources::import_sources(&req.data, req.global, req.project_dir.as_deref())?;
|
crate::sources::import_sources(&req.data, req.global, req.project_dir.as_deref())?;
|
||||||
Ok(ImportSourcesResponse { sources })
|
Ok(ImportSourcesResponse { sources })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3156,7 +3155,7 @@ impl GooseAcpAgent {
|
||||||
req: DictationTranscribeRequest,
|
req: DictationTranscribeRequest,
|
||||||
) -> Result<DictationTranscribeResponse, sacp::Error> {
|
) -> Result<DictationTranscribeResponse, sacp::Error> {
|
||||||
use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
|
use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
|
||||||
let config = goose::config::Config::global();
|
let config = crate::config::Config::global();
|
||||||
|
|
||||||
#[cfg(not(feature = "local-inference"))]
|
#[cfg(not(feature = "local-inference"))]
|
||||||
if req.provider == "local" {
|
if req.provider == "local" {
|
||||||
|
|
@ -3245,7 +3244,7 @@ impl GooseAcpAgent {
|
||||||
&self,
|
&self,
|
||||||
_req: DictationConfigRequest,
|
_req: DictationConfigRequest,
|
||||||
) -> Result<DictationConfigResponse, sacp::Error> {
|
) -> Result<DictationConfigResponse, sacp::Error> {
|
||||||
let config = goose::config::Config::global();
|
let config = crate::config::Config::global();
|
||||||
let mut providers = std::collections::HashMap::new();
|
let mut providers = std::collections::HashMap::new();
|
||||||
|
|
||||||
for def in all_providers() {
|
for def in all_providers() {
|
||||||
|
|
@ -3294,7 +3293,7 @@ impl GooseAcpAgent {
|
||||||
) -> Result<DictationModelsListResponse, sacp::Error> {
|
) -> Result<DictationModelsListResponse, sacp::Error> {
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
{
|
{
|
||||||
use goose::download_manager::{get_download_manager, DownloadStatus};
|
use crate::download_manager::{get_download_manager, DownloadStatus};
|
||||||
|
|
||||||
let manager = get_download_manager();
|
let manager = get_download_manager();
|
||||||
let models = whisper::available_models()
|
let models = whisper::available_models()
|
||||||
|
|
@ -3326,7 +3325,7 @@ impl GooseAcpAgent {
|
||||||
) -> Result<EmptyResponse, sacp::Error> {
|
) -> Result<EmptyResponse, sacp::Error> {
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
{
|
{
|
||||||
use goose::download_manager::get_download_manager;
|
use crate::download_manager::get_download_manager;
|
||||||
|
|
||||||
let model = whisper::get_model(&_req.model_id)
|
let model = whisper::get_model(&_req.model_id)
|
||||||
.ok_or_else(|| sacp::Error::invalid_params().data("Unknown model id"))?;
|
.ok_or_else(|| sacp::Error::invalid_params().data("Unknown model id"))?;
|
||||||
|
|
@ -3339,7 +3338,7 @@ impl GooseAcpAgent {
|
||||||
model.url.to_string(),
|
model.url.to_string(),
|
||||||
model.local_path(),
|
model.local_path(),
|
||||||
Some(Box::new(move || {
|
Some(Box::new(move || {
|
||||||
let config = goose::config::Config::global();
|
let config = crate::config::Config::global();
|
||||||
// Only auto-select this model if the user has no model
|
// Only auto-select this model if the user has no model
|
||||||
// currently selected. This prevents silently switching
|
// currently selected. This prevents silently switching
|
||||||
// the active model mid-session when a user downloads an
|
// the active model mid-session when a user downloads an
|
||||||
|
|
@ -3381,7 +3380,7 @@ impl GooseAcpAgent {
|
||||||
) -> Result<DictationModelDownloadProgressResponse, sacp::Error> {
|
) -> Result<DictationModelDownloadProgressResponse, sacp::Error> {
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
{
|
{
|
||||||
use goose::download_manager::get_download_manager;
|
use crate::download_manager::get_download_manager;
|
||||||
|
|
||||||
let manager = get_download_manager();
|
let manager = get_download_manager();
|
||||||
let progress =
|
let progress =
|
||||||
|
|
@ -3412,7 +3411,7 @@ impl GooseAcpAgent {
|
||||||
) -> Result<EmptyResponse, sacp::Error> {
|
) -> Result<EmptyResponse, sacp::Error> {
|
||||||
#[cfg(feature = "local-inference")]
|
#[cfg(feature = "local-inference")]
|
||||||
{
|
{
|
||||||
use goose::download_manager::get_download_manager;
|
use crate::download_manager::get_download_manager;
|
||||||
|
|
||||||
let manager = get_download_manager();
|
let manager = get_download_manager();
|
||||||
manager
|
manager
|
||||||
|
|
@ -3485,7 +3484,7 @@ impl GooseAcpAgent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
goose::config::Config::global()
|
crate::config::Config::global()
|
||||||
.set_param(key, req.model_id)
|
.set_param(key, req.model_id)
|
||||||
.map_err(|e| sacp::Error::internal_error().data(e.to_string()))?;
|
.map_err(|e| sacp::Error::internal_error().data(e.to_string()))?;
|
||||||
|
|
||||||
|
|
@ -3875,18 +3874,18 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(builtins: Vec<String>) -> Result<()> {
|
pub async fn run(builtins: Vec<String>) -> Result<()> {
|
||||||
register_builtin_extensions(goose_mcp::BUILTIN_EXTENSIONS.clone());
|
|
||||||
info!("listening on stdio");
|
info!("listening on stdio");
|
||||||
|
|
||||||
let outgoing = tokio::io::stdout().compat_write();
|
let outgoing = tokio::io::stdout().compat_write();
|
||||||
let incoming = tokio::io::stdin().compat();
|
let incoming = tokio::io::stdin().compat();
|
||||||
|
|
||||||
let server =
|
let server = crate::acp::server_factory::AcpServer::new(
|
||||||
crate::server_factory::AcpServer::new(crate::server_factory::AcpServerFactoryConfig {
|
crate::acp::server_factory::AcpServerFactoryConfig {
|
||||||
builtins,
|
builtins,
|
||||||
data_dir: Paths::data_dir(),
|
data_dir: Paths::data_dir(),
|
||||||
config_dir: Paths::config_dir(),
|
config_dir: Paths::config_dir(),
|
||||||
});
|
},
|
||||||
|
);
|
||||||
let agent = server.create_agent().await?;
|
let agent = server.create_agent().await?;
|
||||||
serve(agent, incoming, outgoing).await
|
serve(agent, incoming, outgoing).await
|
||||||
}
|
}
|
||||||
|
|
@ -3894,7 +3893,7 @@ pub async fn run(builtins: Vec<String>) -> Result<()> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use goose::conversation::message::{ToolRequest, ToolResponse};
|
use crate::conversation::message::{ToolRequest, ToolResponse};
|
||||||
use rmcp::model::{CallToolRequestParams, Content as RmcpContent};
|
use rmcp::model::{CallToolRequestParams, Content as RmcpContent};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
EnvVariable, HttpHeader, McpServer, McpServerHttp, McpServerSse, McpServerStdio,
|
EnvVariable, HttpHeader, McpServer, McpServerHttp, McpServerSse, McpServerStdio,
|
||||||
|
|
@ -4109,14 +4108,14 @@ print(\"hello, world\")
|
||||||
description: "Mock".to_string(),
|
description: "Mock".to_string(),
|
||||||
default_model: "unused".to_string(),
|
default_model: "unused".to_string(),
|
||||||
configured: true,
|
configured: true,
|
||||||
provider_type: goose::providers::base::ProviderType::Builtin,
|
provider_type: crate::providers::base::ProviderType::Builtin,
|
||||||
config_keys: vec![],
|
config_keys: vec![],
|
||||||
setup_steps: vec![],
|
setup_steps: vec![],
|
||||||
supports_refresh: true,
|
supports_refresh: true,
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
models: models
|
models: models
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|id| goose::providers::inventory::InventoryModel {
|
.map(|id| crate::providers::inventory::InventoryModel {
|
||||||
name: id.clone(),
|
name: id.clone(),
|
||||||
id,
|
id,
|
||||||
family: None,
|
family: None,
|
||||||
|
|
@ -4287,7 +4286,7 @@ print(\"hello, world\")
|
||||||
session_type: SessionType::Acp,
|
session_type: SessionType::Acp,
|
||||||
created_at: Default::default(),
|
created_at: Default::default(),
|
||||||
updated_at: Default::default(),
|
updated_at: Default::default(),
|
||||||
extension_data: goose::session::ExtensionData::default(),
|
extension_data: crate::session::ExtensionData::default(),
|
||||||
total_tokens,
|
total_tokens,
|
||||||
input_tokens,
|
input_tokens,
|
||||||
output_tokens,
|
output_tokens,
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
|
use crate::acp::server::{AcpProviderFactory, GooseAcpAgent};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::server::{AcpProviderFactory, GooseAcpAgent};
|
|
||||||
|
|
||||||
pub struct AcpServerFactoryConfig {
|
pub struct AcpServerFactoryConfig {
|
||||||
pub builtins: Vec<String>,
|
pub builtins: Vec<String>,
|
||||||
pub data_dir: std::path::PathBuf,
|
pub data_dir: std::path::PathBuf,
|
||||||
|
|
@ -23,18 +22,18 @@ impl AcpServer {
|
||||||
let config_path = self
|
let config_path = self
|
||||||
.config
|
.config
|
||||||
.config_dir
|
.config_dir
|
||||||
.join(goose::config::base::CONFIG_YAML_NAME);
|
.join(crate::config::base::CONFIG_YAML_NAME);
|
||||||
let config = goose::config::Config::new(&config_path, "goose")?;
|
let config = crate::config::Config::new(&config_path, "goose")?;
|
||||||
|
|
||||||
let goose_mode = config
|
let goose_mode = config
|
||||||
.get_goose_mode()
|
.get_goose_mode()
|
||||||
.unwrap_or(goose::config::GooseMode::Auto);
|
.unwrap_or(crate::config::GooseMode::Auto);
|
||||||
let disable_session_naming = config.get_goose_disable_session_naming().unwrap_or(false);
|
let disable_session_naming = config.get_goose_disable_session_naming().unwrap_or(false);
|
||||||
|
|
||||||
let provider_factory: AcpProviderFactory =
|
let provider_factory: AcpProviderFactory =
|
||||||
Arc::new(move |provider_name, model_config, extensions| {
|
Arc::new(move |provider_name, model_config, extensions| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
goose::providers::create(&provider_name, model_config, extensions).await
|
crate::providers::create(&provider_name, model_config, extensions).await
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -13,8 +13,8 @@ use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::adapters::{ReceiverToAsyncRead, SenderToAsyncWrite};
|
use crate::acp::adapters::{ReceiverToAsyncRead, SenderToAsyncWrite};
|
||||||
use crate::server_factory::AcpServer;
|
use crate::acp::server_factory::AcpServer;
|
||||||
|
|
||||||
pub(crate) struct HttpState {
|
pub(crate) struct HttpState {
|
||||||
server: Arc<AcpServer>,
|
server: Arc<AcpServer>,
|
||||||
|
|
@ -43,7 +43,8 @@ impl HttpState {
|
||||||
|
|
||||||
let read_stream = ReceiverToAsyncRead::new(to_agent_rx);
|
let read_stream = ReceiverToAsyncRead::new(to_agent_rx);
|
||||||
let write_stream = SenderToAsyncWrite::new(from_agent_tx);
|
let write_stream = SenderToAsyncWrite::new(from_agent_tx);
|
||||||
let fut = crate::server::serve(agent, read_stream.compat(), write_stream.compat_write());
|
let fut =
|
||||||
|
crate::acp::server::serve(agent, read_stream.compat(), write_stream.compat_write());
|
||||||
let handle = tokio::spawn(async move {
|
let handle = tokio::spawn(async move {
|
||||||
if let Err(e) = fut.await {
|
if let Err(e) = fut.await {
|
||||||
error!("ACP session error: {}", e);
|
error!("ACP session error: {}", e);
|
||||||
|
|
@ -18,7 +18,7 @@ use serde_json::Value;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
use tower_http::cors::{Any, CorsLayer};
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
|
|
||||||
use crate::server_factory::AcpServer;
|
use crate::acp::server_factory::AcpServer;
|
||||||
|
|
||||||
pub(crate) const HEADER_SESSION_ID: &str = "Acp-Session-Id";
|
pub(crate) const HEADER_SESSION_ID: &str = "Acp-Session-Id";
|
||||||
pub(crate) const EVENT_STREAM_MIME_TYPE: &str = "text/event-stream";
|
pub(crate) const EVENT_STREAM_MIME_TYPE: &str = "text/event-stream";
|
||||||
|
|
@ -11,8 +11,8 @@ use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
use super::{TransportSession, HEADER_SESSION_ID};
|
use super::{TransportSession, HEADER_SESSION_ID};
|
||||||
use crate::adapters::{ReceiverToAsyncRead, SenderToAsyncWrite};
|
use crate::acp::adapters::{ReceiverToAsyncRead, SenderToAsyncWrite};
|
||||||
use crate::server_factory::AcpServer;
|
use crate::acp::server_factory::AcpServer;
|
||||||
|
|
||||||
pub(crate) struct WsState {
|
pub(crate) struct WsState {
|
||||||
server: Arc<AcpServer>,
|
server: Arc<AcpServer>,
|
||||||
|
|
@ -38,7 +38,8 @@ impl WsState {
|
||||||
|
|
||||||
let read_stream = ReceiverToAsyncRead::new(to_agent_rx);
|
let read_stream = ReceiverToAsyncRead::new(to_agent_rx);
|
||||||
let write_stream = SenderToAsyncWrite::new(from_agent_tx);
|
let write_stream = SenderToAsyncWrite::new(from_agent_tx);
|
||||||
let fut = crate::server::serve(agent, read_stream.compat(), write_stream.compat_write());
|
let fut =
|
||||||
|
crate::acp::server::serve(agent, read_stream.compat(), write_stream.compat_write());
|
||||||
let handle = tokio::spawn(async move {
|
let handle = tokio::spawn(async move {
|
||||||
if let Err(e) = fut.await {
|
if let Err(e) = fut.await {
|
||||||
error!("ACP WebSocket session error: {}", e);
|
error!("ACP WebSocket session error: {}", e);
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use goose_acp::server::GooseAcpAgent;
|
use goose::acp::server::GooseAcpAgent;
|
||||||
use schemars::SchemaGenerator;
|
use schemars::SchemaGenerator;
|
||||||
use serde_json::{json, Map, Value};
|
use serde_json::{json, Map, Value};
|
||||||
use std::collections::{BTreeSet, HashMap};
|
use std::collections::{BTreeSet, HashMap};
|
||||||
|
|
@ -5,6 +5,7 @@ compile_error!("At least one of `rustls-tls` or `native-tls` features must be en
|
||||||
compile_error!("Features `rustls-tls` and `native-tls` are mutually exclusive");
|
compile_error!("Features `rustls-tls` and `native-tls` are mutually exclusive");
|
||||||
|
|
||||||
pub mod acp;
|
pub mod acp;
|
||||||
|
pub use goose_sdk::custom_requests;
|
||||||
pub mod action_required_manager;
|
pub mod action_required_manager;
|
||||||
pub mod agents;
|
pub mod agents;
|
||||||
pub mod builtin_extension;
|
pub mod builtin_extension;
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(unused_attributes)]
|
#![allow(unused_attributes)]
|
||||||
|
|
||||||
#[path = "../fixtures/mod.rs"]
|
#[path = "../acp_fixtures/mod.rs"]
|
||||||
pub mod fixtures;
|
pub mod fixtures;
|
||||||
use fixtures::{
|
use fixtures::{
|
||||||
assert_notifications, Connection, FsFixture, Notification, OpenAiFixture, PermissionDecision,
|
assert_notifications, Connection, FsFixture, Notification, OpenAiFixture, PermissionDecision,
|
||||||
Session, SessionData, TerminalCall, TerminalFixture, TestConnectionConfig,
|
Session, SessionData, TerminalCall, TerminalFixture, TestConnectionConfig,
|
||||||
};
|
};
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
|
use goose::acp::server::AcpProviderFactory;
|
||||||
use goose::config::base::CONFIG_YAML_NAME;
|
use goose::config::base::CONFIG_YAML_NAME;
|
||||||
use goose::config::GooseMode;
|
use goose::config::GooseMode;
|
||||||
use goose_acp::server::AcpProviderFactory;
|
|
||||||
use goose_test_support::{McpFixture, FAKE_CODE, TEST_IMAGE_B64, TEST_MODEL};
|
use goose_test_support::{McpFixture, FAKE_CODE, TEST_IMAGE_B64, TEST_MODEL};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
ListSessionsResponse, McpServer, McpServerHttp, ModelId, SessionInfo, SessionModeId,
|
ListSessionsResponse, McpServer, McpServerHttp, ModelId, SessionInfo, SessionModeId,
|
||||||
|
|
@ -32,7 +32,7 @@ async fn new_basic_session<C: Connection>(config: TestConnectionConfig) -> Basic
|
||||||
let openai = OpenAiFixture::new(
|
let openai = OpenAiFixture::new(
|
||||||
vec![(
|
vec![(
|
||||||
r#"</info-msg>\nwhat is 1+1""#.into(),
|
r#"</info-msg>\nwhat is 1+1""#.into(),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
)],
|
)],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
)
|
)
|
||||||
|
|
@ -147,11 +147,11 @@ pub async fn run_config_mcp<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -198,11 +198,11 @@ pub async fn run_fs_read_text_file_true<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_fs_read_tool_call.txt"),
|
include_str!("../acp_test_data/openai_fs_read_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#""content":"test-read-content-12345""#.into(),
|
r#""content":"test-read-content-12345""#.into(),
|
||||||
include_str!("../test_data/openai_fs_read_tool_result.txt"),
|
include_str!("../acp_test_data/openai_fs_read_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -247,11 +247,11 @@ pub async fn run_fs_write_text_file_false<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_fs_write_tool_call.txt"),
|
include_str!("../acp_test_data/openai_fs_write_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#"Created /tmp/test_acp_write.txt"#.into(),
|
r#"Created /tmp/test_acp_write.txt"#.into(),
|
||||||
include_str!("../test_data/openai_fs_write_tool_result.txt"),
|
include_str!("../acp_test_data/openai_fs_write_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -295,11 +295,11 @@ pub async fn run_fs_write_text_file_true<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_fs_write_tool_call.txt"),
|
include_str!("../acp_test_data/openai_fs_write_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#"Created /tmp/test_acp_write.txt"#.into(),
|
r#"Created /tmp/test_acp_write.txt"#.into(),
|
||||||
include_str!("../test_data/openai_fs_write_tool_result.txt"),
|
include_str!("../acp_test_data/openai_fs_write_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -366,11 +366,11 @@ pub async fn run_load_mode<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -426,7 +426,7 @@ pub async fn run_load_model<C: Connection>() {
|
||||||
let openai = OpenAiFixture::new(
|
let openai = OpenAiFixture::new(
|
||||||
vec![(
|
vec![(
|
||||||
r#""model":"o4-mini""#.into(),
|
r#""model":"o4-mini""#.into(),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
)],
|
)],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
)
|
)
|
||||||
|
|
@ -460,19 +460,19 @@ pub async fn run_load_session_mcp<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -602,11 +602,11 @@ async fn run_mode_set_impl<C: Connection>(via: SetModeVia) {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -779,12 +779,12 @@ async fn run_model_set_impl<C: Connection>(via: SetModelVia) {
|
||||||
// Session B prompt with switched model
|
// Session B prompt with switched model
|
||||||
(
|
(
|
||||||
r#""model":"o4-mini""#.into(),
|
r#""model":"o4-mini""#.into(),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
),
|
),
|
||||||
// Session A prompt with default model
|
// Session A prompt with default model
|
||||||
(
|
(
|
||||||
format!(r#""model":"{TEST_MODEL}""#),
|
format!(r#""model":"{TEST_MODEL}""#),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -919,11 +919,11 @@ pub async fn run_permission_persistence<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.to_string(),
|
prompt.to_string(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -961,7 +961,7 @@ pub async fn run_prompt_basic<C: Connection>() {
|
||||||
let openai = OpenAiFixture::new(
|
let openai = OpenAiFixture::new(
|
||||||
vec![(
|
vec![(
|
||||||
r#"</info-msg>\nwhat is 1+1""#.into(),
|
r#"</info-msg>\nwhat is 1+1""#.into(),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
)],
|
)],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
)
|
)
|
||||||
|
|
@ -989,15 +989,15 @@ pub async fn run_prompt_codemode<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
format!(r#"</info-msg>\n{prompt}""#),
|
format!(r#"</info-msg>\n{prompt}""#),
|
||||||
include_str!("../test_data/openai_builtin_search.txt"),
|
include_str!("../acp_test_data/openai_builtin_search.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#"export async function getCode"#.into(),
|
r#"export async function getCode"#.into(),
|
||||||
include_str!("../test_data/openai_builtin_execute.txt"),
|
include_str!("../acp_test_data/openai_builtin_execute.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#"Created /tmp/result.txt"#.into(),
|
r#"Created /tmp/result.txt"#.into(),
|
||||||
include_str!("../test_data/openai_builtin_final.txt"),
|
include_str!("../acp_test_data/openai_builtin_final.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -1037,11 +1037,11 @@ pub async fn run_prompt_image<C: Connection>() {
|
||||||
(
|
(
|
||||||
r#"</info-msg>\nUse the get_image tool and describe what you see in its result.""#
|
r#"</info-msg>\nUse the get_image tool and describe what you see in its result.""#
|
||||||
.into(),
|
.into(),
|
||||||
include_str!("../test_data/openai_image_tool_call.txt"),
|
include_str!("../acp_test_data/openai_image_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#""type":"image_url""#.into(),
|
r#""type":"image_url""#.into(),
|
||||||
include_str!("../test_data/openai_image_tool_result.txt"),
|
include_str!("../acp_test_data/openai_image_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -1081,7 +1081,7 @@ pub async fn run_prompt_image_attachment<C: Connection>() {
|
||||||
let openai = OpenAiFixture::new(
|
let openai = OpenAiFixture::new(
|
||||||
vec![(
|
vec![(
|
||||||
r#""type":"image_url""#.into(),
|
r#""type":"image_url""#.into(),
|
||||||
include_str!("../test_data/openai_image_attachment.txt"),
|
include_str!("../acp_test_data/openai_image_attachment.txt"),
|
||||||
)],
|
)],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
)
|
)
|
||||||
|
|
@ -1112,11 +1112,11 @@ pub async fn run_prompt_mcp<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
r#"</info-msg>\nUse the get_code tool and output only its result.""#.into(),
|
r#"</info-msg>\nUse the get_code tool and output only its result.""#.into(),
|
||||||
include_str!("../test_data/openai_tool_call.txt"),
|
include_str!("../acp_test_data/openai_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
format!(r#""content":"{FAKE_CODE}""#),
|
format!(r#""content":"{FAKE_CODE}""#),
|
||||||
include_str!("../test_data/openai_tool_result.txt"),
|
include_str!("../acp_test_data/openai_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -1178,7 +1178,7 @@ pub async fn run_prompt_skill<C: Connection>() {
|
||||||
let openai = OpenAiFixture::new(
|
let openai = OpenAiFixture::new(
|
||||||
vec![(
|
vec![(
|
||||||
"skill-loaded-in-acp-session".to_string(),
|
"skill-loaded-in-acp-session".to_string(),
|
||||||
include_str!("../test_data/openai_basic.txt"),
|
include_str!("../acp_test_data/openai_basic.txt"),
|
||||||
)],
|
)],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
)
|
)
|
||||||
|
|
@ -1209,11 +1209,11 @@ pub async fn run_shell_terminal_false<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.clone(),
|
prompt.clone(),
|
||||||
include_str!("../test_data/openai_shell_tool_call.txt"),
|
include_str!("../acp_test_data/openai_shell_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
SHELL_TEST_CONTENT.into(),
|
SHELL_TEST_CONTENT.into(),
|
||||||
include_str!("../test_data/openai_shell_tool_result.txt"),
|
include_str!("../acp_test_data/openai_shell_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -1252,11 +1252,11 @@ pub async fn run_shell_terminal_true<C: Connection>() {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
prompt.clone(),
|
prompt.clone(),
|
||||||
include_str!("../test_data/openai_shell_tool_call.txt"),
|
include_str!("../acp_test_data/openai_shell_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
SHELL_TEST_CONTENT.into(),
|
SHELL_TEST_CONTENT.into(),
|
||||||
include_str!("../test_data/openai_shell_tool_result.txt"),
|
include_str!("../acp_test_data/openai_shell_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
expected_session_id.clone(),
|
expected_session_id.clone(),
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[path = "acp_common_tests/mod.rs"]
|
||||||
mod common_tests;
|
mod common_tests;
|
||||||
|
|
||||||
use common_tests::fixtures::server::AcpServerConnection;
|
use common_tests::fixtures::server::AcpServerConnection;
|
||||||
|
|
@ -6,10 +7,10 @@ use common_tests::fixtures::{
|
||||||
run_test, send_custom, Connection, PermissionDecision, Session, SessionData,
|
run_test, send_custom, Connection, PermissionDecision, Session, SessionData,
|
||||||
TestConnectionConfig,
|
TestConnectionConfig,
|
||||||
};
|
};
|
||||||
|
use goose::acp::server::AcpProviderFactory;
|
||||||
use goose::model::ModelConfig;
|
use goose::model::ModelConfig;
|
||||||
use goose::providers::base::{MessageStream, Provider};
|
use goose::providers::base::{MessageStream, Provider};
|
||||||
use goose::providers::errors::ProviderError;
|
use goose::providers::errors::ProviderError;
|
||||||
use goose_acp::server::AcpProviderFactory;
|
|
||||||
use goose_test_support::{EnforceSessionId, IgnoreSessionId};
|
use goose_test_support::{EnforceSessionId, IgnoreSessionId};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
|
@ -238,11 +239,11 @@ fn test_developer_fs_requests_use_acp_session_id() {
|
||||||
(
|
(
|
||||||
"Use the read tool to read /tmp/test_acp_read.txt and output only its contents."
|
"Use the read tool to read /tmp/test_acp_read.txt and output only its contents."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
include_str!("test_data/openai_fs_read_tool_call.txt"),
|
include_str!("acp_test_data/openai_fs_read_tool_call.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#""content":"test-read-content-12345""#.into(),
|
r#""content":"test-read-content-12345""#.into(),
|
||||||
include_str!("test_data/openai_fs_read_tool_result.txt"),
|
include_str!("acp_test_data/openai_fs_read_tool_result.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
Arc::new(IgnoreSessionId),
|
Arc::new(IgnoreSessionId),
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
|
use goose::acp::server::{serve, AcpProviderFactory, GooseAcpAgent};
|
||||||
pub use goose::acp::{map_permission_response, PermissionDecision};
|
pub use goose::acp::{map_permission_response, PermissionDecision};
|
||||||
use goose::builtin_extension::register_builtin_extensions;
|
use goose::builtin_extension::register_builtin_extensions;
|
||||||
use goose::config::paths::Paths;
|
use goose::config::paths::Paths;
|
||||||
|
|
@ -11,7 +12,6 @@ use goose::providers::api_client::{ApiClient, AuthMethod as ApiAuthMethod};
|
||||||
use goose::providers::base::Provider;
|
use goose::providers::base::Provider;
|
||||||
use goose::providers::openai::OpenAiProvider;
|
use goose::providers::openai::OpenAiProvider;
|
||||||
use goose::session_context::SESSION_ID_HEADER;
|
use goose::session_context::SESSION_ID_HEADER;
|
||||||
use goose_acp::server::{serve, AcpProviderFactory, GooseAcpAgent};
|
|
||||||
use goose_test_support::{ExpectedSessionId, TEST_MODEL};
|
use goose_test_support::{ExpectedSessionId, TEST_MODEL};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
CreateTerminalResponse, KillTerminalResponse, ListSessionsResponse, McpServer,
|
CreateTerminalResponse, KillTerminalResponse, ListSessionsResponse, McpServer,
|
||||||
|
|
@ -52,7 +52,7 @@ impl OpenAiFixture {
|
||||||
.respond_with(
|
.respond_with(
|
||||||
ResponseTemplate::new(200)
|
ResponseTemplate::new(200)
|
||||||
.insert_header("content-type", "application/json")
|
.insert_header("content-type", "application/json")
|
||||||
.set_body_string(include_str!("../test_data/openai_models.json")),
|
.set_body_string(include_str!("../acp_test_data/openai_models.json")),
|
||||||
)
|
)
|
||||||
.mount(&mock_server)
|
.mount(&mock_server)
|
||||||
.await;
|
.await;
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[path = "acp_common_tests/mod.rs"]
|
||||||
mod common_tests;
|
mod common_tests;
|
||||||
use common_tests::fixtures::provider::AcpProviderConnection;
|
use common_tests::fixtures::provider::AcpProviderConnection;
|
||||||
use common_tests::fixtures::run_test;
|
use common_tests::fixtures::run_test;
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[path = "acp_common_tests/mod.rs"]
|
||||||
mod common_tests;
|
mod common_tests;
|
||||||
use common_tests::fixtures::run_test;
|
use common_tests::fixtures::run_test;
|
||||||
use common_tests::fixtures::server::AcpServerConnection;
|
use common_tests::fixtures::server::AcpServerConnection;
|
||||||
|
|
@ -177,7 +177,7 @@ npm install
|
||||||
|
|
||||||
**Option 1: Auto-launch server (recommended)**
|
**Option 1: Auto-launch server (recommended)**
|
||||||
|
|
||||||
The TUI will automatically start the goose-acp-server if you have it installed:
|
The TUI will automatically start the goose acp server if you have it installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm start
|
npm start
|
||||||
|
|
@ -191,7 +191,7 @@ For servers that support the draft standard ACP over Streamable HTTP https://git
|
||||||
npm start -- --server http://HOST:PORT
|
npm start -- --server http://HOST:PORT
|
||||||
|
|
||||||
# example server
|
# example server
|
||||||
cargo run -p goose-acp --bin goose-acp-server
|
cargo run -p goose-cli --bin goose -- serve
|
||||||
```
|
```
|
||||||
|
|
||||||
### Single Prompt Mode
|
### Single Prompt Mode
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ npm link @aaif/goose-sdk
|
||||||
|
|
||||||
### Schema Generation
|
### Schema Generation
|
||||||
|
|
||||||
The TypeScript types are generated from Rust schemas defined in `crates/goose-acp`.
|
The TypeScript types are generated from Rust schemas defined in `crates/goose`.
|
||||||
The build process:
|
The build process:
|
||||||
|
|
||||||
1. Builds the `generate-acp-schema` Rust binary
|
1. Builds the `generate-acp-schema` Rust binary
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ import * as prettier from "prettier";
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
const ROOT = resolve(__dirname, "../..");
|
const ROOT = resolve(__dirname, "../..");
|
||||||
const SCHEMA_PATH = resolve(ROOT, "crates/goose-acp/acp-schema.json");
|
const SCHEMA_PATH = resolve(ROOT, "crates/goose/acp-schema.json");
|
||||||
const META_PATH = resolve(ROOT, "crates/goose-acp/acp-meta.json");
|
const META_PATH = resolve(ROOT, "crates/goose/acp-meta.json");
|
||||||
const OUTPUT_DIR = resolve(__dirname, "src/generated");
|
const OUTPUT_DIR = resolve(__dirname, "src/generated");
|
||||||
|
|
||||||
// Export the main function so it can be imported by build-schema.ts
|
// Export the main function so it can be imported by build-schema.ts
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue