fix(mesh): make recommended agent model actionable

Preserve user token controls through the shared-compute spawn path and preselect the hardware-ranked Gemma recommendation for first-time sharing.\n\nCo-authored-by: Bartok9 <danielrpike9@gmail.com>\nCo-authored-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Michael Neale
2026-07-29 17:01:39 +10:00
parent f1ee9f8cb1
commit 9b09d1ba26
5 changed files with 130 additions and 26 deletions
@@ -44,13 +44,42 @@ pub fn apply_relay_mesh_env(
);
// Keep the requested response inside smaller local-model context windows,
// and spend that budget on an answer/tool call instead of hidden reasoning.
// Without both settings Qwen3 either fails the router's fit check at the
// agent default (32K) or can consume a tight cap before serializing a tool.
env.insert(
"BUZZ_AGENT_MAX_OUTPUT_TOKENS".to_string(),
"4096".to_string(),
);
env.insert("BUZZ_AGENT_THINKING_EFFORT".to_string(), "none".to_string());
// These are defaults, not policy: the effective agent/persona/global env
// may deliberately choose a smaller cap or enable thinking. This function
// runs after those layers during readiness, so never clobber their values.
insert_default_if_unset(env, "BUZZ_AGENT_MAX_OUTPUT_TOKENS", "4096");
insert_default_if_unset(env, "BUZZ_AGENT_THINKING_EFFORT", "none");
}
#[cfg(feature = "mesh-llm")]
fn insert_default_if_unset(
env: &mut std::collections::BTreeMap<String, String>,
key: &str,
value: &str,
) {
if env.get(key).is_none_or(|current| current.trim().is_empty()) {
env.insert(key.to_string(), value.to_string());
}
}
/// Build the final Mesh-specific process overrides from the already-resolved
/// harness environment. Only user-owned generation controls are seeded: the
/// derived provider/base URL/model values remain authoritative, and unrelated
/// credentials (notably `OPENAI_API_KEY`) must not be copied back after the
/// spawn path removes them.
#[cfg(feature = "mesh-llm")]
pub fn relay_mesh_process_env(
effective_env: &std::collections::BTreeMap<String, String>,
model: &str,
) -> std::collections::BTreeMap<String, String> {
let mut env = std::collections::BTreeMap::new();
for key in ["BUZZ_AGENT_MAX_OUTPUT_TOKENS", "BUZZ_AGENT_THINKING_EFFORT"] {
if let Some(value) = effective_env.get(key) {
env.insert(key.to_string(), value.clone());
}
}
apply_relay_mesh_env(&mut env, Some(RELAY_MESH_PROVIDER_ID), Some(model));
env
}
#[cfg(all(test, feature = "mesh-llm"))]
@@ -82,4 +111,52 @@ mod tests {
Some("1")
);
}
#[test]
fn native_provider_preserves_explicit_generation_controls() {
let mut env = BTreeMap::from([
(
"BUZZ_AGENT_MAX_OUTPUT_TOKENS".to_string(),
"2048".to_string(),
),
("BUZZ_AGENT_THINKING_EFFORT".to_string(), "low".to_string()),
]);
apply_relay_mesh_env(
&mut env,
Some(RELAY_MESH_PROVIDER_ID),
Some(RELAY_MESH_AUTO_MODEL_ID),
);
assert_eq!(
env.get("BUZZ_AGENT_MAX_OUTPUT_TOKENS").map(String::as_str),
Some("2048")
);
assert_eq!(
env.get("BUZZ_AGENT_THINKING_EFFORT").map(String::as_str),
Some("low")
);
}
#[test]
fn process_env_seeds_controls_without_restoring_unrelated_credentials() {
let effective_env = BTreeMap::from([
(
"BUZZ_AGENT_MAX_OUTPUT_TOKENS".to_string(),
"1024".to_string(),
),
("OPENAI_API_KEY".to_string(), "must-not-leak".to_string()),
]);
let env = relay_mesh_process_env(&effective_env, "Gemma-4");
assert_eq!(
env.get("BUZZ_AGENT_MAX_OUTPUT_TOKENS").map(String::as_str),
Some("1024")
);
assert_eq!(
env.get("OPENAI_COMPAT_MODEL").map(String::as_str),
Some("Gemma-4")
);
assert!(!env.contains_key("OPENAI_API_KEY"));
}
}
@@ -869,12 +869,7 @@ pub fn spawn_agent_child(
// uses the same trim semantics as the preflight callers.
#[cfg(feature = "mesh-llm")]
if let Some(ref mesh_model_id) = mesh_model_id {
let mut mesh_env = std::collections::BTreeMap::new();
super::apply_relay_mesh_env(
&mut mesh_env,
Some(super::RELAY_MESH_PROVIDER_ID),
Some(mesh_model_id.as_str()),
);
let mesh_env = super::relay_mesh_process_env(&descriptor.env, mesh_model_id);
command.env_remove("OPENAI_API_KEY");
for (key, value) in mesh_env {
command.env(key, value);
@@ -107,7 +107,9 @@ export function MeshComputeSettingsCard() {
// One-shot hardware-aware catalog fetch. Purely additive: when it fails
// (stub build, survey error) the card falls back to the free-text field.
// Keep an empty draft empty so the UI can explicitly ask the member to choose.
// When there is no saved choice, make the curated recommendation the actual
// default so a new member can turn Share Compute on directly. An explicit
// saved draft always wins.
React.useEffect(() => {
let cancelled = false;
(async () => {
@@ -115,6 +117,11 @@ export function MeshComputeSettingsCard() {
const value = await meshModelCatalog();
if (cancelled) return;
setCatalog(value);
setModelInput((current) => {
if (current.trim() !== "" || !value.recommended) return current;
writeDraft(MODEL_DRAFT_STORAGE_KEY, value.recommended);
return value.recommended;
});
} catch {
// Non-fatal — picker just doesn't render.
}
+21 -6
View File
@@ -2887,9 +2887,7 @@ const mockMeshState: {
servingUsage: MockServingUsage;
} = {
admitted: true,
models: [
{ id: "hf://demo/SmolLM2-135M-Instruct-GGUF:Q4_K_M", name: "SmolLM2 135M" },
],
models: [{ id: "Gemma-4-E4B-it-Q4_K_M", name: "Gemma 4 E4B" }],
denyReason: "not a relay member",
nodeState: "off",
nodeMode: null,
@@ -2898,9 +2896,7 @@ const mockMeshState: {
function resetMockMesh() {
mockMeshState.admitted = true;
mockMeshState.models = [
{ id: "hf://demo/SmolLM2-135M-Instruct-GGUF:Q4_K_M", name: "SmolLM2 135M" },
];
mockMeshState.models = [{ id: "Gemma-4-E4B-it-Q4_K_M", name: "Gemma 4 E4B" }];
mockMeshState.denyReason = "not a relay member";
mockMeshState.nodeState = "off";
mockMeshState.nodeMode = null;
@@ -9736,6 +9732,25 @@ export function maybeInstallE2eTauriMocks() {
}
case "mesh_installed_models":
return mockMeshState.models;
case "mesh_model_catalog":
return {
gpuName: "Mock Apple GPU",
vramDisplay: "32 GB",
vramGb: 32,
recommended: "Gemma-4-E4B-it-Q4_K_M",
entries: [
{
name: "Gemma-4-E4B-it-Q4_K_M",
size: "3.5GB",
sizeGb: 3.5,
description: "Buzz-curated local agent model",
fit: "comfortable",
installed: true,
recommended: true,
curated: true,
},
],
};
case "mesh_node_status":
return meshNodeStatus(mockMeshState.nodeState, mockMeshState.nodeMode);
case "mesh_serving_usage":
+16 -6
View File
@@ -15,7 +15,7 @@ type E2eWindow = Window & {
}) => void;
};
test("Share compute has a clear empty state and starts and stops sharing", async ({
test("Share compute selects the curated default and starts and stops sharing", async ({
page,
}) => {
await installMockBridge(page);
@@ -30,22 +30,32 @@ test("Share compute has a clear empty state and starts and stops sharing", async
await expect(card).toContainText(
"Choose a suggested model below, or enter a model reference or local file",
);
await expect(toggle).toBeDisabled();
await model.fill("hf://demo/SmolLM2-135M-Instruct-GGUF:Q4_K_M");
await expect(model).toHaveValue("Gemma-4-E4B-it-Q4_K_M");
await expect(toggle).toBeEnabled();
await expect(card).toContainText(
"Buzz downloads remote models when sharing starts",
);
await expect(toggle).toBeEnabled();
await toggle.click();
await expect(toggle).toBeChecked();
await expect(card).toContainText("Sharing SmolLM2 135M with relay members");
await expect(card).toContainText("Sharing Gemma 4 E4B with relay members");
await expect
.poll(() =>
page.evaluate(() => (window as E2eWindow).__BUZZ_E2E_COMMANDS__ ?? []),
)
.toContain("mesh_start_node");
await expect
.poll(() =>
page.evaluate(
() => (window as E2eWindow).__BUZZ_E2E_COMMAND_PAYLOADS__ ?? [],
),
)
.toContainEqual({
command: "mesh_start_node",
payload: {
request: { mode: "serve", modelId: "Gemma-4-E4B-it-Q4_K_M" },
},
});
await toggle.click();
await expect(toggle).not.toBeChecked();