diff --git a/assets/template.html b/assets/template.html
index 24b81e152..898e6bd15 100644
--- a/assets/template.html
+++ b/assets/template.html
@@ -28,7 +28,7 @@
$endfor$
$if(math)$
$if(mathjax)$
-
+
$endif$
$math$
$endif$
diff --git a/docs/recommendations.md b/docs/recommendations.md
new file mode 100644
index 000000000..c6ac1dd5d
--- /dev/null
+++ b/docs/recommendations.md
@@ -0,0 +1,91 @@
+Entity types for which recommendations are available have an additional property carrying the recommendations and the following annotation pointing to this property:
+```xml
+
+
+
+
+
+
+
+ ...
+
+
+
+
+ ...
+
+```
+
+Clients request recommendations from the server at their discretion.
+
+```mermaid
+sequenceDiagram
+ actor client as Fiori client
+ actor otherclient as Other Fiori client
of same collaborative draft
+ box ABAP
+ participant server as OData service
+ participant task as New task
+ end
+ participant AI as BTP recommendations service
+ client ->>+ server: POST $batch
+ server ->> server: PATCH SalesOrder('A')
+ server ->> server: GET SalesOrder('A')?$expand=... for side effects
+ server -->> client: $batch response
+ par server decides whether to update recommendations
+ opt input for recommendations has changed
+ server ->>+ task: call function ... starting new task
+ deactivate server
+ task ->>+ AI: compute recommendations
+ AI -->>- task: return recommendations
+ task ->> task: update recommendations in draft
+ deactivate task
+ end
+ and
+ client ->>+ server: GET SalesOrder('A')?$select=SAP__Recommendations&$expand=...
+ server ->> server: read recommendations from draft
+ server -->>- client: return recommendations
+ and
+ otherclient ->>+ server: GET SalesOrder('A')?$select=SAP__Recommendations&$expand=...
+ server ->> server: read recommendations from draft
+ server -->>- otherclient: return recommendations
+ end
+```
+
+Alternatively, clients can be notified via web socket if recommendations have been updated.
+
+```mermaid
+sequenceDiagram
+ actor client as Fiori client
+ actor otherclient as Other Fiori client
of same collaborative draft
+ box ABAP
+ participant server as OData service
+ participant task as New task
+ end
+ participant AI as BTP recommendations service
+ client ->>+ server: POST $batch
+ server ->> server: PATCH SalesOrder('A')
+ server ->> server: GET SalesOrder('A')?$expand=... for side effects
+ server -->> client: $batch response
+ opt input for recommendations has changed
+ server ->>+ task: call function ... starting new task
+ deactivate server
+ task ->>+ AI: compute recommendations
+ AI -->>- task: return recommendations
+ task ->> task: update recommendations in draft
+ par
+ task ->> client: notify client of updated recommendations
+ and
+ task ->> otherclient: notify client of updated recommendations
+ end
+ deactivate task
+ par
+ client ->>+ server: GET SalesOrder('A')?$select=SAP__Recommendations&$expand=...
+ server ->> server: read recommendations from draft
+ server -->>- client: return recommendations
+ and
+ otherclient ->>+ server: GET SalesOrder('A')?$select=SAP__Recommendations&$expand=...
+ server ->> server: read recommendations from draft
+ server -->>- otherclient: return recommendations
+ end
+ end
+```
diff --git a/vocabularies/UI.json b/vocabularies/UI.json
index 67d0d029c..32f9ff920 100644
--- a/vocabularies/UI.json
+++ b/vocabularies/UI.json
@@ -1736,6 +1736,42 @@
"@Core.Description": "Path to property in the collection of recommended values. Format is identical to PropertyPath annotations."
}
},
+ "Recommendations": {
+ "$Kind": "Term",
+ "$Type": "Edm.ComplexType",
+ "$AppliesTo": ["EntityType"],
+ "@Common.Experimental": true,
+ "@Core.Description": "Recommendations for an entity",
+ "@Core.LongDescription": "This complex-typed annotation contains structural properties corresponding via name equality\nto non-key structural primitive properties of the entity type for which recommendations are available.\nThe type of such a property is a collection of a informal specialization of [`PropertyRecommendationType`](#PropertyRecommendationType).\n(The specializiations are called \"informal\" because they may omit the property `RecommendedFieldDescription`.)\n\nClients retrieve the recommendations with a GET request that includes this annotation in a `$select` clause.\nThe recommendations MAY be computed asynchronously, see [this diagram](../docs/recommendations.md)."
+ },
+ "PropertyRecommendationType": {
+ "$Kind": "ComplexType",
+ "$Abstract": true,
+ "@Common.Experimental": true,
+ "@Core.Description": "Base type containing recommendations for an entity type property",
+ "RecommendedFieldValue": {
+ "$Type": "Edm.PrimitiveType",
+ "@Core.Description": "Recommended value",
+ "@Core.LongDescription": "In informal specializations of this base type, this property is specialized to the primitive type of the entity type property.\n If the recommendation has a description, this property has a [`Common.Text`](Common.md#Text) annotation\n that evaluates to the `RecommendedFieldDescription` property.",
+ "@Common.Text": { "$Path": "RecommendedFieldDescription" }
+ },
+ "RecommendedFieldDescription": {
+ "$Nullable": true,
+ "@Core.Description": "Description of the recommended value",
+ "@Core.LongDescription": "In informal specializations of this base type, this property is specialized to the string type of the text property corresponding to the entity type property.\n It is omitted from informal specializations for recommendations without description."
+ },
+ "RecommendedFieldScoreValue": {
+ "$Type": "Edm.Decimal",
+ "$Nullable": true,
+ "@Core.Description": "Confidence score of the recommended value"
+ },
+ "RecommendedFieldIsSuggestion": {
+ "$Type": "Edm.Boolean",
+ "$DefaultValue": false,
+ "@Core.Description": "Whether the recommended value shall be suggested in the input field",
+ "@Core.LongDescription": "For any collection of a specialization of `PropertyRecommendationType`\n in a property containing [`Recommendations`](#Recommendations),\n this flag can be true in at most one instance of the collection,\n and only if the `RecommendedFieldScoreValue` exceeds a certain threshold."
+ }
+ },
"ExcludeFromNavigationContext": {
"$Kind": "Term",
"$Type": "Core.Tag",
diff --git a/vocabularies/UI.md b/vocabularies/UI.md
index 9199e01f0..ff6781e68 100644
--- a/vocabularies/UI.md
+++ b/vocabularies/UI.md
@@ -73,9 +73,10 @@ Term|Type|Description
[ParameterDefaultValue](UI.xml#L1827)|PrimitiveType?|Define default values for action parameters
For unbound actions the default value can either be a constant expression, or a dynamic expression using absolute paths, e.g. singletons or function import results. Whereas for bound actions the bound entity and its properties and associated properties can be used as default values
[RecommendationState](UI.xml#L1833)|[RecommendationStateType](#RecommendationStateType)|Indicates whether a field contains or has a recommended value
Intelligent systems can help users by recommending input the user may "prefer".
[RecommendationList](UI.xml#L1863)|[RecommendationListType](#RecommendationListType)|Specifies how to get a list of recommended values for a property or parameter
Intelligent systems can help users by recommending input the user may "prefer".
-[ExcludeFromNavigationContext](UI.xml#L1895)|[Tag](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Tag)|The contents of this property must not be propagated to the app-to-app navigation context
-[DoNotCheckScaleOfMeasuredQuantity](UI.xml#L1899) *([Experimental](Common.md#Experimental))*|Boolean|Do not check the number of fractional digits of the annotated measured quantity
The annotated property contains a measured quantity, and the user may enter more fractional digits than defined for the corresponding unit of measure.
This switches off the validation of user input with respect to decimals.
-[LeadingEntitySet](UI.xml#L1909) *([Experimental](Common.md#Experimental))*|String|The referenced entity set is the preferred starting point for UIs using this service
+[Recommendations](UI.xml#L1895) *([Experimental](Common.md#Experimental))*|ComplexType|Recommendations for an entity
This complex-typed annotation contains structural properties corresponding via name equality to non-key structural primitive properties of the entity type for which recommendations are available. The type of such a property is a collection of a informal specialization of [`PropertyRecommendationType`](#PropertyRecommendationType). (The specializiations are called "informal" because they may omit the property `RecommendedFieldDescription`.)
Clients retrieve the recommendations with a GET request that includes this annotation in a `$select` clause. The recommendations MAY be computed asynchronously, see [this diagram](../docs/recommendations.md).
+[ExcludeFromNavigationContext](UI.xml#L1941)|[Tag](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Tag)|The contents of this property must not be propagated to the app-to-app navigation context
+[DoNotCheckScaleOfMeasuredQuantity](UI.xml#L1945) *([Experimental](Common.md#Experimental))*|Boolean|Do not check the number of fractional digits of the annotated measured quantity
The annotated property contains a measured quantity, and the user may enter more fractional digits than defined for the corresponding unit of measure.
This switches off the validation of user input with respect to decimals.
+[LeadingEntitySet](UI.xml#L1955) *([Experimental](Common.md#Experimental))*|String|The referenced entity set is the preferred starting point for UIs using this service
## [HeaderInfoType](UI.xml#L68)
@@ -1171,8 +1172,19 @@ Property|Type|Description
[LocalDataProperty](UI.xml#L1887)|PropertyPath|Path to editable property for which recommended values exist
[ValueListProperty](UI.xml#L1890)|String|Path to property in the collection of recommended values. Format is identical to PropertyPath annotations.
+
+## [*PropertyRecommendationType*](UI.xml#L1908) *([Experimental](Common.md#Experimental))*
+Base type containing recommendations for an entity type property
+
+Property|Type|Description
+:-------|:---|:----------
+[RecommendedFieldValue](UI.xml#L1911)|PrimitiveType|Recommended value
In informal specializations of this base type, this property is specialized to the primitive type of the entity type property. If the recommendation has a description, this property has a [`Common.Text`](Common.md#Text) annotation that evaluates to the `RecommendedFieldDescription` property.
+[RecommendedFieldDescription](UI.xml#L1920)|String?|Description of the recommended value
In informal specializations of this base type, this property is specialized to the string type of the text property corresponding to the entity type property. It is omitted from informal specializations for recommendations without description.
+[RecommendedFieldScoreValue](UI.xml#L1927)|Decimal?|Confidence score of the recommended value
+[RecommendedFieldIsSuggestion](UI.xml#L1930)|Boolean|Whether the recommended value shall be suggested in the input field
For any collection of a specialization of `PropertyRecommendationType` in a property containing [`Recommendations`](#Recommendations), this flag can be true in at most one instance of the collection, and only if the `RecommendedFieldScoreValue` exceeds a certain threshold.
+
-## [ActionName](UI.xml#L1914)
+## [ActionName](UI.xml#L1960)
**Type:** String
Name of an Action, Function, ActionImport, or FunctionImport in scope
diff --git a/vocabularies/UI.xml b/vocabularies/UI.xml
index edd4ee8a2..6e3e44879 100644
--- a/vocabularies/UI.xml
+++ b/vocabularies/UI.xml
@@ -1892,6 +1892,52 @@ This is in contrast to [DataFieldForIntentBasedNavigation](#DataFieldForIntentBa
+
+
+
+
+ This complex-typed annotation contains structural properties corresponding via name equality
+to non-key structural primitive properties of the entity type for which recommendations are available.
+The type of such a property is a collection of a informal specialization of [`PropertyRecommendationType`](#PropertyRecommendationType).
+(The specializiations are called "informal" because they may omit the property `RecommendedFieldDescription`.)
+
+Clients retrieve the recommendations with a GET request that includes this annotation in a `$select` clause.
+The recommendations MAY be computed asynchronously, see [this diagram](../docs/recommendations.md).
+
+
+
+
+
+
+
+
+ In informal specializations of this base type, this property is specialized to the primitive type of the entity type property.
+ If the recommendation has a description, this property has a [`Common.Text`](Common.md#Text) annotation
+ that evaluates to the `RecommendedFieldDescription` property.
+
+
+
+
+
+
+ In informal specializations of this base type, this property is specialized to the string type of the text property corresponding to the entity type property.
+ It is omitted from informal specializations for recommendations without description.
+
+
+
+
+
+
+
+
+ For any collection of a specialization of `PropertyRecommendationType`
+ in a property containing [`Recommendations`](#Recommendations),
+ this flag can be true in at most one instance of the collection,
+ and only if the `RecommendedFieldScoreValue` exceeds a certain threshold.
+
+
+
+