Skip to content

refactor(native-chat): structured agents declare their capabilities instead of shared code naming Claude and Codex - #25076

Merged
brennanb2025 merged 34 commits into
mainfrom
brennanb2025/acp-a2-agent-registry
Oct 6, 2026
Merged

brennanb2025 merged 34 commits into
mainfrom
brennanb2025/acp-a2-agent-registry

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 80 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​746 $\color{#cf222e}{\Huge{\mathbf{−}}}$​92 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​654
Prod 52 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​594 $\color{#cf222e}{\Huge{\mathbf{−}}}$​223 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​371

Stacked on #24991. Review only what this PR adds on top of it: git diff origin/brennanb2025/acp-a1-opaque-handle 288f72cd43b. The A2 commits are 2667173fed9, 63508a51c34, 88a09c4e4c6, 38ac9109088 and the review-round commits 19c8cb5f417 (required agent registry) and c5aaee8ede9; the rest are merges of #24991 and main.

ELI5

Orca's structured native chat (the chat view that drives an agent through its own protocol instead of scraping a terminal) only knows two agents, Claude and Codex, and that fact was spelled out in many places of the shared code: "if the agent is Codex do this, else assume Claude". Adding a third agent meant editing all of those places. This PR gives each agent a single description of itself (what it can do, and how its options behave while no chat is running) and makes the shared code read that description instead of asking "is this Claude or Codex?".

There is no user-visible change: Claude and Codex chats behave exactly as before.

What Changed

The problem. Before this PR:

  • The router that sends each chat to the right agent backend was typed as exactly { claude, codex }, so a new backend was a type edit, not a registration.
  • What an agent could do (rewind, compact, set a goal, report context usage) was answered by "does this backend happen to implement that optional method". A client cannot know that before a chat is running, and the router's own compact method always existed, so "can compact" was true for any agent.
  • Option reads at rest (no agent process running), frame classification, the create/visibility gates and the renderer's label and validation code each had their own === 'claude' / === 'codex' branches. Some defaulted silently: the chat header label was agent === 'codex' ? 'codex' : 'claude', so any other agent would have been called Claude.
  • The stored account home typed its variable as 'CLAUDE_CONFIG_DIR' | 'CODEX_HOME' inline.

Mechanism now.

  • Agent definition (StructuredAgentDefinition): each agent's own module declares one (claude-structured-agent-definition.ts, codex-structured-agent-definition.ts): its capability record and its at-rest option rules (which option keys it accepts, its fallback model list, whether an unpicked effort means "the model's default").
  • Capability record (AgentSessionCapabilities, plain JSON in src/shared so the next PR can send it to clients unchanged): rewind, compact, threadGoal, contextUsage, imagePrompts, steering: 'inject' | 'queue', approvalEnforcement: 'provider' | 'orca'. The values reproduce today's behavior exactly (a test pins them). A running chat may narrow a declared capability, never widen it: Codex rewind is still narrowed to unsupported for a thread with legacy history.
  • One registry answers "what is this agent" (StructuredAgentRegistry, structured-agent-registry.ts): built once at runtime setup from the { definition, adapter } registrations, and a required dependency of both the host and the router. It answers definition(agent), definitions() and capabilities(agent). It refuses a duplicate registration, and a registration whose definition declares compact, threadGoal or rewind without the adapter method that does it, so a declaration can't drift from what the adapter can do. Every reader asks it: option reads at rest (which options a stopped chat accepts, its fallback model list, its default effort), compact admission, thread goal and rewind. There is no second map of agents: Claude's and Codex's definitions are listed only where the runtime builds the registry, so a definition the runtime did not register cannot affect any read.
  • Router: routes by the registry and refuses an unregistered agent. The per-capability supportsThreadGoal / recordsContextUsage methods and the "method exists" checks are gone, and so are the adapters' own copies of those answers. A running chat may only narrow: the router's rewindSupport applies the declared rewind itself and then the adapter's narrowing, so no caller can widen it.
  • Compact admission: /compact is admitted by the agent's declared compact capability (before, the router's always-present compact method admitted it for any agent). An agent that declares no compaction gets the existing "command refused" answer.
  • Frame classification keeps the same per-agent tables but reaches them through a lookup by agent id; Claude's message:result rule moved into Claude's entry. (This is still a third per-agent table beside the definition; see the temporary list.)
  • Account home: new src/shared/agent-session-account-home.ts owns the concept (the environment variable that points an agent at its config directory). Stored values are byte-identical ({"variable":"CODEX_HOME","path":…}); the stored-record check still admits only a variable some agent declares, because that variable becomes a child process's environment. The Claude and Codex launch checks and the model-catalog fingerprint read it from there.
  • Older clients' turn status text (the line a client that predates the turn item shows) names the session's agent from the catalog instead of === 'claude' ? 'Claude' : 'Codex'. Claude and Codex text is byte-identical; a row with no record and no legacy: id would now say "Agent" instead of guessing "Codex", which no real chat reaches because the record store never deletes records.
  • Renderer: labels come from the agent catalog by agent id (same labels as before), including the cut-turn notice main added. Tab/launch validation and the "show structured chat" choice use the one shared agent guard. The Codex-only "the host's model listing names the configured model" rule is now a field on Codex's option catalog (hostListingNamesConfiguredModel) instead of agent === 'codex'.
  • Gate for adapters with no per-agent check (structured-agent-session-provider-support.ts): the fallback no longer assumes such an adapter is Codex. In production the host always holds the router, which has a per-agent check, so this only affects single-adapter test doubles.

Deliberately left as Claude/Codex lists (each one place, not a branch):

  • AGENT_SESSION_PROVIDER_HANDLE_PROVIDERS / AgentSessionHandleProvider: what stored records, RPC params (including the account-home variable enum) and persisted tab state validate against. Widening it is a wire and stored-data change, which feat(native-chat): open structured chat's wire and stored records to registered agents, behind a negotiated capability #25159 does behind a new host capability (agent-session.structured.registered-agents.v1). temporary
  • The variable table in agent-session-account-home.ts (which environment variable points each agent at its config directory). It is not derived from the registered definitions yet because its one safety-relevant reader is the stored-record check (isPersistedAgentSessionRecord), a pure shared function that the record store runs while loading rows, before any adapter or router exists. That same check still hard-codes the stored agent list itself (claude | codex). Making it read the registrations means passing the runtime's declared variables into record loading, which belongs with widening that stored agent list. temporary: the next PR, which widens the stored agent list behind a host capability, and the protocol-agent launch description, which declares the variable with the agent, move both checks onto the registered definitions.
  • The model-catalog subsystem (agent-model-catalog-*) still types its agent as Claude/Codex: it is probe infrastructure that gets an agent-neutral shape when the first protocol-driven agent reports its own model list. temporary: feat(native-chat): open structured chat's wire and stored records to registered agents, behind a negotiated capability #25159 opens its types to any registered agent.
  • The Claude/Codex account resolution and location rule in the runtime's create path (orca-runtime-get-structured-agent-session-create-support.ts; the location gate picks Claude's or Codex's rule by name because the agent picker asks before the registry exists). temporary: feat(native-chat): open structured chat's wire and stored records to registered agents, behind a negotiated capability #25159 moves account resolution and location support onto each agent's runtime registration (which exists before the host starts), with Claude and Codex as ordinary entries.
  • Codex-specific journal identity branches in rewind/recovery and the unhandled-frame reader: they belong to the shared timeline assembler (Admit one provider event's journal writes as one queued operation, decided when it runs #25141 / Add a shared timeline assembler for structured agent chats (not wired yet) #25064), which owns item identity. temporary
  • The per-agent frame classification table (provider-frame-disposition.ts): classification belongs to the protocol (every ACP agent shares one) or to the definition. temporary: an agent without an entry gets the safe default (its frames stay visible), which is what the ACP adapter PR (feat(native-chat): Grok as a structured chat over the Agent Client Protocol #25225) relies on; moving classification onto the definition or the protocol is a follow-up.
  • Adoption of an existing conversation from history (structured-agent-session-create-adoption.ts) stays Claude/Codex: only they have transcript importers. intended for now.
  • Terminal (transcript-scraping) chat code in use-native-chat-session-options.ts and the option discovery files is a different chat system and out of scope.

Why

Adding an agent should be "write its adapter and its definition, register it", not a sweep through shared types, and a client should be able to learn what an agent supports before a chat runs. A capability record declared per agent and narrowed by the running session is the common pattern: a static declaration readers use instead of the agent's name, with the live session allowed to narrow it but never widen it.

Alternatives considered:

  • Keep "capability = optional method exists". Rejected: it can't be answered before a session runs, can't be sent to a client, and the router (which defines every method) answered "yes" to compact for every agent.
  • Put the whole definition in src/shared so the renderer can read it directly. Rejected: clients must learn capabilities from the host they talk to (an older or remote host may differ), which the next PR does by publishing this same record. Only the account-home variable table is shared, because the stored-record check needs it.
  • Make variable any environment-variable name. Rejected: the stored variable is set on a child process, so it stays limited to names an agent declares.

Differences from the common pattern

Linked Issue

N/A (internal stack: native chat for more agents).

Visual Proof

N/A: no user-visible change; labels resolve from the same catalog entries as before.

CI status (October 5)

Merged current main. On head 288f72cd43b every CI check passes: typecheck, static analysis, all five unit-test shards, cross-version wire compatibility, relay integration, and packaging for macOS and Windows.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

What I verified:

  • New tests: the registry (routes a registered agent the router has no code for, refuses an unregistered one and a duplicate, refuses a registration that declares compact, thread goal or rewind without the adapter method, answers capabilities from the registry, lets a session narrow but never widen rewind, including Claude's undeclared rewind at rest and live), the Claude and Codex definitions (pinned to today's behavior), and the account home (stored values byte-identical, an undeclared variable refused at load).
  • structured-agent-session-registered-definition.test.ts: a router registered with non-default Claude rules routes to its adapter, answers that registration's capabilities, accepts that registration's option keys at rest (and refuses model, which Claude's own module accepts), and reads that registration's fallback models and default effort. A router that did not register Claude refuses its option picks and reads no rules for it, even though this build ships Claude's definition. A pick for a session with no record is refused, as before.
  • Compact admission by declaration, the cut-turn notice label and the older-client turn text each have a test that fails without the fix. Test doubles build the same registry the runtime does.
  • Updated tests that used the old router constructor or the removed per-capability methods.
  • Ran 766 test files in native chat, structured runtime/RPC, Claude/Codex structured adapters, renderer native chat and shared agent-session code (7,592 tests), plus orca-runtime.test.ts and the runtime's other suites (59 files): all pass.
  • Changed-code quality gate (lint, casting, React Doctor, design system) passes since the stack base; oxlint/oxfmt clean on changed files.

What I didn't verify:

  • Review rounds: two round-1 reviews (correctness, and an architecture challenge that recommended the required registry), a round-2 review of the fixes, and a final readiness review: no P0-P2 issues open. Local runs on the final code: 76 A2 test files (637 tests) and 51 runtime suites (387 tests) pass; local typecheck only reports modules missing from the out-of-date shared dependency install.
  • No app run or real agent CLI run: this is a refactor with no UI or wire change, and its behavior is pinned by the tests above.

Review

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

…ed code

Shared structured-chat code parsed each provider's resume handle: Claude's
session id and branch leaf, Codex's thread id, through a 'claude' | 'codex'
union every new agent had to widen. The in-memory handle is now
{ transport, agent, nativeId, providerData? }: shared readers use nativeId,
lease and handle-chain checks compare transport and agent, and only the
Claude adapter reads its leaf (providerData).

Stored and wire forms are unchanged for Claude and Codex. One encoding
module writes their typed shapes and decodes both those and the neutral
shape a new transport uses, which an older build refuses as unreadable
rather than reading as Codex. Key and root strings, which fork seeds,
superseded creations and resume offers persist, stay byte-identical.

The journal's own handle type becomes the journal-row and attach-wire
encoding of the same handle, and the journal identity carries the
neutral handle (null before the provider proves one).

No user-visible change.
…l identity

The journal row converter now takes the identity every caller already holds,
so a row's handle has one obvious constructor. Tests that wrote the in-memory
handle straight into journal rows now build it through that converter, and the
processless Claude fixture names a not-yet-proved handle as null.
A typed Claude or Codex handle that also carries the neutral form's
transport, agent, native id or provider data named two identities; it
was read as Claude or Codex and the next write dropped the other one.
Such a row now stays unreadable and is set aside untouched.
…initions

The structured-chat shared layer named Claude and Codex in a closed router
type, in option reads, in frame classification, and in renderer label and
validation branches, so adding an agent meant editing shared types. Each
agent now has a definition (capabilities, resting option rules) owned by its
own module; the router is a registry of definition + adapter pairs built at
runtime setup, and shared code reads the definition instead of the name.

No behavior change for Claude or Codex; no wire or stored shape change.
The host types, conversation commands, provider-session ownership and the
runtime's create path spelled the structured agent list inline; they now use
the one shared type the record and wire already validate against.
…gent-registry

# Conflicts:
#	src/renderer/src/lib/structured-agent-session-provisional-tab.ts
… definition lookup

The at-rest option reads looked definitions up in a second, separately populated map, so a
registered definition could route and declare capabilities while the static map decided which
options a chat at rest accepted. The router now answers `definition(agent)` from its
registrations, the at-rest readers take it through the host's adapter, and the built-in
definitions are listed only where the runtime composes the router.
…n suite

Main grew the suite to the 800-line limit; the opaque-handle import pushed it
over. The two tests built the same identity inline.
Rename the neutral provider handle's providerData to resumeCursor before any
row persists the neutral form: it is an adapter-owned resume position (Claude's
transcript leaf), never identity. Claude/Codex stored and wire bytes are
unchanged; their typed shapes never carried the field.

State the stored-form contract (a handle's field set is closed; later per-link
data goes on the chain link, which every build preserves) and pin it with a
record round-trip test. Document that transport records the id space the
native id was minted in, which can differ from the agent's current transport.
…e' into brennanb2025/acp-a2-agent-registry

# Conflicts:
#	src/renderer/src/lib/structured-agent-session-provisional-tab.ts
…mit what they claim

A StructuredAgentRegistry, built once from the {definition, adapter}
registrations, is now a required host dependency and the router routes with
it. The adapter interface loses its optional router-only capabilities?() and
definition?(); every reader (options at rest, thread goal, rewind, the
/compact handover) asks the registry. A live session still narrows rewind
through the adapter, and the host combines declared and narrowed in one
helper. The registry refuses a registration that declares compact, a thread
goal or rewind without the adapter method behind it.

/compact is admitted by the declared capability, so an agent that declares
compact:false gets the commandRefused fact instead of a thrown error.

Also: the cut-turn notice names the agent from the catalog, create-support
builds the account home through agentSessionAccountHome, and the turn
status text older clients read names the session's agent instead of
defaulting to Codex (Claude/Codex text unchanged).
The router holds the registry, so its rewindSupport answers the owner's
declared rewind narrowed by the adapter, in one place no reader can bypass.
The host-side combining helper is gone; readers ask the adapter they hold.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review summary (head 288f72cd43b)

The problem. Structured native chat only knew Claude and Codex, and shared code was full of "if Codex do this, else assume Claude" branches. Adding an agent meant editing all of them. Some defaulted silently: any other agent would have been labeled Claude. "Can this agent compact" was answered by whether a method existed, so it was true for every agent.

User-facing change: none. Claude and Codex chats behave exactly as before. Each agent now describes itself once (what it can do, and how its options behave while no chat is running), and shared code reads that description instead of the agent's name.

What the review changed

  • One required agent registry. Before, the agent definitions were reachable only through optional router-only methods on the adapter interface, so any host built without the router would silently lose option rules and capabilities. Now one StructuredAgentRegistry is a required dependency of both the host and the router. It refuses a registration that declares compact, thread goal or rewind without the adapter method that does it.
  • /compact is admitted by the declared capability. Before, the router's always-present compact method admitted it for any agent.
  • Rewind check in one place. The router applies the declared rewind itself, so no caller can widen it. Claude (no rewind) is refused at rest and while running.
  • No more silent name defaults. Two that remained or came in from main now use the agent catalog: the cut-turn notice label (was "Claude" for any non-Codex agent) and the status text older clients show (was "Codex" for any non-Claude agent). Claude and Codex text is unchanged.
  • Small fixes. A leftover inline account-home table now uses the shared helper. A stale comment and a test-only export are cleaned up. The PR description now matches the code and names each temporary item's follow-up PR.

Deferred

Verified

  • Two independent round-1 reviews (correctness, and an architecture challenge that designed its own solution first; verdict keep, no split), a round-2 review of the fixes, and a final readiness review. No P0–P2 issues open.
  • Local runs: 76 test files (637 tests) for this PR's code and 51 runtime suites (387 tests) pass. New tests fail when their fix is reverted.
  • CI on this head: everything passes, including typecheck, all five unit-test shards, cross-version wire compatibility and packaging.

Not verified

  • No app or real agent run. There is no user-visible change, so there was no live QA.
  • No real remote or SSH runtime was exercised; definitions live on the runtime that runs the agent, and no wire or stored data changed.

main #24576 deleted agent-session-journal-recovery.ts and its two tests; take the deletion
(this branch only re-pointed them at the neutral provider handle). Main's new journal and
cross-version tests build journal identities with codexProviderHandle(); the older-build open
in the newer-chat cross-version test keeps the legacy handle shape it reads.
main #24576 removed historyFilePath from the structured adapter interface; drop this branch's
registry-routed copy in the adapter router. Main's new host and turn tests
(newer-content-host, unopened-tab, stop-note-withdrawn-send) pass the agent registry this branch
made required.
- claude-unproven-stop-send.test.ts: deleted on main (replaced by claude-stop-exit-ends-record);
  take the deletion. The replacement builds its host with claudeAndCodexAgents(adapter), as the
  deleted test did here.
- codex-stop-row.test.ts: this branch's agents dep + main's recording logger.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Merged current main into this branch twice (now 3b0c7aba7e1). The first merge brings in the A1 update; the second brings in main's #24862.

  • fix(native-chat): never delete chat history on read; a chat Orca can't load says why once #24576: main removed historyFilePath from the structured adapter interface, so I dropped this branch's registry-routed copy in the adapter router.
  • fix(native-chat): the agent's exit ends its record, and an unconfirmed stop is joined instead of held #24862: main replaced claude-unproven-stop-send.test.ts with claude-stop-exit-ends-record.test.ts, so I took the deletion. In codex-stop-row.test.ts I combined this branch's agents dependency with main's recording logger.
  • Outside the conflicts: four of main's new tests built a host or turn context without the agents registry this branch makes required (newer-content-host, unopened-tab, stop-note-withdrawn-send, claude-stop-exit-ends-record). They now pass it, following this branch's pattern for every other test.
  • Verified: 203 of 210 related test files pass locally (2202 tests); 7 can't load on stale local dependencies. The scoped typecheck has only that stale-dependency error. The line-limit lint (oxlint 1.86, the version CI runs) passes on every file the branch changes, as merged with main.
  • CI: not run yet. The first job waited about 30 minutes for a runner during today's backlog and was cancelled, so it shows as failed; the run is queued again.

… A4/A5/B1)

The conflicts were all "A2's copy of A1" against main's squash of A1. Resolved by
re-merging with old-main+A1 as the base, so the result is main plus exactly A2's
own change.
…n context the current way

The test (#25056) landed before the opaque provider handle (#24991), so main still built
the old {kind, threadId} handle; the turn context also needs this branch's agent registry.
@brennanb2025

brennanb2025 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Earlier CI merges missed main's restored provider-handle import and the test-only parser dependency still needed by old release checkouts. Merged main 08a970a3f117; the branch's own changes are preserved, the submission-position test matches main with exactly one used import, and main's package/lock fix is inherited through the merge with no branch-authored dependency edits. The prior broad run passed 1,429 tests; fresh-main checks passed 118 tests, with remaining local failures limited to stale stream-json/stream-chain dependencies, and scoped oxlint passed; new-head CI is pending.

@brennanb2025
brennanb2025 marked this pull request as ready for review October 6, 2026 03:30
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

Walkthrough

The change introduces registry-backed structured-agent definitions and routes session operations through registered adapters. Agent capabilities and resting-option rules now come from definitions. Shared account-home helpers replace provider-specific variable handling in affected APIs. Renderer and legacy status text use agent identity and display names more directly. Test hosts now receive explicit agent registries.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to db71a

The remaining test-fixture cleanup does not block merging; the test checks the intended behavior.

Security Architecture Review

Security architecture risk: 🔵 Low · up to db71a

The change centralizes security-sensitive routing and operation eligibility. Inspected controls remain in place, but incomplete coverage of identity and permission boundaries leaves limited residual uncertainty.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — Within inspected production composition, registration authority remains host-owned and the selectable execution backends remain the same two providers. Unknown identities are refused rather than dynamically creating an adapter or authority profile.

Trust Boundaries and Controls

  • observed — Attach input carries provider and agent separately: handle admission checks provider, while journal identity and adapter selection use agent. The attach and RPC paths are unchanged, and the base router already selected by agent. This inspection did not establish a newly reachable or exploitable cross-provider path.
  • observed — Persisted account-home variables remain restricted to CLAUDE_CONFIG_DIR and CODEX_HOME. Provider launch checks retain their respective pinned-variable requirements, now obtained from the shared mapping rather than literals.

Resilience and Maintainability Implications

  • observed — Delayed option persistence uses the admitted runtime fence. Replacement refuses a moved fence or an unsuitable lease state, preserving protection against stale writers after ownership changes.
🚥 Pre-merge checks | ✅ 4 | ❓ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ❓ Inconclusive Docstring coverage is 45.71% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 50 files. (80 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: structured agents declare capabilities instead of relying on shared Claude/Codex-specific logic. It is somewhat long, but remains specific and relevant.
Description check ✅ Passed The description covers the required ELI5, changes, rationale, linked-issue status, visual-proof status, testing, agent-skill boundary, notes, and checklist sections. It explains that visual proof is n…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 45.71% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 50 files. (80 skipped: 80 over the file limit.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/native-chat/agent-session-wire/structured-agent-session-mutation-owed-import.test.ts (1)

93-96: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Remove the unused adapter capabilities stub.

The test host already uses claudeAndCodexDeclared(). performThreadGoalChange checks ctx.agents.capabilities(ctx.agent), not an adapter property. The stub does not enable the goal path and misstates where capability declarations come from.

Suggested cleanup
-import { CODEX_STRUCTURED_AGENT } from '../../codex/codex-structured-agent-definition'
...
     Object.assign(host.deps.adapter, {
-      changeThreadGoal,
-      capabilities: () => CODEX_STRUCTURED_AGENT.capabilities
+      changeThreadGoal
     })

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 87506e7a-89f9-4c92-a357-94b0a08fd4a6
📥 Commits

Reviewing files that changed from the base of the PR and between 08a970a and db71a89.

📒 Files selected for processing (132)
  • src/main/claude/claude-api-retry-idle-sweep.test.ts
  • src/main/claude/claude-context-usage-unloaded-turn.test.ts
  • src/main/claude/claude-structured-agent-definition.ts
  • src/main/claude/claude-structured-effort-default-at-rest.test.ts
  • src/main/claude/claude-structured-launch-resolution.ts
  • src/main/claude/claude-structured-session-adapter.ts
  • src/main/claude/claude-structured-session-test-support.ts
  • src/main/codex/codex-provider-retry-idle-sweep.test.ts
  • src/main/codex/codex-structured-agent-definition.ts
  • src/main/codex/codex-structured-launch-resolution.ts
  • src/main/codex/codex-structured-question-order.test.ts
  • src/main/codex/codex-structured-session-adapter.ts
  • src/main/codex/codex-structured-session-close.test.ts
  • src/main/native-chat/agent-model-catalog/agent-model-catalog-fingerprint.ts
  • src/main/native-chat/agent-model-catalog/agent-model-catalog-service.ts
  • src/main/native-chat/agent-session-wire/provider-frame-disposition.ts
  • src/main/native-chat/agent-session-wire/structured-agent-definition.ts
  • src/main/native-chat/agent-session-wire/structured-agent-registry.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-accept-then-deliver.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router-registry.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router-test-support.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter-router.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adopted-import.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-append-delivery.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-at-rest-commands.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-compact-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-echo-working.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-option-queue.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-queued-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-root-exit.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-stop-ends-session.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-stop-exit-ends-record.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-stop-turn-end.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-close-verdict.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-codex-stop-row.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-command-turn.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-conversation-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-crash-mid-start.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-crash-turn-end.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-delivery-loop.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-failed-create-owner-verdict.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-failed-create-sink-release.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-grouped-prompt.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-delivery.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-mutations.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-test-abandon.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-test-harness.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-types.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-import-mismatch.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-late-settlement.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-legacy-handoff-record.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-main-agent-working-agreement.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-mutation-admission.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-mutation-context.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-mutation-owed-import.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-mutation-turn-context.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-newer-content-host.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-operation-settlement.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-operation-start-refusal.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-option-settlement.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-options-read.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-options-read.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-owed-work-release.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-prompt-cancel.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-child-record.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-restore.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-started.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-support.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-message-rig.test-fixture.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-recovery-exits.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-refusal-retry.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-registered-definition.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-repeat-press.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-repeated-stop.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rest-test-rig.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-restart-interruption-test-harness.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-restart-status-publication.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-at-rest.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-send-idempotency.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-send-open-stale-turn.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-send-preparation.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-send-restarts-failed-start.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-settled-attach-retry.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-start-failure-writer.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-startup-reconcile-failure.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-note-opened-turn.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-stop-note-withdrawn-send.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-surface-lifetime.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-thread-goal.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-thread-goal.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turns.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-turns.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-unopened-tab.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-view-start-after-failed-start.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-wedged-profile-migration.test.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-command.test.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-command.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-compaction.test.ts
  • src/main/native-chat/agent-session-wire/structured-provider-session-ownership.ts
  • src/main/runtime/orca-runtime-get-structured-agent-session-create-support.ts
  • src/main/runtime/rpc/methods/structured-agent-session-adoption-replay.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-at-rest.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-hold.test.ts
  • src/main/runtime/rpc/methods/structured-chat-tab-table.test.ts
  • src/main/runtime/structured-agent-session-runtime.ts
  • src/main/runtime/structured-claude-pending-rewind.test.ts
  • src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx
  • src/renderer/src/components/native-chat/use-host-model-catalog-upgrade.ts
  • src/renderer/src/components/native-chat/use-structured-agent-session-options.ts
  • src/renderer/src/components/native-chat/use-structured-agent-session.cut-turn-notice.test.tsx
  • src/renderer/src/components/native-chat/use-structured-agent-session.ts
  • src/renderer/src/lib/structured-agent-session-launch-label.ts
  • src/renderer/src/lib/structured-agent-session-launch-persistence.ts
  • src/renderer/src/lib/structured-agent-session-provisional-tab.ts
  • src/shared/agent-session-account-home.test.ts
  • src/shared/agent-session-account-home.ts
  • src/shared/agent-session-capabilities.ts
  • src/shared/agent-session-option-catalog-claude-codex.ts
  • src/shared/agent-session-option-catalog-types.ts
  • src/shared/agent-session-record.ts
  • src/shared/agent-session-turn-record.test.ts
  • src/shared/agent-session-turn-record.ts
  • src/shared/agent-turn-lifecycle-text.ts
  • src/shared/structured-agent-session-mutation.ts
  • src/shared/tui-agent-display-names.ts
  • tests/e2e/cross-version-wire/cross-version-agent-session-wire.unit.test.ts
  • tests/e2e/structured-chat-owner-status-activation.unit.test.ts
💤 Files with no reviewable changes (2)
  • src/main/codex/codex-structured-session-adapter.ts
  • src/main/claude/claude-structured-session-adapter.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

@brennanb2025
brennanb2025 merged commit 3a03441 into main Oct 6, 2026
56 checks passed
brennanb2025 added a commit that referenced this pull request Oct 6, 2026
Main squash-merged A2 #25076 (db71a89) and A6 #25204 (5df4db2), both already in D3; resolved
against those heads, so only zh.json conflicted: structuredCopy keeps D3's agent-neutral meaning with
main's new 智能体 term.
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