Skip to content

feat(#4209): add ai-model-server API spec type extension - #4211

Open
fullsend-ai-coder[bot] wants to merge 7 commits into
mainfrom
agent/4209-ai-model-server-spec
Open

feat(#4209): add ai-model-server API spec type extension#4211
fullsend-ai-coder[bot] wants to merge 7 commits into
mainfrom
agent/4209-ai-model-server-spec

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

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

  • Branch is not main/master (agent/4209-ai-model-server-spec)
  • Secret scan passed (gitleaks — 6c752b60d5bdc359d1eb6b5b81a34880a0c71c21..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

@rhdh-gh-app

rhdh-gh-app Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
backend workspaces/ai-integrations/packages/backend none v0.0.0
@red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-model-server workspaces/ai-integrations/plugins/catalog-backend-module-ai-model-server minor v0.1.0
@red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-agent workspaces/ai-integrations/plugins/catalog-backend-module-ai-resource-agent patch v0.2.0
@red-hat-developer-hub/backstage-plugin-catalog-backend-module-model-catalog workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog major v0.11.0
@red-hat-developer-hub/backstage-plugin-catalog-model-ai-model-server workspaces/ai-integrations/plugins/catalog-model-ai-model-server minor v0.1.0

@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.78378% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.54%. Comparing base (dac1613) to head (bc41885).
⚠️ Report is 10 commits behind head on main.
✅ All tests successful. No failed tests found.

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    27261       -7     
==========================================
- Hits        56204    56188      -16     
- Misses      41181    41187       +6     
  Partials      274      274              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from 59a00eb
ai-integrations 68.29% <83.78%> (-1.47%) ⬇️
app-defaults 69.79% <ø> (ø) Carriedforward from 59a00eb
augment 46.67% <ø> (ø) Carriedforward from 59a00eb
boost 77.63% <ø> (ø) Carriedforward from 59a00eb
bulk-import 72.79% <ø> (ø) Carriedforward from 59a00eb
cost-management 13.55% <ø> (ø) Carriedforward from 59a00eb
dcm 67.21% <ø> (ø) Carriedforward from 59a00eb
e2e-intelligent-assistant 46.74% <ø> (ø) Carriedforward from 59a00eb
extensions 56.59% <ø> (ø) Carriedforward from 59a00eb
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 59a00eb
global-header 66.50% <ø> (ø) Carriedforward from 59a00eb
homepage 47.50% <ø> (ø) Carriedforward from 59a00eb
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from 59a00eb
intelligent-assistant 75.24% <ø> (ø) Carriedforward from 59a00eb
konflux 91.98% <ø> (ø) Carriedforward from 59a00eb
lightspeed 69.02% <ø> (ø) Carriedforward from 59a00eb
mcp-integrations 83.40% <ø> (ø) Carriedforward from 59a00eb
orchestrator 68.10% <ø> (ø) Carriedforward from 59a00eb
quickstart 63.74% <ø> (ø) Carriedforward from 59a00eb
sandbox 79.56% <ø> (ø) Carriedforward from 59a00eb
scorecard 86.23% <ø> (ø) Carriedforward from 59a00eb
theme 88.77% <ø> (ø) Carriedforward from 59a00eb
translations 5.12% <ø> (ø) Carriedforward from 59a00eb
x2a 55.02% <ø> (ø) Carriedforward from 59a00eb

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dac1613...bc41885. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 9, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:48 PM UTC · Completed 12:07 AM UTC

Commit: 70eaec4 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [consumer-completeness] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.ts — The entity provider now emits only AiModelServerAPI entities with spec.type: 'ai-model-server' instead of Resource entities with spec.type: 'ai-model' (plus Component and API entities). Downstream consumers in the same workspace still query the catalog using the old entity shape: (1) plugins/ai-experience-backend/src/services/ModelService/ModelService.ts:73-74 queries { kind: 'Resource', 'spec.type': 'ai-model' } — this will return zero results. (2) plugins/ai-experience/src/components/ModelSection/ModelSection.tsx:54-55 builds a catalog link with filters[kind]=resource&filters[type]=ai-model — this link will show no results in the UI. After this PR merges, the AI Experience page's model section will be empty.
    Remediation: Update the consumer code in ai-experience-backend and ai-experience to query for { kind: 'AiModelServerAPI', 'spec.type': 'ai-model-server' }, or track this as a follow-up PR merged before or alongside this one.

Medium

  • [breaking-change-output-shape] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.tsGenerateCatalogEntities completely changes its output entity structure (different kinds, apiVersion, spec shapes, cardinality). The changeset correctly declares a MAJOR bump. Verify no external repositories import this function. See also: [consumer-completeness] finding above for in-repo breakage.

  • [new-catalog-kind-registration] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts — The new AiModelServerAPI kind is registered under the backstage.io group. If/when upstream feat(catalog-model): add ai-model-server spec type for API kind backstage/backstage#34476 merges and adds ai-model-server as a specType on the existing API kind (also under backstage.io), there would be two different kinds in the same group namespace handling ai-model-server spec types, which could cause catalog model conflicts. Consider using a vendor-specific group or documenting the migration plan.

  • [scope-creep] workspaces/ai-integrations/plugins/catalog-backend-module-ai-resource-agent/src/module.ts:20 — The PR modifies the ai-resource-agent module to switch from CatalogModelSources.static() to a bare CatalogModelSource implementation. While justified to prevent annotation collisions, this is a behavioral change to a separate published package not covered by the changeset.
    Remediation: Add a separate changeset entry (patch) for @red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-agent.

Low

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49 — The entity interface AiModelServerApiEntity, validator, and filename lack the version suffix used by the sibling package (AgentAiResourceEntityV1alpha1). Since the entity supports both v1alpha1 and v1beta1, the omission is defensible but inconsistent with the workspace convention.

  • [edge-case] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.ts:86 — Only the first model's techdocs annotation is used (the loop breaks after the first hit on line 94). If multiple models have techdocs annotations, all but the first are silently dropped.

  • [test-inadequate] workspaces/ai-integrations/plugins/catalog-backend-module-ai-model-server/src/module.test.ts — The test only asserts expect(catalogModuleAiModelServer).toBeDefined(). It does not verify that addModelSource is called. Consistent with the existing ai-resource-agent test pattern.

  • [type-guard-consistency] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:49 — The type guard isAiModelServerApiEntity checks only kind and spec.type, omitting the apiVersion check present in the sibling isAgentAiResourceEntity. Since the schema accepts both v1alpha1 and v1beta1, the omission is defensible but inconsistent.

  • [type-interface-style] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49 — The AiModelServerApiEntity interface does not pin apiVersion as a string literal. The sibling declares apiVersion: 'backstage.io/v1alpha1'. Consider adding apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1' for type safety.

  • [intent-alignment] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.ts:42 — The changeset correctly marks this as a major bump, but the PR does not include migration guidance for consumers who depend on the previously emitted Component/Resource/API entities.


Labels: PR adds new catalog entity kind and plugins in the ai-integrations workspace, which is a feature enhancement.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

High

  • [intent-misalignment] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:71 — Issue feat: add ai-model-server API spec type (catalog-model layer + backend module) #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 aiModelServerApiEntityModel using createCatalogModelLayer with addKindVersion for kind API." The sibling AgentAiResourceEntityV1alpha1.ts uses addKindVersion as the established pattern. The changeset acknowledges this divergence but the issue does not authorize it. Additionally, the TypeScript type extends Entity directly instead of Omit<ApiEntityV1alpha1, 'spec'> as the issue specifies.
    Remediation: 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 feat: add ai-model-server API spec type (catalog-model layer + backend module) #4209 with the rationale and get approval before proceeding.

  • [unauthorized-breaking-change] workspaces/ai-integrations/.changeset/ai-model-server-schema.md:3 — The changeset declares a major (breaking) version bump for @red-hat-developer-hub/backstage-plugin-catalog-backend-module-model-catalog. This breaking change converts the model catalog entity provider output from multiple entities (Component + Resource + API) to a single AiModelServerAPI entity. Issue feat: add ai-model-server API spec type (catalog-model layer + backend module) #4209 asks for two new plugins but does not authorize refactoring the entity provider or breaking its output shape. Consumers relying on the previous entity kinds (Resource with type ai-model, Component with type model-server, API) will silently stop receiving those entities.
    Remediation: 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.

Medium

  • [schema-runtime-mismatch] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.ts:104 — 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: '' would fail schema validation when the catalog processes it.
    Remediation: Guard GenerateCatalogEntities to return [] when modelServer.API?.url is falsy, or change the fallback to satisfy minLength: 1.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:51 — The type guard isAiModelServerApiEntity does not check entity.apiVersion like the sibling isAgentAiResourceEntity does. The established workspace pattern asserts apiVersion in type guards.
    Remediation: Add an apiVersion check to the condition, matching the sibling pattern.

Low

  • [scope-creep] workspaces/ai-integrations/plugins/catalog-backend-module-ai-resource-agent/src/module.ts:33 — 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 feat: add ai-model-server API spec type (catalog-model layer + backend module) #4209.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49 — The interface name AiModelServerApiEntity omits a version suffix. The sibling package uses AgentAiResourceEntityV1alpha1. This aligns with the upstream PR naming convention but diverges from the workspace pattern.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:26 — The validator aiModelServerApiEntityValidator omits a version suffix, unlike the sibling agentAiResourceEntityV1alpha1Validator. Aligns with upstream naming.

  • [namespace-collision-risk] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:107 — The new kind is registered under group backstage.io (the upstream namespace). The module comments acknowledge this and document migration when upstream ships.

  • [missing-test] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.test.ts:30 — No test covers the case where modelServer is present but modelServer.API is undefined. This path triggers the serverUrl: '' schema mismatch bug.

  • [missing-test] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/clients/ModelCatalogGenerator.test.ts:30 — No test covers the case where models is an empty array. The generated entity would have models: { available: [] } with no default field.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:63 — The plural form aimodelserverapies appears to be an incorrect pluralization. Expected aimodelserverapis.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/types.ts:49 — The interface omits apiVersion as a literal type, inheriting the broad string type from Entity. The sibling pins apiVersion: 'backstage.io/v1alpha1'.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

Medium

  • [potential-registration-overlap] workspaces/ai-integrations/packages/backend/src/index.ts:80 — The dev backend registers both the upstream @backstage/plugin-catalog-backend-module-ai-model (line 79) and this new catalog-backend-module-ai-model-server module. Both register CatalogModelLayers for the API kind. Once upstream feat(catalog-model): add ai-model-server spec type for API kind backstage/backstage#34476 merges and adds ai-model-server support to the upstream module, a double-registration conflict could occur. Consider adding a code comment clarifying this is a stopgap, or opening a follow-up issue to track removal when upstream lands.

Low

  • [edge-case] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/API.v1alpha1.ai-model-server.schema.jsonmodels.default is not cross-validated against models.available. An entity with default: "nonexistent-model" and available: ["llama3"] passes schema validation. This is a JSON Schema draft-07 limitation and cannot be addressed at the schema layer.

  • [backward-compatibility] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:52 — The type guard isAiModelServerApiEntity only checks kind and spec.type but narrows to a type asserting all required spec fields exist. This follows the standard Backstage type guard pattern (e.g., upstream isApiEntity); consumers should call aiModelServerApiEntityValidator.check() for full validation.

  • [api-versioning] workspaces/ai-integrations/plugins/catalog-model-ai-model-server/src/AiModelServerApiEntity.ts:75 — Both v1alpha1 and v1beta1 are registered with identical schemas from the initial release. This follows the upstream pattern from feat(catalog-model): add ai-model-server spec type for API kind backstage/backstage#34476 but creates version ambiguity — consider whether launching with only v1alpha1 would be cleaner.

  • [naming-convention] workspaces/ai-integrations/plugins/catalog-backend-module-ai-model-server/src/module.ts:34 — The moduleId 'ai-model-server' deviates from sibling packages that use the full directory name (e.g., 'catalog-backend-module-model-catalog').

  • [backstage-metadata] workspaces/ai-integrations/plugins/catalog-backend-module-ai-model-server/package.json — Missing pluginPackages array in the backstage section. Some sibling packages include it, though catalog-backend-module-ai-resource-extensions also omits it.

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-coder Bot and others added 5 commits August 10, 2026 21:48
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
@gabemontero
gabemontero force-pushed the agent/4209-ai-model-server-spec branch from 70eaec4 to ec1915a Compare August 11, 2026 02:58
@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:38 PM UTC · Completed 1:55 PM UTC

Commit: ec1915a · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot removed the requires-manual-review Review requires human judgment label Aug 11, 2026
@gabemontero

Copy link
Copy Markdown
Contributor

Response to review findings — approach change rationale

[high] intent-misalignment (AiModelServerApiEntity.ts:71) and [high] unauthorized-breaking-change (changeset)

These two findings are related and both stem from a deliberate design pivot made after the original issue was written.

What changed and why:

The original plan was to register ai-model-server as a specType on the existing API kind using addKindVersion. During implementation, we identified that this would collide with upstream when backstage/backstage#34476 merges — two modules declaring the same kind + specType combination causes a startup crash (Annotation declared more than once). We hit this exact class of error during dev testing when multiple CatalogModelSources.static() calls re-included the default entity model.

The solution: a dedicated AiModelServerAPI kind that avoids the collision entirely. The schema is identical to upstream #34476 — only the kind field differs. When upstream merges, a migration processor can convert entities by simply changing the kind field, and this module can be retired.

The entity provider consolidation (Component + Resource + API → single AiModelServerAPI) aligns with the upstream design direction and is intentionally a breaking change, reflected in the major changeset bump.

Issue #4209 has been updated to document this rationale, the addKind vs addKindVersion distinction, the bare CatalogModelSource pattern (vs CatalogModelSources.static()), and the entity provider consolidation as authorized scope.

The remaining findings are assessed separately below.

- 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
@gabemontero

Copy link
Copy Markdown
Contributor

Response to remaining review findings

[medium] schema-runtime-mismatch (ModelCatalogGenerator.ts:104)

Fixed. Added a guard to return [] when modelServer.API?.url is falsy, preventing entities with an empty serverUrl that would fail the schema's minLength: 1 constraint. Added a corresponding test case.

[medium] naming-convention — type guard missing apiVersion check (AiModelServerApiEntity.ts:51)

No change. The sibling isAgentAiResourceEntity checks apiVersion because AiResource is a shared kind with multiple specTypes — the apiVersion helps disambiguate. AiModelServerAPI is a dedicated kind with a single specType, so kind === 'AiModelServerAPI' is already unambiguous. This also matches the upstream naming in backstage/backstage#34476 which we're mirroring. Since this kind is intended to be temporary (retired when upstream merges), matching upstream conventions over workspace conventions is the right call.

[low] scope-creep — ai-resource-agent module change

Necessary side-effect, not scope creep. The CatalogModelSources.static() → bare CatalogModelSource change in ai-resource-agent was required to prevent a startup crash. CatalogModelSources.static() auto-includes the default entity model layer; with two custom kind modules each calling it, backstage.io/managed-by-location gets declared three times and the catalog plugin crashes. Without this fix, the dev environment cannot start.

[low] naming-convention — no version suffix on type/validator

Intentional. We're matching upstream backstage/backstage#34476 naming (AiModelServerApiEntity, aiModelServerApiEntityValidator), not the workspace's agent pattern which uses version suffixes. Since the goal is parity with upstream for eventual migration, upstream naming takes precedence.

[low] namespace-collision-risk — backstage.io group

Acknowledged, intentional. Using backstage.io as the group means entities use apiVersion: backstage.io/v1alpha1, matching what upstream will use. This makes migration trivial — change the kind field only. The trade-off (temporarily "squatting" on the upstream namespace) is documented in both the code comments and issue #4209.

[low] missing-test — no API-undefined case

Fixed. Added test should return empty array when modelServer has no API url.

[low] missing-test — empty models array

Fixed. Added test should handle empty models array — verifies available: [] with no default field.

[low] plural form typo

Fixed. aimodelserverapiesaimodelserverapis.

[low] missing apiVersion literal on type

No change. Same rationale as the naming conventions — matching upstream, which also inherits the broad string type from Entity. Temporary kind, so matching upstream for easy migration is the priority.

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:32 PM UTC · Completed 2:52 PM UTC

Commit: 59a00eb · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

The CatalogModelSources.static() -> bare CatalogModelSource fix in
catalog-backend-module-ai-resource-agent is a behavioral change to a
published package and needs a changeset entry.

Signed-off-by: gabemontero <gmontero@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Assisted-by: Claude Opus 4.6
@gabemontero

Copy link
Copy Markdown
Contributor

Response to second fullsend review (review 4907533546)

Action taken

No change (with rationale)

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ready-for-review Agent PR ready for human review workspace/ai-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add ai-model-server API spec type (catalog-model layer + backend module)

1 participant