refactor(desktop): converge the three definition→instance mappings (Phase 1B.3.5)#1645
Conversation
The three surfaces that start an agent from a definition (library quick-start, library start-existing, profile start) each built their CreateManagedAgentInput independently and had drifted on five axes. Converge them on one mapping in instanceInputForDefinition.ts: - availableRuntimesForStart: refetch-aware runtime acquisition (profile previously resolved against a possibly-unfetched list and could spuriously refuse). - resolveStartRuntimeForDefinition: refuse with an actionable error when the definition's configured runtime is unavailable, at every surface (profile previously started on a fallback runtime with only a toast). - buildInstanceInputForDefinition: harnessOverride via the backend-aligned formula (create_time_agent_command_override stores None when picked == inherited; harness_override: false keeps the definition authoritative on fallback); avatar through resolveManagedAgentAvatarUrl with an injectable upload fn; definition env vars never seeded into the create input (record.env_vars is overrides-only since #1640 — seeding would manufacture pseudo- overrides that mask definition env edits made before first spawn). Feedback surfaces deliberately stay per-site. B's private getAvailableRuntimesForStart/filterAvailableRuntimes are deleted as dead. 10 unit tests pin the decided rows, including the no-definition- env-ever regression. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Review — APPROVE (via comment; formal approve blocked, same authed account)Reviewed against the six rows and pins locked in-channel. Pins: Helper ( Per-site reads:
envVars independent re-verify (my agreed slot): grepped the branch — Unit tests: 10 tests pin every decided row, including the named regression ( Manual gate (fresh detached checkout of Two non-blocking observations (no change requested):
LGTM — queues at Wes's gate once CI settles. |
What (Phase 1B.3.5 — mapping convergence)
The three surfaces that start an agent from a definition — (A) library quick-start (
usePersonaActions.handleSubmit), (B) library start-existing (useManagedAgentActions.handleStartPersona), (C) profile start (UserProfilePanel.createManagedAgentForPersona) — each builtCreateManagedAgentInputindependently and had drifted. This converges them on one mapping,desktop/src/features/agents/lib/instanceInputForDefinition.ts, per the decision table pressure-tested in-channel:resolveStartRuntimeForDefinitiontrue, B formula, C omittedcreate_time_agent_command_overridestoresNonewhen picked == inherited;harness_override: falsekeeps the definition authoritative on fallback)resolveManagedAgentAvatarUrlwith an injectable upload fn (helper stays unit-testable; plain URLs pass through, base64 data URIs upload)envVars: persona.envVarsinto createrecord.env_varsis overrides-only; a stale seed (definition env edited before first spawn) no longer matches the live value, so the retain() self-heal would classify it as a deliberate override and silently mask the edit — the exact bug class #1640 killed, re-manufactured at createquery.data ?? [](spurious refusal when unfetched)availableRuntimesForStartSubtraction: B's private
getAvailableRuntimesForStart+filterAvailableRuntimesdeleted as dead. Net src delta excluding the new helper+tests: 28 insertions, 97 deletions.Behavior changes (user-visible, disclosed)
envVars downstream-reader audit (agreed at scope time)
Sole frontend reader of
input.envVarson the create path:tauri.ts:1148(envVars: input.envVars ?? {}) — safe default when omitted.CreateAgentDialog's envVars is the standalone-create path (genuine user overrides) and is untouched.channelAgents.ts: no envVars readers. Reviewer re-verifies independently.Pins
Frozen shapes (
CreateManagedAgentInputtype untouched), zero spec edits (desktop/tests/e2e/diff = 0 lines), cascade untouched (submitProfilePersonaDialognot in the diff), budget 6 files.Validation
create input never contains definition env varsregression)