feat(agents): backend slice — definitions, MCP launchers, runtime models#38
Open
ovdmar wants to merge 14 commits into
Open
feat(agents): backend slice — definitions, MCP launchers, runtime models#38ovdmar wants to merge 14 commits into
ovdmar wants to merge 14 commits into
Conversation
Adds the dual-approved tech plan for the Agents system (predefined + custom agent definitions, MCP launchers, plan handoff) and the spec updates that anchor the implementation. Defines the new "Agent definition" core term in spec A, the Agents nav surface in B.2, the launch-time prompt-composition seam in B.3, runtime model discovery + default agent runtime in B.6, and the agent launchers + plan handoff MCP surface in B.7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds AgentDefinitionSchema (+predefined/custom kind), Create/Update input schemas, LaunchPredefinedAgentInputSchema (shared by all four predefined launchers), LaunchCustomAgentInputSchema, RegisterPlanInputSchema, PlanRegistrationSchema, LaunchHandoffAgentInputSchema (with the predefinedKind XOR customAgentId one-of refinement that prevents typos silently 404'ing as custom-agent lookups), AgentsConfigSchema for the global default-runtime knob, and RuntimeModelDescriptor/Response for the per-runtime model probes. All schemas export inferred types and are covered by round-trip parse tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the plan_registrations SQLite table (workspace-scoped, FK to workspaces with ON DELETE CASCADE) and the schema_migrations row for version 8. Store gains insertPlanRegistration / findPlanRegistration / listPlanRegistrationsForWorkspace / deletePlanRegistration methods. PRAGMA foreign_keys=ON preserved. A regression test asserts the cascade: inserting a registration for a workspace, deleting the workspace, then listing registrations returns empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds packages/runtimes/src/models/, mirroring the usage/ adapter pattern. runtimeModelListers registry exposes per-runtime probes; claude-code attempts a TUI scrape via tmux-pty.ts (5s timeout, try/finally killSession cleanup) and degrades to a hardcoded fallback list with a probeError on any failure. codex/cursor-agent/pi return small hardcoded defaults — their CLIs don't expose model selection today. Parser is fixture-driven (fixtures/claude-code-models.txt) so future TUI-format drift is caught at test time. Real-fixture verification against a live claude-code session is a follow-up gate before relying on the parser in production. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds ~/.citadel/agents/ storage backing the four predefined agent definitions (architect, implementation, pm, prototype) plus user-defined custom agents. Each definition lives in its own JSON file for atomic writes and to keep concurrent edits from racing on a shared file. Highlights: - Idempotent seeding: list() re-reads disk on every call (no in-memory cache that could desync across daemons sharing the directory), and the seed only writes when a predefined file is missing OR present-but- unparseable; well-formed user edits are preserved. - Boot-safe: when the directory cannot be created, list() returns [] and state() reports "unavailable" so the daemon does not crashloop under systemd Restart=always. - Predefined IDs are reserved — custom create rejects collisions; remove rejects predefined; resetToDefaults rejects custom and restores the citadel-authored seed (NOT the user's defaultRuntime). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds apps/daemon/src/agents-routes.ts with the new HTTP surface for agent definitions and per-runtime model discovery: - GET/POST/PATCH/DELETE /api/agents (predefined-delete → 409, predefined-reset-by-custom-id → 400, etc.) - POST /api/agents/:id/reset - GET/PUT /api/agents/config - GET /api/runtimes/:id/models with a 1-hour TTL cache and ?refresh=1 bypass (claude-code CLI upgrades happen out-of-band, so daemon-lifetime caching would surface stale models) app.ts gets a single registrar call so it remains thin. To stay under the 800-LoC file-size gate, also compresses the /api/repos/:repoId/ branches handler (behavior unchanged) and extracts agent contracts to packages/contracts/src/agents.ts (and IdSchema to id.ts) since the new schemas pushed index.ts over its budget. Route tests drive the live express app via node:http (no new dev deps; supertest avoided to keep the lockfile clean). The 1h-TTL behavior is exercised with a fake clock that exercises hit/miss/refresh transitions in order. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ntinel Registers the new MCP tool surface for the Agents system: - launch_implementation_agent / launch_prototype_agent / launch_pm_agent / launch_architect_agent — predefined launchers - list_custom_agents, launch_custom_agent — custom launchers - register_plan, launch_handoff_agent — plan handoff All eight tools route through the daemon via a new `agent_launcher_requires_daemon` sentinel (matching the existing per- family pattern: scratchpad_tool_requires_daemon, scheduled_agent_run_tool_requires_daemon, session_tool_requires_daemon). McpToolContext has no fs access and no agentDefinitions handle, so running list_custom_agents in the snapshot path would silently return [] and mislead remote callers — daemon-routed is the correct shape. Definitions live in agent-launcher-tools.ts to keep packages/mcp/src/ index.ts under the 800-line file-size budget. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires the daemon-side dispatch for the four predefined launchers (launch_implementation_agent / launch_prototype_agent / launch_pm_agent / launch_architect_agent), launch_custom_agent, and list_custom_agents. Composition is centralized in a single composeAgentLaunchInput seam in apps/daemon/src/agent-launcher.ts so the system-prompt-prepend path is testable in isolation — the canary against silently dropping the system prompt on a future refactor. System prompt is prepended uniformly across all runtimes under the `## System` / `## User prompt` headers, then handed to operations.launchAgent the same way the existing launch_agent path does. Runtime resolution priority: agent.runtime → agents.config.defaultRuntime → "claude-code". register_plan and launch_handoff_agent dispatch returns `not_yet_implemented_in_v1` — the realpath/fs validation + plan resolution layer is the next slice. The MCP tool surface is registered and the contract is stable, so v2 fills in the dispatch without changing schemas or caller code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Biome's autoformatter expanded the agent-system registrar call into multi-line form, pushing apps/daemon/src/app.ts back over the size gate. Extract the wiring (createAgentDefinitionsStorage + register the routes) into a `wireAgents(app, asyncRoute, config)` helper in agents-routes.ts so app.ts has only a single-line call. Also runs biome --write across the new files to normalize import ordering, type-only import annotations, and trailing-comma formatting. No behavior changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-applied after merging origin/main into the agents-system branch. Single-line collapse on apps/daemon/src/status-monitor-wiring.ts; no behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Main extracted IdSchema to packages/contracts/src/primitives.ts in parallel; this branch had extracted it to id.ts. Resolved by: - Removing this branch's id.ts (main's primitives.ts wins the race) - Repointing agents.ts to import IdSchema from ./primitives.js - Keeping this branch's `export * from "./agents.js"` in index.ts All agents-system tests still pass (59 across contracts, DB cascade, runtime models, storage CRUD, HTTP routes, MCP layer, launcher composition). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Another in-flight branch landed (8, 'agent-sessions-auto-resume-backoff')
on main while this PR was open, so plan_registrations now becomes v9.
INSERT OR IGNORE quietly dropped this PR's row on top of the existing
v8 — packages/db/src/migration.test.ts caught the silent-loss case.
Updates:
- migrate.ts: version 8 → 9 for the plan-registrations row
- index.test.ts: schema_migrations ORDER BY version expectation gets
{ version: 9 } appended
This is the migration-version-drift mitigation the tech plan flagged
under "Pre-merge sequencing".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
origin/maininto the branch and keeps the Agents backend slice compatible with the newer scratchpad, PR, quota, diagnostics, and terminal work on main.Plan
.agents/plans/agents-system.md
What landed
launch_implementation_agent,launch_prototype_agent,launch_pm_agent,launch_architect_agent,list_custom_agents, andlaunch_custom_agent.plan_registrationspersistence via DB migration v13 after merging main's v9-v12 migrations.Deferred Scope
register_planandlaunch_handoff_agentremain stable tool contracts returningnot_yet_implemented_in_v1until the safe file validation and same-workspace handoff path lands.Test Plan
make checkpasses locally on 2026-05-28 after mergingorigin/mainat638c565.How to QA
git checkout agent/12-agents-system-6haz23pnpm installmake checkpnpm devhttp://localhost:4010or the worktree's resolved porthttp://localhost:5173Suggested manual checks:
curl http://localhost:4010/api/agentsreturns the four predefined agents and the default runtime config.curl http://localhost:4010/api/runtimes/claude-code/modelsreturns either live model discovery or fallback models with aprobeError.DELETE /api/agents/implementationreturns409 predefined_agent_cannot_be_deleted.POST /api/agents, then launch it throughlaunch_custom_agentvia MCP.Schema-affecting change. First daemon boot after merge applies migration v13 for
plan_registrations; existing tables are preserved.