Fix RPT-1 dtype map + composition enhancement; add integrator FAQ#14
Open
sleibach wants to merge 9 commits into
Open
Fix RPT-1 dtype map + composition enhancement; add integrator FAQ#14sleibach wants to merge 9 commits into
sleibach wants to merge 9 commits into
Conversation
added 3 commits
April 29, 2026 22:33
RPT-1's /predict endpoint only accepts dtype values 'string', 'numeric' or 'date' and returns 422 for anything else. The map previously emitted 'bool' for cds.Boolean and 'datetime' for cds.DateTime / cds.Timestamp, which broke prediction for any entity carrying those types. - cds.Boolean: 'string' (round-trips as 'true' / 'false') - cds.DateTime / cds.Timestamp: 'string' so the full ISO value is kept as an opaque token (declaring 'date' would drop the time portion and may reject non-YYYY-MM-DD inputs) - cds.Date stays 'date'
Short summary of the runtime behaviour so consumers don't have to read the source to answer the most common questions: what annotations get emitted, when the handler runs, what context is sent to RPT-1 (the 2000 active-rows cap, the column stripping, the [PREDICT] placeholder), how descriptions are filled, the RPT-1 deployment lifecycle, and the local mock behaviour. Includes a callout reminding integrators to opt sensitive fields out via @UI.RecommendationState.
The CSN enhancer walked `entity.compositions[*]` only — a legacy CSN shape. In CDS >= 7 compositions live in `entity.elements[*]` with `type === 'cds.Composition'`, so the legacy walk was empty and nested entities (e.g. `Approvers` under a `ChangeRequests` draft) never received `@UI.Recommendations`. Recommendations would silently be missing from any field on a child of a draft root, even when the child's fields had perfectly good value lists. Replaced the single-level walk with a recursive walk that handles both the legacy `entity.compositions` map and the modern `entity.elements` form, with a visited set to break composition cycles. enhanceEntity is already idempotent, so a target reachable through both paths is enhanced once.
Until now, the CSN enhancer only emitted SAP_Recommendations for fields
auto-detected as having a value help (`@Common.ValueList.CollectionPath`
or `@cds.odata.valuelist` on the association target). Free-form scalar
fields — typically numerics like measurement ranges or planning
estimates — were silently ignored even when they would be excellent
prediction targets.
Adds an opt-in field-level annotation `@AI.Recommend`. When set on a
scalar element (no association / composition / unmanaged), the field is
included in the entity's `<Entity>_Recommendations` companion alongside
auto-detected value-helped fields and Fiori Elements' soft-fill
placeholder renders the prediction in the empty input.
`task_type` is now chosen per target column: numeric scalars opted in
via `@AI.Recommend` (`cds.Integer*`, `cds.Decimal`, `cds.Double`,
`cds.UInt8`) use `regression` so RPT-1 can interpolate continuous
values; everything else — including value-list FKs and string fields —
uses `classification` (existing behaviour). The opt-in check is what
guards FK columns from being reclassified: those carry no
`@AI.Recommend`, so they remain categorical even though their CDS type
is numeric.
Widens the `task_type` enum on `predictRowColumns` from `{classification}`
to `{classification, regression}` so the action signature accepts both.
Contributor
|
Hi @sleibach, thank you for your contribution. We will have a look at it. Don't worry about the hybrid integration tests, we will update the credentials soon so they run again. |
Two related stability bugs hit by larger schemas:
1. Empty rows. Reading a draft entity whose composition was empty
passed `rows: []` to `_fetchPrediction`, whose schema-derivation
reduce immediately dereferenced `rows[0][ele]` on `undefined` —
taking the whole server down on a TypeError. `_fetchPrediction`
now returns `{}` for empty input. The READ handler also
short-circuits when the response set is empty, avoiding a
needless AI Core round-trip.
2. RPT-1 inference limits. The model rejects payloads with more than
10 target columns or more than 100 columns per row, returning a
noisy HTTP 422. The plugin previously sent through whatever the
model had collected, so any sufficiently wide entity (think
denormalised composition children with many value-helped fields)
produced a 422 on every read. `_fetchPrediction` now checks both
limits up front, logs a warning with a hint to opt columns out
via `@UI.RecommendationState : 0`, and returns an empty result —
the surrounding READ still completes, the page still renders, the
user just doesn't get recommendations on that particular entity
until they trim the column set.
Contributor
|
Just as FYI: We are currently working on setting up our CI Pipeline so that the tests can also be executed from forks, so also the integration tests run for your PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small, independent improvements found while integrating the plugin into a CAP application:
Fix: align CDS→RPT-1 dtype map with the inference API enum
/v2/inference/deployments/{id}/predictonly acceptsdtypevalues'string' | 'numeric' | 'date'. The map emitted'bool'forcds.Booleanand'datetime'forcds.DateTime/cds.Timestamp, which caused HTTP 422 from RPT-1 for any entity carrying thosetypes. Booleans now map to
'string'(round-trip as'true'/'false'),DateTime/Timestampmap to'string'so the full ISOvalue is preserved as an opaque categorical token (declaring
'date'would drop the time portion and may reject inputs that aren't pureYYYY-MM-DD), andDatekeeps'date'.Fix: enhance composition children on the current CDS CSN flavour
The CSN enhancer walked
entity.compositions[*]only — a legacy shape. In CDS ≥ 7 compositions live inentity.elements[*]withtype === 'cds.Composition', so on modern projects the legacy walk was empty and nested entities (e.g. anApproverscomposition under adraft
ChangeRequestsroot) never received@UI.Recommendations. Recommendations were silently missing from any field on a draftchild, even with valid value lists. Replaced the single-level walk with a recursive walk over both shapes with cycle protection.
enhanceEntityis idempotent, so targets reachable through both paths are enhanced once.Docs: short "how it works" FAQ for integrators
Added a six-question FAQ to the README covering: what annotations the plugin emits, when the READ handler runs, what context goes to
RPT-1 (the 2000-row cap, stripped audit/binary columns,
[PREDICT]placeholders), how@Common.Textdescriptions are populated, theRPT-1 deployment lifecycle, and the local-mock behaviour. Includes an
[!IMPORTANT]callout pointing at@UI.RecommendationState : 0for sensitive fields, since everything in the context payload is forwarded to AI Core.