Skip to content

fix(models): return inferred type from v1 models - #668

Merged
jjcc123312 merged 1 commit into
mainfrom
codex/fix-v1-models-video-type
Aug 10, 2026
Merged

fix(models): return inferred type from v1 models#668
jjcc123312 merged 1 commit into
mainfrom
codex/fix-v1-models-video-type

Conversation

@jjcc123312

Copy link
Copy Markdown

Problem / background\n\nFollow-up to #661.\n\nProduction verification showed that #661 correctly fixed GET /v1/available_models, but the OpenAI-compatible GET /v1/models endpoint continued omitting data[].type. Clients then defaulted video models such as MiniMax-H3 and seedance2.0-pro to text.\n\n## Evidence / reproduction\n\nAfter #661 was deployed to 100% of both newapi-console and newapi-router:\n\nGET /v1/available_models returned:\n\n {\n "id": "MiniMax-H3",\n "type": "video",\n "supported_endpoint_types": ["video"]\n }\n\nGET /v1/models returned:\n\n {\n "id": "MiniMax-H3",\n "supported_endpoint_types": ["video"]\n }\n\nThe same mismatch was observed for seedance2.0-pro.\n\n## Root cause\n\nThe endpoints use separate response builders:\n\n- /v1/available_models calls AvailableModels(), which already assigns Type with availableModelType().\n- /v1/models calls ListModels() -> buildOpenAIModel(), which populated SupportedEndpointTypes but never assigned Type.\n\nBecause OpenAIModels.Type has json:"type,omitempty", the empty string was omitted from the response.\n\n## Scope / design\n\nAfter buildOpenAIModel() loads SupportedEndpointTypes, assign Type using the existing availableModelType() helper. This keeps both model-list endpoints on the same classification rules without duplicating inference logic.\n\nThe OpenAI response-shape contract test now requires the type field. A new integration regression creates the production-equivalent MiniMax-H3 metadata with a custom video endpoint, executes ListModels(), and asserts:\n\n- type == "video"\n- supported_endpoint_types == ["video"]\n\nNo schema, routing, provider adapter, billing, quota, or dependency changes.\n\n## Impact and risks\n\nRisk is low. The OpenAI-compatible /v1/models response gains the previously omitted type field for every model. Existing clients should tolerate additive response fields; clients already reading type receive a meaningful value instead of a missing/null fallback.\n\nMulti-node behavior is stateless and deterministic. During a rolling deployment, old and new router instances may temporarily differ on whether type is present.\n\n## Validation\n\nPassed:\n\n- go test ./controller -run 'Test(ListModelsClassifiesCustomVideoEndpoint|ListModelsKeepsOpenAIResponseShape|AvailableModelTypeInference|BuildOpenAIModel)' -count=1\n- git diff --check\n- GitNexus compare against origin/main: LOW risk, 2 files, no affected execution flows\n\nFull controller suite:\n\n- The response-shape failure introduced by this contract change was updated and now passes.\n- One unrelated existing failure remains and reproduces alone: TestGetChannelRetryMaterializationFailureClearsStaleMapAndReturnsError in controller/relay_channel_concurrency_test.go:466.\n\n## Acceptance criteria\n\n- GET /v1/models returns type="video" for MiniMax-H3 configured with supported endpoint video.\n- GET /v1/models returns type="video" for Seedance video models.\n- Existing non-video models continue using the shared image/audio/text inference rules.\n- GET /v1/available_models behavior remains unchanged.\n\n## Production deployment recommendation\n\n- Router deploy: required.\n- Reason: controller/model.go changes the runtime response for GET /v1/models served by API router nodes.\n- Other deploy targets: newapi-console should also deploy because it shares the Go image and serves the same route; newapi-web, Terraform, and Cloudflare are not involved.\n- Risk / validation: validate on staging that both /v1/models and /v1/available_models return type="video" for MiniMax-H3 and Seedance, then roll out all production router and console instances.

@jjcc123312
jjcc123312 merged commit 72bdabf into main Aug 10, 2026
1 check passed
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