refactor: collapse multi-agent model into a single @deuce agent#34
Merged
Conversation
Pi is the sole agent harness. Removes the executor/queue/output legacy path, DEUCE_AGENT_HARNESS selection, the agent_status/typing_indicator/ agent_output WS events only it emitted, and the claude_session_id queries. Also commits the single-deuce-agent plan doc.
Migration 013 drops session_agents, de-keys tasks from agents (FK/column drop ordered before row deletes so task history survives), cancels still-queued tasks, repoints historical agent messages to deuce's fixed UUID (nil-UUID system sentinel excluded), reshapes agents to one seeded row (id/name/system_prompt), and drops messages.mentions. Down restores the pre-013 schema and the five role seed rows. Runtime keys on session ID — one Pi process and one serial queue per session. @Deuce mention detection moves server-side (word-boundary regex; emails and @deucebot don't trigger); the mentions plumbing is gone end to end. /stop is exact-match and drains the queue along with the running task (R6). Agent CRUD is replaced by GET/PUT /api/agent for deuce's global system prompt; saving recycles idle Pi processes (StopAndForget deregisters synchronously so a racing enqueue launches fresh). The steer path gains the same workspace-status gate as chat mentions (R8). WS task/action payloads and the steer frame drop agentId; stale-tab fields are tolerated and ignored.
Shared workspace-status gate for the chat-mention and steer paths; scheduler lookups use filtered queries against the (session_id, state) index from 013 instead of walking full task history; the prompt-edit recycle deregisters synchronously but signals the dying process without blocking the HTTP handler; the agents row drops the name column (identity lives in the DeuceAgentName/DEUCE constants, with a drift test pinning the UUID across Go, SQL, and TS); /api/agent's contract shrinks to the system prompt.
The DEUCE constant (src/lib/deuce.ts, id matching the Go constant and migration 013) carries the agent's identity; Session.agents, the Agent type, mention parsing, and the legacy agent_status/typing_indicator/ agent_output handling are gone. The chat visibility filter pins agent- typed messages to hidden unless nil-UUID system notices. Stop relocates to the running task card and the thread-drawer header via a shared atom. The drawer is the session's single deuce thread; the summary panel and drawer derive the agent's status from task state. The settings dialog becomes a single system-prompt editor disclosing global scope, next-launch staleness, and save errors. The session-create agent picker, role color tokens, and the unreferenced src/mocks prototype data are removed. Wires vitest (npm test) for the pure-logic suites.
CLAUDE.md and README drop the role-agent framing, document the Pi-only agent runtime, GET/PUT /api/agent, the AgentRunEvent WS family, and the real frontend check commands (npm test, tsc -b). Marks the plan completed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The status label sat on a second line under the name, pushing the name off-center against the avatar. Name, status dot, and label now share one row, vertically centered.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Collapses the multi-agent model (five role agents, per-session rosters, @mention-by-UUID routing, agent CRUD) into a single built-in agent, @Deuce, implicitly present in every session. Under the Pi harness the role distinction was already a UI fiction —
role/system_promptwere fetched but never reached Pi — so this removes a model the execution layer ignored and clears the ground for skills/subagents on one agent.Plan:
docs/plans/2026-06-09-001-refactor-single-deuce-agent-plan.md(committed in this PR, statuscompleted).What changed
claude -pharness deleted — executor/queue/output,DEUCE_AGENT_HARNESS, and theagent_status/typing_indicator/agent_outputWS events only it emitted. Pi is the sole harness.session_agents, de-keystasksfrom agents (FK/column drop ordered before row deletes so task history survives theON DELETE CASCADE), cancels still-queued tasks, repoints historical agent messages to deuce's fixed UUID (nil-UUID system sentinel excluded), reshapesagentsto one seeded row (id+system_prompt), and dropsmessages.mentions. Down restores the pre-013 schema + the five role seed rows (verified Down/Up cycle on a data-bearing DB, including the NOT NULL backfill).(session_id, state)index.(?i)(^|\W)@deuce\b(emails likeclint@deuce.devand@deucebotdon't trigger); the clientmentionsplumbing is gone end to end./stopis exact-match and now drains the queue along with the running task.GET/PUT /api/agentreplaces agent CRUD: deuce's global system prompt. Saving recycles idle Pi processes (synchronous deregister + async signal, so a racing enqueue launches fresh and the handler doesn't block); sessions mid-task pick the prompt up on their next process launch, and the editor says so.DEUCEconstant carries identity (a Go test pins the UUID across Go/SQL/TS); visibility filter hides agent-typed messages except nil-UUID system notices; Stop button moves to the running task card + drawer header; the drawer is the session's single thread; summary panel derives status from task state; settings dialog is a single prompt editor with global-scope/staleness/save-error states; vitest wired (npm test).Authorization notes (route audit)
POST /sessions/{id}/agent/stopkeepsrequireSessionMember(gate before lookup; 403, no 404 oracle). WS steer staysAuthorize-gated at join and steer.GET/PUT /api/agentare authenticated-user gated by deliberate decision: no finer role model exists yet; the prompt is instructions, not secrets. An admin gate / audit trail for the global prompt is deferred (see plan Scope Boundaries) — flagged here because any team member can change agent behavior instance-wide.Testing
StopAndForgetsynchronous deregister, server-side mention regex, exact/stop, and the cross-layer UUID drift test.npm test(23 vitest specs),tsc -b, lint, production build.GET/PUT /api/agentround-trip, deleted routes 404.Deploy notes
Stop the server before migrating (a task enqueued mid-migration window would slip past the queued-task cancellation). Stale browser tabs hard-crash on the changed session shape — reload recovers; accepted pre-1.0. Running/awaiting tasks at deploy are failed by boot recovery; users re-mention @Deuce.
Post-Deploy Monitoring & Validation
pi harness boot recovery failed(boot panic — should not appear) andruntime:error lines in the first hour.@deucein an existing session → task card renders, reply lands in the drawer;/stopcancels running + queued; prompt edit via settings shows on the next task;clint@deuce.dev-style text does NOT trigger a run.make migrate-down(restores pre-013 schema + role seeds) and redeploy the previous image. Window: first day of dogfood use; owner: @clintberry.Known Residuals / Deferred
Deferred follow-ups are recorded in the plan's Scope Boundaries:
systemauthor type to replace the nil-UUID sentinel, Pi session resume, prompt-edit audit trail/admin gate, unread badges incremented by hidden replies, multi-human answer collisions on a shared pending question.🤖 Generated with Claude Code