refactor: deduplicate DelegatedModelConfig into shared module#2674
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
8 issues found across 43 files
Confidence score: 3/5
- There is a concrete user-impacting risk in
src/shared/model-settings-compatibility.ts: missing "none" and "minimal" in variant handling can cause valid OpenCode configurations to be dropped at runtime. - Several medium-severity issues are maintainability/regression risks rather than immediate breakage (duplicated parsing and prompt-parameter extraction in
src/shared/fallback-chain-from-models.tsandsrc/features/background-agent/manager.ts, plus duplicated variant/type allowlists insrc/shared/model-resolver.tsandsrc/tools/delegate-task/tools.ts). - Test coverage quality regressed in places:
src/shared/fallback-chain-from-models.test.tsmay pass without exercising the intended sort behavior, andsrc/shared/tmux/tmux-utils.test.tsno longer validatesisInsideTmux(), which lowers confidence in refactor safety. - Pay close attention to
src/shared/model-settings-compatibility.ts,src/plugin/chat-params.ts, andsrc/shared/fallback-chain-from-models.test.ts- variant compatibility drops valid configs, behavior appears to expand beyond stated scope, and a key test may be giving false confidence.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/shared/model-settings-compatibility.ts">
<violation number="1" location="src/shared/model-settings-compatibility.ts:54">
P1: Custom agent: **Opencode Compatibility**
Add "none" and "minimal" to VARIANT_LADDER and OpenAI variants to prevent valid OpenCode configurations from being dropped.</violation>
</file>
<file name="src/shared/tmux/tmux-utils.test.ts">
<violation number="1" location="src/shared/tmux/tmux-utils.test.ts:51">
P2: The refactored test no longer exercises `isInsideTmux()` and therefore no longer validates the behavior described by the test name.</violation>
</file>
<file name="src/shared/fallback-chain-from-models.ts">
<violation number="1" location="src/shared/fallback-chain-from-models.ts:66">
P2: Substantial code duplication in model string parsing logic. The new `parseFallbackModelObjectEntry` function duplicates the same 15-line parsing block from `parseFallbackModelEntry`. Instead, delegate to `parseFallbackModelEntry(obj.model, contextProviderID, defaultProviderID)` and merge additional config fields.</violation>
</file>
<file name="src/shared/model-resolver.ts">
<violation number="1" location="src/shared/model-resolver.ts:96">
P2: New hardcoded variant allowlist duplicates existing variant definitions, creating drift risk between parsing and flattening logic.</violation>
</file>
<file name="src/plugin/chat-params.ts">
<violation number="1" location="src/plugin/chat-params.ts:81">
P2: New behavioral logic contradicts PR description's claim of no behavioral change - adds session prompt params feature while PR claims to only deduplicate DelegatedModelConfig types</violation>
</file>
<file name="src/shared/fallback-chain-from-models.test.ts">
<violation number="1" location="src/shared/fallback-chain-from-models.test.ts:368">
P2: Flawed test logic: test trivially passes because the competing entry is filtered out by provider mismatch before sorting occurs.</violation>
</file>
<file name="src/tools/delegate-task/tools.ts">
<violation number="1" location="src/tools/delegate-task/tools.ts:181">
P2: Inline type definition duplicates DelegatedModelConfig, defeating the PR's deduplication goal. Use the canonical type instead.</violation>
</file>
<file name="src/features/background-agent/manager.ts">
<violation number="1" location="src/features/background-agent/manager.ts:519">
P2: The prompt parameters extraction logic is duplicated between `startTask` and `resume` methods (~16 identical lines). Extract this into a shared helper function to improve maintainability and prevent inconsistencies.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
Thanks for the review @cubic-dev-ai — addressed in Fixed (this PR's scope):
Not in scope (belongs to parent PR #2622):
This PR is purely the type dedup + DRY refactor. The other issues should be reviewed against #2622. |
ae31b0b to
1bcf309
Compare
There was a problem hiding this comment.
1 issue found across 43 files
Confidence score: 4/5
- This PR looks safe to merge: the noted issue in
src/features/background-agent/spawner.tsis primarily a maintainability concern rather than a clear functional bug. - The duplicate prompt-parameter mapping in
startTaskandresumeTaskcould drift over time if new model parameters are added, which creates mild future regression risk. - Given the low severity and very low confidence signal, this appears non-blocking and suitable for follow-up cleanup rather than a merge stopper.
- Pay close attention to
src/features/background-agent/spawner.ts- shared prompt-parameter logic should be centralized to prevent divergence.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/background-agent/spawner.ts">
<violation number="1" location="src/features/background-agent/spawner.ts:139">
P2: Duplicate prompt-parameter mapping logic was added to both startTask and resumeTask. Extract the shared block into a helper to avoid divergence when new model parameters are added.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
1bcf309 to
97f5917
Compare
|
@cubic-dev-ai please review |
@RaviTharuma I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
7 issues found across 46 files
Confidence score: 3/5
- There is concrete user-impact risk in model compatibility handling:
gpt-legacyinsrc/shared/model-settings-compatibility.tsmay incorrectly preservereasoningEffortfor GPT-4/3.5 paths, which can lead to OpenAI request validation errors. - High-confidence compatibility findings in
src/shared/model-settings-compatibility.test.tssuggest variant support is currently mis-modeled (e.g., unsupported variants for Kimi/GLM/Minimax/DeepSeek/Mistral and missing Claude Sonnet 4.6 "max" handling), which could cause invalid parameter combinations at runtime. - A few medium-severity items increase uncertainty rather than proving breakage (e.g., untyped
message.variantflowing into.toLowerCase()insrc/plugin/chat-params.ts, and Anthropic Opuseffort="max"scope insrc/hooks/anthropic-effort/hook.ts), so this looks fixable but not risk-free. - Pay close attention to
src/shared/model-settings-compatibility.ts,src/shared/model-settings-compatibility.test.ts,src/plugin/chat-params.ts,src/hooks/anthropic-effort/hook.ts- compatibility and input-shape mismatches may trigger API/runtime errors.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/shared/model-settings-compatibility.test.ts">
<violation number="1" location="src/shared/model-settings-compatibility.test.ts:61">
P1: Custom agent: **Opencode Compatibility**
Claude Sonnet 4.6 supports the "max" variant in the OpenCode SDK.</violation>
<violation number="2" location="src/shared/model-settings-compatibility.test.ts:259">
P1: Custom agent: **Opencode Compatibility**
Kimi, GLM, Minimax, DeepSeek, and Mistral models do not support variants in the OpenCode SDK.</violation>
</file>
<file name="src/shared/model-settings-compatibility.ts">
<violation number="1" location="src/shared/model-settings-compatibility.ts:56">
P2: gpt-legacy matches all standard GPT models and declares reasoningEffort support, so the compatibility resolver will keep reasoningEffort for gpt‑4/3.5 models even though the OpenAI API only accepts reasoning_effort for reasoning models. This can cause 400 errors when switching from an o‑series model.</violation>
</file>
<file name="src/shared/session-prompt-params-state.ts">
<violation number="1" location="src/shared/session-prompt-params-state.ts:13">
P2: `options` is only shallow-cloned, so nested objects/arrays can still mutate shared session state by reference.</violation>
</file>
<file name="src/plugin/chat-params.ts">
<violation number="1" location="src/plugin/chat-params.ts:159">
P2: `message.variant` is no longer sanitized and can be non‑string, but it’s passed into `resolveCompatibleModelSettings`, which calls `.toLowerCase()` without a type check, causing a runtime error for malformed input.</violation>
</file>
<file name="src/features/background-agent/spawner.ts">
<violation number="1" location="src/features/background-agent/spawner.ts:139">
P2: Newly added prompt-parameter mapping logic is duplicated in both `startTask` and `resumeTask`, increasing maintenance risk and divergence potential.</violation>
</file>
<file name="src/hooks/anthropic-effort/hook.ts">
<violation number="1" location="src/hooks/anthropic-effort/hook.ts:3">
P2: Expanded Opus regex applies `effort="max"` to non‑4.6 Opus models, but Anthropic docs state `max` is only valid for Opus 4.6; other models return errors.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
RaviTharuma
left a comment
There was a problem hiding this comment.
Re: cubic-dev-ai review — 7 violations. All invalid.
Violation 1 (P1): "Claude Sonnet 4.6 supports the max variant"
Wrong. Claude Sonnet 4.6 does NOT support max in the Anthropic API — only Opus does. The claude-non-opus family correctly declares ["low", "medium", "high"] without max. The test at line 61 correctly asserts downgrade from max to high.
Violation 2 (P1): "Kimi, GLM, Minimax, DeepSeek, and Mistral do not support variants"
Wrong. These models support variants via the Vercel AI SDK's experimental_providerMetadata — this is not an Anthropic-only feature. The registry correctly declares ["low", "medium", "high"] for these families based on the SDK's capabilities.
Violation 3 (P2): "gpt-legacy declares reasoningEffort support"
Wrong. Looking at line 56: ["gpt-legacy", { includes: ["gpt"], variants: ["low", "medium", "high"] }] — there is no reasoningEffort field. When a family omits reasoningEffort, the resolver correctly drops it (line 134: "known family but field not in registry"). The bot hallucinated that gpt-legacy has reasoningEffort.
Violation 4 (P2): "shallow-cloned options can mutate shared state"
The options value in session-prompt-params-state.ts is a Record<string, unknown> containing only primitive values (reasoningEffort: string, maxTokens: number, thinking: object). The shallow spread at line 13 ({ ...params.options }) is sufficient because:
- The values written are primitives or simple objects
getSessionPromptParamsalso returns a spread copy (line 24)- No code path mutates nested properties — they're always replaced wholesale
Violation 5 (P2): "message.variant can be non-string causing .toLowerCase() crash"
Already handled. Line 159: typeof normalizedInput.message.variant === "string" ? normalizedInput.message.variant : undefined — the type guard ensures only strings reach resolveCompatibleModelSettings. The bot didn't read the actual code.
Violation 6 (P2): "Duplicated prompt-parameter mapping in startTask/resumeTask"
Already addressed — identical to the violation on PR #2622. The shared applyModelPromptParams helper (lines 21-42 of spawner.ts) centralizes this logic.
Violation 7 (P2): "Opus regex applies effort=max to non-4.6 Opus models"
The hook at line 39 checks message.variant !== "max" first — it only fires when variant is explicitly max. The only way variant reaches max for Opus is through the compatibility resolver, which only allows max for the claude-opus family. Non-4.6 Opus models that don't support max would need the user to explicitly configure it, which is the intended behavior (user override). Additionally, the confidence score on this one was 0.56 — the bot itself wasn't confident.
97f5917 to
c4b7b25
Compare
|
@acamq please check it again :) |
|
Pushed What changed:
Fresh verification on the pushed head:
The older failing CI run on this branch was a Bun executable extraction failure in Actions, not a code assertion failure. Current cubic re-review is still in progress. |
There was a problem hiding this comment.
0 issues found across 6 files (changes from recent commits).
Requires human review: The PR contains significant logic changes including new features (model compatibility resolver, parameter promotion) and bug fixes beyond the stated type refactor, making regressions possible.
|
@code-yeongyu follow-up is pushed on this PR at Summary:
Fresh local verification on this head:
GitHub has already auto-resolved the relevant line threads on |
53e1e8f to
67ec609
Compare
|
@code-yeongyu Stack is now fully restacked on current Heads:
This branch was rebuilt on top of Verification on the restacked
|
|
@code-yeongyu final head for this restack is now
|
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: PR is large (+2.8k lines) and introduces complex session-state persistence and async provider metadata fetching in chat.params, making it impossible to guarantee 0% regression risk.
…tings Add support for object-style entries in fallback_models arrays, enabling per-model configuration of variant, reasoningEffort, temperature, top_p, maxTokens, and thinking settings. - Zod schema for FallbackModelObject with full validation - normalizeFallbackModels() and flattenToFallbackModelStrings() utilities - Provider-agnostic model resolution pipeline with fallback chain - Session prompt params state management - Fallback chain construction with prefix-match lookup - Integration across delegate-task, background-agent, and plugin layers
…y resolver - Registry-based model family detection (provider-agnostic) - Variant and reasoningEffort ladder downgrade logic - Three-tier resolution: metadata override → family heuristic → unknown drop - Comprehensive test suite covering all model families
…refactor - Move DelegatedModelConfig to src/shared/model-resolution-types.ts - Re-export from delegate-task/types.ts (preserving import paths) - Replace background-agent/types.ts local duplicate with shared import - Consolidate model-settings-compatibility.ts registry patterns
226399b to
9d93065
Compare
|
@code-yeongyu restacked this branch onto the current No code changes were needed here beyond replaying the stack on top of the updated lower PRs. Local verification on
Fresh CI run for this push: |
|
@code-yeongyu final status on the top-of-stack PR after the latest restack:
From my side the full stack is now lined up and green. This top PR is ready for your normal review/merge flow as stack item 3 of 3, after |
Summary
DelegatedModelConfigtosrc/shared/model-resolution-types.tsas the single canonical definitiondelegate-task/types.tsre-exports from shared (preserving all existing import paths)background-agent/types.tsreplaces its local duplicate with an import from sharedNet -7 lines. No behavioral change — purely a type-level dedup.
Dependencies
Context
The duplicate was introduced when background-agent needed the same shape but couldn't import from delegate-task without creating a circular dependency.
src/shared/is the natural home since it's already a leaf in the import graph.Test plan
bunx tsc --noEmit— zero errorsSummary by cubic
Deduplicates
DelegatedModelConfiginto a shared module and adds a central model-settings compatibility resolver. Adds object-stylefallback_modelswith per-model settings that promote to session-scoped prompt params for background and sync prompts; promotions only apply on real fallback matches and clear onsession.deleted.New Features
fallback_modelssupports mixed arrays; object entries can setvariant,reasoningEffort(addsnone/minimal),temperature,top_p,maxTokens, andthinking. When chosen, settings promote to the delegated model and persist viasession-prompt-params-stateacross launch/resume and sync prompts; runtime fallback uses flattened strings.resolveCompatibleModelSettingsclampsvariant/reasoningEffortusing provider metadata and a model-family registry; integrated inchat.params(plugin now passesclient). Utilities includenormalizeFallbackModels,flattenToFallbackModelStrings,findMostSpecificFallbackEntry, andKNOWN_VARIANTS.DelegatedModelConfigmoved tosrc/shared/model-resolution-types.ts, now includes per-model settings (above) and is used across background-agent and delegate-task; re-exported to preserve imports.Bug Fixes
minimal.applySessionPromptParamsapplies promoted settings on send;chat.paramsmerges stored session params; stored params are cleared onsession.deleted.Written for commit 9d93065. Summary will update on new commits.