Skip to content

fix: preserve native model reasoning capabilities - #579

Merged
pedronauck merged 1 commit into
mainfrom
model-catalog
Sep 9, 2026
Merged

pedronauck merged 1 commit into
mainfrom
model-catalog

Conversation

@pedronauck

Copy link
Copy Markdown
Member

What & why

New models could appear in the catalog without their supported reasoning levels, and selecting an unsupported Cursor combination could return an internal server error. Discovery and merging were losing provider metadata, while a closed effort enum rejected Ultra and future provider identifiers.

  • Discover Codex models and per-model efforts through the native app-server, including pagination and account-specific visibility. Read OpenCode verbose capabilities and variants, preserve complete large CLI responses, and qualify OpenCode Zen model IDs correctly.
  • Preserve Cursor launch-bound reasoning profiles and return HTTP 400 for unsupported combinations. Carry advertised effort identifiers through storage, HTTP/UDS, the SDK, and Web without a hardcoded acceptance list.
  • Refresh expired persisted discovery state, preserve ACP options during session hydration, and serialize runtime-selection writes using acknowledged revisions.

How you verified it

  • Root Turborepo Web lane: 7,106 tests across 771 files passed, typecheck passed, lint reported zero warnings/errors.
  • Production Web build passed; Vite reported CSS optimizer and bundle-size warnings documented in the QA report. Windows compilation of the model-catalog package passed.
  • Focused model-catalog race tests passed. The final local gate passed codegen-check and Go lint (zero issues), plus the corrected OpenAPI/SDK suites before it was stopped. A preceding run passed session and globaldb, with only those subsequently corrected contract expectations failing.
  • Isolated native-provider walkthrough: Astra Ultra returned ASTRA_ULTRA_OK; Cursor Grok 4.6 Extra high created the exact requested file; OpenCode Grok 4.6 Extra high returned OPENCODE_REASONING_OK and acknowledged the selected model and effort through ACP. Grok 4.5 and Luna displayed their own advertised effort ranges. Invalid Cursor Ultra returned 400 and preserved the previous selection. Three OpenCode refreshes completed successfully.
  • QA evidence audit passed with zero blockers/warnings; lab teardown recorded clean: true.

The maintainer explicitly requested publishing this PR and running the remaining full gates in CI. The local gate was stopped accordingly; a complete local gate pass is not claimed.

QA report · Research and diagnosis

Impact

Reasoning effort fields accept additional advertised string identifiers; existing field names, routes, CLI surfaces, and the public SDK ReasoningEffort export remain intact. No SQLite schema change is required. Native runtime membership validation remains authoritative. Model-catalog docs, the official Compozy skill reference, and the affected QA scenarios are updated.

Cross-surface impact audit. The historical queue/session/window-manager errors are documented as unproven causes outside the reproduced catalog failures. The production daemon was not restarted.


  • Required full CI gates are green (pending CI; local completion deferred at maintainer request)
  • Changed behavior is covered by existing owning suites and real native-provider execution
  • Agent contribution disclosed: implemented and verified by Codex

@vercel

vercel Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
compozy-site Ready Ready Preview Sep 9, 2026 5:11pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 14 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: e58331be-bd66-44a2-811f-00631bdb67b5

📥 Commits

Reviewing files that changed from the base of the PR and between 9b422f1 and 4e0c2fd.

⛔ Files ignored due to path filters (15)
  • .audits/exploration/20260909-model-catalog/analysis/01_analysis_competitors.md is excluded by !**/*.md
  • .audits/exploration/20260909-model-catalog/analysis/02_analysis_catalog.md is excluded by !**/*.md
  • .audits/exploration/20260909-model-catalog/analysis/03_analysis_selector_runtime.md is excluded by !**/*.md
  • .audits/exploration/20260909-model-catalog/analysis/04_analysis_upstream.md is excluded by !**/*.md
  • .audits/exploration/20260909-model-catalog/analysis/summary.md is excluded by !**/*.md
  • .audits/exploration/20260909-model-catalog/change-impact.md is excluded by !**/*.md
  • docs/qa/reports/2026-09-09-model-catalog-reasoning.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-web-runtime-selector-minimal-slider.md is excluded by !**/*.md
  • docs/qa/scenarios/RT-cursor-agent-mode.md is excluded by !**/*.md
  • docs/qa/scenarios/RT-model-catalog-cold-open.md is excluded by !**/*.md
  • openapi/compozy.json is excluded by !**/*.json
  • packages/site/content/docs/agents/model-catalog.mdx is excluded by !**/*.mdx
  • sdk/typescript/src/generated/contracts.ts is excluded by !**/generated/**, !**/generated/**
  • skills/compozy/references/runtime-operations.md is excluded by !**/*.md
  • web/src/generated/compozy-openapi.d.ts is excluded by !**/generated/**, !**/generated/**, !**/*.d.ts
📒 Files selected for processing (46)
  • internal/api/core/handlers_test.go
  • internal/api/spec/schema_enum_registry.go
  • internal/api/spec/spec_test.go
  • internal/cli/loop_runtime_flag_test.go
  • internal/codegen/sdkts/enum_registry.go
  • internal/codegen/sdkts/generate_test.go
  • internal/config/agent_test.go
  • internal/config/provider_builtin.go
  • internal/config/provider_test.go
  • internal/config/roles_test.go
  • internal/extension/model_source_test.go
  • internal/loop/runtime_validation_test.go
  • internal/modelcatalog/live_model_rows.go
  • internal/modelcatalog/live_model_rows_cursor.go
  • internal/modelcatalog/live_model_rows_opencode.go
  • internal/modelcatalog/live_sources.go
  • internal/modelcatalog/live_sources_acp.go
  • internal/modelcatalog/live_sources_adapters.go
  • internal/modelcatalog/live_sources_codex.go
  • internal/modelcatalog/live_sources_command.go
  • internal/modelcatalog/live_sources_test.go
  • internal/modelcatalog/modelsdev.go
  • internal/modelcatalog/modelsdev_test.go
  • internal/modelcatalog/reasoning.go
  • internal/modelcatalog/reasoning_merge.go
  • internal/modelcatalog/service_bootstrap.go
  • internal/modelcatalog/service_test.go
  • internal/modelcatalog/sources_test.go
  • internal/reasoning/effort.go
  • internal/reasoning/effort_test.go
  • internal/session/manager_runtime_model_validation.go
  • internal/session/manager_test.go
  • internal/session/runtime_overrides.go
  • internal/store/globaldb/global_db_model_catalog_test.go
  • web/src/lib/api-contract.ts
  • web/src/systems/agent/components/__tests__/agent-create-dialog.test.tsx
  • web/src/systems/agent/hooks/__tests__/use-agent-create-dialog.test.tsx
  • web/src/systems/agent/lib/__tests__/agent-create-draft.test.ts
  • web/src/systems/model-catalog/lib/__tests__/to-runtime-selector-options.test.ts
  • web/src/systems/model-catalog/lib/to-runtime-selector-options.ts
  • web/src/systems/runtime/components/runtime-selector/__tests__/runtime-selector.test.tsx
  • web/src/systems/runtime/components/runtime-selector/types.ts
  • web/src/systems/runtime/components/runtime-selector/use-reasoning-slider.ts
  • web/src/systems/session/contexts/session-prompt-runtime-context.tsx
  • web/src/systems/session/hooks/__tests__/use-session-prompt-runtime.test.tsx
  • web/src/systems/session/hooks/use-session-prompt-runtime.ts

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.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

React Doctor found 1 new issue in 1 file · 1 warning · score 93 / 100 (Great) · 1 fixed · vs main

1 warning

src/systems/session/hooks/use-session-prompt-runtime.ts

  • ⚠️ L85 React function has high control-flow complexity no-high-complexity-react-function

Reviewed by React Doctor for commit 4e0c2fd. See inline comments for fixes.

@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR preserves provider-native reasoning capabilities across discovery, persistence, contracts, runtime selection, and the Web UI.

  • Adds paginated native Codex app-server discovery and verbose OpenCode capability parsing.
  • Preserves open-ended provider effort identifiers through Go, OpenAPI, SDK, and Web contracts.
  • Retains Cursor transport-bound reasoning profiles and maps unsupported selections to client errors.
  • Refreshes expired persisted discovery state and hydrates ACP option selections.
  • Serializes Web runtime writes, but conflict recovery still retries queued updates before acknowledging the latest server revision.

Confidence Score: 4/5

The PR is not yet safe to merge because queued runtime selections can be lost after a revision conflict.

Successful queued writes use acknowledged revisions, but the conflict path retries immediately before the asynchronously refreshed session revision reaches the store, causing repeated conflicts for the latest selection.

Files Needing Attention: web/src/systems/session/hooks/use-session-prompt-runtime.ts

Important Files Changed

Filename Overview
internal/modelcatalog/live_sources_codex.go Adds bounded, paginated Codex app-server discovery and preserves per-model reasoning metadata.
internal/modelcatalog/live_model_rows_opencode.go Parses OpenCode verbose model metadata and provider-advertised reasoning variants.
internal/modelcatalog/reasoning_merge.go Retains reasoning profiles backed by provider-specific transport bindings.
internal/reasoning/effort.go Changes reasoning effort validation from a closed enum to extensible provider identifiers.
internal/session/manager_runtime_model_validation.go Classifies unsupported Cursor options and missing bindings as invalid runtime overrides.
web/src/systems/session/hooks/use-session-prompt-runtime.ts Serializes runtime writes successfully, but retries queued selections with a stale revision after conflicts.
web/src/systems/session/contexts/session-prompt-runtime-context.tsx Preserves effective and selected ACP options during session hydration.
web/src/systems/model-catalog/lib/to-runtime-selector-options.ts Passes well-formed provider-specific effort identifiers into runtime selector options.

Sequence Diagram

sequenceDiagram
  participant UI as Runtime selector
  participant Hook as Session runtime hook
  participant API as Runtime API
  participant Store as Session store
  UI->>Hook: Select runtime A
  Hook->>API: PUT A (expected revision N)
  UI->>Hook: Select runtime B
  Hook->>Hook: Queue B
  API-->>Hook: 409 conflict
  Hook->>Store: Reset optimistic selection
  Hook-->>API: PUT B (still revision N)
  API-->>Hook: 409 conflict
  Note over Hook,Store: Refreshed revision arrives too late
Loading

Reviews (1): Last reviewed commit: "fix: preserve native model reasoning cap..." | Re-trigger Greptile

Comment on lines 205 to +212
onSettled: () => {
if (runtimeSelectionController.current === controller) {
runtimeSelectionController.current = null;
const queued = queuedSelection.current;
queuedSelection.current = null;
if (queued && !controller.signal.aborted) {
persistRuntimeSelection(queued.value, queued.speed);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Queued retry uses stale revision

When an in-flight runtime update returns 409 because another client advanced the session revision, onSettled immediately retries the queued selection with the same stale revision. The conflict handler only starts an asynchronous session refresh, while the retry is sent synchronously before that refresh updates the store. The second request therefore conflicts again, and the user's latest runtime selection is not persisted. Wait for the refreshed revision before retrying, or retain the queued selection until that revision is acknowledged.

This branch was successfully deployed

1 active deployment
Preview — 4e0c2fda Deployed Sep 9, 2026 by vercel[bot]
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.

1 participant