Skip to content

Commit a852514

Browse files
authored
Release October 26 (#2961)
2 parents 9bdcaab + cd70447 commit a852514

30 files changed

Lines changed: 1070 additions & 490 deletions

‎.hyperspace/pull_request_bot_review_focus.md‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
---
2-
description: 'Does a detailed edit on the current file(s).'
3-
tools: ['read', 'agent', 'edit', 'todo', 'search']
4-
---
1+
# capire documentation review focus
52

63
### ROLE
74
You are a helpful editor for a technical writer. Your task is to review and improve the text while ensuring that it adheres to a structured set of writing rules. All categories are of equal priority—no rule should be prioritized over another.
@@ -72,7 +69,7 @@ Focus on content-level accessibility based on WCAG guidelines. Prioritize Level
7269
- Make sure that sentences are complete and that images, code blocks, and so on are not in between overflowing sentences.
7370

7471
7. Consistency
75-
Use the `search` tool to check consistency across the repo. Report findings but do not auto-fix — flag locations for the author to review.
72+
Check consistency across the repo. Report findings but do not auto-fix — flag locations for the author to review. Identify questionable changes, and search the repository or cap.cloud.sap for related terms and references.
7673

7774
- **Terminology**: Identify terms, product names, or UI labels introduced or changed in the diff. Search the repo for prior uses of the old term and flag files where the wording may be inconsistent or outdated.
7875
- **Renamed identifiers**: When a variable, class, method, config key, or file is renamed in the diff, search the repo for references to the old name and list any files that likely need updating.

‎.vitepress/config.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ const siteURL = new URL(process.env.SITE_HOSTNAME || 'http://localhost:4173/docs
141141
if (!siteURL.pathname.endsWith('/')) siteURL.pathname += '/'
142142
config.themeConfig.capire = {
143143
versions: {
144-
java_services: '5.1.1',
145-
java_cds4j: '5.1.1',
144+
java_services: '5.2.0',
145+
java_cds4j: '5.2.0',
146146
cloud_sec_ams: '3.8.1'
147147
},
148148
gotoLinks: [],

‎.vitepress/lib/code-groups/restoreCodeGroupPreferences.js‎

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,19 @@
8989
}
9090

9191
const restoreHashScroll = () => {
92-
if (hashScrollPending) {
93-
history.replaceState(null, '', window.location.pathname + window.location.search + initialHash)
94-
requestAnimationFrame(() => {
95-
scrollToHash(initialHash)
96-
hashScrollPending = false
97-
})
98-
}
92+
if (!hashScrollPending) return
93+
94+
// Put the hash back into the URL as soon as we start handling it, so it
95+
// survives even if the target element hasn't been rendered yet.
96+
history.replaceState(null, '', window.location.pathname + window.location.search + initialHash)
97+
98+
// Don't finish until the target actually exists; the page content may still
99+
// be hydrating. Until then, keep hashScrollPending so later retries can scroll.
100+
const target = document.getElementById(decodeURIComponent(initialHash).slice(1))
101+
if (!target) return
102+
103+
hashScrollPending = false
104+
requestAnimationFrame(() => scrollToHash(initialHash))
99105
}
100106

101107
const initialCodeGroupCount = applyToAllCodeGroups()
@@ -137,13 +143,34 @@
137143
}
138144
}
139145

146+
// Guarantee the hash is restored and scrolled to, even on pages that have no
147+
// code groups (where the MutationObserver above never fires) and regardless of
148+
// readyState when this inline head script runs. Retries each frame until the
149+
// target has hydrated, then stops.
150+
const pollRestore = () => {
151+
const deadline = Date.now() + 3000
152+
const tick = () => {
153+
applyToAllCodeGroups()
154+
restoreHashScroll()
155+
if (hashScrollPending && Date.now() < deadline) {
156+
requestAnimationFrame(tick)
157+
} else {
158+
stopObserving()
159+
}
160+
}
161+
requestAnimationFrame(tick)
162+
}
163+
140164
if (document.readyState === 'loading') {
141165
document.addEventListener('DOMContentLoaded', () => {
142166
applyToAllCodeGroups()
143167
restoreHashScroll()
144-
stopObserving()
168+
if (hashScrollPending) pollRestore()
169+
else stopObserving()
145170
})
146-
} else if (!hashScrollPending) {
171+
} else if (hashScrollPending) {
172+
pollRestore()
173+
} else {
147174
stopObserving()
148175
}
149176
})()

‎cds/cdl.md‎

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,9 @@ service AdminService {
20402040
### Auto-Exposed Entities
20412041
{#auto-expose}
20422042

2043-
Annotate entities with `@cds.autoexpose` to automatically expose them in services containing entities with associations referring to them.
2043+
Annotate entities with `@cds.autoexpose` to auto-expose them in services that contain entities with associations referring to them. Composition targets are auto-exposed without an annotation.
2044+
2045+
#### Using @cds.autoexpose
20442046

20452047
For example, given the following entity definitions:
20462048

@@ -2066,16 +2068,16 @@ service Zoo {
20662068
}
20672069
```
20682070

2069-
... would result in the service being automatically extended like this:
2071+
... results in the service being automatically extended like this:
20702072

20712073
```cds
20722074
extend service Zoo with { // auto-exposed entities:
2073-
@readonly entity Foo_bar as projection on Bar;
2074-
@readonly entity Foo_car as projection on Car;
2075+
entity Bar as projection on my.Bar;
2076+
entity Car as projection on my.Car;
20752077
}
20762078
```
20772079

2078-
You can still expose such entities explicitly, for example, to make them read-write:
2080+
You can still expose such entities directly, for example, to make them read-write:
20792081

20802082
```cds
20812083
service MyOrders {
@@ -2084,9 +2086,58 @@ service MyOrders {
20842086
}
20852087
```
20862088

2089+
#### Using Compositions
2090+
2091+
Besides entities annotated with `@cds.autoexpose`, composition targets are auto-exposed.
2092+
2093+
Example:
2094+
```cds
2095+
// schema.cds
2096+
namespace travels;
2097+
entity Travels {
2098+
key id : Integer;
2099+
bookings : Composition of many Bookings on Bookings.Travel = $self;
2100+
}
2101+
entity Bookings {
2102+
key Travel : Association to Travels;
2103+
key Pos : Integer;
2104+
}
2105+
```
2106+
2107+
When `Travels` is exposed in a service ...
2108+
2109+
```cds
2110+
using { travels } from './schema.cds';
2111+
service TravelService {
2112+
entity Travels as projection on travels.Travels
2113+
}
2114+
```
2115+
2116+
... the composition target `Bookings` is auto-exposed as follows:
2117+
2118+
```cds
2119+
extend service TravelService with { // auto-exposed entity:
2120+
entity Bookings as projection on travels.Bookings;
2121+
}
2122+
```
2123+
20872124
[Learn more about **CodeLists in `@sap/cds/common`**.](./common#code-lists){.learn-more}
20882125

20892126

2127+
#### Switch Off Auto-Exposure
2128+
2129+
To switch off auto-exposure of entities annotated with `@cds.autoexpose` in a service, annotate the service with `@cds.autoexpose: false`:
2130+
```cds
2131+
@cds.autoexpose: false
2132+
service Zoo {
2133+
// ...
2134+
// Bar and Car are not auto-exposed in this service
2135+
}
2136+
```
2137+
2138+
>[!important] Not valid for compositions
2139+
> The `@cds.autoexpose: false` annotation does not affect auto-exposure of composition targets.
2140+
20902141

20912142
### Custom Actions and Functions {#actions}
20922143

‎get-started/bookshop.md‎

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ annotate AdminService.Books with {
733733
734734
### Custom Handlers in Node.js
735735
736-
Prepare your project for custom coding in Node.js by adding the respective facet:
736+
Custom handlers are required for implementing business logic that cannot be expressed declarativatively, for example, through constraints. Prepare your project for custom coding in Node.js by adding the respective facet:
737+
737738
```shell
738739
cds add nodejs
739740
npm install
@@ -743,33 +744,22 @@ Put implementations for services into equally named _.js_ files placed next to a
743744
744745
```zsh
745746
├─ srv/
746-
│ ├─ cat-service.cds # [!code focus]
747-
│ └─ cat-service.js # [!code focus]
747+
│ ├─ admin-service.cds # [!code focus]
748+
│ └─ admin-service.js # [!code focus]
748749
└─ ...
749750
```
750751
751752
::: code-group
752-
```js [srv/cat-service.js]
753-
const cds = require('@sap/cds')
754-
class CatalogService extends cds.ApplicationService { init() {
755-
756-
// After READ handler on Books to add discount info
757-
this.after ('READ', 'Books', results => results.forEach (book => {
758-
if (book.stock > 111) book.title += ` -- 11% discount!`
759-
}))
760-
761-
return super.init()
762-
}}
763-
module.exports = { CatalogService }
764-
```
765-
```js [srv/cat-service.mjs]
753+
```js [srv/admin-service.js]
766754
import cds from '@sap/cds'
767-
export class CatalogService extends cds.ApplicationService { init() {
755+
export class AdminService extends cds.ApplicationService { init() {
768756
769-
// After READ handler on Books to add discount info
770-
this.after ('READ', 'Books', results => results.forEach (book => {
771-
if (book.stock > 111) book.title += ` -- 11% discount!`
772-
}))
757+
/** Auto-fill integer primary keys, if necessary */
758+
this.before ('CREATE', 'Books', async req => {
759+
if (req.data.ID) return // skip if ID is already set
760+
let {id} = await SELECT.one`max(ID) as id`.from(req.target)
761+
req.data.ID = id + 4 // not safe, but ok for demo purposes
762+
})
773763
774764
return super.init()
775765
}}
@@ -852,11 +842,18 @@ While you **_can_** add custom handlers for standard CRUD events, you **_have to
852842
```js [srv/cat-service.js]
853843
// Action handler for submitOrder
854844
this.on ('submitOrder', async req => {
855-
let { book:id, quantity } = req.data
856-
let affected = await UPDATE (Books,id)
845+
846+
// Try to reduce the stock of the ordered book, the good case
847+
let { book:id, quantity=1 } = req.data
848+
let { affected } = await UPDATE.entity (Books,id)
857849
.with `stock = stock - ${quantity}`
858850
.where `stock >= ${quantity}`
859-
if (!affected) req.error `${quantity} exceeds stock for book #${id}`
851+
if (affected) return //> done, the update was successful
852+
853+
// The update failed, let's check why, and respond accordingly...
854+
let exists = await SELECT.one`stock`.from(Books,id)
855+
if (!exists) req.error (404, `Book #${id} doesn't exist`)
856+
else req.error (409, `${quantity} exceeds stock for book #${id}`, { id, quantity, ...exists })
860857
})
861858
```
862859
:::

‎guides/ai/cap-agents.md‎

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ annotate CatalogService.submitOrder with @agent.hitl; // [!code focus]
7070
When the agent decides to call the action, the task pauses and transitions to the A2A [`input-required`](https://a2a-protocol.org/latest/specification/#413-taskstate) state instead of running the action immediately.
7171

7272
> [!warning] Only supported by CAP Node.js
73-
> `@agent.hitl` is not yet supported by CAP Java
73+
> `@agent.hitl` is not yet supported by CAP Java.
7474
7575

7676

@@ -248,7 +248,7 @@ DEBUG=agents cds watch
248248
> The plugin can automatically fetch required/missing credentials from local installations of supported LLMs, allowing you to work with zero additional configuration.
249249
250250
> [!warning] CAP Node.js only
251-
> Auto configuration from local Claude and OpenCode installations is not supported by CAP Java
251+
> Auto configuration from local Claude and OpenCode installations is not supported by CAP Java.
252252
253253
### Using Chat Preview <Alpha/>
254254

@@ -269,7 +269,7 @@ Also answer the questions that the agent asks you back.
269269
![Chat conversation in Chat Preview](chat-preview-bookshop.png)
270270

271271
> [!tip] Embedded with the CAP application
272-
> Essentially we see that the CAP-level agent accomplishes the same functionality than the generic agent that comes with _OpenCode_. The main difference is that it is tightly integrated with the CAP application, allowing for more seamless interaction with the underlying services and data models. Also the end user doesn't need any local AI client like _OpenCode_, nor do they need access to an LLM directly.
272+
> Essentially we see that the CAP-level agent accomplishes the same functionality as the generic agent that comes with _OpenCode_. The main difference is that it is tightly integrated with the CAP application, allowing for more seamless interaction with the underlying services and data models. Also the end user doesn't need any local AI client like _OpenCode_, nor do they need access to an LLM directly.
273273
274274

275275
## Served out of the box
@@ -352,9 +352,9 @@ For details on configuring and using audit logging, refer to the documentation a
352352

353353
### Persistence
354354

355-
The CAP-based harness provides short-term memory for agents by storing conversational and checkpoints in the connected primary database.
355+
The CAP-based agent harness provides short-term memory out-of-the-box via the connected primary database – that is in _SQLite_ in local dev, _SAP HANA_ in production.
356356

357-
Agents can leverage this short-term memory to maintain context across multiple interactions within a session.
357+
This allows agents to persist conversational context and workflow checkpoints, so that they can resume sessions seamlessly even after server restarts, as well as boosting scalability in clustered environments. In addition, it provides a foundation for implementing long-term memory, monitoring and analytics on agent interactions.
358358

359359

360360

@@ -406,9 +406,7 @@ The plugin can also export traces to [MLflow](https://mlflow.org/docs/latest/llm
406406
```
407407
:::
408408

409-
When enabled, an _MLflow_ exporter is added as a **second span processor** alongside any existing exporter (Dynatrace, Cloud Logging, Grafana, etc.),
410-
and the plugin automatically adds the following `mlflow.*` span attributes to existing OTel spans so the MLflow OTLP ingestion endpoint assembles them
411-
into proper MLflow traces — no additional SDK required.
409+
When enabled, an _MLflow_ exporter is added as a **second span processor** alongside any existing exporter (Dynatrace, Cloud Logging, Grafana, etc.), and the plugin automatically adds the following `mlflow.*` span attributes to existing OTel spans so the MLflow OTLP ingestion endpoint assembles them into proper MLflow traces — no additional SDK required.
412410

413411
| Attribute | Source |
414412
|--------------------------|-------------------------------------------------------------------------------------------------------|
@@ -552,17 +550,17 @@ cds:
552550
```
553551
:::
554552

555-
| Kind | Description |
556-
|----------|-----------------------------------------------------------------------------|
557-
| `aicore` | The default for `production` and `hybrid`, connects to SAP AI Core |
558-
| `auto` | The default for `development`, using local Claude or OpenCode configuration |
559-
| `mock` | A pure mock for `development`, provides dummy responses when called |
553+
| Kind | Description |
554+
|----------|------------------------------------------------------------------------------------|
555+
| `aicore` | The default for `production` and `hybrid`, connects to SAP AI Core |
556+
| `auto` | The default for `development`, using local Claude, Codex or OpenCode configuration |
557+
| `mock` | A pure mock for `development`, provides dummy responses when called |
560558

561-
See [SAP AI Core → Create a Service Instance](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-instance) for how to create an instance.vite
559+
See [SAP AI Core → Create a Service Instance](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-instance) for how to create an instance.
562560

563561

564562
> [!tip] Automatically Fetching Credentials
565-
> In development profile, with the pre-configured `auto` kind, the plugin tries to fetch missing credentials from local installation of [Claude Code](https://claude.ai) or [OpenCode](https://opencode.ai).
563+
> In development profile, with the pre-configured `auto` kind, the plugin tries to fetch missing credentials from local installation of [Claude Code](https://claude.ai), [Codex](https://openai.com/codex/) or [OpenCode](https://opencode.ai).
566564
> This allows you to work with local LLM instances without providing any additional config at all.
567565
568566

@@ -581,5 +579,5 @@ See section [_Quotas_](#quotas) above for details.
581579
## SAP API Policy
582580

583581
> [!caution]
584-
> CAP-level agents as documented herein must not be used as gateways or proxies for SAP Application APIs. The _cap/agents_ plugins are not an SAP-endorsed architecture, data service, or service-specific pathway under section 2.2.2 of the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy) and is not an endorsed mechanism for exposing, proxying, or providing agentic access to SAP Application APIs.
585-
> Any use of SAP Application APIs must be in accordance with the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy). For SAP-endorsed patterns on agentic access to SAP Application APIs, consult the [_SAP Architecture Center_](https://architecture.learning.sap.com/docs/ref-arch/98efa0) reference architectures.
582+
> CAP-level agents as documented herein must not be used as gateways or proxies for SAP Application APIs. The `@cap-js/agents` plugin is not an SAP-endorsed architecture, data service, or service-specific pathway under section 2.2.2 of the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy) and is not an endorsed mechanism for exposing, proxying, or providing agentic access to SAP Application APIs.
583+
> Any use of SAP Application APIs must be in accordance with the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy). For SAP-endorsed patterns on agentic access to SAP Application APIs, consult the [_SAP Architecture Center_](https://architecture.learning.sap.com/docs/ref-arch/98efa0) reference architectures.

‎guides/ai/cap-mcp.md‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ Instead of annotating an existing service with `@mcp` and exposing all its entit
125125

126126
::: code-group
127127
```cds [srv/mcp-service.cds]
128-
using { CatalogService } from './cat-service';
128+
using { AdminService } from './admin-service';
129129
130-
@agent service BookshopService {
130+
@mcp service BooksService {
131131
132132
@readonly entity Authors as projection on AdminService.Authors excluding {
133133
createdBy, modifiedBy,
@@ -139,9 +139,6 @@ using { CatalogService } from './cat-service';
139139
genre.name as genre,
140140
currency.name as currency,
141141
}
142-
143-
@agent.hitl
144-
action submitOrder ( book: Books:ID, quantity: Integer );
145142
}
146143
```
147144
:::
@@ -524,4 +521,4 @@ Future versions of the adapter may add support for data changes using CREATE, UP
524521

525522
> [!caution]
526523
> The CAP MCP adapter must not be used as a gateway or proxy for SAP Application APIs. The adapter is not an SAP-endorsed architecture, data service, or service-specific pathway under section 2.2.2 of the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy) and is not an endorsed mechanism for exposing, proxying, or providing agentic access to SAP Application APIs.
527-
> Any use of SAP Application APIs must be in accordance with the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy). For SAP-endorsed patterns on agentic access to SAP Application APIs, consult the [_SAP Architecture Center_](https://architecture.learning.sap.com/docs/ref-arch/98efa0) reference architectures.
524+
> Any use of SAP Application APIs must be in accordance with the [_SAP API Policy_](https://help.sap.com/docs/business-accelerator-hub/sap-business-accelerator-hub/sap-api-policy). For SAP-endorsed patterns on agentic access to SAP Application APIs, consult the [_SAP Architecture Center_](https://architecture.learning.sap.com/docs/ref-arch/98efa0) reference architectures.

‎guides/deploy/microservices.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ build-parameters:
354354
Add [security configuration](../security/authentication) using the command:
355355
356356
```shell
357-
cds add xsuaa --for production
357+
cds add xsuaa
358358
```
359359

360360
Add the admin role

‎guides/deploy/to-kyma.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ cds build --production
194194

195195
# Buildpack commands
196196
pack build bookshop-srv:latest --path gen/srv --builder builder-jammy-base --env BP_NODE_RUN_SCRIPTS=""
197-
pack build bookshop-html5-deployer:latest --path app/html5-deployer --builder builder-jammy-base --env BP_NODE_RUN_SCRIPTS=""
197+
pack build bookshop-html5-deployer:latest --path .deploy/html5-deployer --builder builder-jammy-base --env BP_NODE_RUN_SCRIPTS=""
198198

199199
# Final assembly and deployment, e.g.
200200
helm upgrade --install bookshop ./gen/chart --namespace bookshop --wait --wait-for-jobs --timeout=10m

0 commit comments

Comments
 (0)