fix(acp): pick the reasoning-effort ladder from the selected model - #286
fix(acp): pick the reasoning-effort ladder from the selected model#286Astro-Han wants to merge 3 commits into
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36e6a05e1f
ℹ️ 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".
36e6a05 to
4242863
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4242863562
ℹ️ 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".
4242863 to
97dd43d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 97dd43d578
ℹ️ 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".
97dd43d to
ca3b71f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ca3b71f362
ℹ️ 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".
ca3b71f to
65bb180
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65bb1807a2
ℹ️ 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".
65bb180 to
8604664
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 860466473f
ℹ️ 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".
8604664 to
eae92ca
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eae92cad85
ℹ️ 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".
eae92ca to
3d6d68b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d6d68b317
ℹ️ 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".
3d6d68b to
4e66a56
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e66a561f3
ℹ️ 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".
2ffb88f to
8a400be
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a400be590
ℹ️ 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".
8a400be to
47e3335
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47e3335117
ℹ️ 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".
The capability cache treated the probed model's thought-level list as global. An adapter can now publish each model's reasoning-effort ladder under the Lody-owned "_meta.lody.modelReasoningEfforts" namespace on the session response (the Grok adapter does), and the capability normalization merges that map with the existing legacy "model[effort]" derivation into modelReasoningEfforts. No cache-version bump: the startup capability refresh re-probes every configured agent unconditionally and every session rewrites its entry, so existing caches pick up the map without a global invalidation that would hide registry/custom selectors until the refresh completes. "summarizeAgentRunConfigCapabilities" and "resolveAgentRunConfigSelection" already consume the map, so MCP callers and dispatch validation get per-model efforts without further change. Ref: LodyAI#149 Model: glm-5.3
The composer's reasoning-effort picker rendered whatever thought-level list the capability probe captured, no matter which model was selected: selecting Grok 4.6 while the probe ran under a model with a high/low/max ladder hid "medium" and offered the invalid "max" (LodyAI#149). A new normalizeReasoningEffortSelectors rebuilds the thought-level selector from the per-model ladder the capability source publishes (cached runtime map or static builtin table), reusing probe-time labels and descriptions for values the ladder still offers and synthesizing labels for the rest. It runs in both the selector builders and the selection resolution, so a model moved by authoritative validation re-normalizes against the RESOLVED model, and it skips Codex, which keeps its own hardcoded extended-effort table for now. The map is a required field of the selection input, so the session, draft, and Role composer call sites cannot drop it silently; the Role editor passes its pinned model so its picker and compatibility check agree on the same ladder. The static builtin Grok table gains per-model ladders so the picker is correct before any probe, and resolveConfigOptions now surfaces the cached per-model map alongside configOptions. Model: glm-5.3
…tract Model: glm-5.3
47e3335 to
9cba5f6
Compare
Related issue
Closes #149
Problem / pressure
The reasoning-effort picker showed one flat list, measured for whatever model was current at probe time, for every model. With the Grok runtime pointed at a catalog whose default model has a
high/low/maxladder, selecting Grok 4.6 hidmedium/xhighand offeredmax, which xAI rejects with400 Invalid reasoning effort. The same class of bug appears between Grok 4.5 and 4.6 (xhighonly on 4.6): the picker contents depended on probe-time model, not the selected model.Three layers conspired: the Grok adapter kept one flat ladder and never rebuilt it on model change; the capability cache derived per-model efforts only from Codex-style
model[effort]ids; and the UI normalized per-model effort lists only for Codex.Summary
model_changednotification into standardconfig_option_update, and publishes the per-model view on the session response as_meta.lody.modelReasoningEfforts(fix: follow the selected model's reasoning-effort ladder acp-extension-grok#11; the root gitlink is bumped after that PR merges, per the runtime-upgrade convention from chore: upgrade built-in AI agent runtimes #201).model[effort]derivation, which now applies to builtin Codex only: Claude lists context-window variants with the same brackets (opus[1m]), and reading those as a ladder would rebuild Claude's effort picker to the sole value1monce the picker followed the map. No cache-version bump: the startup capability refresh re-probes every configured agent unconditionally and every session rewrites its entry, so caches pick up the map progressively without globally invalidating other agents' entries.summarizeAgentRunConfigCapabilitiesandresolveAgentRunConfigSelectionalready consume the map, so MCP options and dispatch validation pick it up unchanged.normalizeReasoningEffortSelectorsrebuilds the thought-level selector from the per-model ladder the capability source publishes (cached runtime map or static builtin table), in both the selector builders and the selection resolution, so the picker follows the selected model before any probe and after it. The map is a required field of the selection input, so the session, draft, and Role composer call sites cannot drop it silently; the Role editor passes its pinned model so its picker and compatibility check agree on the same ladder. The selection resolution returns the re-normalized selectors, so dispatch filtering follows the resolved model instead of dropping a value the stale candidate selector does not list. A model the map does not cover keeps the probe-time list: the adapter is the authority on the wire and rejects an unsupported effort with a visible warning, so the UI does not duplicate that guard. (A UI-side withdrawal was added during review and rolled back — staying correct needed a four-branch rule plus an explicit measured-model pipeline, for a second guard behind the adapter's; the rollback restores the pre-fix behavior for uncovered models, which the issue's repro does not depend on.) Codex keeps its own hardcoded extended-effort table for now; migrating Codex onto the map and deleting that table is a follow-up.Before / after
high/low/maxxhigh/high/medium/lowreasoning_effortvalidated against the probed model's ladder in the adapterlody_session_create_optionsreports one flatreasoningEffortValuesmodels[].reasoningEffortValuesfor GrokTest plan
packages/acp-extension-grok:npm test— 39 passing (model-switch rebuild, effort validation/translation against the selected model, control withdrawal for unmeasured models, runtimemodel_changedtranslation, still-valid effort survives a switch, published meta).apps/cli:npx vitest run tests/acp-capability-normalization.test.ts src/mcp/lody-mcp-server.test.ts src/commands/session.test.ts— passing;tsc --noEmitclean.packages/components:npx vitest run tests/acp-selector-options.test.ts tests/acp-session-config-selection.test.ts tests/session-config-selection-oscillation.test.tsx tests/agent-role-form.test.ts— passing (Grok picker rebuild from cache, Codex stays on its hardcoded path, re-normalization against the resolved model, required-field wiring enforced by typecheck).packages/shared:npx vitest run— 995 passing.pnpm typecheck,pnpm lint(0 errors),pnpm lint:i18n,pnpm check:code-collab-imports,pnpm check:platform-boundaries,pnpm check:public-boundary— all pass. Fulltest:ciwas not run; the known environment-related component failures (app-initializer, app-store-review, clear-local-cache) reproduce on a clean checkout without this change.Context handoff
Instructions for reviewing agents
packages/components/src/components/shared/acp-selector-options.ts(normalizeReasoningEffortSelectorsand the required-field plumbing),apps/cli/src/agent/acp-capability-normalization.ts(the zod-scoped_meta.lodyread and merge), and the three composer call sites that now carry the map._meta.lody.modelReasoningEffortscontract mirrors the inbound_meta.lody.sessionConfigconvention (documented in AGENTS.md, not declared in acp-extension-core) — say the word if you prefer it in core; deferred items below are real but out of scope.Authoring context
_metamust not leak into Lody business code; the Grok adapter's startupsessionConfigtranslation (model/effort at session start) is untouched.mediumtier over the ladder's first (most expensive) entry — pinned by a test; the UI keeps the probe-time list for a model the map does not cover instead of withdrawing the control — the adapter withdraws and rejects on the wire, so the picker stays a display of the adapter's truth rather than a second guard. The adapter half settles bare model switches on the target model's published default (the official runtime's semantics, per fix: follow the selected model's reasoning-effort ladder acp-extension-grok#11).mediumand does not use the vendor's per-model default (the contract does not carry defaults yet); the provisional (non-authoritative) selection branch still takes stored values verbatim, matching its documented policy — a runtime rejection surfaces a visible warning; registry/custom agents' model choice lives inconfigOptionValues, whichresolveSelectedModelIddoes not read — no such agent publishes the map today; a capability probe that times out before the models snapshot publishes no map until the next probe; a UI-side withdrawal of the effort control for uncovered models (if a silent guard ahead of the adapter's rejection is ever wanted) would need the contract to carry the measured model explicitly. All are recorded as follow-ups; no machine-level end-to-end Grok run was performed here.