fix(proxy): make proxy connectors work on non-EPAM tenant model catalogs - #566
Closed
vadimvlasenko wants to merge 12 commits into
Closed
vadimvlasenko wants to merge 12 commits into
vadimvlasenko wants to merge 12 commits into
Conversation
Generalizes codex-model-resolver.ts's date-stripping identity-parse shape to strip vendor prefixes (GPT) and match both token orders (Claude) so VS Code Copilot BYOK and Claude Desktop can resolve tenant-shaped model ids (philips-tenant-model-catalog task 1). Generated with AI Co-Authored-By: codemie-ai <[email protected]>
Add fetchTenantModelCatalog and thread a live gateway catalog through buildManagedModels via resolveTenantModelId, so the capability table (previous commit) resolves each family to whatever id the tenant actually registers instead of a fixed EPAM-shaped id. Unmatched families are dropped; a fully unmatched catalog now rejects with no file written. gatewayKey is threaded through writeVsCodeLanguageModelsConfig[AtPath] and connect-orchestrator.ts, which also reports the real resolved model count instead of the static table length (philips-tenant-model-catalog tasks 3-4). Squashed with task 2's vscode-models.ts capability-table rename (VS_CODE_SUPPORTED_MODELS -> VS_CODE_CAPABILITY_TABLE): the rename's sole consumers are vscode.ts and connect-orchestrator.ts, so the two land together to keep every commit typecheck-clean and pre-commit green, matching this repo's hook that runs `tsc --noEmit` on every commit. Generated with AI Co-Authored-By: codemie-ai <[email protected]>
Replace selectPreferredClaudeModels's suffix-only exact/dated matching with the shared resolveTenantModelId, so a tenant that names models version-first (e.g. claude-5-opus) resolves correctly instead of never matching PREFERRED_CLAUDE_MODELS's family-first entries (philips-tenant-model-catalog task 5). Generated with AI Co-Authored-By: codemie-ai <[email protected]>
…Code settings Read settings.json with jsonc-parser (allowTrailingComma) instead of strict JSON.parse, and write the two managed keys via targeted modify()/applyEdits() passes against the original text instead of re-serializing the whole object, so a hand-edited settings.json with // comments survives the write (philips-tenant-model-catalog task 6). A genuinely unparseable file still rejects with ConfigurationError and is left untouched. Generated with AI Co-Authored-By: codemie-ai <[email protected]>
…es by recency RELEASE_DATE_PATTERN only matched separator-delimited dates, so a single-number preferred family (claude-opus-5, claude-sonnet-5) never resolved against a realistically-shaped concatenated-date tenant id (claude-opus-5-20260101) — two-number families only worked by positional coincidence. pickMostRecent's lexicographic tie-break was also unsound across mixed id shapes (vendor-prefixed vs. dated vs. -vertex-suffixed). Extend the date pattern to cover both shapes and rank same-identity candidates by an explicit non-vertex-before-vertex, then parsed-date precedence instead of raw string comparison. philips-tenant-model-catalog CR-001, CR-002 Generated with AI Co-Authored-By: codemie-ai <[email protected]>
…ch fallback
fetchTenantModelCatalog was a ~73-line function mixing fetch, HTTP-status
handling, content-type validation, response-shape parsing, and logging —
over the code-quality function-length/single-responsibility limit. It also
had no timeout on its fetch() call, so a hung gateway blocked `codemie proxy
connect` indefinitely, and its `{ data: [...] }` response branch only read
`m.id`, dropping the same base_name/deployment_name fallback the array
branch already applied.
Extract the parsing and logging into small named helpers, wrap the fetch in
an AbortController-backed timeout (converted into the same ConfigurationError
contract on abort), and apply one shared id/base_name/deployment_name
fallback chain to both response shapes.
philips-tenant-model-catalog CR-003, CR-004, CR-005
Generated with AI
Co-Authored-By: codemie-ai <[email protected]>
…tings writeVsCodeClaudeCodeConfigAtPath's two jsonc-parser modify() calls passed an empty ModificationOptions object, leaving `formattingOptions` undefined. Per jsonc-parser's own contract that inserts the edit completely unformatted — no newline, no indent — rather than falling back to any default, so the managed keys could land jammed onto the same line as the preceding property. Detect the file's actual indentation and EOL from its raw text and pass real formattingOptions to both modify() calls. philips-tenant-model-catalog CR-006 Generated with AI Co-Authored-By: codemie-ai <[email protected]>
Both integration test files still imported the removed VS_CODE_SUPPORTED_MODELS/VsCodeModelDefinition (renamed to VS_CODE_CAPABILITY_TABLE/VsCodeCapabilityEntry, whose entries carry a `family` name instead of a literal tenant id). vscode-byok.test.ts's writeVsCodeLanguageModelsConfigAtPath call was also missing the new required gatewayKey argument, and its mock upstream server never served a /v1/llm_models catalog body, so the connector's catalog fetch found zero models and the test never exercised its own scenario. Update both files to the renamed exports and the family-based shape, pass gatewayKey through, and have the BYOK test's mock server serve a catalog whose ids exactly match every VS_CODE_CAPABILITY_TABLE family so each entry resolves verbatim. philips-tenant-model-catalog CR-007 Generated with AI Co-Authored-By: codemie-ai <[email protected]>
Test fixtures and descriptions named a real customer. Rename them to describe the tenant-naming shape under test instead: PHILIPS_CLAUDE_FIXTURE -> VERSION_FIRST_CLAUDE_FIXTURE (desktop.test.ts) and PHILIPS_FIXTURE -> NON_EPAM_TENANT_FIXTURE (vscode.test.ts), with matching test/describe titles. No behavior change. Generated with AI Co-Authored-By: codemie-ai <[email protected]>
…t-model-catalog Generated with AI Co-Authored-By: codemie-ai <[email protected]>
state.local.json/gate-plan.local.json replaced .state.json/gate-plan.json in the sdlc-factory scripts; the ignore patterns here still named the old filenames, so every finished sdlc run left the task dir looking dirty. Generated with AI Co-Authored-By: codemie-ai <[email protected]>
8 tasks
Collaborator
Author
|
Closed accidentally by a branch rename (removing a client name from the branch/directory names per internal policy) — GitHub deleted the old ref and auto-closed this PR instead of migrating it, and it can't be reopened without its head ref. Continued as #567 with identical content. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
codemie proxy connectbroke on any tenant whose model catalog doesn't follow EPAM's naming convention (surfaced live on a customer call). Three connectors — VS Code Copilot BYOK, Claude Desktop, and VS Code Claude Code — each hardcoded assumptions about model-id shape or format that only held for EPAM's own tenant. Ref: EPMCDME-15073.Changes
vscode.ts,vscode-models.ts, newtenant-catalog.ts): replaced the static 25-model hardcoded list with a capability table intersected against the tenant's liveGET /v1/llm_modelscatalog at connect time; writes the tenant's own model identifier verbatim.desktop.ts, newmodel-name-resolver.ts): preferred-model resolution now handles both EPAM'sclaude-<family>-<version>and version-first (claude-<version>-<family>) naming, plus undated ids and vendor-prefixed ids (e.g.openai.gpt-...), instead of only appending suffixes.vscode-claude-code.ts): switched from strictJSON.parse/JSON.stringifytojsonc-parser, so asettings.jsonwith comments or trailing commas parses correctly and the write preserves the file's existing formatting instead of being silently skipped.github-copilot-*deployments are explicitly excluded from both the VS Code Copilot BYOK picker and Claude Desktop (product decision, documented inspec.md).codex-model-resolver.tsis untouched.Full design rationale, acceptance criteria, and non-goals are in
docs/superpowers/tasks/2026-09-17-philips-tenant-model-catalog/spec.mdandplan.md(committed on this branch), produced by ansdlc-autonomousrun with a full code-review cycle (initial round: 7 findings incl. 1 critical, all fixed and independently re-verified in a check round).Testing
npx vitest run— full suite green.npm run typecheck/npm run lint— clean.spec.md's open risks).Checklist
npm run ci) locally viaqa-gatesmainX-CodeMie-*attribution header, the Responses APIuserfield, or JWT claim overrides — confirmed, out of scope for this change.