feat(#4209): add ai-model-server API spec type extension - #4211
feat(#4209): add ai-model-server API spec type extension#4211fullsend-ai-coder[bot] wants to merge 6 commits into
Conversation
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Missing ChangesetsThe following package(s) are changed by this PR but do not have a changeset:
See CONTRIBUTING.md for more information about how to add changesets. Changed Packages
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4211 +/- ##
==========================================
- Coverage 57.55% 57.54% -0.02%
==========================================
Files 2447 2449 +2
Lines 97659 97649 -10
Branches 27268 27262 -6
==========================================
- Hits 56204 56188 -16
+ Misses 41181 41180 -1
- Partials 274 281 +7
*This pull request uses carry forward flags. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
|
/fs-review |
|
🤖 Finished Review · ✅ Success · Started 11:48 PM UTC · Completed 12:07 AM UTC Commit: |
ReviewFindingsHigh
Medium
Low
Next steps:
Previous runReviewFindingsMedium
Low
|
Add two new plugins implementing the ai-model-server spec type for the API kind, replicating the upstream backstage/backstage#34476 schema as an rhdh-plugins module while the upstream PR is pending. catalog-model-ai-model-server provides the AiModelServerApiEntity TypeScript type, JSON schema, KindValidator, type guard, and CatalogModelLayer. The schema requires serverType and serverUrl fields and supports optional requiresApiKey, apiEntityRef, and models (discoverable, available, default). catalog-backend-module-ai-model-server registers the model layer with the catalog via catalogModelExtensionPoint.addModelSource. Includes example YAML, changeset, API reports, and dev backend wiring. Closes #4209 Assisted-by: Claude
… API Switch from extending the upstream API kind with specType ai-model-server to a dedicated AiModelServerAPI kind. This avoids colliding with the upstream catalog model layer for API entities while backstage/backstage#34476 is pending. The schema is identical to upstream — only the kind field differs. When #34476 merges, a migration processor can convert AiModelServerAPI entities into API entities with spec.type: ai-model-server by simply changing the kind field. Signed-off-by: gabemontero <gmontero@redhat.com> Assisted-by: Claude Opus 4.6 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite ModelCatalogGenerator to produce a single AiModelServerAPI entity per ModelCatalog instead of separate Component, Resource, and API entities. Model names are collected into spec.models.available. - Rewrite GenerateCatalogEntities to build AiModelServerAPI from ModelCatalog.modelServer data (tags, links, annotations, techdocs) - Return empty array when modelServer is absent - Add catalog-model-ai-model-server workspace dependency - Update entity provider log message and test fixtures - Fix typo and syntax error in dev backend index.ts - Add major changeset bump for catalog-backend-module-model-catalog Signed-off-by: gabemontero <gmontero@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Assisted-by: Claude Opus 4.6
CatalogModelSources.static() auto-includes the default entity model layer. When multiple backend modules each call it, the default model annotations (e.g. backstage.io/managed-by-location) get declared multiple times, crashing the catalog plugin on startup. Replace CatalogModelSources.static() with a bare CatalogModelSource implementation that yields only the custom layer, leaving the default model to be provided once by the catalog plugin itself. Signed-off-by: gabemontero <gmontero@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Assisted-by: Claude Opus 4.6
addKindVersion requires the kind to already exist in the catalog model. Since AiModelServerAPI is a brand-new kind (not extending an existing one like AiResource), the layer must use addKind to declare the kind with its group, names, description, and versions together. Signed-off-by: gabemontero <gmontero@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Assisted-by: Claude Opus 4.6
70eaec4 to
ec1915a
Compare
|
/fs-review |
|
🤖 Finished Review · ✅ Success · Started 1:38 PM UTC · Completed 1:55 PM UTC Commit: |
There was a problem hiding this comment.
See the review comment for full details.
Note: The following inline comments could not be posted on the diff (GitHub returned 422) and are included here instead:
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:71: [high] intent-misalignment
Issue #4209 specifies registering ai-model-server as a specType on the existing API kind using addKindVersion. The PR instead introduces a new custom kind AiModelServerAPI via addKind. The issue body explicitly states: CatalogModelLayer using addKindVersion for kind API. The sibling AgentAiResourceEntityV1alpha1.ts uses addKindVersion as the established pattern. The TypeScript type also extends Entity directly instead of Omit<ApiEntityV1alpha1, spec> as the issue specifies.
Suggested fix: Follow the issue specification: use addKindVersion for the existing API kind instead of addKind for a new AiModelServerAPI kind. If there is a technical reason for the new kind approach, update issue #4209 with the rationale and get approval before proceeding.
workspaces/ai-integrations/.changeset/ai-model-server-schema.md:3: [high] unauthorized-breaking-change
The changeset declares a major (breaking) version bump for catalog-backend-module-model-catalog. This converts the model catalog entity provider output from multiple entities (Component + Resource + API) to a single AiModelServerAPI entity. Issue #4209 asks for two new plugins but does not authorize refactoring the entity provider or breaking its output shape.
Suggested fix: Split the entity provider refactoring into a separate, explicitly authorized issue with its own changeset. Document the old entity kinds removed and the new AiModelServerAPI kind that replaces them.
workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.ts:104: [medium] schema-runtime-mismatch
When modelServer.API is undefined, serverUrl defaults to empty string. The JSON schema declares serverUrl as required with minLength: 1. An entity produced with serverUrl: empty string would fail schema validation.
Suggested fix: Guard GenerateCatalogEntities to return [] when modelServer.API?.url is falsy, or change the fallback to satisfy minLength: 1.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:51: [medium] naming-convention
The type guard isAiModelServerApiEntity does not check entity.apiVersion like the sibling isAgentAiResourceEntity does. The established workspace pattern asserts apiVersion in type guards.
Suggested fix: Add an apiVersion check to the condition, matching the sibling pattern.
workspaces/ai-integrations/plugins/catalog-backend-module-ai-resource-agent/src/module.ts(file-level): Line 33 · [low] scope-creep
The PR modifies the existing catalog-backend-module-ai-resource-agent plugin to change from CatalogModelSources.static to an inline async generator pattern. This change is unrelated to issue #4209.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49: [low] naming-convention
The interface name AiModelServerApiEntity omits a version suffix. The sibling package uses AgentAiResourceEntityV1alpha1. Aligns with upstream PR naming but diverges from workspace pattern.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:26: [low] naming-convention
The validator aiModelServerApiEntityValidator omits a version suffix, unlike the sibling agentAiResourceEntityV1alpha1Validator. Aligns with upstream naming.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts(file-level): Line 107 · [low] namespace-collision-risk
The new kind AiModelServerAPI is registered under group backstage.io (the upstream namespace). The module comments acknowledge this and document migration when upstream ships.
workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.test.ts:30: [low] missing-test
No test covers the case where modelServer is present but modelServer.API is undefined. This path triggers the serverUrl empty-string schema mismatch bug.
workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.test.ts:30: [low] missing-test
No test covers the case where models is an empty array. The generated entity would have models: { available: [] } with no default field.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:63: [low] naming-convention
The plural form aimodelserverapies appears to be an incorrect pluralization. Expected aimodelserverapis.
workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49: [low] naming-convention
The interface omits apiVersion as a literal type, inheriting the broad string type from Entity. The sibling pins apiVersion to backstage.io/v1alpha1.
Response to review findings — approach change rationale
|
- Return [] from GenerateCatalogEntities when modelServer.API?.url is falsy, preventing entities with empty serverUrl that would fail schema validation (minLength: 1) - Fix plural form: aimodelserverapies -> aimodelserverapis - Add test for modelServer present but API undefined - Add test for empty models array (available: [], no default) Signed-off-by: gabemontero <gmontero@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Assisted-by: Claude Opus 4.6
Response to remaining review findings
|
|
|
/fs-review |
|
🤖 Review · Started 2:32 PM UTC Commit: |



Add two new plugins implementing the ai-model-server spec type for the API kind, replicating the upstream backstage/backstage#34476 schema as an rhdh-plugins module while the upstream PR is pending.
catalog-model-ai-model-server provides the AiModelServerApiEntity TypeScript type, JSON schema, KindValidator, type guard, and CatalogModelLayer. The schema requires serverType and serverUrl fields and supports optional requiresApiKey, apiEntityRef, and models (discoverable, available, default).
catalog-backend-module-ai-model-server registers the model layer with the catalog via catalogModelExtensionPoint.addModelSource.
Includes example YAML, changeset, API reports, and dev backend wiring.
Assisted-by: Claude
Closes #4209
Post-script verification
agent/4209-ai-model-server-spec)6c752b60d5bdc359d1eb6b5b81a34880a0c71c21..HEAD)