Skip to content

feat(acp): add Devin model families and workspace skills for v2 - #11850

Closed
Derpedyea wants to merge 482 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Derpedyea:t3code/devin-acp-v2
Closed

Derpedyea wants to merge 482 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Derpedyea:t3code/devin-acp-v2

Conversation

@Derpedyea

@Derpedyea Derpedyea commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

What Changed

Devin's ACP model list can be stale and exposes native variants as separate rows. This adds fresh account-specific model families, exact thinking/Fast/context options, Fusion pairing controls, and native workspace skill invocation to the existing Orchestrator v2 ACP Registry integration.

The registry-resolved CLI supplies models and skills for the configured executable, account environment, and workspace. Saved choices remain visible if they become unavailable. Web/desktop and mobile share Fusion grouping, valid pair selection, and exact option handling. The Fusion editor owns its own view state; returning to the list preserves search and focus. Keyboard shortcuts use the visible list. Refresh and logout retire cached workspace probes, and resumed sessions discover models in their current workspace. Readiness checks preserve the CLI model catalog, workspace skill discovery keeps live slash commands, and saved context choices can be replaced when an account loses a variant.

Why

Targets t3code/codex-turn-mapping (#2829) and replaces #11276. V2 already owns Devin's sessions, authentication, approvals, MCP tools, and subagent handling through ACP Registry. This change extends that path and keeps provider-specific catalog and skill translation at the adapter boundary.

Implements the model/skill experience from Ideas discussion #6749.

UI Changes

Before/after below use the same deterministic catalog to compare the base v2 picker with the Fusion editor.

Before After
Base v2 model picker Fusion pairing editor

The verification provider now uses the installed Devin CLI. Its live catalog contained 48 families and 385 native variants, represented as 73 entries including 26 Fusion pairs; no family was missing.

Current live catalog Live Fusion selection
Current Devin model catalog GPT-6 Astra and SWE-2 High

Short recording of the Fusion editor (idle time removed).

Validation

  • 379 focused tests across 15 server, web, mobile, and shared files pass, including catalog refresh lifecycle, workspace command inheritance, unavailable context selection, cache invalidation, and account selection.
  • Server, web, mobile, and client-runtime typechecks pass. Scoped lint completes with warnings; formatting passes.
  • Headless web: model search, Fusion lead/sidekick selection, exact High thinking, workspace skill expansion, Back/search focus, filtered Ctrl+1 navigation, and a 390px layout.
  • Live Devin through v2: GPT-6 Astra + SWE-2 High completed a turn successfully. Screenshot.
  • Workspace skill invocation was exercised with an ACP fixture. Native mobile runtime, iOS, Windows, and macOS were not exercised on this v2 branch.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Model: GPT-6. Harness: Codex in T3 Code.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-15T03:01:48.687042Z f915168 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Sep 15, 2026
@github-actions github-actions Bot added the size:XXL 1,000+ changed lines (additions + deletions). label Sep 15, 2026
Comment thread packages/shared/src/model.ts
Comment thread apps/web/src/modelSelection.ts
Comment thread apps/web/src/components/ChatView.logic.ts
Comment thread apps/server/src/provider/Drivers/AcpRegistryDriver.ts Outdated
Comment thread apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts Outdated
Comment thread apps/server/src/provider/Drivers/AcpRegistryDriver.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This XXL change adds a new Devin ACP integration with account/workspace model discovery, Fusion selection, native option resolution, skill invocation, and coordinated web/mobile UI behavior across production paths. Its scope and product-default changes are substantial, and unresolved Medium/High findings cover stale-account/workspace state and model-option dispatch risks.

Not approved because:

  • 6 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f915168404

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/server/src/provider/Drivers/AcpRegistryDriver.ts Outdated
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from 463d0c6 to e10a1e2 Compare September 15, 2026 06:28
juliusmarminge and others added 20 commits September 15, 2026 10:24
- Keep prominent activity rows visible with lifecycle status and provider metadata
- Move feed sizing logic into tested helpers and preserve native measurement for activity groups
Re-applies the deltas that mid-stack blob reverts discarded, and merges
main's round-9 work into the v2-owned surfaces:

- settings: main's Integrations page (pingdotgg#7082) coexists with the branch's
  Scheduled Tasks page in the path union, section labels, icons, and
  search catalog
- contracts: main's preview appearance/zoom/viewport settings imports
  restored beside the branch's modelSelection home for ModelSelection
- mobile: main's built-in themes (pingdotgg#6619) re-applied to the v2 thread
  screens and work log (useThemeColor over hand-rolled color-scheme
  ternaries)
- MessagesTimeline: main's pingdotgg#7157 cleanup adopted (toolCallExpandedBody
  class name unexported, implementation-detail test dropped)
- ChangedFilesTree: main's styled tooltip (pingdotgg#7209) carrying the v2 runId
- pullRequestDetail tests: branch's row-action coverage renamed onto
  main's buildAddSelectionToAgentHandoff (pingdotgg#6597)
- lint: migrated the six branch-owned native title tooltips that main's
  new no-native-title-tooltip rule (pingdotgg#7209) flags to styled Tooltips
  (GitActionsControl, QueuedRunsControl, TimelineSystemDivider,
  MessagesTimeline intent badge and MCP tool logo)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports pingdotgg#7083 into the v2 session path, which replaced the v1
ProviderService where main's gate lives. Instead of withholding the whole
t3-code MCP credential — on this branch it also carries the thread
orchestration and worktree toolkits — the credential is minted without
the "preview" capability when enableAgentBrowserAccess is off, so every
preview tool call rejects while orchestration stays available.

ProviderSessionManager reads the setting at prepare time (deny on an
unreadable settings file, matching main), rotates a reused credential
whose capability set no longer reflects the setting, and the session
config now carries browserToolsAvailable so the Codex adapter keeps its
developer instructions truthful via main's parameterized instruction
builders instead of the removed constants.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s style simplification

Main's pingdotgg#6381 deleted the shared .workspace-topbar and scroll-fade rules
from index.css after inlining them at main's own call sites, but this
branch's slim chat chrome still references both classes. The round-8
rebase took the deletion without migrating the branch call sites, so the
header collapsed to zero height — the breadcrumb sat on the window edge,
timeline rows scrolled unfaded through it, and the thread-details popover
anchored to the collapsed header.

Restores both as composable utilities in pingdotgg#6381's own style: a
workspace-topbar utility for the titlebar rows, and the branch's
chat-timeline-scroll-fade mask (soft ramp plus a full-height scrollbar
column). Also drops the duplicated media override and its dead
settings-page-scroll-fade selector.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation

A follow-up sweep against pingdotgg#6381 found the branch still carrying the
pre-simplification forms it replaced, which my earlier fix had papered
over with a compat utility instead of finishing the migration:

- ChatView now uses main's inlined titlebar sizing and the
  data-workspace-titlebar-controls hook on both control clusters. The
  class-based markup was silently missing the themed-toggle bridge
  (html[data-theme-id] [data-workspace-titlebar-controls] …), so custom
  themes lost their titlebar accent in the thread view.
- The scroll-to-end pill becomes main's Button size="xs" variant="glass"
  instead of a hand-rolled button recreating it.
- MessagesTimeline uses main's consolidated topbar-scroll-fade utility;
  the byte-identical chat-timeline-scroll-fade copy and the
  workspace-topbar compat utility are gone.
- The composer-glass dark rules move into nested @variant dark like
  main's (the raw .dark duplicates could drift from the nested copies
  they shadowed), including the branch-only queue strip.
- The pre-pingdotgg#6381 dialog-glass/dialog-backdrop/dropdown-glass class rules
  and their .dark variants are deleted: the pingdotgg#6381 utilities plus
  call-site shadow utilities own every declaration, and the stale
  dropdown rule still had the saturate-less backdrop-filter. The dead
  model-picker-surface dark rule goes with them.

index.css now has zero raw .dark selectors outside the variant
definitions, matching the doctrine in
.macroscope/check-run-agents/ui-consistency.md. Verified against the
emitted production CSS: dark variants compile to :is(.dark,.dark *) with
their @supports color-mix fallbacks intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Complete retry items when provider activity resumes
- Keep retry progress visible across web and mobile clients
Ten days of main (194 commits, 640 files) re-integrated with the v2
re-architecture. The headline mechanics:

- migrations: main added 041-043 (AuthSessionClientConnection,
  ProjectionThreadLinkedPullRequest, ProjectionThreadsUnsettledAt), so the
  v2 block renumbers 041-049 → 044-052 with the migration tests shifted to
  match
- contracts: OrchestrationClientOrigin (pingdotgg#7774) and the origin metadata
  field live in applicationEvent.ts and re-export through the legacy
  path; ProviderApprovalOption + acceptAlways + mcp-elicitation (pingdotgg#8058)
  land in providerPolicy.ts; OrchestrationDispatchCommandError (pingdotgg#8824)
  added; the send-turn image-mime home stays chatAttachment.ts
- threadSettled: main's settle-once-on-merge semantics (pingdotgg#7454) and
  un-settle re-anchor (pingdotgg#8231) hand-merged onto the v2 duck-typed shells
  (latestRun ?? latestTurn reads); web callers pass the new
  ChangeRequestSettleSource shape
- timeline anchoring: main's pingdotgg#7897 (follow-up sends no longer push to the
  top) ported by scanning user rows only; the branch test now encodes the
  new semantics, as does mobile's pingdotgg#7969 settled-pinned shelf behavior
- vcs: branch's deleteLocalBranch coexists with main's pruneWorktrees and
  the pingdotgg#7674 submodule checkout tests
- ws: v2 RPC surface keeps its dispatch path; main's attachment upload
  RPCs (pingdotgg#8048) and client-connection analytics recording are wired;
  providerUploadFeedback (pingdotgg#7949) fails explicitly pending a v2 route
- approvals: main's option-driven approval buttons (pingdotgg#8058) render through
  the v2 canRespond gate on web and mobile
- ChatView/ChatComposer/MessagesTimeline/Sidebar/session-logic/
  threadActivity keep the branch's v2 architecture; main's v1-coupled
  deltas to those files are recorded for follow-up rather than
  force-fitted

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in the v2 work log

Ports main's pingdotgg#7999/pingdotgg#7893 failure policy onto the v2 turn-item work log:
output text that reports a failure (command not found, ENOENT, nonzero
exit markers) now flags a row even when the provider item completed
"successfully", while the rendered row judges only its displayed result —
a command that merely greps for failure strings stays calm. Success now
also requires the failure check to pass, so recovered failures no longer
get the blue check.

The server half of pingdotgg#7893 needs no port: CodexAdapterV2 already projects
item.status directly, so a failed item never masquerades as completed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dotgg#8160)

Main's thread↔PR linking never reached the v2 runtime: the client types
were optional stubs and the v2 server dropped the field, so linking a PR
on a v2 environment silently no-opped and pingdotgg#7454's settle-once logic could
never match the linked identity.

The link now flows end to end: thread.metadata.update carries an optional
linkedPullRequest (object to link, null to unlink), the orchestrator
folds it into thread state, and both shell builders project it — no
migration needed since v2 shells persist as payload JSON. The client
command sends the field and the shell mapper surfaces it, so the existing
web/mobile badge and settle plumbing light up on v2 threads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lient (pingdotgg#8058)

Round 10 ported main's option-driven approval buttons, but v2 runtime
requests had no way to deliver the data — every approval rendered the
default button set, MCP app names never showed, and worse, the Codex
app-server's mcpServer/elicitation/request went entirely unhandled on the
v2 adapter, so ChatGPT-app access requests could never be answered.

The v2 approval_request turn item now carries optional appName and
options, the client derivation passes them into ThreadPendingApproval,
and CodexAdapterV2 handles mcpServer/elicitation/request end to end:
unsupported shapes decline immediately (mirroring the v1 runtime), and
supported ones surface a mcp-elicitation approval built from the shared
describeMcpElicitation/toMcpElicitationResponse helpers, so the persist
tiers (session / always) advertise exactly the choices the elicitation
can express.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pingdotgg#7949)

The round-10 rebase stubbed providerUploadFeedback to an explicit error
because its v1 ProviderService route died with the v2 rewrite. The route
now goes through the v2 runtime: session runtimes may expose an optional
uploadFeedback capability, the Codex adapter implements it against the
app-server's feedback/upload request, and the WS handler resolves the
thread's live provider session through ProviderSessionManagerV2 —
failing with a plain-language reason when no session has run, the session
is gone, or the driver has no feedback channel. This also un-blocks the
dormant mobile feedback UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ingdotgg#7774)

Main records which client surface started each thread and turn; the v2
dispatch path replaced the v1 handler that did the recording, so v2
environments only reported connections. The v2 RPC layer now records
client.thread.started on thread launches (plus client.turn.requested when
the launch carries an initial message) and client.turn.requested on
message dispatches, using the connection's announced origin. Recording is
best-effort — attribution can never fail the user's command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…#8358, partial)

Ports the rate-limit half of main's pingdotgg#8358 into the branch's reworked XAi
extension: a prompt_complete carrying stopReason rate_limit now fails the
hung prompt with the -32003 usage-limit error instead of settling it as a
normal end_turn, so the turn surfaces "usage limit reached" rather than
silently ending. The prompt-completion deferreds carry the error channel
end to end.

The exit_plan_mode approval gate from pingdotgg#8358 is NOT ported here: it needs
a v2 plan-flow design in AcpAdapterV2 (the v1 GrokAdapter it lived in is
gone) and is tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gg#8144)

The v2 context meter could only show token counts after a compaction had
already happened — v2 had no live usage plumbing at all, so main's
compaction-threshold UX was invisible on v2 threads. Provider turns now
carry an optional tokenUsage report: the Codex adapter maps the
app-server's thread/tokenUsage/updated notification (total breakdown +
model context window) onto the active provider turn, ChatView picks the
newest report out of the projection, and the meter prefers it over the
compaction fallback — so usage and remaining-context percentages update
while the turn runs.

Claude's v2 adapter does not report usage yet; its meter falls back to
compaction items as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ingdotgg#6519)

Ports main's anchor-release semantics onto the branch's timeline anchor
state: the scroll-to-end pill and a manual scroll back to the live edge
both drop the send-time anchored end space before re-enabling follow, and
the pill's scroll runs a frame later so the list measures without the
anchor space and lands on the true end. Without this the timeline could
settle into following-end with the anchor still installed — following
nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ngdotgg#8358)

Completes the deferred half of pingdotgg#8358: Grok's plan-approval gate now works
on the v2 runtime. The XAi extension regains main's exit-plan helpers
(request schemas, plan-markdown extraction, the abandoned-with-feedback
response, and the plan.md session-path sniffing), and the v2 ACP adapter
grows a captureProposedPlan primitive that emits a completed
proposed-plan artifact for the active turn — one plan id per turn, so
plan.md rewrites and the exit gate update a single card.

The Grok flavor wires both ends: tool calls that write plan.md under a
Grok session dir surface the plan while plan mode is still active, and
x.ai/exit_plan_mode (plus the underscore alias) captures the final plan —
request content first, then the sniffed plan.md contents, then the
empty-state placeholder — and abandons the native gate so the turn does
not hang, mirroring the Claude ExitPlanMode pattern.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…er chrome

Two post-rebase regressions from the round-10 index.css merge:

- The merge seam ate the closing brace of .chat-composer-glass, silently
  nesting the entire composer-glass section (shell, host, context strip,
  shoulder tab, banner cap) inside it as descendant rules that never
  matched — the composer surface stopped painting and thread content
  showed straight through the input. The brace is restored and the
  compensating over-close removed; every composer selector emits at top
  level again.

- The thread-details popover grew dropdown-glass card chrome around the
  panel: round 9 deleted the legacy components-layer .dropdown-glass rule
  in favor of the @Utility, which the popover's border-0/bg-transparent
  suppressors no longer outrank (the utility emits later in the layer).
  The suppressors are now important variants, matching the !overflow
  override already there.

Verified against the emitted production CSS: shell::before is top-level,
no descendant-of-glass selectors remain, and the important suppressors
(including [backdrop-filter:none]!) are emitted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s survives shoulder tabs

The composer went frameless exactly when the stash or tasks badge was
showing: main's pingdotgg#7150 css hides the classic shell chrome whenever the
shell :has() a shoulder tab or top drawer and repaints the glass on
[data-chat-composer-main-surface] instead — an element the branch's
composer body never rendered, since it predates the drawer system while
the badges and css came through the rebase in main's new form.

The branch composer's frame div now carries the main-surface attribute
(with main's relative z-10 stacking) so attached mode paints background,
outline, and backdrop on it and the tab connects to the surface, and
ChatView applies chat-composer-glass-shell-attached while banner items
render in the drawer slot, matching main's externalComposerDrawerAttached
wiring. Without a tab or banner the attribute is inert and the classic
shell chrome paints as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Round 10 restored the branch's pre-pingdotgg#7150 composer body while its
satellites (shoulder badges, banner drawers, glass css) arrived in
main's new form, and every seam between the two was a visible bug:
opaque/frameless composer, overflowing stash tab, detached stash menu.

Rebuilt ChatComposer via a reverse three-way merge (main's body as the
base, branch delta re-applied): dispatchMode send boundary, live-capable
approval gates, latestRun reads, and the v2 context-window meter stay;
everything else now matches main, including ComposerPrimaryActions and
the sendDisabledReason send gating. Attachment uploads stay off until
the v2 claim path lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The v2 timeline rendered every tool call as its own raw row; main's
tool-group collapsing (generated "Ran N commands and changed M files"
summaries, the live "Running <program>" pill for the active tool run,
and the "+N previous log entries" clamp for mixed groups) never made it
into the v2 row model.

Ported the work-live/work-toggle row kinds and group summarization into
the v2 derive, keyed on v2 item types (command_execution, file_change,
file_search, dynamic_tool, subagent) and runId lifecycle instead of v1
activities. Expanded groups keep the branch's richer per-entry detail
rows (V2ItemInspector) — only the collapsed presentation converges on
main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge and others added 16 commits September 15, 2026 10:25
…g#11499)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…#11574)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… scheduler (pingdotgg#11585)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…pingdotgg#11590)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…g#11490)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…registry (pingdotgg#11578)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…vergent migration ids (pingdotgg#11639)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch from a5ebe9a to a62d7ad Compare September 15, 2026 17:25
@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 5 times, most recently from f63b335 to 08a1b86 Compare September 16, 2026 07:02
@t3-code

t3-code Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

thanks for building on the shared ACP registry and for the testing. this follows the OV2 ACP direction; we are closing it because of the additional feature scope, particularly the dedicated Fusion lead/sidekick editors and grouping across web and mobile.

account-specific catalog freshness and exact model-option selection address correctness. the Fusion-specific UI, decorative animation, and workspace skill invocation go beyond those fixes and introduce product and maintenance commitments we are not taking on here.

catalog and option-selection bugs can be considered independently through focused reproductions and fixes against the shared ACP implementation.

closed at the request of @StiensWout.

@t3-code t3-code Bot closed this Sep 16, 2026
@Derpedyea
Derpedyea deleted the t3code/devin-acp-v2 branch September 16, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants