@cap-js/agents 0.0.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +155 -0
  3. package/_i18n/messages.properties +31 -0
  4. package/cds-plugin.js +140 -0
  5. package/index.cds +105 -0
  6. package/index.js +0 -0
  7. package/lib/agents/markdown/backends/mime-utils.js +37 -0
  8. package/lib/agents/markdown/backends/outputs-backend.js +152 -0
  9. package/lib/agents/markdown/backends/uploads-backend.js +143 -0
  10. package/lib/agents/markdown/deep-agent.js +93 -0
  11. package/lib/agents/middleware/agent-actions.js +18 -0
  12. package/lib/agents/middleware/content-filter.js +191 -0
  13. package/lib/agents/middleware/hitl-edit-note-injector.js +18 -0
  14. package/lib/agents/middleware/hitl.js +20 -0
  15. package/lib/agents/middleware/index.js +19 -0
  16. package/lib/agents/middleware/patch-tool-calls.js +51 -0
  17. package/lib/agents/middleware/quota-enforcer.js +94 -0
  18. package/lib/agents/middleware/status-update.js +153 -0
  19. package/lib/agents/middleware/tool-selection.js +22 -0
  20. package/lib/agents/quota-enforcer-at-start.js +198 -0
  21. package/lib/agents/summarize-on-timeout.js +91 -0
  22. package/lib/compile.js +55 -0
  23. package/lib/index.cjs +1 -0
  24. package/lib/index.js +422 -0
  25. package/lib/models/aicore.js +441 -0
  26. package/lib/models/anthropic.js +77 -0
  27. package/lib/models/mock.js +88 -0
  28. package/lib/preview/chat.html +875 -0
  29. package/lib/preview/preview.js +46 -0
  30. package/lib/protocol/agent-card.js +297 -0
  31. package/lib/protocol/persistence/checkpoint-saver.js +317 -0
  32. package/lib/protocol/persistence/file-store.js +209 -0
  33. package/lib/protocol/persistence/push-notification-store.js +59 -0
  34. package/lib/protocol/persistence/task-store.js +47 -0
  35. package/lib/protocol/push-notification-sender.js +57 -0
  36. package/lib/sidecar.js +162 -0
  37. package/lib/telemetry/active-users.js +106 -0
  38. package/lib/telemetry/chat-tracing.js +342 -0
  39. package/lib/telemetry/metrics.js +85 -0
  40. package/lib/telemetry/mlflow.js +290 -0
  41. package/lib/telemetry/tool-tracing.js +164 -0
  42. package/lib/telemetry/tracing.js +150 -0
  43. package/lib/utils/inner-auth.js +33 -0
  44. package/lib/utils/markdown.js +199 -0
  45. package/lib/utils/message-handling.js +155 -0
  46. package/lib/utils/utils.js +168 -0
  47. package/package.json +225 -2
  48. package/srv/graph-cache.js +82 -0
  49. package/srv/handlers/graph-executor.js +1369 -0
  50. package/srv/handlers/index.js +173 -0
  51. package/srv/handlers/mcp-tools.js +159 -0
  52. package/srv/handlers/sub-agent-tools.js +314 -0
  53. package/srv/handlers/system-prompt.js +25 -0
  54. package/srv/handlers/tools.js +366 -0
  55. package/srv/langgraph-executor-srv.js +70 -0
  56. package/srv/push-notification-srv.js +149 -0
package/package.json CHANGED
@@ -1,4 +1,227 @@
1
1
  {
2
2
  "name": "@cap-js/agents",
3
- "version": "0.0.0"
4
- }
3
+ "version": "0.9.1",
4
+ "description": "CDS plugin for building agents",
5
+ "author": "SAP SE (https://www.sap.com)",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://cap.cloud.sap/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/cap-js/agents.git"
11
+ },
12
+ "type": "module",
13
+ "exports": {
14
+ ".": "./index.js",
15
+ "./package.json": "./package.json",
16
+ "./cds-plugin": "./cds-plugin.js",
17
+ "./index.cds": "./index.cds",
18
+ "./lib/models/*": "./lib/models/*.js",
19
+ "./srv/langgraph-executor-srv": "./srv/langgraph-executor-srv.js",
20
+ "./srv/*": "./srv/*",
21
+ "./lib/*": "./lib/*"
22
+ },
23
+ "main": "index.js",
24
+ "scripts": {
25
+ "lint": "npx eslint .",
26
+ "test": "CDS_ENV=test npx vitest run --config vitest.config.js",
27
+ "test:hybrid": "CDS_ENV=test,hybrid,tracing cds bind --exec -- npx vitest run --config vitest.config.hybrid.js",
28
+ "test:mtx": "CDS_ENV=test npx vitest run --config vitest.config.js tests/integration/mtx.test.js",
29
+ "watch:sample": "cds w tests/projects/bookshop",
30
+ "watch:hybrid": "DEBUG=agents cds bind --exec -- cds w tests/projects/bookshop",
31
+ "watch:with-claude": "cds w tests/projects/bookshop --profile with-claude",
32
+ "watch:deep-agent": "cds w tests/projects/deep-agent --profile hybrid",
33
+ "prettier": "npx -y prettier@3 --write .",
34
+ "prettier:check": "npx -y prettier@3 --check ."
35
+ },
36
+ "files": [
37
+ "index.js",
38
+ "index.cds",
39
+ "lib",
40
+ "srv",
41
+ "cds-plugin.js",
42
+ "_i18n"
43
+ ],
44
+ "dependencies": {
45
+ "@a2a-js/sdk": "^0.3.12",
46
+ "@cap-js/attachments": "^4",
47
+ "@cap-js/mcp": "^1.4",
48
+ "@langchain/anthropic": "^1.5.1",
49
+ "@langchain/core": "^1",
50
+ "@langchain/langgraph": "^1",
51
+ "@langchain/mcp-adapters": "^1.1.3",
52
+ "@sap-ai-sdk/langchain": "^2.13.0",
53
+ "@sap-ai-sdk/orchestration": "^2.11.0",
54
+ "@sap-cloud-sdk/connectivity": "^4.7.0",
55
+ "@sap-cloud-sdk/resilience": "^4.7.0",
56
+ "deepagents": "^1.10.0",
57
+ "langchain": "^1.5.0",
58
+ "marked": "^18",
59
+ "zod": "^4.0.0"
60
+ },
61
+ "devDependencies": {
62
+ "@cap-js/cds-test": "^1",
63
+ "@cap-js/sqlite": "^3",
64
+ "@sap/cds-mtxs": "^4",
65
+ "@toon-format/toon": ">=2.3",
66
+ "deepagents": "^1.10.2"
67
+ },
68
+ "peerDependencies": {
69
+ "@cap-js/audit-logging": ">=1",
70
+ "@cap-js/telemetry": ">=1",
71
+ "@sap/cds": ">=9"
72
+ },
73
+ "peerDependenciesMeta": {
74
+ "@cap-js/telemetry": {
75
+ "optional": true
76
+ },
77
+ "@cap-js/audit-logging": {
78
+ "optional": true
79
+ }
80
+ },
81
+ "engines": {
82
+ "node": ">=22.0.0"
83
+ },
84
+ "cds": {
85
+ "agents": {
86
+ "streaming": true,
87
+ "trace_langchain": true,
88
+ "mlflow": false,
89
+ "connect": "auto",
90
+ "[development]": {
91
+ "pushNotifications": {
92
+ "allowedDomains": [
93
+ "127.0.0.1",
94
+ "localhost",
95
+ "cloud.sap"
96
+ ]
97
+ }
98
+ },
99
+ "[hybrid]": {
100
+ "pushNotifications": {
101
+ "allowedDomains": [
102
+ "127.0.0.1",
103
+ "localhost",
104
+ "cloud.sap"
105
+ ]
106
+ }
107
+ },
108
+ "pushNotifications": {
109
+ "allowedDomains": [
110
+ "cloud.sap"
111
+ ]
112
+ },
113
+ "persistAllCheckpointWrites": false,
114
+ "activeUsersInterval": "24h",
115
+ "params": {
116
+ "max_tokens": 4096,
117
+ "temperature": 0
118
+ },
119
+ "contentFilter": true,
120
+ "fileIO": {
121
+ "enabled": false,
122
+ "maxInputFileSizeBytes": 2097152,
123
+ "maxOutputFileSizeBytes": 10485760,
124
+ "defaultInputModes": [
125
+ "text/csv",
126
+ "application/json",
127
+ "text/plain",
128
+ "application/pdf",
129
+ "image/png",
130
+ "image/jpeg"
131
+ ],
132
+ "defaultOutputModes": [
133
+ "text/csv",
134
+ "application/json",
135
+ "text/plain",
136
+ "application/pdf",
137
+ "image/png",
138
+ "image/jpeg"
139
+ ]
140
+ },
141
+ "pool": {
142
+ "maxConcurrentTasks": 10,
143
+ "maxConcurrentTasksPerUser": 4,
144
+ "maxTasksPerHour": 100,
145
+ "maxTasksPerHourPerUser": 20,
146
+ "maxLLMTokensPerDay": 5000000,
147
+ "maxToolCallsPerHour": 1000,
148
+ "maxToolCallsPerTask": 50,
149
+ "maxLLMInvocationsPerTask": 50,
150
+ "maxLLMTokensPerTask": 200000,
151
+ "maxLLMCallTimeout": "120s",
152
+ "maxExecutionTimePerTask": "5min",
153
+ "timeoutGrace": "15s",
154
+ "maxIncomingMessageLength": 5000
155
+ }
156
+ },
157
+ "requires": {
158
+ "agents": {
159
+ "model": "@cap-js/agents"
160
+ },
161
+ "agent-push-notifications": {
162
+ "impl": "@cap-js/agents/srv/push-notification-srv.js"
163
+ },
164
+ "mlflow": {
165
+ "vcap": {
166
+ "label": "user-provided",
167
+ "name": "mlflow"
168
+ }
169
+ },
170
+ "kinds": {
171
+ "aicore": {
172
+ "impl": "@cap-js/agents/lib/models/aicore",
173
+ "model": "anthropic--claude-4.6-sonnet",
174
+ "contentFilter": true
175
+ },
176
+ "anthropic": {
177
+ "impl": "@cap-js/agents/lib/models/anthropic"
178
+ },
179
+ "llm-mock": {
180
+ "impl": "@cap-js/agents/lib/models/mock"
181
+ }
182
+ },
183
+ "[development]": {
184
+ "llm": "mock"
185
+ },
186
+ "[with-claude]": {
187
+ "llm": "anthropic"
188
+ },
189
+ "[hybrid]": {
190
+ "llm": "aicore"
191
+ },
192
+ "[production]": {
193
+ "llm": "aicore"
194
+ }
195
+ },
196
+ "protocols": {
197
+ "agent": {
198
+ "path": "/a2a",
199
+ "impl": "@cap-js/agents/lib/index.cjs"
200
+ }
201
+ },
202
+ "[agent-sidecar]": {
203
+ "server": {
204
+ "port": 4006
205
+ },
206
+ "[java]": {
207
+ "agent": {
208
+ "_javaHcqlCompat": true
209
+ }
210
+ }
211
+ }
212
+ },
213
+ "workspaces": [
214
+ "tests/projects/bookshop/",
215
+ "tests/projects/deep-agent/",
216
+ "tests/projects/mtx/mtx/sidecar/",
217
+ "tests/projects/telemetry-debug/",
218
+ "tests/projects/telemetry-v1/",
219
+ "tests/projects/travel/travel-agent/",
220
+ "tests/projects/travel/xflights/",
221
+ "tests/projects/travel/leisure-services/",
222
+ "tests/sidecar-projects/java-bookshop/agent/sidecar",
223
+ "tests/sidecar-projects/java-bookshop",
224
+ "tests/sidecar-projects/node-bookshop/agent/sidecar",
225
+ "tests/sidecar-projects/node-bookshop"
226
+ ]
227
+ }
@@ -0,0 +1,82 @@
1
+ import cds from "@sap/cds"
2
+ import crypto from "crypto"
3
+
4
+ const LOG = cds.log("agents")
5
+
6
+ /**
7
+ * Compute a stable hash key from cds.context.features.
8
+ * Returns empty string for empty/undefined features (default graph).
9
+ */
10
+ export function hashFeatures(features) {
11
+ if (!features || typeof features !== "object") return ""
12
+ const keys = Object.keys(features).sort()
13
+ if (keys.length === 0) return ""
14
+ const normalized = JSON.stringify(keys.map((k) => [k, features[k]]))
15
+ return crypto.createHash("sha256").update(normalized).digest("hex").slice(0, 16)
16
+ }
17
+
18
+ /**
19
+ * FIFO cache for compiled LangGraph executors keyed by feature vector hash.
20
+ * Eviction: oldest entry removed when full.
21
+ * Dedup: promise map prevents parallel builds for same key.
22
+ */
23
+ export class GraphCache {
24
+ constructor() {
25
+ this._maxSize = cds.env.agents?.graphCacheSize || 20
26
+ this._cache = new Map()
27
+ this._building = new Map()
28
+ }
29
+
30
+ get size() {
31
+ return this._cache.size
32
+ }
33
+
34
+ has(key) {
35
+ return this._cache.has(key)
36
+ }
37
+
38
+ get(key) {
39
+ return this._cache.get(key)
40
+ }
41
+
42
+ set(key, executor) {
43
+ if (this._cache.size >= this._maxSize && !this._cache.has(key)) {
44
+ const oldest = this._cache.keys().next().value
45
+ this._cache.delete(oldest)
46
+ LOG.debug("Cache evicted", { key: oldest })
47
+ }
48
+ this._cache.set(key, executor)
49
+ }
50
+
51
+ async getOrBuild(key, factory) {
52
+ if (this._cache.has(key)) return this._cache.get(key)
53
+ if (this._building.has(key)) return this._building.get(key)
54
+
55
+ // Store promise BEFORE invoking factory to prevent TOCTOU race on same tick
56
+ let resolve, reject
57
+ const promise = new Promise((res, rej) => {
58
+ resolve = res
59
+ reject = rej
60
+ })
61
+ this._building.set(key, promise)
62
+
63
+ factory()
64
+ .then((executor) => {
65
+ this.set(key, executor)
66
+ resolve(executor)
67
+ })
68
+ .catch((err) => {
69
+ reject(err)
70
+ })
71
+ .finally(() => {
72
+ this._building.delete(key)
73
+ })
74
+
75
+ return promise
76
+ }
77
+
78
+ clear() {
79
+ this._cache.clear()
80
+ this._building.clear()
81
+ }
82
+ }