🤖 feat: route skills to model classes (Settings-managed large/medium/small) - #3849
🤖 feat: route skills to model classes (Settings-managed large/medium/small)#3849asm wants to merge 3 commits into
Conversation
|
To use Codex here, create a Codex account and connect to github. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 60f19ad5e5
ℹ️ 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".
|
@codex review All three findings addressed in b1b0bf8:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1b0bf8591
ℹ️ 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".
|
@codex review Round-2 finding addressed in 6c4903d: routed sends now compact within |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6c4903deb0
ℹ️ 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".
|
@codex review Both round-3 findings addressed in 297b210:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 297b210330
ℹ️ 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".
|
@codex review Round-4 finding addressed in 50b68ee: added |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50b68ee8fc
ℹ️ 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".
|
@codex review All three round-5 findings addressed in 6452b8a:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6452b8a491
ℹ️ 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".
|
@codex review Both round-6 findings addressed in 47afc04:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47afc04612
ℹ️ 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".
|
@codex review Round-7 findings in 44facc0:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 44facc03ea
ℹ️ 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".
|
@codex review All three round-8 findings addressed in 79fb8e0:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79fb8e040b
ℹ️ 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".
|
@codex review Round-9 finding addressed in 6284377: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62843778d0
ℹ️ 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".
6284377 to
3d6ffbd
Compare
|
@codex review Both round-10 findings addressed, and the branch is rebased onto latest main (the #3844 conflict in agentSession.ts resolved by adopting the new gateway-preserving
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d6ffbd18d
ℹ️ 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".
|
@codex review Round-11 finding addressed: the compact-and-retry metadata rebuild now carries |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9eb115404
ℹ️ 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".
|
@codex review Round-12 finding addressed: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ecc3f4b18
ℹ️ 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".
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e835591c2
ℹ️ 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".
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 836dd19681
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e16c845436
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: e16c845436
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 121cb4b98e
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: a7a2e8281d
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7a2e8281d
ℹ️ 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".
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: 6a11d23f43
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
Squashed, review-hardened branch (7 Codex rounds), rebased onto the config-module/turn-engine/ChatInput refactors. Per-skill model routing: skills bind to a class (frontmatter metadata.model-class, or the skillModelClasses table in config.json which wins over frontmatter), classes map to models in Settings → Models. Routing applies to the slash invocation's send only; explicit one-shot models bypass it, thinking-only one-shots layer on top with model-relative numeric indices re-resolved against the routed model. Security: project-scope skills get no class routing (frontmatter or name-keyed table entry) in untrusted projects — repo-controlled content must not reroute the transcript to another configured provider, and a repo shadow must not inherit table consent given to the user's own skill. Authoritative scope resolves from the on-disk package. Hardening from review: routed compaction runs on the larger-window model with the durable context whitelist-schema-validated from chat.jsonl; routed-retry rows keep child-workspace precedence rules; service pricing preflight defers to the routing-aware dispatch gate for skill sends with AI-settings persistence moved to acceptance; the class editor generation-guards write acks across client swaps and keeps explicit gateway identities; suggestion/PDF/queue-timestamp edge cases covered. Rebase reconciliation: getConfig/updateModelClasses live on Config (getClientConfig + Config.updateModelClasses); routed-send payload mapping in sendWorkspaceMessage; one-shot × skill composition ported into prepareMessagePayload; continuation-sender widening moved to turnRequestBuilder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review — rebased onto latest main across the config-module split, turn-engine, and ChatInput payload refactors; the branch is now squashed to a single review-hardened commit (all prior rounds' fixes included; the review history lives in the resolved threads). Reconciliation notes: getConfig/updateModelClasses moved onto Config (getClientConfig + Config.updateModelClasses), the routed-send payload mapping lives in sendWorkspaceMessage, and the one-shot × skill composition moved into prepareMessagePayload. Head is 9c8e47d. |
6a11d23 to
9c8e47d
Compare
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c8e47dd9a
ℹ️ 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".
…ust, schema-derived payload) Nine findings from the post-squash review (three were pre-squash stragglers): - Class candidates dedupe by EXACT selection identity: a direct model and its explicit gateway form dispatch differently and must both stay selectable. - Rejected queued skill sends keep their agent-skill muxMetadata, so the preserved row shows the typed /skill command and badge instead of the rewritten model-facing prompt. - Security: scratch workspaces never route project skills — app-level scratch trust must not extend to provider-selection consent, since scratch workdirs routinely hold cloned third-party repos whose .xum/skills are discovered. - useModelClasses composes full-map writes at DISPATCH time, after any in-flight config fetch settles, so an edit racing a peer's config-change notification can no longer delete the peer's freshly added class. - Plus-bearing custom model ids (proxy:model+v2) parse correctly: the thinking suffix is the text after the LAST plus and only when it parses as a thinking token. - Availability mirrors resolveRoute's final direct fallback, so a class model the ordinary send-path serves is never rejected by the gate (contradicting test flipped — its premise was wrong). - getClientConfig exposes skillModelClasses alongside modelClasses (P2 via the schema contract). - SendMessageAccepted is now inferred from SendMessageAcceptedSchema — the wire shape and compile-time shape share one source (P1). - The custom-classes line break-alls at phone width, with a long hand-edited class in the pinned mobile story (P1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review — addressed all nine findings from the squash review (including the three earlier threads that had slipped past my resolution pass): exact-identity candidates, preserved skill metadata on rejected rows, scratch workspaces excluded from routing trust, dispatch-time map composition, plus-safe class parsing, direct-fallback-aware availability, skillModelClasses in getClientConfig, schema-derived SendMessageAccepted (P1), and phone-width wrap for custom classes (P1). Inline replies on each thread. Head is 1b93391. |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b93391539
ℹ️ 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".
… failed refresh Two remaining squash-review findings: - The direct-fallback availability check now also applies the gateway-model catalog predicate: a configured Coder instance whose catalog tombstones or omits the model is rejected by the factory (model_not_available), so the class gate must not pass it. The predicate fails open for providers without a catalog, so this only removes false positives. - A failed config refresh (current fetch version) marks useModelClasses unloaded: latestMapRef may be behind the peer edit whose notification triggered the fetch, and accepting a full-map write composed from it would delete that edit. Writes stay refused until a later fetch lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d97fa73088
ℹ️ 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".
| await fetchInFlightRef.current?.catch(() => { | ||
| // Best-effort: a failed refresh falls back to the latest known map. | ||
| }); |
There was a problem hiding this comment.
Recheck freshness after awaiting a config refresh
When an edit is queued while a config-change refresh is in flight and that refresh subsequently fails, fetchConfig() catches the error internally, so this await resolves and the write continues from stale latestMapRef even though the catch just marked the hook unloaded. The resulting full-map replacement can still delete the peer edit that triggered the refresh. Fresh evidence beyond the addressed failed-refresh finding is this already-enqueued write path; abort it unless the awaited refresh successfully re-established authoritative state.
AGENTS.md reference: AGENTS.md:L150-L150
Useful? React with 👍 / 👎.
| const fallback = resolveRoute( | ||
| args.canonicalModel, | ||
| args.routePriority ?? ["direct"], | ||
| args.routeOverrides ?? {}, | ||
| isConfigured, | ||
| (gateway, modelId) => isRouteGatewayModelAccessible(providersConfig, gateway, modelId) | ||
| ); |
There was a problem hiding this comment.
Resolve Coder fallback identity from instance metadata
When a class selects a cross-typed Coder model such as coder:openai/claude-sonnet-4-5 backed by an Anthropic-typed instance and the explicit Coder route is unavailable or catalog-rejected, the factory derives an anthropic: fallback from discoveredProviders, but this call resolves the raw value using the instance name and therefore tests an openai: fallback. With only Anthropic configured, the class preflight rejects a route that an ordinary send can serve; with only OpenAI configured, it can pass a route the factory will not use. Seed availability resolution with the same metadata-derived Coder identity as ProviderModelFactory while retaining the explicit gateway catalog check.
Useful? React with 👍 / 👎.
| if (provider === "openai") { | ||
| return canDirectOpenAIServeModel(args.canonicalModel, providersConfig); |
There was a problem hiding this comment.
Canonicalize explicit gateway models before OAuth gating
When a class contains an explicit gateway model such as openrouter:openai/gpt-5.5, that gateway is unavailable, and direct OpenAI has only Codex OAuth credentials, this passes the raw gateway-prefixed value to canDirectOpenAIServeModel(). The OAuth compatibility check consequently rejects it because it is not an openai: model, while ProviderModelFactory canonicalizes the selection to openai:gpt-5.5 before resolving the fallback and can serve it directly. Fresh evidence beyond the resolved OAuth findings is this explicit-gateway fallback path; apply the credential predicate to the canonical origin model rather than the raw selection.
Useful? React with 👍 / 👎.
| await updateModelClasses({ modelClasses: next }); | ||
| if (clientGenerationRef.current !== writeGeneration) { | ||
| return; | ||
| } | ||
| // Newer than any in-flight fetch: the ack is the freshest truth. | ||
| fetchVersionRef.current++; | ||
| latestMapRef.current = next; | ||
| setMap(next); |
There was a problem hiding this comment.
Propagate model-class persistence failures
When the atomic config write fails, such as on a read-only or full filesystem, Config.saveConfig() logs and swallows the error, so this RPC still resolves and the hook publishes next as the freshest backend truth. Subsequent routing reloads the unchanged file and continues using the old class while Settings displays the new one; the emitted config notification cannot repair this because the acknowledgement invalidates its fetch. Make this update reject when persistence fails so the existing catch path refetches and reverts the UI.
AGENTS.md reference: AGENTS.md:L150-L150
Useful? React with 👍 / 👎.
Summary
Skills can now be routed to user-defined model size classes so mechanical skills (wrap-up chores, formatting passes, routine repo tasks) don't consume frontier-model tokens. Classes map a name to a
model[+thinking]value (one-shot syntax) and are edited in Settings → Models → Model Classes; skills bind to a class via the spec-standard frontmattermetadata: model-class: smallor a localskillModelClassesconfig table. The class model applies to that invocation only — the workspace model is untouched. One-shot overrides also compose with skill invocations now (/haiku+0 /deep-review), and an explicit one-shot always beats class routing.Background
Models churn constantly, so per-skill bindings shouldn't name concrete models — they name a class (
large/medium/small), and only the class map names models. Updating one class re-routes every bound skill.model) and extends it to compose with skill slash invocations.ai.modelparsed but not consulted); this PR takes the same position for skills — a declared model preference should be honored — while keeping it strictly opt-in.metadatamap, which other harnesses ignore. Frontmatter bindings to a class the user never defined are deliberately inert, so skills shippingmetadata: model-classcan never break users who haven't opted in. The config table exists for routing skills the user doesn't own — and because the table is the user's own explicit intent, a dangling table entry (naming a class that was deleted) fails loudly instead of silently unrouting.Implementation
modelClassesandskillModelClassesrecords (schema, load normalization,saveConfigwhitelist,config.updateModelClassesroute). Maps are stored verbatim — entries this build can't parse are preserved, not dropped, so edits from an older/newer build never destroy classes they don't understand. Validity is judged lazily at send time by the resolver.src/common/utils/ai/skillModelClasses.ts): binding resolution as a discriminated union (unbound/unknown-class/invalid-value/resolved), plusisModelServableWithProvidersConfig(modelAvailability.ts) wrapping the routing layer'sisModelAvailablewith the same exported provider/gateway predicatesuseRoutingconsumes — so a model reachable only via a configured gateway (e.g. OpenRouter) correctly counts as available, route-priority membership is honored, and the editor warning cannot drift from the send-time gate.AgentSession.sendMessage): the override is resolved before the pricing gate, PDF-support preflight, and any history mutation, so those gates evaluate the model that will actually stream and a broken binding errors before persisting side effects. Routing is gated by a dedicatedskipSkillModelRoutingsend option (set by explicit one-shot composition and compaction retries) rather than overloadingskipAiSettingsPersistence. Bound-but-broken mappings (dangling table entry, invalid value, no configured route for the model) fail the send with an actionable error naming the fix and the one-shot bypass; unbound skills take a null fast-path and infrastructure failures (unreadable skill/config, providers state unavailable) fail open.ROUTED_SEND_COMPACTION_HEADROOM_PERCENT(10 points) of the routed model's window — headroom for the pending turn, while still far above the workspace threshold so a small-context class model can't trigger surprise compaction of a history the workspace model handles fine.large/medium/small— a shared vocabulary keeps skill frontmatter portable across machines), model + thinking selects per class, custom hand-edited classes preserved on save and listed read-only (unparseable raw values shown in a tooltip), and an inline "no configured route can serve this model" warning using the same predicate as the send-time check. Edits are disabled until config and routing state finish loading, so an early click can't clobber persisted classes; thinking suffixes carry across model swaps only when the target model's policy supports them.parseCommandWithSkillInvocationcomposes a leading one-shot with a skill invocation by re-runningparseCommandon the one-shot's message — registered commands and nested one-shots stay out of skill resolution, mirroring direct-invocation semantics exactly. Composed sends record the full command prefix (model /skill) in message metadata so transcript badges render what was actually typed. Numeric one-shot thinking is model-relative, so a thinking-only composed send (/+0 /skill) also passes the raw index (oneShotThinkingIndex) for the backend to re-resolve against the routed model's ladder —+0means the class model's lowest level, not the workspace model's. Compact-and-retry rebuilds re-derive the one-shot's model and thinking from the original text (withskipAiSettingsPersistence, so a re-dispatch never persists one-shot values as new workspace defaults), andprepareCompactionMessagekeeps carried one-shot fields from being clobbered by ambient stored options.requestedModel), so the pending-turn label and history consumers see the model that actually streams.Review-round hardening
Sixteen Codex review rounds tightened the edges (all threads resolved):
skipAiSettingsPersistence), and process relaunch (durablecompactionBaseOptionsinretrySendOptions, honored even in child task workspaces).ProviderModelFactory.resolveModelRouteboth apply model-aware OpenAI credential rules (Codex-OAuth-only serves the OAuth set; API keys attempt anything; custom openai-compatible providers shadowing theopenaiid are exempt).routedModel+ post-floorroutedThinkingLevel; persisted metadata re-stampsrequestedModel. Queued-send event attribution is documented as a follow-up (needs backend-side event capture).Validation
saveConfigwhitelist (including preservation of unknown classes), end-to-end AgentSession routing and error paths via the session harness (gate ordering,skipSkillModelRoutingexemption, thinking-only bindings, compaction follow-up model), composition parser cases, and editor UI behavior (clear preserves custom classes; load gating; warning states).bun test srcfailure set is identical tomain's on the same machine (pre-existing env-sensitive tests only).ModelsSectionstories now seed classes, including one pointing at an unconfigured provider to exercise the warning; row layout wraps at mobile widths) and in a packaged build used for daily work.Risks
The sensitive area is the insertion in
AgentSession.sendMessage. Scope is tightly bounded: only sends carryingagent-skillmetadata withoutskipSkillModelRoutingare considered, and workspaces with nomodelClasses/table binding hit an early return before any skill read — no behavior change for anyone who hasn't opted in. Compaction interplay (threshold on the routed model, compaction request and mid-stream forced compaction on the user's model, follow-up resume options) is covered by tests. One known asymmetry, documented at the helper: the shared servability predicate mirrors the routing layer's gateway/priority gates but not per-request policy checks, so an editor warning can under-report in exotic policy setups — the send-time error remains authoritative.🤖 Generated with Claude Code