🤖 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 17 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".
|
@codex review All three round-13 findings addressed:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 642c4389c4
ℹ️ 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-14 findings addressed:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d35a3c78fd
ℹ️ 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".
…), compose one-shots with skill invocations Skills bound to a model class (frontmatter metadata model-class, or the skillModelClasses config table) stream on the class's model for that send only. Classes are edited in Settings -> Models -> Model Classes; broken bindings fail the send with actionable errors; /model+thinking one-shots compose with skill invocations and bypass class routing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Send path: - Resolve the skill model-class override before the pricing gate, PDF preflight, and history mutations so a broken binding can no longer charge gates against the wrong model or persist side effects before erroring. - Route compaction follow-ups with the pre-routing options so a routed skill send that triggers auto-compaction resumes on the original model/thinking, and only compact routed sends at >=100% usage. - Add a dedicated skipSkillModelRouting wire flag instead of overloading skipAiSettingsPersistence; one-shot model overrides set it explicitly and compaction retries re-derive it from the original message text. - One-shot composed sends now carry the full command prefix in muxMetadata so transcript badges render the model prefix. Binding semantics: - Frontmatter bindings to an unconfigured class are inert (portable skills can ship model-class metadata without breaking sends); a dangling skillModelClasses table entry still errors loudly since the table is the user's explicit routing intent. Blank table entries are treated as unbound. Settings/editor: - Store model-class maps verbatim instead of sanitizing away entries this build cannot parse, so edits from an older/newer build no longer destroy unknown classes. - Gate class edits and the unroutable-model warning on config/routing load completion to avoid clobbering state during the initial fetch. - Carry thinking suffixes across model swaps only when the new model's policy supports them; show raw invalid values in a tooltip. - Share provider/gateway servability predicates between the editor warning and the send-time gate so the two can't drift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rides through retry Codex review round 1: - Numeric one-shot thinking is model-relative, but the frontend resolves it against the workspace model before routing is known. Pass the raw index (oneShotThinkingIndex) and re-resolve it against the routed class model in AgentSession, so "/+0 /skill" means the routed model's lowest level rather than the workspace model's. - Compact-and-retry rebuilds now carry the one-shot's thinking (named resolved as-is, numeric resolved against the explicit model or kept as a raw index for routed re-resolution) and skipAiSettingsPersistence, and prepareCompactionMessage stops letting ambient stored options clobber carried one-shot fields — without the persistence flag the re-dispatch would also have persisted the one-shot model as the new workspace default. - Preserve skipSkillModelRouting and oneShotThinkingIndex in pickPreservedSendOptions so backend-built compaction follow-ups keep one-shot semantics too. - Stamp the routed model into the persisted user-message metadata (requestedModel) so the pending-turn label and history consumers attribute routed sends to the model that actually streams. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 2: the >=100% band left no room for the new message, attachments, or skill snapshot (recorded usage excludes the pending turn), so a near-limit history could overrun the routed model at request startup instead of compacting. Routed sends now compact within ROUTED_SEND_COMPACTION_HEADROOM_PERCENT of the routed window — still far above the workspace threshold, so a cheap skill invocation still cannot force an unrequested compaction of a fitting history. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…odel that fits Codex review round 3: - Mid-stream usage updates during a routed turn applied the workspace threshold+buffer against the (smaller) routed window, immediately forcing the exact surprise compaction the pre-send band declined. checkMidStream now takes a force-threshold override and routed turns pass the routed-send headroom policy. - When a class routes UP to a larger-window model, repeated routed turns can outgrow the user's model; summarizing on it would just context-error again. On-send and mid-stream compaction now run on whichever of the user/routed model has the larger usable window (normally still the user's model). The deferred follow-up keeps pre-routing options and re-routes at dispatch either way. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 4: OpenAI's isConfigured can mean Codex-OAuth-only credentials, which serve only the OAuth-allowed model set — the class preflight would pass for an OAuth-ineligible model (e.g. gpt-5.5-pro) and the direct route would win over a later gateway, only for the factory to fail with api_key_not_found. canDirectOpenAIServeModel mirrors the factory's credential selection (OAuth-required models need stored tokens even with an API key; OAuth-only configs serve only the allowed set) and the shared servability predicate consults it, so the editor warning and send-time error stay aligned with what a send would really do. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d model
Codex review round 5:
- ProviderModelFactory.resolveModelRoute now passes the canonical model
into isProviderAvailableForRouting: a Codex-OAuth-only OpenAI
credential no longer wins the direct route for a model outside the
OAuth-allowed set (which createModel would reject with
api_key_not_found) — a usable gateway later in routePriority wins
instead, matching the shared canDirectOpenAIServeModel predicate.
Also realigned that predicate with the factory's actual fallback: an
API key attempts any model (OAuth-preferred models fall back to the
key), while tokens-only serves only the allowed set.
- ChatInput's client-side PDF preflight judged the workspace model,
rejecting routable skill sends before the IPC call ever reached the
backend's routed-model gate; it now defers to that authoritative
check when a routable skill invocation is present.
- sendMessage now returns SendMessageAccepted { routedModel } through
AgentSession → WorkspaceService → router → wire schema, and ChatInput
attributes successful-send telemetry to the routed model (queued
sends report none and fall back to the requested model).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… for class rows Codex review round 6: - React Compiler conventions ban useCallback for identity stabilization: the subscription's fetch now lives inside the effect (its natural scope) and the write-failure revert reaches it through a ref, so no manual memoization and no exhaustive-deps suppressions. - ModelsConfiguredPhone pins a Pixel phone matrix variant (mirrored with globals.viewport) so CI snapshots the Model Classes rows at the narrow width their wrapping layout exists for; verified live at 375px (label/select wrap, inline no-route warning, no overflow). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in telemetry Codex review round 7: - Class edits persisted AFTER the UI published them: a quick /skill invocation would route on the backend's old map while the editor claimed the new one. useModelClasses now serializes writes and publishes state on the write's ack; rapid edits build on the newest pending intent and failures still revert to backend truth. - The accepted-send payload gains routedThinkingLevel (class thinking suffix or re-resolved numeric one-shot) and ChatInput attributes message_sent telemetry to it, so small:"haiku+0" invocations stop reporting the workspace's ambient thinking level. - Queued sends still attribute to the requested model: routing resolves only at dispatch, and correct queued attribution needs backend-side event capture (frontend-only provenance in the payload) — descoped as a follow-up; the persisted requestedModel stamp already attributes the durable record correctly at dispatch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…king Codex review round 8: - Routable skill sends skip the browser PDF preflight (round 5), so a queued send whose PDF the routed model rejects died on a bare Err in the queue drain — composer already cleared, text and attachment gone. Both PDF rejection branches now persist + surface the error through preserveRejectedManualSend, like the pricing and routing gates. - routedThinkingLevel reported the pre-policy value while the stream clamps against per-model minimum floors; the floor resolution + clamping now live in one shared method used by both the stream build and the accepted-send payload. - messageSent's thinking fallback reads the send's actual options (composed one-shot thinking included) rather than the ambient workspace setting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 9: routedThinkingLevel was populated only when
routing replaced the thinking, so a named one-shot riding through
("/+off /skill") onto a floor-clamped model reported nothing while the
stream ran at the clamped level. The payload now reports whatever
optionsForStream carries — class suffix, re-resolved numeric index, or
a named/ambient level — clamped by the shared per-model floor
enforcement.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 10: - Same-session stream retries (retryActiveStream → resumeStream, and the post-compaction context-exceeded retry) restarted the stream without the routed turn's compaction context, reverting mid-stream checks to the workspace threshold against the routed window and summarization to the smaller model. The auto-retry resume state now carries compactionBaseOptions, resumeStream threads it through, and the post-compaction retry reads it from the captured stream context. - The compact-retry one-shot reparse guard anchored at column zero while parseCommand trims leading whitespace; " /haiku+0 /done" lost its override. The guard now trims before checking. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 11: the follow-up metadata rebuild passed rawCommand
but dropped commandPrefix, so a recovered composed invocation
("/haiku+0 /done") lost its command badge — UserMessageContent keys its
highlighting on that value.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex review round 12: a custom openai-compatible provider defined under the "openai" id is direct-only and authenticates against its own endpoint (key optional), but canDirectOpenAIServeModel applied built-in OpenAI credential rules and reported every class model on it unavailable — rejecting class-bound skills while ordinary sends worked. The predicate now recognizes the custom-provider shape and defers to the ordinary isConfigured gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… compaction context Codex review round 13: - Rejected EDITS no longer append the edited text as a new tail turn: the class-routing and PDF gates skip preserveRejectedManualSend when editMessageId is set — preservation exists for dequeued sends whose composer already cleared, and the browser restores the edit draft on failure. - Editor rows disable while their write is in flight (per-class pending counts from useModelClasses): with state publishing on the write's ack, a rapid model→thinking edit would otherwise compose the second value from the still-old rendered model and overwrite the first. - The persisted retrySendOptions embed a durable one-level compactionBaseOptions pick for routed turns, and startup recovery feeds it back into the resume state — the routed compaction policy (90% force bar, larger-window compaction base) now survives a relaunch. Rows written by older versions lack the field and fall back to today's behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he pricing gate Codex review round 14: - deriveStartupAutoRetryRequest never copied the persisted retrySendOptions.compactionBaseOptions into the retry request, so the round-13 restore always read undefined and a relaunched routed turn still reverted to the workspace compaction policy. The builder now restores the field. - The budgeted-goal pricing gate gets the same editMessageId guard as the class-routing and PDF gates: a rejected EDIT (reachable here via routed skill edits judging the class model) returns bare instead of appending the edited text as a new tail turn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
d35a3c7 to
b299bc7
Compare
…rkspaces Codex review round 15: child task workspaces prefer creation-time agent settings for startup retry, which would resume a class-routed turn on the workspace model while restoring a routed compaction policy — mismatched in both directions. Retry rows marked with routed compaction context now use the persisted model/thinking (the class values the turn actually streamed with); the child's agent identity precedence is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review Round-15 finding addressed: |
|
Codex Review: Didn't find any major issues. Keep them coming! 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". |
Summary
Skills can now be routed to user-defined model size classes so mechanical skills (session wrap-up, worktree helpers, PR chores) 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 /done), 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