-
Notifications
You must be signed in to change notification settings - Fork 960
feat(cursor): umbrella capability catalog — single source of truth for model identities #2801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd5b7c5
3cdb77f
2be819e
54965ef
22c073e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # 260828 cursor umbrella catalog — unit plan (wp1 docs-only) | ||
|
|
||
| Goal: collapse the 69-row hand-maintained cursor picker into per-base umbrella | ||
| rows (thinking merged, fast inside, 1M/Max-Mode generalized), sourced from a | ||
| single capability module informed by senpi's architecture but cleaner. | ||
|
|
||
| ## Loop-spec | ||
|
|
||
| - Archetype: spec-satisfaction. Verifiers per phase: bun test <file>, tsc, | ||
| privacy scan, catalog sync output row counts. Repo-wide suite forbidden. | ||
| - References: senpi (scratch path in /tmp/senpi-scratch.txt) — capability | ||
| table/grouping/selection cited in 001; omo-ai@beta has NO cursor model map | ||
| (verified — provider-map.json is a provider-name alias list only). | ||
| - Non-goals: other providers, releases, protobuf schema changes. | ||
| - Bounds: ~10h wall; stacked PRs codex/* -> dev pre-approved, --no-verify ok, | ||
| unlimited subagents (sol + xai/grok-4.6). | ||
| - Terminal: DONE per goalplan c1-c5; NEEDS_HUMAN for user-visible id renames | ||
| beyond aliasing. | ||
|
|
||
| ## Work-phase map | ||
|
|
||
| - wp1 docs (this cycle): 000-002 research + 010/020/030 decade docs. | ||
| - wp2 (010): capability core module + variant grammar + umbrella grouping. | ||
| - wp3 (020): catalog integration (discovery/registry/sync/request path). | ||
| - wp4 (030): closure — cleanliness comparison + picker proof + stack final. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # 001 — senpi/omo architecture analysis (sol-high lane, verified) | ||
|
|
||
| ## senpi (packages/ai/src/cursor/*) | ||
|
|
||
| - CURSOR_MODEL_CAPABILITIES (model-capabilities.ts:81-195): 34 capability ids, | ||
| schema { evidence, window, maxWindow?, parameterOrder, defaultContext?, | ||
| requestContext?, levels: {level -> {value, encoding: parameters|variant-id}} }. | ||
| Claude order [thinking,context,effort]; GPT [context,reasoning,fast]. | ||
| 1M via requestContext="1m" when window>=1M. | ||
| - Variant grammar (model-capabilities.ts:204-248): strip terminal -fast; then | ||
| -thinking-<level> | -<level>-thinking | -thinking | -<level>; tokens | ||
| minimal|low|medium|high|extra-high|xhigh|max|none. | ||
| - Grouping (catalog-grouping.ts): group key = targetId + fast — FAST IS A | ||
| SEPARATE GROUP; Claude-only thinkingMode split (isClaude guard :45-47); | ||
| members with efforts collapse to one entry with thinkingLevelMap; 336-row | ||
| generated alias JSON maps live ids -> {targetId, level, legacyVariantId}. | ||
| - Wire (selection-descriptor.ts:85-120): alias-first — send catalog-served | ||
| suffix id when known (Cursor Run rejects bare capability ids with Connect | ||
| not_found, issue #1008); parameters fallback only when no alias; fast | ||
| parameter hardcoded "false" (fast reachable only via separate fast ids). | ||
| - Discovery (cursor-agent.ts:4362-4495): 1M inferred from display-name /\b1m\b/i | ||
| labels OR maxMode on /claude|gemini/ ids; reads thinkingDetails for | ||
| reasoning flag; multimodal from id pattern. | ||
|
|
||
| ## senpi weaknesses (our targets) | ||
|
|
||
| 1. Fast modeled twice (parameter always false + separate groups) — incoherent. | ||
| 2. Claude-only thinkingMode split — separate thinking identities remain rows. | ||
| 3. Truth split across static TS table + 336-row generated JSON + name regex. | ||
| 4. variant-id fallback silently degrades to representative id. | ||
|
|
||
| ## omo-ai@beta | ||
|
|
||
| provider-map.json contains ZERO cursor model rows (cursor only in | ||
| builtinProviderIds; 5 provider-name aliases). Cursor architecture is delegated | ||
| to its pinned senpi runtime. Nothing to adopt beyond "don't do this" — | ||
| objective's cleanliness bar vs omo is met by having any self-contained map. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # 002 — current opencodex cursor surface (grok-4.6 lane, verified) | ||
|
|
||
| - effort-map.ts (229 L): CURSOR_MODEL_EFFORT_TIERS 46 hand-kept ids; | ||
| CURSOR_THINKING_FAMILIES 13 ids with per-family wire order; consumers: | ||
| discovery.ts + request-builder.ts only. | ||
| - discovery.ts: 69-row static seed (4 router + 52 + 13 thinking); | ||
| inferCursorContextWindow (:27-38) hardcodes per-family windows; synthetic | ||
| ultra marker = kimi-k3-1m ONLY (:158-174); live merge is a FILTER (45 of 69 rows carry ladders; quarantined opus-5 is a map key but not seeded) (never | ||
| adds rows, provider-fetch.ts:1276); claude-opus-5 quarantined; dead | ||
| CURSOR_REASONING_EFFORTS const. | ||
| - live-models.ts: decode keeps modelId + maxMode only; DISCARDS displayName, | ||
| displayNameShort, displayModelId, aliases, thinkingDetails; maxModeModels | ||
| returned but unconsumed. | ||
| - sync.ts/effort.ts: picker rows cursor/<id>, efforts via | ||
| cursorModelReasoningEfforts; synthetic max+ultra appended (effort.ts:219); | ||
| kimi-k3-1m default effort falls to high (not pinned). | ||
| - request path (request-builder.ts:189, protobuf-request.ts:996): suffix-id | ||
| first; parameters only for grok-fast / router level / maxMode(ultra); | ||
| thinkingDetails never sent. | ||
| - Duplicate rows today: 13 thinking + 7 fast + 2 x 1m = 22 of 69 are variants | ||
| of a base. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| # 003 — umbrella design (locks the shape both implementation phases build) | ||
|
|
||
| ## Principles (beats senpi where it is weak) | ||
|
|
||
| 1. ONE source of truth: a single capability module owns the variant grammar, | ||
| per-base levels, thinking/fast/1M dimensions, and wire encoding. No second | ||
| generated alias JSON (senpi weakness 3): aliases are DERIVED by the grammar, | ||
| not enumerated. | ||
| 2. Thinking MERGES into the base identity for every family (no Claude-only | ||
| split — senpi weakness 2) AS A DIMENSION, not by discarding identities | ||
| (A-gate blocker 1): the capability schema carries per-variant ladders | ||
| ({ regular?, thinking?, fast?, thinkingFast? } each with its own effort | ||
| list + wire order), because live ladders differ (claude-opus-5-fast | ||
| low/med/high vs thinking-fast low..max). The UMBRELLA ROW defaults to the | ||
| thinking variant when one exists (user decision: "thinking 하나로 합치고"); | ||
| regular/fast/thinking-fast remain reachable via aliases that select the | ||
| variant dimension explicitly. resolveCursorSelection takes the PICKED id | ||
| (which encodes the variant via the alias) — never guesses. | ||
| 3. Fast is a dimension INSIDE the umbrella (senpi weakness 1): no fast picker | ||
| rows; cursor/<base>-fast stays routable as an alias that sets fast mode on | ||
| the same umbrella identity. | ||
| 4. 1M split into TWO separate capabilities (A-gate blocker 4 — window size | ||
| does NOT imply maxMode; prior probes found maxMode only on opus-fast | ||
| variants, 260822_senpi_cursor_transfer/210+310): | ||
| - window: context-window METADATA generalized per senpi's table (1M for | ||
| claude/gemini/kimi/gpt-5.6 families) — display/routing metadata only. | ||
| - maxMode (ultra rung): gated on EVIDENCE — the union of live | ||
| maxModeModels (decoded in live-models.ts:123-136, discarded by | ||
| provider-fetch today) and an explicit verified static list (currently | ||
| exactly kimi-k3, user-verified). Ultra generalizes automatically as live | ||
| evidence arrives, never from window size. | ||
| 5. Back-compat absolute (A-gate blockers 2/3): | ||
| - Parser precedence: EXACT known identity/alias table first (covers | ||
| gpt-5.1-codex-max-as-base, gpt-5.5-extra, claude-4-sonnet-1m real wire | ||
| id), then cursor- prefix normalization (cursor-grok-4.5/4.6 wire forms), | ||
| then suffix grammar. A frozen fixture table pins parse+resolve for all | ||
| 69 picker ids + observed prefixed/suffixed wire forms. | ||
| - Alias retention contract: picker ROWS shrink, but the REQUEST path keeps | ||
| resolving every legacy slug (router forwards provider-qualified ids to | ||
| the adapter, router.ts:673-678; the adapter's resolver owns aliases). | ||
| A pinned session/config naming a removed slug keeps routing identically; | ||
| only fresh picker lists shrink. Tested explicitly (020). | ||
|
Comment on lines
+38
to
+42
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Normalize the provider-qualified The parser currently normalizes only the
📍 Affects 2 files
🤖 Prompt for AI Agents |
||
| - Quarantine is VARIANT-specific: claude-opus-5 regular stays quarantined | ||
| while thinking/fast siblings remain selectable. | ||
|
|
||
| ## Picker shape (after) | ||
|
|
||
| - Rows: 4 router + ~30 base umbrellas (from 69). Efforts per row from the | ||
| default-variant ladder. Synthetic max+ultra spawn-validation appendage | ||
| (effort.ts:219-226) is a SEPARATE policy from wire ultra: effort.ts stays | ||
| in the diff (blocker 5) — synthetic max/ultra continue to be appended for | ||
| spawn validation on every reasoning row (no downstream break), while the | ||
| WIRE maps ultra to maxMode only for evidence-gated bases and clamps to the | ||
| ladder top elsewhere (exactly today's clamp behavior). | ||
| - Codex effort -> wire: suffix-id-first (Cursor rejects bare capability ids, | ||
| senpi #1008 confirmed + our own request-builder already suffix-first). | ||
| Thinking-capable base + effort E -> thinking wire id at E (family wire | ||
| order preserved from CURSOR_THINKING_FAMILIES). ultra -> base ladder top + | ||
| maxMode=true. Fast alias -> {stem}-{E}-fast. | ||
|
|
||
| ## Module plan | ||
|
|
||
| - NEW src/adapters/cursor/catalog.ts: capability table (schema: | ||
| { levels: readonly string[], thinking?: { wireOrder }, fast?: true, | ||
| bigContext?: true, window, quarantined?: true }), parseCursorVariantId | ||
| (senpi grammar: strip -fast; -thinking-<lvl> | -<lvl>-thinking | -thinking | ||
| | -<lvl> | -1m), resolveCursorSelection(baseOrAlias, codexEffort) -> | ||
| { wireId | wireBase+params, maxMode, fast }, umbrellaCatalog() -> | ||
| picker rows. effort-map.ts becomes a thin re-export shim during wp2 and is | ||
| DELETED in wp3 once consumers move. | ||
|
Comment on lines
+63
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Use one typed contract for the catalog and its consumers. The planning documents describe
📍 Affects 3 files
🤖 Prompt for AI Agents |
||
|
|
||
| ## NEEDS_HUMAN boundary | ||
|
|
||
| Picker row ids stay cursor/<base> (already true for bases). Removing separate | ||
| thinking/fast/1m ROWS changes what the picker lists but not what routes — | ||
| within the user's explicit instruction, so not escalated. | ||
|
Comment on lines
+74
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- repository conventions ---'
for f in /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732/*/*.md; do
[ -f "$f" ] || continue
printf '\n### %s\n' "$f"
head -80 "$f"
done
printf '%s\n' '--- target document ---'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/003_design.md | sed -n '1,130p'
printf '%s\n' '--- related umbrella-row references ---'
rg -n -i -C 3 'umbrella|picker row|row id|claude-opus-5|cursor/' devlog test tests .github 2>/dev/null | head -300Repository: lidge-jun/opencodex Length of output: 50377 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- plan files ---'
git ls-files 'devlog/_plan/260828_cursor_umbrella_catalog/*'
printf '%s\n' '--- exact test and identifier references ---'
rg -n -C 5 'claude-opus-5|umbrellaCatalog|picker.*row|row.*id|cursor/<base>|cursor/' \
tests src devlog/_plan/260828_cursor_umbrella_catalog \
-g '*.ts' -g '*.md' | head -500
printf '%s\n' '--- catalog and registry candidates ---'
git ls-files 'src/**' | rg -i 'cursor|catalog|registry|model'Repository: lidge-jun/opencodex Length of output: 46794 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- cursor catalog ---'
cat -n src/adapters/cursor/catalog.ts | sed -n '1,280p'
printf '%s\n' '--- cursor discovery ---'
cat -n src/adapters/cursor/discovery.ts | sed -n '1,260p'
printf '%s\n' '--- planned integration and closure contracts ---'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/020_catalog_integration.md | sed -n '1,180p'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/030_closure.md | sed -n '1,180p'
printf '%s\n' '--- picker construction and registry boundary ---'
rg -n -C 6 'gatherRoutedModels|cursorModel|providerName.*model|model.*provider|new Model|id:.*cursor|provider/|defaultAliases|registry' \
src/codex/catalog src/adapters/registry.ts src/cli/registry.ts src/providers/registry.ts \
-g '*.ts' | head -500Repository: lidge-jun/opencodex Length of output: 50375 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- catalog row/ID functions ---'
rg -n -C 12 'export function (cursorUmbrellaRows|cursorModelIds)|cursorUmbrellaRows|modelIds|provider/' src/adapters/cursor/catalog.ts src/adapters/cursor/discovery.ts
printf '%s\n' '--- discovery exports and ID mapping ---'
cat -n src/adapters/cursor/discovery.ts | sed -n '250,520p'
printf '%s\n' '--- registry cursor entry ---'
cat -n src/providers/registry.ts | sed -n '1088,1120p'
printf '%s\n' '--- catalog sync qualification ---'
rg -n -C 10 'provider.*model|model.*provider|`${.*provider|model.id|providerName' src/codex/catalog/sync.ts src/codex/catalog/bundled.ts src/codex/catalog/native-models.ts src/codex/catalog/provider-fetch.ts src/codex/catalog.tsRepository: lidge-jun/opencodex Length of output: 16741 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- umbrella row type and implementation ---'
cat -n src/adapters/cursor/catalog.ts | sed -n '430,490p'
printf '%s\n' '--- provider catalog model qualification ---'
rg -n -C 8 -e 'providerName' -e 'providerId' -e '`${.*\/.*}`' -e 'model.id' \
src/codex/catalog src/codex/catalog.ts src/server/management/model-rows.ts \
-g '*.ts' | head -400
printf '%s\n' '--- routed-model assembly ---'
rg -n -C 10 -e 'gatherRoutedModels' -e 'provider.*\/.*model' -e 'modelId.*provider' \
src/codex src/server src/providers -g '*.ts' | head -400Repository: lidge-jun/opencodex Length of output: 37925 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- routed model fetch and qualification ---'
rg -n -C 12 -F 'provider:' src/codex/catalog/provider-fetch.ts src/codex/catalog.ts src/codex/catalog/sync.ts
rg -n -C 12 -F 'modelId:' src/codex/catalog/provider-fetch.ts src/codex/catalog.ts src/codex/catalog/sync.ts
rg -n -C 12 -F 'provider/model' src/codex/catalog/provider-fetch.ts src/codex/catalog.ts src/codex/catalog/sync.ts
printf '%s\n' '--- model row assembly definitions ---'
rg -n -C 15 -e 'function .*Routed' -e 'function .*Catalog' -e 'type CatalogModel' -e 'interface CatalogModel' \
src/codex/catalog/provider-fetch.ts src/codex/catalog.ts src/codex/catalog/sync.tsRepository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- Cursor discovery-to-catalog path ---'
cat -n src/codex/catalog/provider-fetch.ts | sed -n '1278,1335p'
cat -n src/codex/catalog/provider-fetch.ts | sed -n '1880,1925p'
cat -n src/codex/catalog/provider-fetch.ts | sed -n '2078,2108p'
printf '%s\n' '--- routed slug contract and catalog serialization ---'
rg -n -C 8 -F 'function routedSlug' src
rg -n -C 8 -F 'routedSlug(' src/codex/catalog.ts src/codex/catalog/sync.ts src/codex/catalog/provider-fetch.tsRepository: lidge-jun/opencodex Length of output: 19704 Document the picker row ID boundary.
🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # 004 — roadmap lock (wp1 B closure) | ||
|
|
||
| Locked after A-gate round 1 (5 High + 2 Medium folded, 3cdb77fc8). | ||
|
|
||
| | wp | doc | branch/PR | | ||
| |---|---|---| | ||
| | wp2 | 010_capability_core.md | codex/cursor-umbrella-core -> dev | | ||
| | wp3 | 020_catalog_integration.md | codex/cursor-umbrella-wire (stacked on core) | | ||
| | wp4 | 030_closure.md | comparison + proof, docs on the wire branch | | ||
|
|
||
| Key locked decisions: variant-dimension schema (defaultVariant=thinking); | ||
| parser precedence with frozen oracle; alias retention (resolver keeps all | ||
| 69 slugs); maxMode evidence-gated (kimi-k3 + live maxModeModels union); | ||
| effort.ts synthetic policy untouched. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # 010 — wp2: capability core module (PR A, codex/cursor-umbrella-core -> dev) | ||
|
|
||
| ## Changes | ||
|
|
||
| ### 1. ADD src/adapters/cursor/catalog.ts | ||
|
|
||
| - export type CursorVariantKind = "regular" | "thinking" | "fast" | "thinkingFast"; | ||
| - export interface CursorVariantSpec { levels: readonly string[]; | ||
| order?: "thinking-then-effort" | "effort-then-thinking" | "bare"; | ||
| quarantined?: boolean } | ||
| - export interface CursorCapability { variants: Partial<Record<CursorVariantKind, | ||
| CursorVariantSpec>>; defaultVariant: CursorVariantKind; window: number; | ||
| maxModeVerified?: boolean; wirePrefix?: "cursor-" } | ||
| (A-gate blocker 1: per-variant ladders — claude-opus-5 fast low/med/high | ||
| vs thinkingFast low..max representable; defaultVariant = thinking when a | ||
| thinking variant exists, else regular; quarantine per-variant — blocker 3.) | ||
| - export const CURSOR_CAPABILITIES: Record<string, CursorCapability> — | ||
| seeded 1:1 from CURSOR_MODEL_EFFORT_TIERS + CURSOR_THINKING_FAMILIES + | ||
| senpi window table; maxModeVerified only on kimi-k3 (blocker 4); | ||
| wirePrefix "cursor-" on grok-4.5/grok-4.6 regular. | ||
| - export function parseCursorVariantId(id): { baseId, kind, level?, ultra } | ||
| with STRICT precedence (blocker 2): (1) exact base-id table hit (covers | ||
| gpt-5.1-codex-max, gpt-5.5-extra, claude-4-sonnet-1m as real identities); | ||
| (2) cursor- prefix strip + re-lookup; (3) -1m synthetic suffix; (4) senpi | ||
| suffix grammar (strip -fast; -thinking-<lvl> | -<lvl>-thinking | | ||
| -thinking | -<lvl>); tokens minimal|low|medium|high|extra-high|xhigh|max|none. | ||
| - export function resolveCursorSelection(pickedId, codexEffort?): | ||
| { wireId, maxMode, params: [] } — suffix-id-first composition reusing the | ||
| order rules currently in cursorWireModelIdWithEffort; ultra -> | ||
| top-level + maxMode when bigContext; grok fast keeps the parameter path. | ||
| - export function cursorUmbrellaRows(): { id, efforts, defaultEffort, | ||
| window, bigContext }[] — picker list derivation (router ids stay in | ||
| discovery). | ||
|
|
||
| ### 2. Tests — ADD tests/cursor-catalog.test.ts | ||
|
|
||
| Named activation per branch, with a FROZEN fixture table (all 69 seed ids + | ||
| cursor- prefixed wire forms + representative live suffix ids) asserting | ||
| (parsedBase, kind, level) AND resolved wire id byte-equality against the | ||
| CURRENT cursorWireModelIdWithEffort/cursorRequestWireModelIdWithEffort | ||
| output (generated once from the old module while it still exists — the | ||
| back-compat oracle). Plus: precedence cases (gpt-5.1-codex-max stays a base; | ||
| gpt-5.5-extra + any effort -> gpt-5.5-extra-high; cursor-grok-4.6-xhigh | ||
| round-trips); thinking default variant; bare-thinking ignores effort; | ||
| per-variant ladder divergence (opus-5 fast vs thinkingFast); ultra -> | ||
| maxMode ONLY on maxModeVerified; ultra elsewhere clamps to ladder top | ||
| without maxMode; variant-specific quarantine (opus-5 regular excluded, | ||
| thinking present); unknown id passthrough. | ||
|
|
||
| ### 3. NO consumer changes in this PR (effort-map untouched) — additive | ||
| module + tests only, so the diff reviews clean. | ||
|
|
||
| ## Verifiers | ||
|
|
||
| bun test tests/cursor-catalog.test.ts; bun x tsc --noEmit; privacy scan. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # 020 — wp3: integration (PR B, codex/cursor-umbrella-wire, stacked on PR A) | ||
|
|
||
| ## Changes | ||
|
|
||
| ### 1. MODIFY src/adapters/cursor/discovery.ts | ||
|
|
||
| - CURSOR_STATIC_MODELS: replace 52+13 explicit rows with rows generated from | ||
| cursorUmbrellaRows() (+ 4 router rows kept literal). claude-4-sonnet-1m | ||
| stays (real wire id) as alias metadata. | ||
| - CURSOR_ULTRA_1M_MODEL_IDS + cursorUltraBaseModelId: reimplement over | ||
| parseCursorVariantId ultra dimension (any bigContext base), keeping the | ||
| kimi-k3-1m alias. | ||
|
Comment on lines
+10
to
+12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Gate synthetic The current parser accepts 🤖 Prompt for AI Agents |
||
| - filterCursorConfiguredModelsByLiveDiscovery: match live suffix ids via | ||
| parseCursorVariantId(base match) instead of enumerated suffix compose. | ||
| - inferCursorContextWindow: read window from CURSOR_CAPABILITIES first, | ||
| fall through to current heuristics for unknown ids. | ||
|
|
||
| ### 2. MODIFY src/codex/catalog/provider-fetch.ts (~:1276-1310) — consume | ||
| the maxModeModels ALREADY returned by live-models.ts (:123-136; decoder | ||
| needs no change, A-gate finding 6): live maxMode ids union with | ||
| maxModeVerified static flags to arm the ultra->maxMode wire rung per base. | ||
|
Comment on lines
+18
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: printf '%s\n' '--- repository conventions ---'
find /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732 -type f -name '*.md' -maxdepth 3 -print
printf '%s\n' '--- review target ---'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/020_catalog_integration.md | sed -n '1,45p'
printf '%s\n' '--- relevant source files ---'
fd -i 'provider-fetch|live-models' .Repository: lidge-jun/opencodex Length of output: 4874 🏁 Script executed: printf '%s\n' '--- source conventions ---'
cat /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732/conventions/src.md
printf '%s\n' '--- relevant learnings ---'
cat /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732/learnings/src.md
cat /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732/learnings/src-providers.md
printf '%s\n' '--- live-models definitions and exports ---'
rg -n -C 8 'maxModeModels|parseCursorVariantId|resolveCursorSelection' src/adapters/cursor/live-models.ts src/codex/catalog/provider-fetch.ts src tests
printf '%s\n' '--- provider-fetch target ---'
cat -n src/codex/catalog/provider-fetch.ts | sed -n '1230,1335p'Repository: lidge-jun/opencodex Length of output: 30643 🏁 Script executed: printf '%s\n' '--- selection resolver ---'
cat -n src/adapters/cursor/catalog.ts | sed -n '284,330p'
cat -n src/adapters/cursor/catalog.ts | sed -n '418,475p'
printf '%s\n' '--- live discovery producer ---'
cat -n src/adapters/cursor/live-models.ts | sed -n '1,55p'
cat -n src/adapters/cursor/live-models.ts | sed -n '90,142p'
printf '%s\n' '--- provider-fetch bindings and cursor flow ---'
rg -n -C 5 'fetchCursorUsableModels|filterCursorConfiguredModelsByLiveDiscovery|resolveCursorSelection|setCached|cachedCursor|liveResult' src/codex/catalog/provider-fetch.ts src/adapters/cursor
printf '%s\n' '--- relevant test fixtures ---'
rg -n -C 8 'maxModeModels|maxMode|max.mode|prefixed|suffix|GetUsableModels' tests src/adapters/cursorRepository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: printf '%s\n' '--- catalog parser and resolver ---'
cat -n src/adapters/cursor/catalog.ts | sed -n '284,325p'
cat -n src/adapters/cursor/catalog.ts | sed -n '418,468p'
printf '%s\n' '--- cursor discovery filtering ---'
rg -n -C 12 'filterCursorConfiguredModelsByLiveDiscovery|parseCursorVariantId' src/adapters/cursor/discovery.ts
printf '%s\n' '--- provider-fetch imports and cursor branch ---'
sed -n '1,90p' src/codex/catalog/provider-fetch.ts
sed -n '1278,1338p' src/codex/catalog/provider-fetch.ts
printf '%s\n' '--- plan and related catalog notes ---'
rg -n -C 8 'maxModeModels|provider-fetch|normalize|live max' devlog/_plan/260828_cursor_umbrella_catalog devlog/_plan/260826* devlog/_plan/260822* 2>/dev/nullRepository: lidge-jun/opencodex Length of output: 50375 🏁 Script executed: printf '%s\n' '--- live-models validation and decode loop ---'
cat -n src/adapters/cursor/live-models.ts | sed -n '100,140p'
rg -n -C 6 'function isValidModelDiscoveryModelId|isValidModelDiscoveryModelId|modelId' src/adapters/cursor/live-models.ts src/adapters/cursor/*.ts
printf '%s\n' '--- parser suffix handling ---'
cat -n src/adapters/cursor/catalog.ts | sed -n '308,370p'
printf '%s\n' '--- cursor live-model tests ---'
rg -n -C 10 'maxModeModels|maxMode: true|modelId:|cursor-' tests/cursor-hardening.test.ts tests/cursor-ultra-mode.test.ts tests/provider-live-models.test.ts
printf '%s\n' '--- integration plan test requirements ---'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/020_catalog_integration.md | sed -n '42,100p'
cat -n devlog/_plan/260828_cursor_umbrella_catalog/003_design.md | sed -n '22,42p'Repository: lidge-jun/opencodex Length of output: 50375 🏁 Script executed: cat -n devlog/_plan/260828_cursor_umbrella_catalog/020_catalog_integration.md | sed -n '42,82p'
printf '%s\n' '--- model-id validation contract ---'
rg -n -C 12 'export function isValidModelDiscoveryModelId|function isValidModelDiscoveryModelId' src/providers/model-discovery-limits.ts
printf '%s\n' '--- focused live-model fixtures ---'
rg -n -C 5 'maxModeModels' tests/cursor-hardening.test.ts tests/provider-live-models.test.ts tests/cursor-ultra-mode.test.tsRepository: lidge-jun/opencodex Length of output: 2330 Normalize 🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 18-18: Headings should be surrounded by blank lines (MD022, blanks-around-headings) 🤖 Prompt for AI Agents |
||
|
|
||
| ### 3. MODIFY src/providers/registry.ts (~:1092 cursor section) — model ids | ||
| from cursorUmbrellaRows(); modelReasoningEfforts from each row's | ||
| defaultVariant ladder; modelDefaultReasoningEfforts keeps kimi-k3: max. | ||
|
|
||
| ### 3b. MODIFY src/codex/catalog/effort.ts (:219-226) — POLICY UNCHANGED | ||
| (A-gate blocker 5): synthetic max+ultra stay appended to every | ||
| reasoning-capable row for spawn validation. Add a comment distinguishing | ||
| catalog-synthetic ultra from wire maxMode. Regression test: spawn-validation | ||
| efforts for a cursor row WITHOUT maxModeVerified still include ultra, and | ||
| the adapter clamps it (existing clamp test extended). | ||
|
|
||
| ### 4. MODIFY src/adapters/cursor/request-builder.ts — normalizeCursorModelId | ||
| / effort composition delegate to resolveCursorSelection; grok-fast parameter | ||
| path preserved; ultra path generalized (maxMode for any bigContext base). | ||
|
|
||
| ### 5. DELETE src/adapters/cursor/effort-map.ts once discovery + | ||
| request-builder consume catalog.ts; migrate any residual export the tests | ||
| reference. | ||
|
|
||
| ### 6. Tests (exact paths, A-gate blocker 7): | ||
| - MODIFY tests/cursor-effort-suffix.test.ts — wire-id oracle table from 010 | ||
| stays green after consumers switch (the byte-equal back-compat proof). | ||
| - MODIFY tests/cursor-hardening.test.ts discovery sections — live filter | ||
| with suffix + cursor-prefixed fixtures via the new parser. | ||
| - ADD tests/cursor-umbrella-rows.test.ts — cursorUmbrellaRows row count | ||
| (4 router excluded; ~30 umbrellas), thinking-merged rows list their | ||
| default-variant ladder, removed slugs absent from rows but RESOLVABLE via | ||
| resolveCursorSelection (pinned-session survival unit proof), quarantined | ||
| regular excluded while thinking sibling present. | ||
| - ADD focused catalog sync test: sync output cursor section row count + | ||
| synthetic max/ultra still appended (spawn validation). | ||
| - Pinned-session integration: request with model cursor/claude-opus-5-thinking | ||
| (removed row) through request-builder resolves to same wire id as today. | ||
|
|
||
| ## Verifiers | ||
|
|
||
| bun test tests/cursor-catalog.test.ts tests/cursor-hardening.test.ts | ||
| + discovery/sync-focused files; tsc; privacy scan; catalog sync dry-run | ||
| row output captured for 030. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # 030 — wp4: closure | ||
|
|
||
| 1. Cleanliness comparison table: rows before/after (69 -> ~34), effort-map | ||
| 229 LOC deleted vs catalog.ts added, single-module truth vs senpi's | ||
| 3-surface split (static TS + 336-row JSON + regex) vs omo's absent map; | ||
| thinking merged for ALL families (senpi: Claude split remains); fast as | ||
| dimension (senpi: separate groups). | ||
| 2. Picker proof: opencodex-catalog.json cursor section before/after row | ||
| counts + one umbrella row excerpt showing efforts incl ultra. | ||
| 3. Back-compat proof: legacy-id wire table test green (every 69 id routes | ||
| to the same wire id as before, or documented intentional change). | ||
|
Comment on lines
+3
to
+11
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Make the closure proof exact and behavior-complete. Replace Also require focused assertions for exact-identity precedence, As per path instructions, keep these assertions in a focused regression test near the existing 🤖 Prompt for AI AgentsSource: Path instructions |
||
| 4. Stack finalization: PR A -> dev, PR B stacked; retarget checks. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Preserve real wire identities before applying synthetic
-1m.Line 34 names
claude-4-sonnet-1mas a real wire identity. The catalog table containsclaude-4-sonnet, but notclaude-4-sonnet-1m. The parser therefore treats this ID as the synthetic{ baseId: "claude-4-sonnet", ultra: true }case. The resolver then composes from the base identity, so byte-equal legacy wire output is not guaranteed. Add an exact wire-identity lookup before synthetic suffix handling and pin the resolved wire ID in the compatibility fixture.🤖 Prompt for AI Agents