Skip to content

feat(desktop): unified AgentDialog create entry point with create intents (Phase 1B.2)#1626

Merged
wesbillman merged 1 commit into
mainfrom
feat/agent-dialog-create
Jul 8, 2026
Merged

feat(desktop): unified AgentDialog create entry point with create intents (Phase 1B.2)#1626
wesbillman merged 1 commit into
mainfrom
feat/agent-dialog-create

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

Phase 1B.2 — unified AgentDialog create entry point

Second slice of Phase 1B (UI unification, #centralize-personas-and-agents). Routes both create entry points on the Agents surface through a single AgentDialog that owns the create intent:

Intent What it creates Form rendered
definition_start (default) definition + linked, spawned instance (personaId) — today's quick-start PersonaDialog (create mode) with "Start agent after create" toggle on
definition definition only — new behavior, see below same form, toggle off
instance standalone keyed managed agent CreateAgentDialog, unchanged

Stacked on #1624 (B1 shared sections). Wire shapes (CreatePersonaInput / CreateManagedAgentInput) untouched — frontend recomposition only; independent of #1623 (A2).

Composition: pass-through router, not a new form

AgentDialog (~110 lines) is an intent router. The definition family renders PersonaDialog itself in create mode (via a new 2-line createFooterSlot prop — footer-left is empty in create mode; edit's import button owns it otherwise); the instance intent renders CreateAgentDialog unchanged. A new standalone form would have duplicated ~400 lines that B3 deletes anyway; physical consolidation of the forms into one file is B3's job. Consequence: B1's shared sections are consumed transitively (both forms already use them).

Entry point implies intent — "New agent" opens the definition family, "Custom agent" and the open-create-agent event open the instance form. There is no in-dialog mode picker; don't read AgentDialog expecting one.

Sequencing stays hook-side

usePersonaActions.handleSubmit(input, intent?) keeps ownership of create-then-instance (it already holds the mutations, feedback surfaces, and SecretRevealDialog plumbing). The definition intent is the existing create branch minus the instance step; upstream (runtime guard, avatar resolve) and downstream (instance step, error taxonomy, dialog close, pending reset) are untouched. Return type widens to Promise<boolean> so the unified mount can close on success — legacy callers ignore the return.

definition_start preserves this hook's semantics (harnessOverride: true, hard-error on unavailable runtime, resolveManagedAgentAvatarUrl before create feeding both records) — not handleStartPersona's card-start mapping, which diverges (conditional harnessOverride, resolvePersonaRuntime fallback) and stays untouched on the card path. Converging the two definition→instance mappings is a real cleanup but belongs to a visible future slice, not this PR.

Intent defaults pin legacy behavior

resolveCreateIntent defaults to definition_start: PersonaDialog's duplicate path still calls handleSubmit without an intent until B3, and create/duplicate both always quick-start today. A unit test pins the default so duplicate can't silently become definition-only. The toggle-on dialog copy is derived from createPersonaDialogState and deepEqual-pinned against it — it cannot drift from the flow it replaces.

Divergence flags (per the B1 rule: each intent preserves the flow it replaces)

  • lockedRuntimeReset stays per-form by construction: definition intents replace PersonaDialog-create → "full"; instance replaces CreateAgentDialog → "provider-only". The flag choice is a consequence of the replaces-rule, not a judgment call.
  • Definition-only is genuinely new behavior — today's UI has no way to create a definition without starting an instance ("Create an agent profile and start its managed agent instance"). This is the Phase-1 "definition without instance" goal, disclosed as new rather than dressed as recomposition. Skip-step-2 in the hook; notice copy "Created X."
  • Runtime-required guard kept as-is for definition-only: create mode still requires choosing an available runtime, even though a definition-only record arguably shouldn't need one. Relaxing it is a product question (below), not smuggled in.

Both-paths-alive (weaker form for one path — explicit)

  • CreateAgentDialog: fully alive and reachable — it is the instance form, byte-identical.
  • PersonaDialog create mode: in-tree but unreachable via UI (edit/duplicate/import mounts remain live). Rollback = one-line revert of the AgentsView mount wiring; openCreate is intact in the hook, unwired.
  • Mount exclusivity: create no longer sets personaDialogState (prepareCreate split out of openCreate primes feedback/runtime-load without it), so the old and new PersonaDialog mounts — which share testids until B4's rename — can never coexist. Comment at the mount site names the assumption.

Testids

The definition form reuses PersonaDialog's existing testids/ids (persona-dialog, persona-dialog-submit, #persona-runtime, …), so the existing create-path e2e specs run unchanged — verified locally. Renames are B4's vocabulary flip. New: agent-dialog-start-toggle.

Open product questions for @wesbillman (none block this PR)

  1. Does "Persona" survive as the catalog name? (B4)
  2. Create-flow default: quick-start vs definition-first? (currently quick-start = today's de-facto behavior; one constant to flip)
  3. Should definition-only creation still require choosing an available runtime? (guard kept as-is here)

Verification

  • tsc, biome (full src/), file-size/px-text/pubkey checks clean
  • 2061/0 unit tests (5 new: intent resolver default pin, toggle mapping, copy derivation pins)
  • smoke e2e -g "agent|persona" 56/56 locally; full suite in CI
  • Cross-reviewed by Pinky (scope pre-pass + line-by-line on the diff, this thread)

…ents (Phase 1B.2)

Route both create entry points (New agent, Custom agent / open-create-agent
event) through a single AgentDialog that owns the create intent: definition,
definition+start (default, today's quick-start), or standalone instance.

- agentCreateIntent.ts: pure intent model. resolveCreateIntent defaults
  un-migrated handleSubmit callers (PersonaDialog's duplicate path until B3)
  to definition_start so duplicate keeps create-then-start semantics;
  toggle-on dialog copy is derived from createPersonaDialogState so it
  cannot drift from the legacy create flow.
- usePersonaActions.handleSubmit(input, intent?) -> Promise<boolean>:
  definition intent runs the existing create branch minus the instance
  step; all other paths unchanged. prepareCreate split out of openCreate
  so the unified dialog can prime feedback/runtime loading without setting
  personaDialogState (keeps the old and new PersonaDialog mounts mutually
  exclusive); openCreate itself is untouched for one-line rollback.
- AgentDialog.tsx: intent router. Definition family renders PersonaDialog
  in create mode with a "Start agent after create" toggle injected via the
  new createFooterSlot prop (footer-left is empty in create mode); instance
  renders CreateAgentDialog unchanged. Physical consolidation of the two
  forms is Phase 1B.3.
- AgentsView: entry point implies intent (no in-dialog mode picker).
  PersonaDialog stays mounted for edit/duplicate/import; CreateAgentDialog
  remains reachable as the instance form.

Wire shapes (CreatePersonaInput / CreateManagedAgentInput) unchanged.
Definition-only is the one genuinely new behavior: today's UI always
quick-starts. The create-mode runtime-required guard is kept as-is for
definition-only; relaxing it is a product question, not smuggled in here.

Verified: tsc, biome (full src), file-size checks, 2061/0 unit tests
(5 new intent-model tests incl. the duplicate-default pin), smoke e2e
-g "agent|persona" 56/56 locally.

Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
@wesbillman wesbillman force-pushed the feat/agent-dialog-create branch from bea5793 to 8f3426f Compare July 8, 2026 14:16
@wesbillman wesbillman merged commit 6f38db6 into main Jul 8, 2026
25 checks passed
@wesbillman wesbillman deleted the feat/agent-dialog-create branch July 8, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant