Skip to content

fix(acp): treat other models' effort menus as unknown so new chats can seed an effort - #31998

Closed
pandudpn wants to merge 1 commit into
stablyai:mainfrom
pandudpn:fix/acp-model-only-message
Closed

pandudpn wants to merge 1 commit into
stablyai:mainfrom
pandudpn:fix/acp-model-only-message

Conversation

@pandudpn

@pandudpn pandudpn commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

When you open a new OMP chat on a model other than OMP's starting model, Orca sends that model plus your thinking level. Orca's saved model list said that model had no thinking levels at all, so it refused to create the chat and the desktop showed "Chat connection could not be confirmed." OMP never said that; it only lists thinking levels for the model a session is running. Orca now records "unknown" for the other models and lets the agent decide.

What Changed

Before: AcpStructuredOptions.read() gave every model except the session's current one efforts: [] when the dialect has no per-model menu (OMP has no modelEfforts). The catalog stored those rows, and assertAgentSessionOptionsAdmitted reads an explicit empty menu as "admits none" (agentSessionEffortLevels). A new chat seeded with {model: 'omniroute/coding-max', effort: 'xhigh'} was refused with agent_session_operation_invalid / optionRejected, before any session record was written.

After: when the agent reports a thought_level option but no per-model menu, models other than the current one get { efforts: [], effortsKnown: false }. agentSessionEffortLevels returns null for those rows, so admission lets the effort through. Catalog persistence already keeps effortsKnown: false (agent-model-catalog-persistence.ts).

Unchanged:

  • The current model still takes the session's menu.
  • A dialect that advertises menus (Grok) keeps its explicit rows, including real empty ones.
  • An agent with no thought_level option keeps efforts: [], so an effort is still refused there.

This PR first carried the send-path guard fix. #32004 shipped that fix upstream, so I rebased onto main and replaced the old commit with this one.

Why

#32004 fixed sending a message after a model-only change. The same report shows up again on 1.4.239 one step earlier, at chat creation, because the composer seeds an effort (OMP's defaultThinkingLevel) and the catalog row for the seeded model claims no efforts.

Alternative considered: copying the session's effort menu onto every model. Rejected, because Orca would then claim menus OMP never reported for those models.

Linked Issue

Fixes #31995

Visual Proof

N/A. No interface changes. The difference is that the create request is accepted instead of failing behind the "Chat connection could not be confirmed." banner.

Testing

pnpm exec vitest run src/main/acp/acp-structured-options.test.ts src/main/acp/acp-model-catalog-probe.test.ts src/main/acp/acp-structured-session-adapter.test.ts
# 44 passed
pnpm exec oxlint src/main/acp/acp-structured-options.ts src/main/acp/acp-structured-options.test.ts
pnpm exec oxfmt --check src/main/acp/acp-structured-options.ts src/main/acp/acp-structured-options.test.ts

Throwaway check (not committed): an OMP-shaped session (model + thought_level config options, current model omniroute/chat) fed into assertAgentSessionOptionsAdmitted('omp', models, { model: 'omniroute/coding-max', effort: 'xhigh' }). It throws on main and passes on this branch. An unlisted effort on the current model is still refused.

tsc -p config/tsconfig.node.json reports two errors in src/main/git/command-runner/exec-file-capture.ts. They come from main and have nothing to do with this change.

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

AI Disclosure

The patch and tests were drafted with an AI coding agent (OMP, running an OmniRoute-hosted model), then reviewed and verified on macOS by the reporter.

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Cross-platform: main-process TypeScript only, no paths or platform APIs.

Checklist

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

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 176fd2b2-fb4d-4895-87f6-af8bc8580ccf
Commits

Reviewing files that changed from the base of the PR and between 6ec0c15e68b95fea09b28dcf2b5d9272181ac106 and d59d1eb.

Files selected for processing: 2
  • src/main/acp/acp-structured-options.test.ts
  • src/main/acp/acp-structured-options.ts

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

Walkthrough

The ACP structured-options reader now distinguishes an unknown effort menu from a known-empty menu for non-current models. The test expects model-a’s effort menu to be unknown when the session effort menu belongs to model-b. The current model continues to use the session effort choices.

Priority: Normal

Severity of issue fixed: Medium

Merge Risk: Minimal · up to d59d1

The change preserves delivery of model-only ACP messages while retaining protection when an effort selected by Orca cannot be restored.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title names the main change: models other than the current one now have their effort menus marked unknown, so new chats can seed an effort. It uses the fix(acp) convention and stays specific to th…
Description check Passed The description follows the repository template closely. It has ELI5, What Changed, Why, Linked Issue (Fixes #31995), Visual Proof marked N/A with a reason, Testing with commands and results, AI Discl…
Linked Issues check Passed Issue #31995 requires a saved model without a saved effort to remain deliverable while the agent retains its own thinking level. AcpStructuredOptions.read() now marks non-current models as `effortsK…
Out of Scope Changes check Passed The pull request changes ACP model-effort catalog facts and updates the related regression test. These changes directly support issue #31995 by distinguishing an unknown effort menu from a confirmed e…
Full details: Title check

Explanation

The title names the main change: models other than the current one now have their effort menus marked unknown, so new chats can seed an effort. It uses the fix(acp) convention and stays specific to the ACP options code. It is a single sentence, a bit long at 85 characters, but it is clear.

Full details: Description check

Explanation

The description follows the repository template closely. It has ELI5, What Changed, Why, Linked Issue (Fixes #31995), Visual Proof marked N/A with a reason, Testing with commands and results, AI Disclosure, the upstream boundary checkbox, Notes, and the checklist. It explains the before and after behavior and the alternative that was rejected. The Testing section shows the author ran targeted tests, lint, and format checks. The full pnpm lint, typecheck, test, and build checks were left to CI, which the author states openly. The 'Review' heading is empty, which is a minor gap.

Full details: Linked Issues check

Explanation

Issue #31995 requires a saved model without a saved effort to remain deliverable while the agent retains its own thinking level. AcpStructuredOptions.read() now marks non-current models as effortsKnown: false when the agent reports an effort option but does not advertise a per-model menu. This prevents an explicit empty effort list from rejecting the seeded effort. The current model still uses the session menu, and dialect-provided per-model menus remain supported. The updated test verifies that the non-current model has an unknown, not empty, effort menu.

Full details: Out of Scope Changes check

Explanation

The pull request changes ACP model-effort catalog facts and updates the related regression test. These changes directly support issue #31995 by distinguishing an unknown effort menu from a confirmed empty menu. No unrelated implementation or test changes appear in the whole-PR diff.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

❤️ Share

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

…n seed an effort

An ACP agent without per-model effort metadata (OMP) only reports the
running session's thought_level menu. Every other model was recorded with
efforts: [], which admission reads as 'offers no effort', so a new chat
seeded with that model plus an effort was refused with optionRejected.
Mark those rows effortsKnown: false instead.
@pandudpn
pandudpn force-pushed the fix/acp-model-only-message branch from 6ec0c15 to d59d1eb Compare October 25, 2026 06:31
@pandudpn pandudpn changed the title fix(acp): keep model-only messages deliverable fix(acp): treat other models' effort menus as unknown so new chats can seed an effort Oct 25, 2026
@nwparker

Copy link
Copy Markdown
Contributor

Thanks @pandudpn — your analysis was spot on. Your commit is included in #33646 (with you as author), which marks non-current OMP models' efforts as unknown, plus a small follow-up so a model that later gets a real menu is checked strictly again. Closing in favor of #33646.

@nwparker nwparker closed this Oct 25, 2026
nwparker added a commit that referenced this pull request Oct 25, 2026
…ort in new chats (#33646)

OMP native chats keep a remembered or explicit effort on models other than OMP's current one: for dialects that clamp unlisted efforts themselves (OMP only, via clampsUnlistedEffort), non-current models' efforts are recorded as unknown instead of "admits none"; catalog merges keep an older explicit empty list. OpenCode keeps main's behaviour.

Fixes #31995
Supersedes #31998

Co-authored-by: Pandu dwi Putra <218730385+pandudpn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: OMP native chat rejects every message when the saved model differs from OMP's default and no effort is saved

2 participants