Skip to content

gut(config): remove obsolete LLM model feature catalog types (#2478)#2484

Merged
alexey-pelykh merged 1 commit intomainfrom
gut/2478-model-feature-catalog-types
Apr 22, 2026
Merged

gut(config): remove obsolete LLM model feature catalog types (#2478)#2484
alexey-pelykh merged 1 commit intomainfrom
gut/2478-model-feature-catalog-types

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

Remove MODEL_APIS, ModelApi, ModelCompatConfig, ModelApiSchema, and ModelCompatSchema from the config surface. These predate the fork and stored metadata that no production code inspects — CLI runtimes (Claude Code, Gemini, Codex, OpenCode) own model API routing and capability detection at runtime.

Closes #2478.

Migration choice — Option A (silent passthrough)

Per the issue's migration-behavior decision point: Option A chosen. compat and api become z.unknown().optional() stubs on ModelDefinitionSchema and ModelProviderSchema, matching the fork convention already established by memorySearch / embeddedPi / pdfModel. Existing user configs that carry these fields continue to parse unchanged; the fields are simply passed through and ignored downstream.

Option B (migration warning via the legacy-field channel) was rejected because it introduces new code for no user benefit — the fields don't map to any runtime behavior, so there's nothing for the user to migrate to.

Changes

Types and schemas

  • src/config/types.models.ts — remove MODEL_APIS, ModelApi, ModelCompatConfig; drop api? + compat? from ModelDefinitionConfig; drop api? from ModelProviderConfig.
  • src/config/zod-schema.core.ts — remove MODEL_APIS import, ModelApiSchema, ModelCompatSchema; replace strict compat / api fields with z.unknown().optional() passthrough stubs.
  • src/config/schema.base.generated.ts — regenerated via tsx scripts/generate-base-config-schema.ts --write.

Dead-metadata writers

  • src/config/defaults.ts — remove resolveDefaultProviderApi helper; remove api-assignment branches in applyModelDefaults; drop unused normalizeProviderId import. (applyModelDefaults was writing the api field on both providers and models with no downstream reader.)
  • src/commands/doctor-config-analysis.ts + doctor-config-flow.ts — drop the stale api diagnostic line that referenced the dead metadata.
  • src/commands/onboard-custom.ts — remove resolveProviderApi helper and the api field assignment in applyCustomApiConfig.

Schema help/labels

  • src/config/schema.help.ts — remove models.providers.*.api help; update models.providers.*.models help to drop the "compatibility" phrase.
  • src/config/schema.labels.ts — remove models.providers.*.api label.
  • src/config/schema.help.quality.test.ts — remove models.providers.*.api expected path.

Tests

  • src/config/config-misc.test.ts — keep the legacy-field fixture as a regression canary for the Option A passthrough shim; rename the describe/it to reflect the new intent.
  • src/config/config.secrets-schema.test.ts — same treatment (rename + clarifying comment).
  • src/config/config.identity-defaults.test.ts — drop api fixture fields (no longer informative).
  • src/config/model-alias-defaults.test.ts — drop two tests that asserted api-default assignment (behavior now gone); drop api from the shared fixture builder.
  • src/config/redact-snapshot.test.ts — drop maxTokensField from one fixture (other *tokens*-style names still cover the redactor's non-redaction behavior).
  • src/commands/onboard-custom.test.ts — drop api assertion from expectOpenAiCompatResult; drop api from buildCustomProviderConfig.

Docs

  • docs/concepts/model-providers.md — remove three bullets that claimed RemoteClaw forces compat.supportsDeveloperRole: false at runtime. This claim was false — no production code enforces anything of the sort after the Pi orchestrator was removed.
  • docs/gateway/configuration-reference.md — drop the models.providers.*.api and compat.supportsDeveloperRole path descriptions.
  • docs/.generated/config-baseline.json — regenerated.
  • docs/.generated/plugin-sdk-api-baseline.json — surgical removal of the ModelApi entry only. The regeneration script (scripts/generate-plugin-sdk-api-baseline.ts) references a pre-existing missing source file (src/plugin-sdk/api-baseline.ts), so a full regen wasn't possible; line-number drift in other entries is pre-existing and out of scope.

Stub-marker convention note

Two passthrough-stub comments in src/config/zod-schema.core.ts use lowercase "gutted" phrasing (matching the existing memorySearch / embeddedPi precedent in zod-schema.agent-defaults.ts), not the capitalized Gutted in RemoteClaw fork marker. This is deliberate: the audit gate (scripts/check-obsolescence-audit.mjs) treats the capitalized phrase as a file-level stub signature. These are field-level stubs within an otherwise-live schema file; counting zod-schema.core.ts as a fully-stub file would be a false positive.

Rename for AC grep hygiene

  • src/agents/transcript-policy.ts — rename local OPENAI_MODEL_APISOPENAI_API_VARIANTS. The constant is unrelated to the gutted catalog but substring-matched the AC grep pattern. Pure rename, no behavior change.

Acceptance criteria

  • rg "MODEL_APIS|ModelCompatConfig|ModelApiSchema|supportsReasoningEffort|supportsStrictMode|thinkingFormat" src/ — the only remaining hits are src/config/config-misc.test.ts:321-322, which are the fixture for the backward-compat regression test. Under Option A, the z.unknown().optional() passthrough IS the migration shim, and this test is its regression canary; per the AC wording, these hits are "inside the migration shim."
  • Existing user configs containing api or compat fields still parse (regression guarded by config-misc.test.ts and config.secrets-schema.test.ts).
  • pnpm tsgo — exit 0.
  • Test suite passes — pnpm test = 800 files, 7006 pass + 3 pre-existing skips.

Test plan

  • pnpm check (format:check + tsgo + lint + project-specific gates) → all pass locally
  • pnpm canvas:a2ui:bundle → ok
  • pnpm test → 7006/7009 (3 pre-existing skips)
  • pnpm build + pnpm release:check → ok
  • Fork-integrity CI gates run locally → all pass: rebrand, zombie-import, stub-debt, throwing-stub-callers, obsolescence-audit (49 == baseline 49), attestations

Out-of-scope findings (not addressed here)

  • src/auto-reply/reply/directive-handling.model-picker.ts — entire file is dead (no importers); resolveProviderEndpointLabel is an exported function with zero callers. Uses a self-cast type so it continued to compile after ModelProviderConfig.api was removed.
  • src/agents/transcript-policy.ts:14isGoogleModelApi stub shadow (..._args: unknown[]): boolean => false remains (unrelated to this issue).

🤖 Generated with Claude Code

Remove `MODEL_APIS`, `ModelApi`, `ModelCompatConfig`, `ModelApiSchema`,
and `ModelCompatSchema` from the config surface. These predate the fork
and stored metadata that no production code inspects — CLI runtimes
(Claude Code, Gemini, Codex, OpenCode) own model API routing and
capability detection at runtime.

Migration: Option A (silent passthrough) — matches the fork convention
established by `memorySearch` / `embeddedPi` / `pdfModel` gutted fields.
`compat` and `api` become `z.unknown().optional()` stubs on
`ModelDefinitionSchema` and `ModelProviderSchema`, so existing user
configs still parse unchanged.

- Drop `api?` and `compat?` from `ModelDefinitionConfig`
- Drop `api?` from `ModelProviderConfig`
- Remove `MODEL_APIS` import and strict enum validators from zod schema
- Remove `resolveDefaultProviderApi` + api-assignment branches from
  `applyModelDefaults` (writer of dead metadata; no downstream reader)
- Remove `api` field reads/writes from doctor-config diagnostics and
  onboard-custom; drop corresponding tests and fixture fields
- Rename local `OPENAI_MODEL_APIS` → `OPENAI_API_VARIANTS` in
  transcript-policy.ts (avoids substring match on AC grep; no behavior
  change)
- Remove stale `models.providers.*.api` + `compat.supportsDeveloperRole`
  help/label entries and docs paragraphs (runtime-forcing claim was
  false — no code enforces anything of the sort)
- Regenerate `schema.base.generated.ts` and `config-baseline.json`
- Surgical removal of `ModelApi` from `plugin-sdk-api-baseline.json`
  (regeneration script references a pre-existing missing source file)
- Rename config-misc.test / config.secrets-schema.test cases to
  reflect their new role as backward-compat regression canaries

AC verification: `pnpm tsgo` clean; `pnpm test` 7006/7009 (3 pre-existing
skips); fork-integrity gates (rebrand, zombie-import, stub-debt,
throwing-stub-callers, obsolescence-audit, attestations) pass locally.
Remaining AC grep hits are confined to the legacy-field regression test
— they are the migration-shim canary by design.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh merged commit 3eff332 into main Apr 22, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the gut/2478-model-feature-catalog-types branch April 22, 2026 19:12
alexey-pelykh added a commit that referenced this pull request Apr 22, 2026
Remove the `embeddedPi: z.unknown().optional()` passthrough stub from
`AgentDefaultsSchema`. The Pi orchestrator was replaced by AgentRuntime
early in the fork; this stub was kept to let existing user configs still
parse during the transition window. That window has closed.

Unlike #2478 (which kept `memorySearch` / `pdfModel` as silent-passthrough
Option A stubs because nothing in the user's config needed to change),
#2479 fully removes `embeddedPi` and wires a migration:

- Legacy rule in `legacy.rules.ts` surfaces `agents.defaults.embeddedPi`
  in `snap.legacyIssues` with a user-facing warning.
- Legacy migration in `legacy.migrations.ts` strips the field before
  strict validation. Pattern matches the existing `strip-agent-default-field`
  sibling (#1581).
- Gateway startup (`server.impl.ts`) already calls `migrateLegacyConfig`
  when `legacyIssues.length > 0`, writes the migrated config back, and
  re-reads the snapshot — so configs carrying `embeddedPi` continue to
  load successfully, with the warning logged once.

Changes:
- Drop `embeddedPi` from `zod-schema.agent-defaults.ts` (strict schema)
  and `types.agent-defaults.ts` (mirror type).
- Drop `agents.defaults.embeddedPi[.projectSettingsPolicy]` help and
  label entries from `schema.help.ts` and `schema.labels.ts`.
- Add legacy rule + migration with issue-referenced describe/messages.
- Add two tests in `config-misc.test.ts`: (1) warning fires when
  `agents.defaults.embeddedPi` is present; (2) migration strips the
  field and the migrated config validates.
- Regenerate `schema.base.generated.ts` and `docs/.generated/config-baseline.json`.

AC verification: `rg "embeddedPi" src/` hits only within the migration
shim (rule text, migration code, regression-test fixture) — matches the
#2484 precedent interpretation. `pnpm tsgo` clean; `pnpm check` passes
(format + tsgo + lint + tmp-no-random-messaging + no-remoteclaw-ai).
Config+middleware tests: 129 files / 1396 tests pass. Fork-integrity
gates (zombie-import, stub-debt, throwing-stub-callers, obsolescence-audit)
all pass at baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
alexey-pelykh added a commit that referenced this pull request Apr 22, 2026
Remove the `embeddedPi: z.unknown().optional()` passthrough stub from
`AgentDefaultsSchema`. The Pi orchestrator was replaced by AgentRuntime
early in the fork; this stub was kept to let existing user configs still
parse during the transition window. That window has closed.

Unlike #2478 (which kept `memorySearch` / `pdfModel` as silent-passthrough
Option A stubs because nothing in the user's config needed to change),
#2479 fully removes `embeddedPi` and wires a migration:

- Legacy rule in `legacy.rules.ts` surfaces `agents.defaults.embeddedPi`
  in `snap.legacyIssues` with a user-facing warning.
- Legacy migration in `legacy.migrations.ts` strips the field before
  strict validation. Pattern matches the existing `strip-agent-default-field`
  sibling (#1581).
- Gateway startup (`server.impl.ts`) already calls `migrateLegacyConfig`
  when `legacyIssues.length > 0`, writes the migrated config back, and
  re-reads the snapshot — so configs carrying `embeddedPi` continue to
  load successfully, with the warning logged once.

Changes:
- Drop `embeddedPi` from `zod-schema.agent-defaults.ts` (strict schema)
  and `types.agent-defaults.ts` (mirror type).
- Drop `agents.defaults.embeddedPi[.projectSettingsPolicy]` help and
  label entries from `schema.help.ts` and `schema.labels.ts`.
- Add legacy rule + migration with issue-referenced describe/messages.
- Add two tests in `config-misc.test.ts`: (1) warning fires when
  `agents.defaults.embeddedPi` is present; (2) migration strips the
  field and the migrated config validates.
- Regenerate `schema.base.generated.ts` and `docs/.generated/config-baseline.json`.

AC verification: `rg "embeddedPi" src/` hits only within the migration
shim (rule text, migration code, regression-test fixture) — matches the
#2484 precedent interpretation. `pnpm tsgo` clean; `pnpm check` passes
(format + tsgo + lint + tmp-no-random-messaging + no-remoteclaw-ai).
Config+middleware tests: 129 files / 1396 tests pass. Fork-integrity
gates (zombie-import, stub-debt, throwing-stub-callers, obsolescence-audit)
all pass at baseline.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.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.

refactor(config): remove obsolete LLM model feature catalog types

1 participant