Skip to content

feat(#4128): add AiResource agent typed schema - #4164

Open
fullsend-ai-coder[bot] wants to merge 4 commits into
mainfrom
agent/4128-airesource-agent-schema
Open

feat(#4128): add AiResource agent typed schema#4164
fullsend-ai-coder[bot] wants to merge 4 commits into
mainfrom
agent/4128-airesource-agent-schema

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Add AgentAiResourceEntityV1alpha1 types, KindValidator, type guard, JSON schema, example fixtures, and unit tests for the agent-shaped AiResource entity (spec.type: 'agent').

Implementation follows the upstream skill/rule discriminated-union pattern from @backstage/catalog-model. Agent entities require spec.instructions (non-empty string) and support optional fields per the design D3 mapping: handoffDescription, model, handoffs, tools, toolUseBehavior, resetToolChoice, modelSettings (temperature, maxTokens, toolChoice), and outputSchema.

Changes:

  • plugins/ai-experience-common/src/agent/: new AgentAiResource types,
    validator, type guard, and JSON schema
  • examples/ai-resource-agents.yaml: router + specialist multi-agent
    handoff example demonstrating required and optional fields
  • examples/ai-resources-oci-skills.yaml: fix plural spec.type
    'skills' -> 'skill' (D8)
  • app-config.yaml: wire agent example into catalog locations
  • report.api.md: regenerated with new public exports

No @openai/agents-core dependency; opaque string[] for handoffs/tools (no entity-ref format enforcement).

Assisted-by: Claude Opus 4.6


Closes #4128

Post-script verification

  • Branch is not main/master (agent/4128-airesource-agent-schema)
  • Secret scan passed (gitleaks — bb5785cf9f6139b82812b9825cf35738d216944b..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

Add AgentAiResourceEntityV1alpha1 types, KindValidator, type guard,
JSON schema, example fixtures, and unit tests for the agent-shaped
AiResource entity (spec.type: 'agent').

Implementation follows the upstream skill/rule discriminated-union
pattern from @backstage/catalog-model. Agent entities require
spec.instructions (non-empty string) and support optional fields
per the design D3 mapping: handoffDescription, model, handoffs,
tools, toolUseBehavior, resetToolChoice, modelSettings (temperature,
maxTokens, toolChoice), and outputSchema.

Changes:
- plugins/ai-experience-common/src/agent/: new AgentAiResource types,
  validator, type guard, and JSON schema
- examples/ai-resource-agents.yaml: router + specialist multi-agent
  handoff example demonstrating required and optional fields
- examples/ai-resources-oci-skills.yaml: fix plural spec.type
  'skills' -> 'skill' (D8)
- app-config.yaml: wire agent example into catalog locations
- report.api.md: regenerated with new public exports

No @openai/agents-core dependency; opaque string[] for handoffs/tools
(no entity-ref format enforcement).

Closes #4128

Assisted-by: Claude Opus 4.6
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@rhdh-gh-app

rhdh-gh-app Bot commented Aug 4, 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-resource-agent workspaces/ai-integrations/plugins/catalog-backend-module-ai-resource-agent minor v0.1.0
@red-hat-developer-hub/backstage-plugin-catalog-model-ai-resource-agent workspaces/ai-integrations/plugins/catalog-model-ai-resource-agent minor v0.1.0

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 4, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:26 PM UTC · Completed 3:41 PM UTC
Commit: fec9daf · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Medium

  • [schema-type-contract-mismatch] workspaces/ai-integrations/plugins/ai-experience-common/src/agent/types.ts:34 — The AgentAiResourceModelSettings TypeScript interface has an index signature [key: string]: JsonValue | undefined that permits arbitrary additional keys, but the corresponding JSON schema sets "additionalProperties": false on modelSettings. The test suite explicitly verifies that unknown properties are rejected (the "rejects modelSettings with unknown property" test), confirming the runtime enforcement of a closed set. The TypeScript type misleadingly tells consumers they can include arbitrary properties that will be rejected at validation time, and this mismatch is visible in the published report.api.md.
    Remediation: Remove the index signature from AgentAiResourceModelSettings so the TypeScript type accurately reflects the closed schema. If JsonObject compatibility is needed at specific call sites, use a utility type or intersection there instead of widening the public interface.

  • [stale-reference] workspaces/ai-integrations/examples/ai-resource-oci.yaml:24 — The PR fixes the plural type: skills to singular type: skill in ai-resources-oci-skills.yaml per design decision D8, and the commit message states "fix plural spec.type 'skills' -> 'skill'". However, the same stale plural type: skills remains in examples/ai-resource-oci.yaml at line 24. This file was not included in the fix.
    Remediation: Change spec.type: skills to spec.type: skill on line 24 of workspaces/ai-integrations/examples/ai-resource-oci.yaml.

Low

  • [naming-convention] workspaces/ai-integrations/plugins/ai-experience-common/src/agent/AiResource.v1alpha1.agent.schema.json:3 — The JSON schema $id is AiResourceV1alpha1Agent but the TypeScript type is AgentAiResourceEntityV1alpha1. Minor naming asymmetry between the schema identifier and the code-level names (schema puts the discriminant last, TypeScript prefixes it).

  • [scope-gap] Issue tasks 6.2 (update docs implying agent typing is blocked on RHDHPLAN-1113) and 6.3 (update package README with agent field table) are listed in the OpenSpec tasks but not addressed in this PR. These documentation tasks may be reasonably deferred to a follow-up.

  • [missing-changeset] This PR adds new public types (AgentAiResourceEntityV1alpha1, AgentAiResourceModelSettings) and exports (agentAiResourceEntityV1alpha1Validator, isAgentAiResourceEntity) but includes no changeset file. The CHANGELOG will not reflect this feature addition when the next release is cut.

@johnmcollier johnmcollier left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Requested changes

Please land the agent typed schema in a dedicated package (not ai-experience-common), wire catalog-model registration in this PR, and address the inline notes below.

Also required (no diff hunk)

  • Fix remaining plural drift: workspaces/ai-integrations/examples/ai-resource-oci.yaml still has spec.type: skills — upstream/discriminator is singular skill.
  • Add a minor changeset for the new package (workspace packages are still 0.x).

Out of scope

  • Catalog processor validation (#4129 / RHIDP-15868).

Comment thread workspaces/ai-integrations/plugins/ai-experience-common/src/index.ts Outdated
Comment thread workspaces/ai-integrations/plugins/ai-experience-common/src/agent/types.ts Outdated
@johnmcollier

Copy link
Copy Markdown
Member

/fs-fix address review comments

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 11:29 PM UTC · Completed 11:52 PM UTC
Commit: fec9daf · View workflow run →

…tration

- Move types, JSON schema, KindValidator, type guard, and tests from
  ai-experience-common into new catalog-model-ai-resource-agent package
- Remove open index signature from AgentAiResourceModelSettings (use
  type alias for implicit JsonObject compat) to match closed JSON schema
- Add agentAiResourceEntityModel CatalogModelLayer with specType 'agent'
- Add catalog-backend-module-ai-resource-agent backend module that
  registers the agent model source via catalogModelExtensionPoint
- Wire backend module into packages/backend
- Fix remaining plural drift: spec.type 'skills' → 'skill' in
  examples/ai-resource-oci.yaml
- Add minor changeset for new packages
- Regenerate API reports

Addresses review feedback on #4164

Assisted-by: Claude Opus 4.6
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Addressed all 6 review findings. Moved agent schema to dedicated catalog-model-ai-resource-agent package, fixed schema/type mismatch by removing index signature (using type alias for JsonObject compat), added CatalogModelLayer + backend module for catalog registration, fixed plural drift in ai-resource-oci.yaml, and added minor changeset.

Fixed (6):

  1. Wrong package home — move agent types to dedicated package (plugins/catalog-model-ai-resource-agent/): Moved types, JSON schema, KindValidator, type guard, tests, and API report from ai-experience-common/src/agent/ into a new dedicated catalog-model-ai-resource-agent package. Removed the export * from './agent' re-export from ai-experience-common/src/index.ts and regenerated its report.api.md.
  2. Schema/type contract mismatch — index signature on AgentAiResourceModelSettings (plugins/catalog-model-ai-resource-agent/src/types.ts): Removed the open [key: string]: JsonValue | undefined index signature from AgentAiResourceModelSettings. Changed from interface to type alias so TypeScript generates an implicit index signature for Entity.spec (JsonObject) compatibility, matching the closed JSON schema (additionalProperties: false).
  3. Catalog-model registration required — add CatalogModelLayer and backend module (plugins/catalog-backend-module-ai-resource-agent/src/module.ts): Created agentAiResourceEntityModel CatalogModelLayer using createCatalogModelLayer with addKindVersion (specType: 'agent', v1alpha1). Added a thin catalog-backend-module-ai-resource-agent backend module that registers the agent model source via catalogModelExtensionPoint.addModelSource, following the upstream pattern from @backstage/plugin-catalog-backend-module-ai-model. Wired the module into packages/backend/src/index.ts.
  4. Public exports should come from new dedicated package (plugins/catalog-model-ai-resource-agent/src/index.ts): All agent public exports (types, validator, type guard, CatalogModelLayer) are now exported from the new catalog-model-ai-resource-agent package entrypoint instead of ai-experience-common.
  5. Fix remaining plural drift in ai-resource-oci.yaml (examples/ai-resource-oci.yaml): Changed spec.type from 'skills' (plural) to 'skill' (singular) to match the upstream discriminator convention.
  6. Add minor changeset for new package (.changeset/ai-resource-agent-schema.md): Added a minor changeset covering both the new catalog-model-ai-resource-agent and catalog-backend-module-ai-resource-agent packages.

Tests: passed

Decision points
  • Used type alias instead of interface for AgentAiResourceModelSettings to resolve the reviewer's index-signature concern while maintaining Entity.spec (JsonObject) compatibility (alternatives: Keep interface with index signature (rejected by reviewer), Use Omit<Entity, 'spec'> on the entity type (breaks type predicate); rationale: TypeScript generates implicit index signatures for type aliases but not interfaces, so a type alias satisfies both the closed-schema intent and the structural type constraint.)
  • Placed CatalogModelLayer in the catalog-model library package and the backend module in a separate catalog-backend-module package (alternatives: Single package with both model and module; rationale: Matches the upstream separation: @backstage/catalog-model exports the CatalogModelLayer, and @backstage/plugin-catalog-backend-module-ai-model is the separate backend module. This allows frontend consumers to import types without pulling backend dependencies.)

Updated by fullsend fix agent

@johnmcollier

Copy link
Copy Markdown
Member

/fs-fix address failing CI check and resolve GitHub review comments that have been addressed

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 7:24 PM UTC · Completed 7:40 PM UTC
Commit: 226788f · View workflow run →

Add the required `pluginPackages` array to the backstage metadata
in catalog-model-ai-resource-agent/package.json. This fixes the
`backstage-cli repo fix --check --publish` CI gate.

Addresses review feedback on #4164

Assisted-by: Claude Opus 4.6
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (human-triggered)

Fixed CI publish check by adding missing pluginPackages array to catalog-model-ai-resource-agent/package.json. All 4 review comments from the previous iteration were already addressed. Tests pass (26/26).

Fixed (5):

  1. CI publish check failing: catalog-model-ai-resource-agent package out of sync: Added missing pluginPackages array to backstage metadata in catalog-model-ai-resource-agent/package.json. The backstage-cli repo fix --check --publish CI gate requires this field for published packages. Running yarn backstage-cli repo fix --publish generated the fix.
  2. Wrong package home — move to dedicated package: Already addressed in previous iteration (commit 226788f). Agent types, JSON schema, KindValidator, type guard, tests, and API report are in the dedicated catalog-model-ai-resource-agent package. The agent re-export was removed from ai-experience-common.
  3. Schema/type contract mismatch — remove index signature: Already addressed in previous iteration (commit 226788f). The [key: string]: JsonValue | undefined index signature was removed from AgentAiResourceModelSettings in types.ts. The type alias pattern is used instead.
  4. Catalog-model registration required — add CatalogModelLayer and backend module: Already addressed in previous iteration (commit 226788f). agentAiResourceEntityModel CatalogModelLayer is exported from catalog-model-ai-resource-agent. A thin catalog-backend-module-ai-resource-agent backend module registers the agent specType via catalogModelExtensionPoint.addModelSource. The module is wired into packages/backend.
  5. Public exports should come from dedicated package: Already addressed in previous iteration (commit 226788f). All public exports (types, validator, model layer, type guard) come from the catalog-model-ai-resource-agent package entrypoint with its own report.api.md.

Tests: passed

Updated by fullsend fix agent

- Add missing technical-specialist-agent entity to examples (issue 1)
- Add module smoke test for catalog-backend-module-ai-resource-agent (issue 2)
- Add minLength: 1 to handoffDescription schema field (issue 3)

Signed-off-by: John Collier <jcollier@redhat.com>
Assisted-by: Claude Sonnet 4.6
@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

@johnmcollier

Copy link
Copy Markdown
Member

/fs-fix address my review comments

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 6:26 PM UTC · Completed 6:45 PM UTC

Commit: 7097b69 · View workflow run →

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 3 (human-triggered)

Verified all 6 review findings from johnmcollier are addressed. Agent types are in a dedicated catalog-model-ai-resource-agent package (not ai-experience-common). Index signature removed from AgentAiResourceModelSettings. CatalogModelLayer and backend module are implemented and wired into packages/backend. Public exports come from the dedicated package. Plural drift fixed in both YAML files. Changeset exists. All 26 tests pass, both packages build, lint clean, API reports current.

Fixed (6):

  1. Wrong package home — move agent types to dedicated package (workspaces/ai-integrations/plugins/catalog-model-ai-resource-agent/): Already addressed (iteration 1). Verified: agent types, JSON schema, KindValidator, type guard, tests, and API report are in the dedicated catalog-model-ai-resource-agent package. The ./agent re-export was removed from ai-experience-common/src/index.ts. No agent directory remains in ai-experience-common.
  2. Schema/type contract mismatch — remove index signature from AgentAiResourceModelSettings (workspaces/ai-integrations/plugins/catalog-model-ai-resource-agent/src/types.ts): Already addressed (iteration 1). Verified: the [key: string]: JsonValue | undefined index signature was removed. AgentAiResourceModelSettings is now a type alias (not interface) for implicit index signature compatibility with Entity.spec (JsonObject), matching the closed JSON schema (additionalProperties: false). report.api.md is up to date.
  3. Catalog-model registration required — add CatalogModelLayer and backend module (workspaces/ai-integrations/plugins/catalog-model-ai-resource-agent/src/AgentAiResourceEntityV1alpha1.ts): Already addressed (iteration 1). Verified: agentAiResourceEntityModel CatalogModelLayer is exported from catalog-model-ai-resource-agent using createCatalogModelLayer with addKindVersion (specType: 'agent', v1alpha1, with owner/system relationFields). Backend module catalog-backend-module-ai-resource-agent calls catalogModelExtensionPoint.addModelSource(CatalogModelSources.static([agentAiResourceEntityModel])). Module is wired into packages/backend/src/index.ts. Both packages build and test successfully.
  4. Public exports should come from dedicated package entrypoint (workspaces/ai-integrations/plugins/catalog-model-ai-resource-agent/src/index.ts): Already addressed (iteration 1). Verified: all public exports (AgentAiResourceEntityV1alpha1, AgentAiResourceModelSettings types; agentAiResourceEntityV1alpha1Validator, agentAiResourceEntityModel, isAgentAiResourceEntity values) come from the catalog-model-ai-resource-agent package entrypoint with its own report.api.md.
  5. Fix remaining plural drift in ai-resource-oci.yaml (workspaces/ai-integrations/examples/ai-resource-oci.yaml): Already addressed (iteration 1). Verified: spec.type changed from 'skills' (plural) to 'skill' (singular) in both ai-resource-oci.yaml and ai-resources-oci-skills.yaml.
  6. Add minor changeset for new packages (workspaces/ai-integrations/.changeset/ai-resource-agent-schema.md): Already addressed (iteration 1). Verified: minor changeset exists covering both @red-hat-developer-hub/backstage-plugin-catalog-model-ai-resource-agent and @red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-agent.

Tests: passed

Strategy change: Iteration 3: instead of making code changes, performed full verification pass — confirmed all 6 findings are already resolved with passing build, tests (26/26), lint, and API report checks.

Decision points
  • All 6 review findings were verified as already addressed in prior iterations. No new code changes needed. (alternatives: Make redundant changes to signal completion, Add additional improvements beyond review scope; rationale: All review comments are fully resolved: packages build, 26/26 tests pass, lint clean, API reports up to date, CI checks pass. Making unnecessary changes would violate the minimal-diff principle.)

Updated by fullsend fix agent

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

Labels

ready-for-review Agent PR ready for human review requires-manual-review Review requires human judgment workspace/ai-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ai-integrations: AiResource agent typed schema (catalog-model validator + examples)

2 participants