mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
fix(desktop): make agent definition authoritative for model/provider/prompt (#1968)
## Summary
Introduces a single effective-config resolver that makes agent
definitions authoritative for model, provider, system prompt, and
relay-mesh routing on linked instances. Stale materialized record bytes
are never consulted at spawn, deploy, readiness, hash, card summary, or
mesh preflight.
**Resolution semantics (field-specific):**
- **model/provider (linked):** definition → global. `None` = inherit
global default. Record value never consulted.
- **model/provider (definition-less):** instance → global.
- **system_prompt (linked):** strictly from definition; blank = no
prompt. No global tier for prompt.
- **system_prompt (definition-less):** from the instance.
- **relay-mesh preflight (both):** driven by the same
`resolve_effective_config` resolution spawn's mesh env consults. For a
linked instance the record's own `provider`/`model`/`relay_mesh` bytes
are never consulted; for a definition-less instance with no provider of
its own, the legacy marker and env preset are the last fallback (see
below).
- **Orphaned (linked record, definition missing):** spawn, deploy, and
mesh preflight blocked with actionable user-facing error.
**Changes:**
- New `effective_config` resolver module with `ConfigSource` metadata
(`definition`, `global`, `instance_legacy`)
- All consumers routed through the single resolver: local spawn, deploy,
readiness, spawn hash, card summary, relay-mesh preflight (interactive
start and restore-on-launch)
- `apply_persona_snapshot` no longer preserves stale record
model/provider when definition is blank
- Backend `update_managed_agent` blocks model/provider/prompt writes for
linked records
- Frontend omits model/provider/systemPrompt submission for linked
instances; system prompt override hidden
- `model_source` field added to `ManagedAgentSummary` so card labels
distinguish inherited (`Default model (X)`) from explicit
- Spawn hash now digests resolved model/provider (not raw record fields)
so global default changes trip the restart badge even for runtimes
without `model_env_var`
- Orphan spawn/deploy/mesh-preflight blocked with jargon-free error
("This agent's configuration is missing — it may still be syncing or was
deleted on another device")
- `EffectiveAgentConfig::relay_mesh_model_id()` and
`resolve_effective_relay_mesh_model_id()` added; both mesh preflights
(`start_local_agent_with_preflight`, `restore_managed_agents_on_launch`)
call this instead of the deleted
`relay_mesh_config`/`relay_mesh_model_id` record-byte sniffs
- Legacy relay-mesh records keep their mesh routing. Two shipped
generations predate `provider: "relay-mesh"` and are never rewritten on
load: the typed `relay_mesh` marker (added when `ManagedAgentRecord` had
no `provider` field), and before it the mesh preset written directly
into `env_vars`. `resolve_definition_less` falls back to the marker,
then to the env preset, so these records still resolve to mesh instead
of silently misrouting to an unrelated provider while their stale env
bytes reach the child. The fallback is skipped when the record carries
an explicit `provider` — that states current intent, including a switch
away from mesh — and `resolve_linked` has no legacy fallback at all
- The env discriminator accepts both spellings of the two sentinels
renamed in the Jun-11 window without a record migration: the provider
env key (`BUZZ_AGENT_PROVIDER`, previously `SPROUT_AGENT_PROVIDER`) and
the api-key value (`buzz-mesh-local`, previously `sprout-mesh-local`).
Each is independent, since a record can straddle the window; the current
provider-key spelling wins when both are present
- Dead `persona_field_with_record_fallback` and wrapper
`persona_snapshot_with_agent_config_fallback` deleted; callers use
`persona_snapshot` directly
- New resolver/deploy/hash/write-guard/mesh-preflight tests, including
switch-away and global-inheritance regressions for both mesh preflight
call sites, per-class legacy-mesh resolution (typed marker and env
preset, in every rename-window spelling combination), and the paired
assertions that a linked instance's legacy mesh bytes stay inert
---------
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
This commit is contained in:
@@ -80,7 +80,15 @@ const overrides = new Map([
|
||||
// ratcheting 1443 -> 1295. Queued to split further in the A2 fold.
|
||||
// global-agent-config: resolve_deploy_model_provider + visibility exports
|
||||
// add ~40 lines on top of the 1A.1 ratchet. Queued to split.
|
||||
["src-tauri/src/commands/agents.rs", 1340],
|
||||
// +22 (1340 -> 1360): agent-config-resolver — start_local_agent_with_preflight
|
||||
// uses resolve_effective_relay_mesh_model_id at both preflight call sites;
|
||||
// preview_prospective_persona_snapshot helper extracted; orphan guard threaded
|
||||
// through restore path. Load-bearing feature changes; queued to split.
|
||||
// +9 (1360 -> 1369): start_local_agent_pairs_with_preflight — added
|
||||
// personas/global load + resolve_effective_relay_mesh_model_id call to
|
||||
// replace stale record-byte preflight. Same resolver pattern as
|
||||
// start_local_agent_with_preflight. Load-bearing; queued to split.
|
||||
["src-tauri/src/commands/agents.rs", 1369],
|
||||
// agent-lifecycle-fixes: cascade-delete in delete_persona restructured into
|
||||
// 3-phase (stage/stop/commit) + commit_cascade_agents injectable helper for
|
||||
// retry-safety. Load-bearing reviewer-required change; queued to split.
|
||||
@@ -168,7 +176,9 @@ const overrides = new Map([
|
||||
// Windows PATH-correctness fix: 3 #[cfg(windows)] test functions covering
|
||||
// .cmd shim rejection, .bat shim rejection, and .exe acceptance for
|
||||
// configure_runtime_cli (fix #2397). Test-only growth; queued to split.
|
||||
["src-tauri/src/managed_agents/runtime/tests.rs", 1041],
|
||||
// +7 (1041 -> 1048): rebase onto main — this PR's resolver tests land on top
|
||||
// of main's #2397 Windows shim tests. Test-only; queued to split.
|
||||
["src-tauri/src/managed_agents/runtime/tests.rs", 1055],
|
||||
// applyWorkspace reposDir parameter plus the validateReposDir binding,
|
||||
// threaded through Tauri invokes for configurable repos_dir, plus the
|
||||
// harness-persona-sync `harnessOverride` create-input bit — load-bearing
|
||||
@@ -203,7 +213,8 @@ const overrides = new Map([
|
||||
// mapper. This is the existing API boundary; split remains queued.
|
||||
// team-instructions-first-class: createManagedAgent Tauri bridge threads the
|
||||
// new teamId input through to the backend (+1 line).
|
||||
["src/shared/api/tauri.ts", 1305],
|
||||
// +2 for model_source field in RawManagedAgent + fromRawManagedAgent mapping.
|
||||
["src/shared/api/tauri.ts", 1307],
|
||||
// doctor-npm-eacces-preflight: hint field added to InstallStepResult (+1 line).
|
||||
// codex-acp-package-swap: "adapter_outdated" variant added to AcpAvailabilityStatus (+1 line).
|
||||
// doctor-install-reliability: AuthStatus tagged union + nodeRequired/authStatus/
|
||||
@@ -438,7 +449,15 @@ const overrides = new Map([
|
||||
// (if let Some(provider_update) = input.provider { record.provider = provider_update; }).
|
||||
// +8: harness_override thread-through in update_managed_agent so a deliberate
|
||||
// Custom pin routes to update_time_agent_command_override (comment + call).
|
||||
["src-tauri/src/commands/agent_models.rs", 1079],
|
||||
// +22 (1079 -> 1101): Finding 2 — model discovery now resolves through
|
||||
// resolve_effective_model_provider instead of raw record bytes
|
||||
// (saved_agent_model_discovery_config takes personas/global and the
|
||||
// get_agent_models call site loads global config), plus
|
||||
// apply_model_provider_prompt_update's linked-instance write-guard
|
||||
// extraction and its regression tests.
|
||||
// +4 (1101 -> 1105): rebase onto agents-everywhere — agents.rs function
|
||||
// signatures updated for ManagedAgentRuntimeKey-keyed runtimes map.
|
||||
["src-tauri/src/commands/agent_models.rs", 1113],
|
||||
// global-agent-config: get_agent_config_surface / write_agent_config_field /
|
||||
// put_agent_session_config commands + GlobalAgentConfig serde types. New file
|
||||
// in this PR; queued to split with the command module refactor.
|
||||
@@ -454,7 +473,12 @@ const overrides = new Map([
|
||||
// relay from the harness-attached payload relayUrl (with effective-relay
|
||||
// fallback for older harnesses) instead of a required arg the frontend
|
||||
// wrapper never passed, which silently broke the session-config cache.
|
||||
["src-tauri/src/commands/agent_config.rs", 1050],
|
||||
// +60 (1050 -> 1110): agent-config-resolver — resolve_config_surface now
|
||||
// clears a linked instance's own system_prompt/model/provider before
|
||||
// computing had_* so stale materialized snapshot bytes can never be tagged
|
||||
// BuzzExplicit and shadow the definition/global fallthrough; the dead
|
||||
// persona-model re-tag branch replaced; two new regression tests added.
|
||||
["src-tauri/src/commands/agent_config.rs", 1110],
|
||||
// codex-install-auto-restart review-fixes: should_restart_after_install
|
||||
// takes pid_alive:bool (pure predicate, no OS-dependent call); 3 racy
|
||||
// cache tests replaced with 6 pure availability_drift predicate tests;
|
||||
@@ -532,7 +556,9 @@ const overrides = new Map([
|
||||
// for Databricks v1 gate; prospectiveRuntimeId default fallback for builtins.
|
||||
// PR-B moves default/API-key derivation into shared hooks; the explicit
|
||||
// hidden-key projection keeps the top-level secret out of Advanced rows.
|
||||
["src/features/agents/ui/AgentInstanceEditDialog.tsx", 1195],
|
||||
// +6 (1195 -> 1201): rebase onto main — this PR's model-source label wiring
|
||||
// lands on top of main's dialog growth. Queued to split.
|
||||
["src/features/agents/ui/AgentInstanceEditDialog.tsx", 1201],
|
||||
// AgentDefinitionDialog grew past 1000 with the following load-bearing fixes:
|
||||
// isRuntimeAutoSeededRef tracking for edit-mode seeding (Fizz shows models);
|
||||
// runtimeSupportsLlmProviderSelection guard on discovery provider (codex fix);
|
||||
|
||||
Reference in New Issue
Block a user