nexus-ai-pro 2.2.0 → 2.4.0

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 (298) hide show
  1. package/API_STABILITY.md +225 -0
  2. package/CHANGELOG.md +325 -1
  3. package/README.md +20 -6
  4. package/SECURITY.md +140 -0
  5. package/dist/adapter-kit/contracts.d.ts +87 -0
  6. package/dist/adapter-kit/contracts.js +237 -0
  7. package/dist/adapter-kit/errors.d.ts +39 -0
  8. package/dist/adapter-kit/errors.js +52 -0
  9. package/dist/adapter-kit/index.d.ts +144 -0
  10. package/dist/adapter-kit/index.js +178 -0
  11. package/dist/adapter-kit/semver.d.ts +12 -0
  12. package/dist/adapter-kit/semver.js +55 -0
  13. package/dist/agent/capabilities.d.ts +39 -0
  14. package/dist/agent/capabilities.js +36 -0
  15. package/dist/agent/create-agent.d.ts +61 -11
  16. package/dist/agent/create-agent.js +136 -22
  17. package/dist/agent/index.d.ts +3 -2
  18. package/dist/agent/index.js +1 -1
  19. package/dist/agent/middleware/approval.d.ts +26 -0
  20. package/dist/agent/middleware/approval.js +23 -0
  21. package/dist/agent/{middleware.d.ts → middleware/basic.d.ts} +5 -4
  22. package/dist/agent/{middleware.js → middleware/basic.js} +3 -5
  23. package/dist/agent/middleware/context-editor.d.ts +52 -0
  24. package/dist/agent/middleware/context-editor.js +66 -0
  25. package/dist/agent/middleware/filesystem.d.ts +44 -0
  26. package/dist/agent/middleware/filesystem.js +83 -0
  27. package/dist/agent/middleware/index.d.ts +19 -0
  28. package/dist/agent/middleware/index.js +9 -0
  29. package/dist/agent/middleware/limits.d.ts +42 -0
  30. package/dist/agent/middleware/limits.js +52 -0
  31. package/dist/agent/middleware/models.d.ts +48 -0
  32. package/dist/agent/middleware/models.js +44 -0
  33. package/dist/agent/middleware/pii.d.ts +67 -0
  34. package/dist/agent/middleware/pii.js +142 -0
  35. package/dist/agent/middleware/retry.d.ts +66 -0
  36. package/dist/agent/middleware/retry.js +59 -0
  37. package/dist/agent/middleware/shared.d.ts +41 -0
  38. package/dist/agent/middleware/shared.js +73 -0
  39. package/dist/agent/middleware/tool-selector.d.ts +64 -0
  40. package/dist/agent/middleware/tool-selector.js +106 -0
  41. package/dist/agent/permissions.d.ts +113 -0
  42. package/dist/agent/permissions.js +180 -0
  43. package/dist/agent/sandbox.d.ts +151 -0
  44. package/dist/agent/sandbox.js +257 -0
  45. package/dist/agent/tool.d.ts +8 -3
  46. package/dist/agent/tool.js +14 -3
  47. package/dist/core/secure-stream.js +4 -3
  48. package/dist/deep-agent/index.d.ts +109 -0
  49. package/dist/deep-agent/index.js +216 -0
  50. package/dist/embeddings/adapters.js +2 -1
  51. package/dist/evals/judge.js +2 -5
  52. package/dist/evaluate/cache.d.ts +0 -14
  53. package/dist/evaluate/cache.js +0 -30
  54. package/dist/evaluate/file-cache.d.ts +15 -0
  55. package/dist/evaluate/file-cache.js +30 -0
  56. package/dist/evaluate/index.d.ts +2 -1
  57. package/dist/evaluate/index.js +2 -1
  58. package/dist/evaluate/review.js +2 -2
  59. package/dist/evaluate/run.js +2 -2
  60. package/dist/evaluate/version.js +3 -3
  61. package/dist/graph/functional.d.ts +9 -0
  62. package/dist/graph/functional.js +20 -3
  63. package/dist/graph/graph.js +27 -6
  64. package/dist/graph/lint.d.ts +4 -1
  65. package/dist/graph/lint.js +35 -0
  66. package/dist/graph/node-cache.js +3 -3
  67. package/dist/hallucination/rag.d.ts +4 -1
  68. package/dist/hallucination/rag.js +6 -1
  69. package/dist/images/asset-stores.js +2 -3
  70. package/dist/images/asset-support.js +2 -2
  71. package/dist/images/assets.js +1 -2
  72. package/dist/images/evals.js +4 -4
  73. package/dist/insights/proposals.js +1 -2
  74. package/dist/insights/regressions.d.ts +26 -2
  75. package/dist/insights/regressions.js +129 -3
  76. package/dist/loaders/git.js +8 -1
  77. package/dist/loaders/web.js +7 -1
  78. package/dist/mcp/client.d.ts +14 -0
  79. package/dist/mcp/client.js +59 -1
  80. package/dist/mcp/registry.d.ts +6 -0
  81. package/dist/mcp/registry.js +7 -0
  82. package/dist/postgres/fulltext.d.ts +67 -0
  83. package/dist/postgres/fulltext.js +91 -0
  84. package/dist/prompts/file.js +28 -11
  85. package/dist/protocols/a2a.d.ts +235 -0
  86. package/dist/protocols/a2a.js +386 -0
  87. package/dist/protocols/acp.d.ts +87 -0
  88. package/dist/protocols/acp.js +322 -0
  89. package/dist/protocols/ag-ui.d.ts +120 -0
  90. package/dist/protocols/ag-ui.js +180 -0
  91. package/dist/protocols/shared.d.ts +80 -0
  92. package/dist/protocols/shared.js +49 -0
  93. package/dist/providers/anthropic.js +1 -0
  94. package/dist/providers/cohere.js +2 -2
  95. package/dist/providers/google.js +2 -11
  96. package/dist/providers/openai.js +1 -0
  97. package/dist/rag/elasticsearch.d.ts +71 -0
  98. package/dist/rag/elasticsearch.js +130 -0
  99. package/dist/rag/file-ingestion.js +15 -9
  100. package/dist/rag/pipeline.d.ts +140 -0
  101. package/dist/rag/pipeline.js +187 -0
  102. package/dist/rag/rerankers.d.ts +92 -0
  103. package/dist/rag/rerankers.js +97 -0
  104. package/dist/rag/retrievers.d.ts +12 -1
  105. package/dist/runtime/detect.d.ts +17 -0
  106. package/dist/runtime/detect.js +16 -0
  107. package/dist/runtime/index.d.ts +19 -0
  108. package/dist/runtime/index.js +7 -0
  109. package/dist/security/injection-detector.d.ts +2 -0
  110. package/dist/security/injection-detector.js +7 -1
  111. package/dist/security/input-guard.js +5 -2
  112. package/dist/security/output-guard.js +8 -4
  113. package/dist/security/pii-detector.js +22 -6
  114. package/dist/security/prompt-hardening.js +6 -2
  115. package/dist/security/semantic-injection-classifier.d.ts +2 -1
  116. package/dist/security/semantic-injection-classifier.js +31 -35
  117. package/dist/security/upload-scanner.d.ts +8 -0
  118. package/dist/security/upload-scanner.js +51 -9
  119. package/dist/server/assistant.d.ts +5 -1
  120. package/dist/server/assistant.js +4 -2
  121. package/dist/server/auth.d.ts +250 -0
  122. package/dist/server/auth.js +392 -0
  123. package/dist/server/deployments.d.ts +63 -1
  124. package/dist/server/deployments.js +75 -2
  125. package/dist/server/runs.d.ts +9 -0
  126. package/dist/server/runs.js +20 -0
  127. package/dist/server/server.js +5 -0
  128. package/dist/store/memory.d.ts +10 -0
  129. package/dist/store/memory.js +10 -0
  130. package/dist/testing/record.js +2 -2
  131. package/dist/tracing/stores.js +2 -1
  132. package/dist/tracing/tracer.js +2 -2
  133. package/dist/types/config.d.ts +20 -0
  134. package/dist/types/graph.d.ts +38 -0
  135. package/dist/types/messages.d.ts +36 -2
  136. package/dist/types/principal.d.ts +21 -0
  137. package/dist/types/principal.js +1 -0
  138. package/dist/types/server.d.ts +8 -9
  139. package/dist/utils/base64.d.ts +4 -0
  140. package/dist/utils/base64.js +21 -0
  141. package/dist/utils/checksums.d.ts +22 -0
  142. package/dist/utils/checksums.js +39 -0
  143. package/dist/utils/ids.d.ts +8 -0
  144. package/dist/utils/ids.js +26 -2
  145. package/dist/utils/sha256.d.ts +22 -0
  146. package/dist/utils/sha256.js +120 -0
  147. package/dist/utils/tenant.d.ts +11 -0
  148. package/dist/utils/tenant.js +14 -0
  149. package/dist/version.d.ts +1 -1
  150. package/dist/version.js +1 -1
  151. package/dist-cjs/adapter-kit/contracts.d.ts +87 -0
  152. package/dist-cjs/adapter-kit/contracts.js +243 -0
  153. package/dist-cjs/adapter-kit/errors.d.ts +39 -0
  154. package/dist-cjs/adapter-kit/errors.js +57 -0
  155. package/dist-cjs/adapter-kit/index.d.ts +144 -0
  156. package/dist-cjs/adapter-kit/index.js +194 -0
  157. package/dist-cjs/adapter-kit/semver.d.ts +12 -0
  158. package/dist-cjs/adapter-kit/semver.js +59 -0
  159. package/dist-cjs/agent/capabilities.d.ts +39 -0
  160. package/dist-cjs/agent/capabilities.js +41 -0
  161. package/dist-cjs/agent/create-agent.d.ts +61 -11
  162. package/dist-cjs/agent/create-agent.js +136 -22
  163. package/dist-cjs/agent/index.d.ts +3 -2
  164. package/dist-cjs/agent/index.js +4 -4
  165. package/dist-cjs/agent/middleware/approval.d.ts +26 -0
  166. package/dist-cjs/agent/middleware/approval.js +26 -0
  167. package/dist-cjs/agent/{middleware.d.ts → middleware/basic.d.ts} +5 -4
  168. package/dist-cjs/agent/{middleware.js → middleware/basic.js} +3 -5
  169. package/dist-cjs/agent/middleware/context-editor.d.ts +52 -0
  170. package/dist-cjs/agent/middleware/context-editor.js +70 -0
  171. package/dist-cjs/agent/middleware/filesystem.d.ts +44 -0
  172. package/dist-cjs/agent/middleware/filesystem.js +86 -0
  173. package/dist-cjs/agent/middleware/index.d.ts +19 -0
  174. package/dist-cjs/agent/middleware/index.js +28 -0
  175. package/dist-cjs/agent/middleware/limits.d.ts +42 -0
  176. package/dist-cjs/agent/middleware/limits.js +57 -0
  177. package/dist-cjs/agent/middleware/models.d.ts +48 -0
  178. package/dist-cjs/agent/middleware/models.js +48 -0
  179. package/dist-cjs/agent/middleware/pii.d.ts +67 -0
  180. package/dist-cjs/agent/middleware/pii.js +147 -0
  181. package/dist-cjs/agent/middleware/retry.d.ts +66 -0
  182. package/dist-cjs/agent/middleware/retry.js +63 -0
  183. package/dist-cjs/agent/middleware/shared.d.ts +41 -0
  184. package/dist-cjs/agent/middleware/shared.js +83 -0
  185. package/dist-cjs/agent/middleware/tool-selector.d.ts +64 -0
  186. package/dist-cjs/agent/middleware/tool-selector.js +109 -0
  187. package/dist-cjs/agent/permissions.d.ts +113 -0
  188. package/dist-cjs/agent/permissions.js +189 -0
  189. package/dist-cjs/agent/sandbox.d.ts +151 -0
  190. package/dist-cjs/agent/sandbox.js +297 -0
  191. package/dist-cjs/agent/tool.d.ts +8 -3
  192. package/dist-cjs/agent/tool.js +14 -3
  193. package/dist-cjs/core/secure-stream.js +4 -3
  194. package/dist-cjs/deep-agent/index.d.ts +109 -0
  195. package/dist-cjs/deep-agent/index.js +219 -0
  196. package/dist-cjs/embeddings/adapters.js +2 -1
  197. package/dist-cjs/evals/judge.js +2 -5
  198. package/dist-cjs/evaluate/cache.d.ts +0 -14
  199. package/dist-cjs/evaluate/cache.js +1 -65
  200. package/dist-cjs/evaluate/file-cache.d.ts +15 -0
  201. package/dist-cjs/evaluate/file-cache.js +67 -0
  202. package/dist-cjs/evaluate/index.d.ts +2 -1
  203. package/dist-cjs/evaluate/index.js +3 -2
  204. package/dist-cjs/evaluate/review.js +2 -2
  205. package/dist-cjs/evaluate/run.js +2 -2
  206. package/dist-cjs/evaluate/version.js +3 -3
  207. package/dist-cjs/graph/functional.d.ts +9 -0
  208. package/dist-cjs/graph/functional.js +20 -3
  209. package/dist-cjs/graph/graph.js +27 -6
  210. package/dist-cjs/graph/lint.d.ts +4 -1
  211. package/dist-cjs/graph/lint.js +35 -0
  212. package/dist-cjs/graph/node-cache.js +3 -3
  213. package/dist-cjs/hallucination/rag.d.ts +4 -1
  214. package/dist-cjs/hallucination/rag.js +6 -1
  215. package/dist-cjs/images/asset-stores.js +2 -3
  216. package/dist-cjs/images/asset-support.js +2 -2
  217. package/dist-cjs/images/assets.js +1 -2
  218. package/dist-cjs/images/evals.js +4 -4
  219. package/dist-cjs/insights/proposals.js +1 -2
  220. package/dist-cjs/insights/regressions.d.ts +26 -2
  221. package/dist-cjs/insights/regressions.js +129 -3
  222. package/dist-cjs/loaders/git.js +8 -1
  223. package/dist-cjs/loaders/web.js +7 -1
  224. package/dist-cjs/mcp/client.d.ts +14 -0
  225. package/dist-cjs/mcp/client.js +60 -1
  226. package/dist-cjs/mcp/registry.d.ts +6 -0
  227. package/dist-cjs/mcp/registry.js +7 -0
  228. package/dist-cjs/postgres/fulltext.d.ts +67 -0
  229. package/dist-cjs/postgres/fulltext.js +129 -0
  230. package/dist-cjs/prompts/file.js +28 -11
  231. package/dist-cjs/protocols/a2a.d.ts +235 -0
  232. package/dist-cjs/protocols/a2a.js +393 -0
  233. package/dist-cjs/protocols/acp.d.ts +87 -0
  234. package/dist-cjs/protocols/acp.js +326 -0
  235. package/dist-cjs/protocols/ag-ui.d.ts +120 -0
  236. package/dist-cjs/protocols/ag-ui.js +186 -0
  237. package/dist-cjs/protocols/shared.d.ts +80 -0
  238. package/dist-cjs/protocols/shared.js +59 -0
  239. package/dist-cjs/providers/anthropic.js +1 -0
  240. package/dist-cjs/providers/cohere.js +2 -2
  241. package/dist-cjs/providers/google.js +3 -12
  242. package/dist-cjs/providers/openai.js +1 -0
  243. package/dist-cjs/rag/elasticsearch.d.ts +71 -0
  244. package/dist-cjs/rag/elasticsearch.js +135 -0
  245. package/dist-cjs/rag/file-ingestion.js +14 -8
  246. package/dist-cjs/rag/pipeline.d.ts +140 -0
  247. package/dist-cjs/rag/pipeline.js +191 -0
  248. package/dist-cjs/rag/rerankers.d.ts +92 -0
  249. package/dist-cjs/rag/rerankers.js +107 -0
  250. package/dist-cjs/rag/retrievers.d.ts +12 -1
  251. package/dist-cjs/runtime/detect.d.ts +17 -0
  252. package/dist-cjs/runtime/detect.js +19 -0
  253. package/dist-cjs/runtime/index.d.ts +19 -0
  254. package/dist-cjs/runtime/index.js +31 -0
  255. package/dist-cjs/security/injection-detector.d.ts +2 -0
  256. package/dist-cjs/security/injection-detector.js +7 -1
  257. package/dist-cjs/security/input-guard.js +5 -2
  258. package/dist-cjs/security/output-guard.js +8 -4
  259. package/dist-cjs/security/pii-detector.js +22 -6
  260. package/dist-cjs/security/prompt-hardening.js +6 -2
  261. package/dist-cjs/security/semantic-injection-classifier.d.ts +2 -1
  262. package/dist-cjs/security/semantic-injection-classifier.js +31 -35
  263. package/dist-cjs/security/upload-scanner.d.ts +8 -0
  264. package/dist-cjs/security/upload-scanner.js +53 -9
  265. package/dist-cjs/server/assistant.d.ts +5 -1
  266. package/dist-cjs/server/assistant.js +4 -2
  267. package/dist-cjs/server/auth.d.ts +250 -0
  268. package/dist-cjs/server/auth.js +402 -0
  269. package/dist-cjs/server/deployments.d.ts +63 -1
  270. package/dist-cjs/server/deployments.js +75 -2
  271. package/dist-cjs/server/runs.d.ts +9 -0
  272. package/dist-cjs/server/runs.js +20 -0
  273. package/dist-cjs/server/server.js +5 -0
  274. package/dist-cjs/store/memory.d.ts +10 -0
  275. package/dist-cjs/store/memory.js +10 -0
  276. package/dist-cjs/testing/record.js +2 -2
  277. package/dist-cjs/tracing/stores.js +2 -1
  278. package/dist-cjs/tracing/tracer.js +2 -2
  279. package/dist-cjs/types/config.d.ts +20 -0
  280. package/dist-cjs/types/graph.d.ts +38 -0
  281. package/dist-cjs/types/messages.d.ts +36 -2
  282. package/dist-cjs/types/principal.d.ts +21 -0
  283. package/dist-cjs/types/principal.js +2 -0
  284. package/dist-cjs/types/server.d.ts +8 -9
  285. package/dist-cjs/utils/base64.d.ts +4 -0
  286. package/dist-cjs/utils/base64.js +25 -0
  287. package/dist-cjs/utils/checksums.d.ts +22 -0
  288. package/dist-cjs/utils/checksums.js +46 -0
  289. package/dist-cjs/utils/ids.d.ts +8 -0
  290. package/dist-cjs/utils/ids.js +28 -2
  291. package/dist-cjs/utils/sha256.d.ts +22 -0
  292. package/dist-cjs/utils/sha256.js +125 -0
  293. package/dist-cjs/utils/tenant.d.ts +11 -0
  294. package/dist-cjs/utils/tenant.js +15 -0
  295. package/dist-cjs/version.d.ts +1 -1
  296. package/dist-cjs/version.js +1 -1
  297. package/llms.txt +7 -3
  298. package/package.json +193 -6
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDeepAgent = createDeepAgent;
4
+ const create_agent_js_1 = require("../agent/create-agent.js");
5
+ const context_editor_js_1 = require("../agent/middleware/context-editor.js");
6
+ const filesystem_js_1 = require("../agent/middleware/filesystem.js");
7
+ const tool_selector_js_1 = require("../agent/middleware/tool-selector.js");
8
+ const permissions_js_1 = require("../agent/permissions.js");
9
+ const sandbox_js_1 = require("../agent/sandbox.js");
10
+ const tool_js_1 = require("../agent/tool.js");
11
+ const MOUNT = '/workspace';
12
+ const CORE_TOOLS = [
13
+ 'write_todos',
14
+ 'delegate',
15
+ 'load_skill',
16
+ 'read_file',
17
+ 'write_file',
18
+ 'edit_file',
19
+ 'list_files',
20
+ 'run_command',
21
+ ];
22
+ function createDeepAgent(options) {
23
+ const { instructions, sandbox, commands = [], planning = true, subagents = [], skills = [], include = ['AGENTS.md'], offload, contextEditing, toolSelection, permissions, middleware = [], tools: extraTools = [], ...agentOptions } = options;
24
+ const workspace = sandbox
25
+ ? [...(0, sandbox_js_1.sandboxTools)(sandbox, { shell: commands.length > 0, mount: MOUNT }), editFileTool(sandbox)]
26
+ : [];
27
+ const own = [
28
+ ...(planning ? [writeTodosTool()] : []),
29
+ ...(skills.length > 0 ? [loadSkillTool(skills, sandbox)] : []),
30
+ ...workspace,
31
+ ...extraTools,
32
+ ];
33
+ const helpers = new Map();
34
+ const approved = new Set(Object.keys(agentOptions.interruptOn ?? {}));
35
+ const { interruptOn: _approvals, ...helperOptions } = agentOptions;
36
+ for (const helper of subagents) {
37
+ const allowed = helper.tools ? new Set(helper.tools) : undefined;
38
+ helpers.set(helper.name, (0, create_agent_js_1.createAgent)({
39
+ ...helperOptions,
40
+ name: `${options.name ?? 'deep-agent'}.${helper.name}`,
41
+ ...(helper.model ? { model: helper.model } : {}),
42
+ maxIterations: helper.maxIterations ?? 20,
43
+ systemPrompt: `${helper.instructions}\n\n${WORKSPACE_NOTE}`,
44
+ tools: own.filter((candidate) => !approved.has(candidate.name) && (allowed ? allowed.has(candidate.name) : true)),
45
+ ...(permissions === false ? {} : { permissions: permissions ?? defaultPolicy(commands) }),
46
+ checkpointer: false,
47
+ }));
48
+ }
49
+ const tools = [...own, ...(helpers.size > 0 ? [delegateTool(subagents, helpers)] : [])];
50
+ const kit = [
51
+ ...(sandbox && (include.length > 0 || offload !== false)
52
+ ? [
53
+ (0, filesystem_js_1.filesystemContext)({
54
+ source: sandbox,
55
+ include,
56
+ ...(offload === false ? {} : { offload: { overChars: 20_000, ...offload } }),
57
+ }),
58
+ ]
59
+ : []),
60
+ ...(contextEditing === false
61
+ ? []
62
+ : [
63
+ (0, context_editor_js_1.contextEditor)({
64
+ triggerTokens: 60_000,
65
+ ...contextEditing,
66
+ exclude: ['write_todos', ...(contextEditing?.exclude ?? [])],
67
+ }),
68
+ ]),
69
+ ...(toolSelection
70
+ ? [(0, tool_selector_js_1.toolSelector)({ ...toolSelection, always: [...CORE_TOOLS, ...(toolSelection.always ?? [])] })]
71
+ : []),
72
+ ];
73
+ return (0, create_agent_js_1.createAgent)({
74
+ maxIterations: 40,
75
+ ...agentOptions,
76
+ systemPrompt: systemPrompt(instructions, { planning, sandbox: Boolean(sandbox), commands, subagents, skills }),
77
+ tools,
78
+ middleware: [...kit, ...middleware],
79
+ ...(permissions === false ? {} : { permissions: permissions ?? defaultPolicy(commands) }),
80
+ });
81
+ }
82
+ function defaultPolicy(commands) {
83
+ return (0, permissions_js_1.permissionPolicy)({
84
+ filesystem: { write: [`${MOUNT}/**`] },
85
+ shell: { allow: commands },
86
+ tools: { write_todos: 'allow', delegate: 'allow', load_skill: 'allow' },
87
+ });
88
+ }
89
+ const WORKSPACE_NOTE = `Files live in ${MOUNT}; paths are relative to it.`;
90
+ function systemPrompt(instructions, parts) {
91
+ const lines = [];
92
+ if (instructions)
93
+ lines.push(instructions, '');
94
+ lines.push('Work through the task step by step, checking each step before the next.');
95
+ if (parts.planning) {
96
+ lines.push('For any task of more than two steps, first record a plan with write_todos, then keep it current: mark a step in_progress when you start it and completed when it is done.');
97
+ }
98
+ if (parts.sandbox) {
99
+ lines.push(`${WORKSPACE_NOTE} Read before you change a file; prefer edit_file to rewriting a whole file. A large result may be saved to a file and shown as a preview: read the file when you need the rest.`);
100
+ if (parts.commands.length > 0)
101
+ lines.push(`You may run these commands: ${parts.commands.join(', ')}.`);
102
+ }
103
+ if (parts.subagents.length > 0) {
104
+ lines.push('', 'Delegate a self-contained piece of work with delegate, to one of:');
105
+ for (const helper of parts.subagents)
106
+ lines.push(`- ${helper.name}: ${helper.description}`);
107
+ }
108
+ if (parts.skills.length > 0) {
109
+ lines.push('', 'Skills you can load with load_skill when a task calls for one:');
110
+ for (const skill of parts.skills)
111
+ lines.push(`- ${skill.name}: ${skill.description}`);
112
+ }
113
+ return lines.join('\n');
114
+ }
115
+ function writeTodosTool() {
116
+ return (0, tool_js_1.tool)({
117
+ name: 'write_todos',
118
+ description: 'Records the plan for this task as a list of steps, each pending, in_progress, or completed. Send the whole list each time.',
119
+ parameters: {
120
+ type: 'object',
121
+ properties: {
122
+ todos: {
123
+ type: 'array',
124
+ items: {
125
+ type: 'object',
126
+ properties: {
127
+ content: { type: 'string' },
128
+ status: { type: 'string', enum: ['pending', 'in_progress', 'completed'] },
129
+ },
130
+ required: ['content', 'status'],
131
+ },
132
+ },
133
+ },
134
+ required: ['todos'],
135
+ },
136
+ capabilities: [],
137
+ execute: ({ todos }) => {
138
+ const list = Array.isArray(todos) ? todos : [];
139
+ const mark = { pending: '[ ]', in_progress: '[~]', completed: '[x]' };
140
+ const done = list.filter((todo) => todo.status === 'completed').length;
141
+ return `Plan (${done}/${list.length} done):\n${list.map((todo) => `${mark[todo.status] ?? '[ ]'} ${todo.content}`).join('\n')}`;
142
+ },
143
+ });
144
+ }
145
+ function editFileTool(sandbox) {
146
+ const local = (file) => String(file ?? '')
147
+ .replace(/\\/g, '/')
148
+ .replace(new RegExp(`^${MOUNT}/`), '')
149
+ .replace(/^\/+/, '');
150
+ return (0, tool_js_1.tool)({
151
+ name: 'edit_file',
152
+ description: `Replaces one exact occurrence of old_text with new_text in a file. Paths are relative to ${MOUNT}.`,
153
+ parameters: {
154
+ type: 'object',
155
+ properties: { path: { type: 'string' }, old_text: { type: 'string' }, new_text: { type: 'string' } },
156
+ required: ['path', 'old_text', 'new_text'],
157
+ },
158
+ capabilities: (args) => [`filesystem:write:${MOUNT}/${local(args.path)}`],
159
+ execute: async ({ path, old_text: oldText, new_text: newText }) => {
160
+ const file = local(path);
161
+ const text = await sandbox.readFile(file);
162
+ const count = text.split(String(oldText)).length - 1;
163
+ if (count === 0)
164
+ throw new Error(`old_text was not found in ${file}`);
165
+ if (count > 1)
166
+ throw new Error(`old_text appears ${count} times in ${file}; include more context so it appears once`);
167
+ await sandbox.writeFile(file, text.replace(String(oldText), () => String(newText)));
168
+ return { edited: file };
169
+ },
170
+ });
171
+ }
172
+ function loadSkillTool(skills, sandbox) {
173
+ const byName = new Map(skills.map((skill) => [skill.name, skill]));
174
+ return (0, tool_js_1.tool)({
175
+ name: 'load_skill',
176
+ description: 'Loads the instructions of a skill by name.',
177
+ parameters: {
178
+ type: 'object',
179
+ properties: { name: { type: 'string', enum: skills.map((skill) => skill.name) } },
180
+ required: ['name'],
181
+ },
182
+ capabilities: [],
183
+ execute: async ({ name }) => {
184
+ const skill = byName.get(String(name));
185
+ if (!skill)
186
+ throw new Error(`No skill named "${String(name)}"`);
187
+ if (skill.instructions !== undefined)
188
+ return skill.instructions;
189
+ if (skill.file && sandbox)
190
+ return sandbox.readFile(skill.file);
191
+ throw new Error(`Skill "${skill.name}" has no instructions`);
192
+ },
193
+ });
194
+ }
195
+ function delegateTool(subagents, helpers) {
196
+ return (0, tool_js_1.tool)({
197
+ name: 'delegate',
198
+ description: 'Hands a self-contained task to a helper, which works in a fresh context and returns its answer.',
199
+ parameters: {
200
+ type: 'object',
201
+ properties: {
202
+ agent: { type: 'string', enum: subagents.map((helper) => helper.name) },
203
+ task: { type: 'string', description: 'Everything the helper needs to know: it sees nothing else.' },
204
+ },
205
+ required: ['agent', 'task'],
206
+ },
207
+ capabilities: [],
208
+ execute: async ({ agent, task }, context) => {
209
+ const helper = helpers.get(String(agent));
210
+ if (!helper)
211
+ throw new Error(`No helper named "${String(agent)}"`);
212
+ const result = await helper.invoke((0, create_agent_js_1.agentInput)(String(task)), {
213
+ ...(context.principal ? { principal: context.principal } : {}),
214
+ ...(context.signal ? { signal: context.signal } : {}),
215
+ });
216
+ return (result.state.answer || `The ${String(agent)} helper finished without an answer (${result.state.stopReason}).`);
217
+ },
218
+ });
219
+ }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OllamaEmbeddingProvider = exports.MistralEmbeddingProvider = exports.CohereEmbeddingProvider = exports.GoogleEmbeddingProvider = exports.OpenAIEmbeddingProvider = void 0;
4
+ const base64_js_1 = require("../utils/base64.js");
4
5
  const errors_js_1 = require("../providers/errors.js");
5
6
  const errors_js_2 = require("./errors.js");
6
7
  class HttpEmbeddingProvider {
@@ -34,7 +35,7 @@ class HttpEmbeddingProvider {
34
35
  }
35
36
  }
36
37
  function decodeBase64Vector(value) {
37
- const bytes = Buffer.from(value, 'base64');
38
+ const bytes = (0, base64_js_1.decodeBase64)(value);
38
39
  const floats = new Float32Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 4));
39
40
  return Array.from(floats);
40
41
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LLMJudge = void 0;
4
4
  exports.createLLMJudgeEval = createLLMJudgeEval;
5
5
  exports.parseJudgeResponse = parseJudgeResponse;
6
- const node_crypto_1 = require("node:crypto");
6
+ const sha256_js_1 = require("../utils/sha256.js");
7
7
  const provenance_js_1 = require("../evaluate/provenance.js");
8
8
  const DEFAULT_SYSTEM_PROMPT = [
9
9
  'You are a careful evaluation judge.',
@@ -69,10 +69,7 @@ class LLMJudge {
69
69
  name: options.key ?? 'judge',
70
70
  judge: {
71
71
  model: this.options.model,
72
- promptVersion: (0, node_crypto_1.createHash)('sha256')
73
- .update(this.options.systemPrompt ?? 'default')
74
- .digest('hex')
75
- .slice(0, 12),
72
+ promptVersion: (0, sha256_js_1.sha256Hex)(this.options.systemPrompt ?? 'default').slice(0, 12),
76
73
  temperature: this.options.temperature ?? 0,
77
74
  },
78
75
  ...(this.options.rubric ? { rubric: this.options.rubric } : {}),
@@ -42,20 +42,6 @@ export declare class MemoryEvaluationCache implements EvaluationCache {
42
42
  /** Drops every output. */
43
43
  clear(): void;
44
44
  }
45
- /**
46
- * Target outputs as JSON files in a directory, one per key, so a CI job keeps them between runs by
47
- * caching the directory. Writes go through a temporary file and a rename, so a reader never sees half
48
- * an entry. Outputs must survive `JSON.stringify()`.
49
- */
50
- export declare class FileEvaluationCache implements EvaluationCache {
51
- private readonly directory;
52
- constructor(directory: string);
53
- /** The output under a key, or `undefined` when there is none or its file cannot be read. */
54
- get(key: string): Promise<CachedOutput | undefined>;
55
- /** Writes an output under a key. */
56
- set(key: string, value: CachedOutput): Promise<void>;
57
- private fileOf;
58
- }
59
45
  /**
60
46
  * A fingerprint for whatever decides a target's output — a model name, a prompt version, a
61
47
  * temperature, a context bundle version — as `f` and 16 hex digits of a SHA-256 over its canonical
@@ -1,39 +1,6 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.FileEvaluationCache = exports.MemoryEvaluationCache = void 0;
3
+ exports.MemoryEvaluationCache = void 0;
37
4
  exports.fingerprintOf = fingerprintOf;
38
5
  exports.evaluationCacheKey = evaluationCacheKey;
39
6
  const version_js_1 = require("../prompts/version.js");
@@ -67,37 +34,6 @@ class MemoryEvaluationCache {
67
34
  }
68
35
  }
69
36
  exports.MemoryEvaluationCache = MemoryEvaluationCache;
70
- class FileEvaluationCache {
71
- directory;
72
- constructor(directory) {
73
- this.directory = directory;
74
- }
75
- async get(key) {
76
- const { readFile } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
77
- try {
78
- return JSON.parse(await readFile(await this.fileOf(key), 'utf8'));
79
- }
80
- catch {
81
- return undefined;
82
- }
83
- }
84
- async set(key, value) {
85
- const { mkdir, rename, writeFile } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
86
- const path = await Promise.resolve().then(() => __importStar(require('node:path')));
87
- const file = await this.fileOf(key);
88
- await mkdir(path.dirname(file), { recursive: true });
89
- const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
90
- await writeFile(temporary, JSON.stringify(value), 'utf8');
91
- await rename(temporary, file);
92
- }
93
- async fileOf(key) {
94
- if (!/^[0-9a-f]{16,}$/.test(key))
95
- throw new RangeError('An evaluation cache key is a hex string');
96
- const path = await Promise.resolve().then(() => __importStar(require('node:path')));
97
- return path.join(this.directory, key.slice(0, 2), `${key}.json`);
98
- }
99
- }
100
- exports.FileEvaluationCache = FileEvaluationCache;
101
37
  async function fingerprintOf(value) {
102
38
  return `f${(await sha256((0, version_js_1.canonicalJson)(value))).slice(0, 16)}`;
103
39
  }
@@ -0,0 +1,15 @@
1
+ import type { CachedOutput, EvaluationCache } from './cache.js';
2
+ /**
3
+ * Target outputs as JSON files in a directory, one per key, so a CI job keeps them between runs by
4
+ * caching the directory. Writes go through a temporary file and a rename, so a reader never sees half
5
+ * an entry. Outputs must survive `JSON.stringify()`.
6
+ */
7
+ export declare class FileEvaluationCache implements EvaluationCache {
8
+ private readonly directory;
9
+ constructor(directory: string);
10
+ /** The output under a key, or `undefined` when there is none or its file cannot be read. */
11
+ get(key: string): Promise<CachedOutput | undefined>;
12
+ /** Writes an output under a key. */
13
+ set(key: string, value: CachedOutput): Promise<void>;
14
+ private fileOf;
15
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FileEvaluationCache = void 0;
37
+ class FileEvaluationCache {
38
+ directory;
39
+ constructor(directory) {
40
+ this.directory = directory;
41
+ }
42
+ async get(key) {
43
+ const { readFile } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
44
+ try {
45
+ return JSON.parse(await readFile(await this.fileOf(key), 'utf8'));
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ }
51
+ async set(key, value) {
52
+ const { mkdir, rename, writeFile } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
53
+ const path = await Promise.resolve().then(() => __importStar(require('node:path')));
54
+ const file = await this.fileOf(key);
55
+ await mkdir(path.dirname(file), { recursive: true });
56
+ const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
57
+ await writeFile(temporary, JSON.stringify(value), 'utf8');
58
+ await rename(temporary, file);
59
+ }
60
+ async fileOf(key) {
61
+ if (!/^[0-9a-f]{16,}$/.test(key))
62
+ throw new RangeError('An evaluation cache key is a hex string');
63
+ const path = await Promise.resolve().then(() => __importStar(require('node:path')));
64
+ return path.join(this.directory, key.slice(0, 2), `${key}.json`);
65
+ }
66
+ }
67
+ exports.FileEvaluationCache = FileEvaluationCache;
@@ -3,6 +3,7 @@ export { contentVersion, createDataset, type CreateDatasetOptions, datasetFromTr
3
3
  export { completed, contains, embeddingSimilarity, exactMatch, mustNotMatch, pairwise, passRate, recallAtK, reciprocalRank, type RetrievalEvaluatorOptions, totalCost, trajectory, type TrajectoryOptions, underCost, underLatency, } from './evaluators.js';
4
4
  export { AnnotationQueue, type AnnotationQueueOptions, evaluateOnline, type OnlineEvaluationOptions, type OnlineEvaluationReport, type ReviewAnswer, type ReviewItem, type ReviewQuestion, } from './review.js';
5
5
  export { evaluate, type EvaluateOptions, type EvaluationTarget, stats, summarize } from './run.js';
6
- export { type CachedOutput, type EvaluationCache, evaluationCacheKey, FileEvaluationCache, fingerprintOf, MemoryEvaluationCache, type MemoryEvaluationCacheOptions, } from './cache.js';
6
+ export { type CachedOutput, type EvaluationCache, evaluationCacheKey, fingerprintOf, MemoryEvaluationCache, type MemoryEvaluationCacheOptions, } from './cache.js';
7
+ export { FileEvaluationCache } from './file-cache.js';
7
8
  export type { Dataset, DatasetExample, DatasetStore, EvaluationContext, EvaluationScore, Evaluator, ExampleResult, Experiment, ExperimentStore, MetricSummary, SummaryEvaluator, } from '../types/evaluate.js';
8
9
  export { withProvenance } from './provenance.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withProvenance = exports.MemoryEvaluationCache = exports.fingerprintOf = exports.FileEvaluationCache = exports.evaluationCacheKey = exports.summarize = exports.stats = exports.evaluate = exports.evaluateOnline = exports.AnnotationQueue = exports.underLatency = exports.underCost = exports.trajectory = exports.totalCost = exports.reciprocalRank = exports.recallAtK = exports.passRate = exports.pairwise = exports.mustNotMatch = exports.exactMatch = exports.embeddingSimilarity = exports.contains = exports.completed = exports.splitOf = exports.readExperiment = exports.MemoryExperimentStore = exports.MemoryDatasetStore = exports.FileExperimentStore = exports.FileDatasetStore = exports.datasetFromTraces = exports.createDataset = exports.contentVersion = exports.scoreMap = exports.formatComparison = exports.compareExperiments = void 0;
3
+ exports.withProvenance = exports.FileEvaluationCache = exports.MemoryEvaluationCache = exports.fingerprintOf = exports.evaluationCacheKey = exports.summarize = exports.stats = exports.evaluate = exports.evaluateOnline = exports.AnnotationQueue = exports.underLatency = exports.underCost = exports.trajectory = exports.totalCost = exports.reciprocalRank = exports.recallAtK = exports.passRate = exports.pairwise = exports.mustNotMatch = exports.exactMatch = exports.embeddingSimilarity = exports.contains = exports.completed = exports.splitOf = exports.readExperiment = exports.MemoryExperimentStore = exports.MemoryDatasetStore = exports.FileExperimentStore = exports.FileDatasetStore = exports.datasetFromTraces = exports.createDataset = exports.contentVersion = exports.scoreMap = exports.formatComparison = exports.compareExperiments = void 0;
4
4
  var compare_js_1 = require("./compare.js");
5
5
  Object.defineProperty(exports, "compareExperiments", { enumerable: true, get: function () { return compare_js_1.compareExperiments; } });
6
6
  Object.defineProperty(exports, "formatComparison", { enumerable: true, get: function () { return compare_js_1.formatComparison; } });
@@ -38,8 +38,9 @@ Object.defineProperty(exports, "stats", { enumerable: true, get: function () { r
38
38
  Object.defineProperty(exports, "summarize", { enumerable: true, get: function () { return run_js_1.summarize; } });
39
39
  var cache_js_1 = require("./cache.js");
40
40
  Object.defineProperty(exports, "evaluationCacheKey", { enumerable: true, get: function () { return cache_js_1.evaluationCacheKey; } });
41
- Object.defineProperty(exports, "FileEvaluationCache", { enumerable: true, get: function () { return cache_js_1.FileEvaluationCache; } });
42
41
  Object.defineProperty(exports, "fingerprintOf", { enumerable: true, get: function () { return cache_js_1.fingerprintOf; } });
43
42
  Object.defineProperty(exports, "MemoryEvaluationCache", { enumerable: true, get: function () { return cache_js_1.MemoryEvaluationCache; } });
43
+ var file_cache_js_1 = require("./file-cache.js");
44
+ Object.defineProperty(exports, "FileEvaluationCache", { enumerable: true, get: function () { return file_cache_js_1.FileEvaluationCache; } });
44
45
  var provenance_js_1 = require("./provenance.js");
45
46
  Object.defineProperty(exports, "withProvenance", { enumerable: true, get: function () { return provenance_js_1.withProvenance; } });
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AnnotationQueue = void 0;
4
4
  exports.evaluateOnline = evaluateOnline;
5
- const node_crypto_1 = require("node:crypto");
5
+ const ids_js_1 = require("../utils/ids.js");
6
6
  class AnnotationQueue {
7
7
  options;
8
8
  items = new Map();
@@ -13,7 +13,7 @@ class AnnotationQueue {
13
13
  }
14
14
  enqueue(subject, metadata) {
15
15
  const item = {
16
- id: `review-${(0, node_crypto_1.randomBytes)(6).toString('hex')}`,
16
+ id: `review-${(0, ids_js_1.randomHex)(6)}`,
17
17
  subject,
18
18
  rubric: this.options.rubric,
19
19
  status: 'pending',
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.evaluate = evaluate;
4
4
  exports.summarize = summarize;
5
5
  exports.stats = stats;
6
- const node_crypto_1 = require("node:crypto");
6
+ const ids_js_1 = require("../utils/ids.js");
7
7
  const version_js_1 = require("../version.js");
8
8
  const cache_js_1 = require("./cache.js");
9
9
  const provenance_js_1 = require("./provenance.js");
@@ -34,7 +34,7 @@ async function evaluate(target, dataset, evaluators, options = {}) {
34
34
  for (const evaluator of options.summary ?? [])
35
35
  summary.push(...(await evaluator(results)));
36
36
  const experiment = {
37
- id: `exp-${(0, node_crypto_1.randomBytes)(6).toString('hex')}`,
37
+ id: `exp-${(0, ids_js_1.randomHex)(6)}`,
38
38
  name: options.name ?? `${dataset.name} ${startedAt}`,
39
39
  dataset: { name: dataset.name, version: dataset.version },
40
40
  startedAt,
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.contentVersion = contentVersion;
4
- const node_crypto_1 = require("node:crypto");
4
+ const sha256_js_1 = require("../utils/sha256.js");
5
5
  function contentVersion(examples) {
6
- const hash = (0, node_crypto_1.createHash)('sha256');
6
+ const hash = new sha256_js_1.Sha256();
7
7
  for (const example of examples) {
8
8
  hash.update(JSON.stringify({ id: example.id, inputs: example.inputs, expected: example.expected }));
9
9
  }
10
- return `v${hash.digest('hex').slice(0, 12)}`;
10
+ return `v${hash.digest().slice(0, 12)}`;
11
11
  }
@@ -1,4 +1,5 @@
1
1
  import type { OperationLifecycleLike } from '../types/lifecycle.js';
2
+ import type { Principal } from '../types/principal.js';
2
3
  import { GraphError } from './errors.js';
3
4
  import type { GraphCheckpoint, GraphCheckpointer, GraphDescription, GraphEvent, GraphStatus, InterruptRequest, PendingInterrupt, RetryPolicy, RunControlLike } from '../types/graph.js';
4
5
  import type { Store } from '../types/store.js';
@@ -86,6 +87,8 @@ export interface WorkflowContext {
86
87
  readonly threadId: string;
87
88
  /** The tenant the run is for, when it has one. */
88
89
  readonly tenantId?: string;
90
+ /** Who the run is for, when it was started with a principal: the caller the server authenticated. */
91
+ readonly principal?: Readonly<Principal>;
89
92
  /** Aborted when the run is cancelled. */
90
93
  readonly signal: AbortSignal;
91
94
  /** Long-term memory, when the workflow was created with a store. In a tenant's run, the tenant's view of it. */
@@ -162,6 +165,12 @@ export interface WorkflowRunOptions {
162
165
  * without one carries on the thread's.
163
166
  */
164
167
  tenantId?: string;
168
+ /**
169
+ * Who the run is for, read as `context.principal`. Its `tenantId` is the run's tenant when
170
+ * `tenantId` is not given, and a run whose two tenants differ is refused; its `userId` is recorded
171
+ * on every checkpoint as `metadata.userId`.
172
+ */
173
+ principal?: Principal;
165
174
  }
166
175
  /** One event of a streamed workflow run. */
167
176
  export type WorkflowEvent<O = unknown> = {
@@ -6,6 +6,7 @@ const checkpointer_js_1 = require("./checkpointer.js");
6
6
  const run_js_1 = require("../lifecycle/run.js");
7
7
  const checkpoint_migration_js_1 = require("./checkpoint-migration.js");
8
8
  const tenant_js_1 = require("../store/tenant.js");
9
+ const tenant_js_2 = require("../utils/tenant.js");
9
10
  const errors_js_1 = require("./errors.js");
10
11
  class WorkflowStepTimeoutError extends errors_js_1.GraphError {
11
12
  stepName;
@@ -57,9 +58,10 @@ class Workflow {
57
58
  const threadId = runOptions.threadId ?? generatedId();
58
59
  return this.execute(threadId, runOptions, async () => {
59
60
  const latest = await this.latest(threadId);
60
- if (latest && runOptions.tenantId !== undefined) {
61
+ const tenantId = runOptions.tenantId ?? runOptions.principal?.tenantId;
62
+ if (latest && tenantId !== undefined) {
61
63
  const owner = latest.metadata?.tenantId;
62
- if (typeof owner === 'string' && owner !== runOptions.tenantId) {
64
+ if (typeof owner === 'string' && owner !== tenantId) {
63
65
  throw new errors_js_1.GraphError(`Thread "${threadId}" cannot be used by this tenant; choose another id`, 'GRAPH_VALIDATION_ERROR');
64
66
  }
65
67
  }
@@ -153,7 +155,21 @@ class Workflow {
153
155
  }
154
156
  execute(threadId, runOptions, start) {
155
157
  const queue = new EventQueue();
156
- void (0, run_js_1.withLifecycle)(this.options.lifecycle, { family: 'graph', operation: `workflow.${this.name}`, metadata: { threadId, graph: this.name } }, runOptions.signal ? { signal: runOptions.signal } : {}, () => this.run(threadId, runOptions, start, queue)).then(() => queue.close(), (error) => queue.fail(error));
158
+ let options;
159
+ try {
160
+ options = (0, tenant_js_2.withPrincipal)(runOptions);
161
+ }
162
+ catch (error) {
163
+ queue.fail(error);
164
+ return queue;
165
+ }
166
+ const metadata = {
167
+ threadId,
168
+ graph: this.name,
169
+ ...(options.tenantId !== undefined ? { tenantId: options.tenantId } : {}),
170
+ ...(options.principal?.userId !== undefined ? { userId: options.principal.userId } : {}),
171
+ };
172
+ void (0, run_js_1.withLifecycle)(this.options.lifecycle, { family: 'graph', operation: `workflow.${this.name}`, metadata }, options.signal ? { signal: options.signal } : {}, () => this.run(threadId, options, start, queue)).then(() => queue.close(), (error) => queue.fail(error));
157
173
  return queue;
158
174
  }
159
175
  async run(threadId, runOptions, start, queue) {
@@ -208,6 +224,7 @@ class Workflow {
208
224
  const context = {
209
225
  threadId,
210
226
  ...(tenantId === undefined ? {} : { tenantId }),
227
+ ...(runOptions.principal ? { principal: runOptions.principal } : {}),
211
228
  signal: controller.signal,
212
229
  ...(this.options.store
213
230
  ? { store: tenantId === undefined ? this.options.store : (0, tenant_js_1.tenantStore)(this.options.store, tenantId) }