Repository navigation
Conversation
22813f9 to
db941de
Compare
db941de to
4ee3cc1
Compare
| import com.sap.cds.services.runtime.CdsRuntimeAware; | ||
| import java.io.InputStream; | ||
|
|
||
| public interface OrdResolver extends CdsRuntimeAware { |
There was a problem hiding this comment.
What is the reason to go away from the CdsProvider approach? This is common practise in CAP Java in regards to extensibility and plug-ability.
There was a problem hiding this comment.
The idea behind the OrdResovler interface is to allow for granular control over the exposure of ORD resources. E.g. if one wants to register a custom resolver for an agent - this can happen in complete isolation from all other resolvers.
| import com.sap.cds.services.runtime.CdsRuntimeAware; | ||
| import java.util.function.Predicate; | ||
|
|
||
| public interface CdsOrdNodeCustomizer extends CdsRuntimeAware { |
There was a problem hiding this comment.
If I understand correctly, CdsOrdNodeCustomizer is for modifying content while CdsOrdNodeGenerator is for contributing new things, correct?
There was a problem hiding this comment.
Correct. The customizers can only modify existing nodes in the JSON tree. Generators - on the contrary - they provide new nodes on arbitrary positions in the document.
| * @param context the JSON stream context | ||
| * @return the generated node as a string | ||
| */ | ||
| String generate(JsonStreamContext context); |
There was a problem hiding this comment.
Taking the following snippet as what is required to be added for agents, would you see that all the content is contributed via this interface? Or would it just be the agent card?
I´m wondering how e.g. the "partOfPackage" could be calculated correctly based on the given JsonStreamContext. Ideally, we can come up with an implementation idea for this given snippet.
{
"apiResources": [
{
"ordId": "sap.agtpocxtrv:apiResource:TravelAgent:v1",
"title": "Travel Agent",
"shortDescription": "Short description of Travel Agent",
"description": "Long description of Travel Agent",
"version": "1.0.8",
"lastUpdate": "2026-09-22T09:48:00Z",
"apiProtocol": "a2a",
"releaseStatus": "beta",
"partOfPackage": "sap.agtpocxtrv:package:capirextravelsjava-api:v1",
"visibility": "internal",
"extensible": {"supported": "no"},
"resourceDefinitions": [
{
"type": "a2a-agent-card",
"mediaType": "application/json",
"url": "/a2a/travel/.well-known/agent-card.json",
"accessStrategies": [{ "type": "open" }]
}
],
"exposedEntityTypes": [
],
"tags": ["travel", "ai-agent", "a2a"]
}
],
"agents": [
{
"ordId": "sap.agtpocxtrv:agent:travelAgent:v1",
"title": "Travel Agent",
"shortDescription": "AI agent specialized in travel woizh cuetom conettna",
"description": "A longer description of this Agent with **markdown**...",
"version": "1.0.8",
"visibility": "public",
"releaseStatus": "active",
"lastUpdate": "2026-09-22T09:48:00Z",
"partOfPackage": "sap.agtpocxtrv:package:capirextravelsjava-api:v1",
"relatedEntityTypes": [
],
"exposedApiResources": [
{"ordId": "sap.agtpocxtrv:apiResource:TravelAgent:v1"}
],
"integrationDependencies": [
],
"partOfGroups": [],
"labels": {
"sap.ai:interactionMode": ["conversational", "system-triggered"],
"sap.joule:scenario.mapping": ["agent"]
},
"tags": ["travel", "ai-agent", "a2a"]
}
]
}
There was a problem hiding this comment.
This is a very valid question. Let's discuss what makes sense in this case - either the generator needs to inspect its environment or we need to change the interface so that the generator consumes some sort of ORD context.
In the current implementation where CDS compilation is responsible for generating the ORD metadata these relationships can be expressed via specific CDS annotations. I don't think that this can be considered applicable for the current approach... unless the Agent plugin begins understanding these annotations 🤔
There was a problem hiding this comment.
The cds model for agents look like this:
@agent @odata @path: 'travel' service TravelService {
...
}
The @agent annotation will trigger the addition of an agents node in the metadata plus an apiResources with a resourceDefinitions of type a2a-agent-card. The url should be derivable from the model. Maybe node and java differ in some prefix. But I don´t see a reason, why this skeleton of the metadata cannot be added at build time already. Model wise this is stable. Maybe the current approach goes too far to also generate the metadata of the ord document.
When it comes to the content of the agent card, it will be different. This is calculated at runtime and might be called by ord through a service to serve the agent card in the context of ord.
Let´s discuss this.
There was a problem hiding this comment.
This is why the OrdResolver concept is introduced. It allows for granular control over the contents of each ORD resource, e.g. the content of the agent card itself.
Refactor ORD Resource Resolution with Extensible Resolvers
Refactor
♻️ Replaced the centralized ORD resource provider with service-loaded resolvers that select static or dynamic resources based on the requested resource and perspective. ORD document processing is now split into dedicated node customizers and generators, improving extensibility and separation of concerns.
Changes
resolver/*: Added theOrdResolverextension point and dedicated resolvers for static/dynamic ORD documents and resource definitions.DocumentsServlet.java: Loads applicable resolvers, selects them by priority, defaults missing perspectives tosystem-version, and returns404when no resolver applies.OrdJsonInputStream.java: Replaced generic node processors with context-aware customizers and generators, supporting generated content at matching JSON structure boundaries.common/customizers/*: Introduced the customizer API and migrated entry-point and resource-definition transformations to it.common/generators/CdsOrdNodeGenerator.java: Added an extension point for generating ORD nodes from the JSON stream context.MtxSidecarClient*: Changed sidecar responses from strings to raw byte arrays to preserve resource content without unnecessary encoding conversion.Utils.java: Updated ORD stream construction for generators/customizers and made iterator conversion null-safe.META-INF/services/*: Registered resolvers and customizers through the service loader; removed obsolete provider and processor registrations.OrdResourcesProviderimplementations, configuration, andCdsOrdNodeProcessor.PR Bot Information
Version:
1.32.6pull_request.opened8b041230-c3db-11f1-9dca-be85dcdcc9bdgpt-5.6-sol