Skip to content

[recommendations] Support @UI.RecommendationState annotation #28

Description

@Schmarvinius

Context

The Node.js counterpart (@cap-js/ai) supports dynamic @UI.RecommendationState expressions that are evaluated per-row at runtime. This allows conditionally disabling recommendations for specific fields based on the current row's data (e.g., disable genre recommendation once a genre is already set).
Currently, the Java cds-feature-recommendations module only supports the static form @UI.RecommendationState: 0 (completely disables a field at compile time).

Example

entity Books : cuid, managed {
  title    : String;
  genre    : Association to Genres;
  currency : Association to Currencies;
}
// Static (already supported): always disabled
annotate Books with { genre @UI.RecommendationState: 0 };
// Dynamic (not yet supported): disabled when genre is already filled
annotate Books with { genre @UI.RecommendationState: { $edmJson: { $If: [{ $Ne: [{ $Path: 'genre_ID' }, null] }, 0, 2] } } };

Approach (from Node.js reference)

  1. During context row retrieval, detect elements with @UI.RecommendationState containing an expression (xpr)
  2. Add them as computed columns to the SELECT query: { xpr: [...], as: 'SAP_RECOMMENDATION_STATE_{field}', cast: Integer }
  3. After fetching the draft row, evaluate the result per-field:
  • If SAP_RECOMMENDATION_STATE_{field} == 0 → skip prediction for that field (don't set [PREDICT])
  • Otherwise → proceed as normal
  1. Exclude fields with disabled state from the final SAP_Recommendations response

Acceptance Criteria

  • Dynamic expressions in @UI.RecommendationState are evaluated per-row
  • Fields with state 0 (disabled) are excluded from prediction and response
  • Static @UI.RecommendationState: 0 continues to work (no regression)
  • Unit test covering dynamic expression evaluation
  • Integration test with a draft entity using conditional recommendation state

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions