mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
feat(mesh): bump mesh-llm to current main; goose runtime option for mesh preset
- Bump mesh-llm pin ebc3ab4c -> 49cf0342 (113 commits: server-side tool-call emulation for models without native tool support, reasoning format fixes, iroh 1.0 stable, and more) - Adapt to initialize_host_runtime() becoming async upstream - mesh_agent_preset now takes an optional runtimeId: "goose" emits goose's env dialect (GOOSE_PROVIDER=openai, OPENAI_HOST without /v1, GOOSE_MODEL) with no sidecar MCP, so goose — including the bundled goose-acp sidecar — can run inference on the relay mesh. Default and unknown ids preserve the buzz-agent behavior.
This commit is contained in:
Generated
+966
-259
File diff suppressed because it is too large
Load Diff
@@ -77,8 +77,8 @@ metrics-exporter-prometheus = { workspace = true }
|
||||
dev = ["buzz-auth/dev"]
|
||||
|
||||
[dev-dependencies]
|
||||
mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"] }
|
||||
mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"] }
|
||||
mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "49cf03427ad86becf8dc0596b738c055d166e7e2", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"] }
|
||||
mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "49cf03427ad86becf8dc0596b738c055d166e7e2", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"] }
|
||||
buzz-core = { workspace = true, features = ["test-utils"] }
|
||||
buzz-auth = { workspace = true, features = ["dev"] }
|
||||
reqwest = { workspace = true }
|
||||
|
||||
Generated
+801
-162
File diff suppressed because it is too large
Load Diff
@@ -84,8 +84,8 @@ buzz_core_pkg = { package = "buzz-core", path = "../../crates/buzz-core" }
|
||||
buzz_persona_pkg = { package = "buzz-persona", path = "../../crates/buzz-persona" }
|
||||
buzz_sdk_pkg = { package = "buzz-sdk", path = "../../crates/buzz-sdk" }
|
||||
buzz_agent_pkg = { package = "buzz-agent", path = "../../crates/buzz-agent" }
|
||||
mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"], optional = true }
|
||||
mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"], optional = true }
|
||||
mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "49cf03427ad86becf8dc0596b738c055d166e7e2", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"], optional = true }
|
||||
mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "49cf03427ad86becf8dc0596b738c055d166e7e2", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"], optional = true }
|
||||
base64 = "0.22"
|
||||
sha2 = "0.11"
|
||||
tar = "0.4"
|
||||
|
||||
@@ -203,7 +203,7 @@ pub struct DesktopMeshRuntime {
|
||||
model_name: Option<String>,
|
||||
}
|
||||
|
||||
fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
|
||||
async fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
|
||||
let cache = mesh_llm_sdk::native_runtime::native_runtime_cache(None)?;
|
||||
let installed = cache.installed()?;
|
||||
let current = mesh_llm_sdk::native_runtime::CURRENT_MESH_VERSION;
|
||||
@@ -215,17 +215,20 @@ fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
|
||||
"mesh native runtime for MeshLLM {current} is not installed; run `just mesh=1 staging` or `just mesh-e2e-hardware` to prepare it"
|
||||
);
|
||||
}
|
||||
mesh_llm_host_runtime::initialize_host_runtime().map_err(|error| {
|
||||
anyhow::anyhow!(
|
||||
"mesh native runtime failed to load; run `just mesh=1 staging` or `just mesh-e2e-hardware` to repair it: {error}"
|
||||
)
|
||||
})
|
||||
// initialize_host_runtime became async upstream (mesh-llm #900s series).
|
||||
mesh_llm_host_runtime::initialize_host_runtime()
|
||||
.await
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(
|
||||
"mesh native runtime failed to load; run `just mesh=1 staging` or `just mesh-e2e-hardware` to repair it: {error}"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
impl DesktopMeshRuntime {
|
||||
pub async fn start(request: StartMeshNodeRequest) -> anyhow::Result<Self> {
|
||||
validate_no_leak_request(&request)?;
|
||||
initialize_mesh_native_runtime()?;
|
||||
initialize_mesh_native_runtime().await?;
|
||||
let model_id = request
|
||||
.model_id
|
||||
.clone()
|
||||
|
||||
@@ -41,6 +41,7 @@ fn agent_preset_runs_on_buzz_agent_not_goose() {
|
||||
// buzz-agent, which reads those vars.
|
||||
let preset = super::agent_preset(super::MeshAgentPresetRequest {
|
||||
model_id: "Qwen3-8B-Q4_K_M".to_string(),
|
||||
runtime_id: None,
|
||||
})
|
||||
.expect("preset for a valid model id");
|
||||
|
||||
@@ -64,3 +65,42 @@ fn agent_preset_runs_on_buzz_agent_not_goose() {
|
||||
Some("Qwen3-8B-Q4_K_M")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agent_preset_goose_runtime_gets_goose_env_dialect() {
|
||||
// Opting into the goose runtime must emit goose's env dialect
|
||||
// (GOOSE_PROVIDER + OPENAI_HOST without /v1 — goose appends its own
|
||||
// base path), no sidecar MCP (goose has builtin developer tools), and
|
||||
// the goose command from the catalog (matches user-installed goose or
|
||||
// the bundled goose-acp sidecar via discovery).
|
||||
let preset = super::agent_preset(super::MeshAgentPresetRequest {
|
||||
model_id: "Qwen3-8B-Q4_K_M".to_string(),
|
||||
runtime_id: Some("goose".to_string()),
|
||||
})
|
||||
.expect("preset for a valid model id");
|
||||
|
||||
assert_eq!(preset.agent_command, "goose");
|
||||
assert_eq!(preset.mcp_command, "");
|
||||
assert_eq!(
|
||||
preset.env_vars.get("GOOSE_PROVIDER").map(String::as_str),
|
||||
Some("openai")
|
||||
);
|
||||
assert_eq!(
|
||||
preset.env_vars.get("GOOSE_MODEL").map(String::as_str),
|
||||
Some("Qwen3-8B-Q4_K_M")
|
||||
);
|
||||
let host = preset.env_vars.get("OPENAI_HOST").expect("OPENAI_HOST set");
|
||||
assert!(
|
||||
!host.ends_with("/v1"),
|
||||
"goose appends its own base path; host must not end in /v1: {host}"
|
||||
);
|
||||
assert!(preset.env_vars.contains_key("OPENAI_API_KEY"));
|
||||
|
||||
// Unknown runtime ids fall back to the buzz-agent dialect.
|
||||
let fallback = super::agent_preset(super::MeshAgentPresetRequest {
|
||||
model_id: "Qwen3-8B-Q4_K_M".to_string(),
|
||||
runtime_id: Some("something-else".to_string()),
|
||||
})
|
||||
.expect("preset for a valid model id");
|
||||
assert_eq!(fallback.agent_command, "buzz-agent");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,12 @@ use super::{
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MeshAgentPresetRequest {
|
||||
pub model_id: String,
|
||||
/// Runtime the agent should run on. `None` (or unknown ids) preserves the
|
||||
/// historical behavior: buzz-agent. `Some("goose")` emits goose-flavored
|
||||
/// env (`GOOSE_PROVIDER=openai` + `OPENAI_HOST`) so goose — including the
|
||||
/// bundled `goose-acp` sidecar — can use the mesh for inference too.
|
||||
#[serde(default)]
|
||||
pub runtime_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
@@ -33,8 +39,44 @@ pub fn agent_preset(request: MeshAgentPresetRequest) -> Result<MeshAgentPreset,
|
||||
if model.is_empty() {
|
||||
return Err("modelId is required".to_string());
|
||||
}
|
||||
// Run on buzz-agent, not the global default (goose). Source command +
|
||||
// MCP from the catalog so this can't drift from the provider definition.
|
||||
let base_url = relay_mesh_api_base_url()?;
|
||||
|
||||
// Goose reads a different env dialect than buzz-agent: provider selection
|
||||
// via GOOSE_PROVIDER, endpoint via OPENAI_HOST (it appends /v1/... itself).
|
||||
if matches!(request.runtime_id.as_deref(), Some("goose")) {
|
||||
let goose = crate::managed_agents::known_acp_runtime_exact("goose");
|
||||
let agent_command = goose
|
||||
.and_then(|p| p.commands.first().copied())
|
||||
.unwrap_or("goose")
|
||||
.to_string();
|
||||
let host = base_url
|
||||
.strip_suffix("/v1")
|
||||
.unwrap_or(base_url.as_str())
|
||||
.to_string();
|
||||
return Ok(MeshAgentPreset {
|
||||
provider_id: "relay-mesh".to_string(),
|
||||
label: "Relay mesh".to_string(),
|
||||
acp_command: crate::managed_agents::DEFAULT_ACP_COMMAND.to_string(),
|
||||
agent_command,
|
||||
agent_args: Vec::new(),
|
||||
// Goose ships its own developer tools; no sidecar MCP needed.
|
||||
mcp_command: String::new(),
|
||||
model: model.to_string(),
|
||||
env_vars: BTreeMap::from([
|
||||
("GOOSE_PROVIDER".to_string(), "openai".to_string()),
|
||||
("GOOSE_MODEL".to_string(), model.to_string()),
|
||||
("OPENAI_HOST".to_string(), host),
|
||||
(
|
||||
"OPENAI_API_KEY".to_string(),
|
||||
RELAY_MESH_API_KEY_PLACEHOLDER.to_string(),
|
||||
),
|
||||
]),
|
||||
});
|
||||
}
|
||||
|
||||
// Default: buzz-agent (the historical behavior; also the fallback for
|
||||
// unknown runtime ids). Source command + MCP from the catalog so this
|
||||
// can't drift from the provider definition.
|
||||
let buzz_agent = crate::managed_agents::known_acp_runtime_exact(MESH_AGENT_PROVIDER_ID);
|
||||
let agent_command = buzz_agent
|
||||
.and_then(|p| p.commands.first().copied())
|
||||
|
||||
@@ -143,8 +143,9 @@ export async function meshInstalledModels(): Promise<MeshModelOption[]> {
|
||||
|
||||
export async function meshAgentPreset(
|
||||
modelId: string,
|
||||
runtimeId?: string,
|
||||
): Promise<MeshAgentPreset> {
|
||||
return await invokeTauri<MeshAgentPreset>("mesh_agent_preset", {
|
||||
request: { modelId },
|
||||
request: { modelId, runtimeId: runtimeId ?? null },
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user