eve 0.58.1 → 0.59.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 (234) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/src/approval/definition.d.ts +2 -0
  3. package/dist/src/channel/session.d.ts +2 -0
  4. package/dist/src/channel/session.js +1 -1
  5. package/dist/src/channel/types.d.ts +8 -1
  6. package/dist/src/chunks/{use-eve-agent-X0asmJg-.js → use-eve-agent-Dmc6sX4d.js} +558 -233
  7. package/dist/src/chunks/{use-eve-agent-CxWcZCsU.js → use-eve-agent-jSR8P4nK.js} +565 -235
  8. package/dist/src/cli/dev/tui/runner.d.ts +4 -0
  9. package/dist/src/cli/dev/tui/runner.js +1 -1
  10. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  11. package/dist/src/client/eve-agent-projection.d.ts +10 -0
  12. package/dist/src/client/eve-agent-projection.js +1 -0
  13. package/dist/src/client/eve-agent-store-helpers.d.ts +6 -2
  14. package/dist/src/client/eve-agent-store-helpers.js +2 -2
  15. package/dist/src/client/eve-agent-store-state.d.ts +54 -1
  16. package/dist/src/client/eve-agent-store.d.ts +12 -82
  17. package/dist/src/client/eve-agent-store.js +1 -1
  18. package/dist/src/client/index.d.ts +2 -2
  19. package/dist/src/client/index.js +1 -1
  20. package/dist/src/client/message-response.d.ts +5 -1
  21. package/dist/src/client/message-response.js +1 -1
  22. package/dist/src/client/ndjson.d.ts +1 -0
  23. package/dist/src/client/ndjson.js +2 -2
  24. package/dist/src/client/open-stream.d.ts +4 -1
  25. package/dist/src/client/open-stream.js +1 -1
  26. package/dist/src/client/session-event-stream.d.ts +30 -0
  27. package/dist/src/client/session-event-stream.js +1 -0
  28. package/dist/src/client/session-utils.d.ts +2 -1
  29. package/dist/src/client/session-utils.js +1 -1
  30. package/dist/src/client/session.d.ts +14 -1
  31. package/dist/src/client/session.js +1 -1
  32. package/dist/src/client/sessions.d.ts +8 -2
  33. package/dist/src/client/sessions.js +1 -1
  34. package/dist/src/client/types.d.ts +7 -0
  35. package/dist/src/compiled/.vendor-stamp.json +2 -3
  36. package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +88 -1
  37. package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +1 -1
  38. package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +41 -1
  39. package/dist/src/compiled/@vercel/sandbox/constants.d.ts +3 -3
  40. package/dist/src/compiled/@vercel/{sandbox-drives → sandbox}/drive.d.ts +13 -2
  41. package/dist/src/compiled/@vercel/sandbox/index.d.ts +3 -2
  42. package/dist/src/compiled/@vercel/sandbox/index.js +15 -9
  43. package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +40 -5
  44. package/dist/src/compiled/_chunks/node/auth-DDrvYko5.js +2 -0
  45. package/dist/src/compiled/_chunks/node/version-C__MqbLM.js +1 -0
  46. package/dist/src/compiler/default-tool-policy.d.ts +3 -1
  47. package/dist/src/compiler/default-tool-policy.js +1 -1
  48. package/dist/src/compiler/extension-compatibility.d.ts +16 -16
  49. package/dist/src/compiler/extension-compatibility.js +1 -1
  50. package/dist/src/compiler/manifest.d.ts +8 -2
  51. package/dist/src/compiler/manifest.js +1 -1
  52. package/dist/src/compiler/normalize-agent-config.js +1 -1
  53. package/dist/src/compiler/normalize-manifest-helpers.js +1 -1
  54. package/dist/src/compiler/normalize-manifest.js +1 -1
  55. package/dist/src/compiler/normalize-subagent.d.ts +1 -0
  56. package/dist/src/compiler/normalize-subagent.js +1 -1
  57. package/dist/src/compiler/remote-agent-node.d.ts +1 -0
  58. package/dist/src/compiler/remote-agent-node.js +1 -1
  59. package/dist/src/compiler/source-graph.d.ts +1 -0
  60. package/dist/src/compiler/source-graph.js +1 -1
  61. package/dist/src/context/build-dynamic-tools.js +1 -1
  62. package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
  63. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  64. package/dist/src/context/memory-tools.js +1 -1
  65. package/dist/src/evals/context.d.ts +1 -1
  66. package/dist/src/evals/context.js +1 -1
  67. package/dist/src/evals/define-eval.d.ts +1 -1
  68. package/dist/src/evals/define-eval.js +1 -1
  69. package/dist/src/evals/index.js +1 -1
  70. package/dist/src/evals/judge.d.ts +1 -1
  71. package/dist/src/evals/runner/execute-task.d.ts +1 -1
  72. package/dist/src/evals/runner/execute-task.js +1 -1
  73. package/dist/src/evals/session-manager.d.ts +27 -0
  74. package/dist/src/evals/session-manager.js +1 -0
  75. package/dist/src/evals/session.d.ts +8 -28
  76. package/dist/src/evals/session.js +2 -1
  77. package/dist/src/evals/target.d.ts +1 -1
  78. package/dist/src/evals/target.js +1 -1
  79. package/dist/src/evals/types.d.ts +19 -15
  80. package/dist/src/eve-channel/create-request.d.ts +24 -0
  81. package/dist/src/eve-channel/create-request.js +1 -0
  82. package/dist/src/eve-channel/index.js +1 -1
  83. package/dist/src/eve-channel/request.d.ts +3 -12
  84. package/dist/src/eve-channel/request.js +2 -2
  85. package/dist/src/eve-channel/types.d.ts +4 -2
  86. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  87. package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
  88. package/dist/src/execution/runtime-context.js +1 -1
  89. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.d.ts +3 -3
  90. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
  91. package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +1 -4
  92. package/dist/src/execution/sandbox/bindings/vercel.d.ts +1 -2
  93. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  94. package/dist/src/execution/session/entry.js +1 -1
  95. package/dist/src/execution/session/handoff-steps.js +1 -1
  96. package/dist/src/execution/session/program.d.ts +2 -0
  97. package/dist/src/execution/session/program.js +1 -1
  98. package/dist/src/execution/session/turn-step.js +1 -1
  99. package/dist/src/execution/session/turn.js +1 -1
  100. package/dist/src/execution/session-inbox/protocol.js +1 -1
  101. package/dist/src/execution/tools/connection-search.js +1 -1
  102. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  103. package/dist/src/execution/workflow-runtime.js +1 -1
  104. package/dist/src/experimental/evaluate/auto-model.js +2 -2
  105. package/dist/src/experimental/evaluate/evaluate.d.ts +7 -0
  106. package/dist/src/experimental/evaluate/evaluate.js +1 -0
  107. package/dist/src/framework/sources/registry.js +1 -1
  108. package/dist/src/harness/compaction.d.ts +3 -3
  109. package/dist/src/harness/compaction.js +1 -1
  110. package/dist/src/harness/request-envelope.d.ts +11 -0
  111. package/dist/src/harness/request-envelope.js +1 -0
  112. package/dist/src/harness/tool-loop.js +2 -2
  113. package/dist/src/harness/tools.d.ts +1 -1
  114. package/dist/src/harness/tools.js +1 -1
  115. package/dist/src/instrumentation/prepare-trace-context.d.ts +2 -1
  116. package/dist/src/instrumentation/prepare-trace-context.js +1 -1
  117. package/dist/src/internal/application/package.js +1 -1
  118. package/dist/src/internal/authored-definition/core.js +1 -1
  119. package/dist/src/internal/authored-module-loader.d.ts +4 -1
  120. package/dist/src/internal/authored-module-loader.js +1 -1
  121. package/dist/src/internal/bundler/nitro-rolldown.d.ts +2 -0
  122. package/dist/src/internal/nitro/host/build-extension.js +1 -1
  123. package/dist/src/internal/nitro/host/extension-capability-requirements.d.ts +1 -0
  124. package/dist/src/internal/nitro/host/extension-capability-requirements.js +1 -1
  125. package/dist/src/internal/nitro/host/extension-distribution.d.ts +1 -1
  126. package/dist/src/internal/nitro/host/extension-distribution.js +1 -1
  127. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  128. package/dist/src/public/definitions/connections/mcp.d.ts +1 -0
  129. package/dist/src/public/definitions/connections/openapi.d.ts +1 -0
  130. package/dist/src/public/definitions/remote-agent.d.ts +5 -0
  131. package/dist/src/public/definitions/workspace-agent.d.ts +5 -0
  132. package/dist/src/public/definitions/workspace-agent.js +1 -1
  133. package/dist/src/public/experimental/evaluate/index.d.ts +1 -0
  134. package/dist/src/public/experimental/evaluate/index.js +1 -1
  135. package/dist/src/public/sandbox/vercel-sandbox.d.ts +1 -1
  136. package/dist/src/public/sandbox/vercel.d.ts +1 -1
  137. package/dist/src/public/sandbox/vercel.js +1 -1
  138. package/dist/src/public/tools/approval/index.d.ts +2 -1
  139. package/dist/src/public/tools/approval/index.js +1 -1
  140. package/dist/src/public/tools/index.d.ts +1 -0
  141. package/dist/src/public/tools/index.js +1 -1
  142. package/dist/src/react/use-eve-agent.d.ts +4 -0
  143. package/dist/src/react/use-eve-agent.js +1 -1
  144. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  145. package/dist/src/runtime/resolve-agent.js +1 -1
  146. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +1 -0
  147. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  148. package/dist/src/runtime/subagents/dynamic-remote-agent-config.d.ts +1 -0
  149. package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
  150. package/dist/src/runtime/subagents/registry.d.ts +5 -2
  151. package/dist/src/runtime/subagents/registry.js +1 -1
  152. package/dist/src/runtime/types.d.ts +2 -0
  153. package/dist/src/setup/scaffold/create/project.js +1 -1
  154. package/dist/src/shared/agent-definition.d.ts +9 -0
  155. package/dist/src/subagents/handle-dispatch.js +1 -1
  156. package/dist/src/svelte/index.js +1 -1
  157. package/dist/src/svelte/use-eve-agent.d.ts +4 -0
  158. package/dist/src/svelte/use-eve-agent.js +1 -1
  159. package/dist/src/tools/approval/policies.d.ts +18 -0
  160. package/dist/src/tools/approval/policies.js +1 -1
  161. package/dist/src/tools/definition.d.ts +6 -3
  162. package/dist/src/tools/definition.js +1 -1
  163. package/dist/src/tools/durable-callbacks.d.ts +8 -2
  164. package/dist/src/tools/durable-callbacks.js +1 -1
  165. package/dist/src/tools/durable-schema.d.ts +16 -0
  166. package/dist/src/tools/durable-schema.js +1 -0
  167. package/dist/src/vue/index.js +1 -1
  168. package/dist/src/vue/use-eve-agent.d.ts +4 -0
  169. package/dist/src/vue/use-eve-agent.js +1 -1
  170. package/docs/agent-config.md +1 -0
  171. package/docs/channels/eve.mdx +20 -10
  172. package/docs/concepts/context-control.md +4 -0
  173. package/docs/concepts/sessions-runs-and-streaming.md +18 -3
  174. package/docs/connections/mcp.mdx +2 -2
  175. package/docs/connections/overview.mdx +1 -1
  176. package/docs/evals/assertions.mdx +6 -6
  177. package/docs/evals/cases.mdx +59 -23
  178. package/docs/evals/judge.mdx +10 -8
  179. package/docs/evals/overview.mdx +6 -6
  180. package/docs/evals/reporters.mdx +1 -1
  181. package/docs/evals/targets.mdx +5 -0
  182. package/docs/guides/client/messages.mdx +5 -5
  183. package/docs/guides/client/overview.mdx +15 -1
  184. package/docs/guides/dynamic-capabilities.md +22 -0
  185. package/docs/guides/evaluate.md +78 -3
  186. package/docs/guides/frontend/overview.mdx +54 -5
  187. package/docs/guides/frontend/use-eve-agent-svelte.mdx +13 -8
  188. package/docs/guides/frontend/use-eve-agent-vue.mdx +13 -8
  189. package/docs/guides/remote-agents.md +2 -1
  190. package/docs/reference/typescript-api.md +38 -37
  191. package/docs/subagents/index.mdx +25 -8
  192. package/docs/tools/human-in-the-loop.md +27 -5
  193. package/docs/tools/overview.mdx +2 -2
  194. package/docs/tools/workflows.mdx +2 -3
  195. package/package.json +2 -3
  196. package/dist/src/compiled/@vercel/sandbox-drives/LICENSE +0 -201
  197. package/dist/src/compiled/@vercel/sandbox-drives/_async-retry.d.ts +0 -8
  198. package/dist/src/compiled/@vercel/sandbox-drives/_workflow-serde.d.ts +0 -5
  199. package/dist/src/compiled/@vercel/sandbox-drives/api-client/api-client.d.ts +0 -1815
  200. package/dist/src/compiled/@vercel/sandbox-drives/api-client/api-error.d.ts +0 -29
  201. package/dist/src/compiled/@vercel/sandbox-drives/api-client/base-client.d.ts +0 -39
  202. package/dist/src/compiled/@vercel/sandbox-drives/api-client/file-writer.d.ts +0 -66
  203. package/dist/src/compiled/@vercel/sandbox-drives/api-client/index.d.ts +0 -2
  204. package/dist/src/compiled/@vercel/sandbox-drives/api-client/validators.d.ts +0 -932
  205. package/dist/src/compiled/@vercel/sandbox-drives/api-client/with-retry.d.ts +0 -10
  206. package/dist/src/compiled/@vercel/sandbox-drives/auth/error.d.ts +0 -15
  207. package/dist/src/compiled/@vercel/sandbox-drives/auth/file.d.ts +0 -18
  208. package/dist/src/compiled/@vercel/sandbox-drives/auth/index.d.ts +0 -6
  209. package/dist/src/compiled/@vercel/sandbox-drives/auth/oauth.d.ts +0 -111
  210. package/dist/src/compiled/@vercel/sandbox-drives/auth/poll-for-token.d.ts +0 -28
  211. package/dist/src/compiled/@vercel/sandbox-drives/auth/project.d.ts +0 -40
  212. package/dist/src/compiled/@vercel/sandbox-drives/command.d.ts +0 -292
  213. package/dist/src/compiled/@vercel/sandbox-drives/constants.d.ts +0 -15
  214. package/dist/src/compiled/@vercel/sandbox-drives/execution-context.d.ts +0 -116
  215. package/dist/src/compiled/@vercel/sandbox-drives/filesystem.d.ts +0 -258
  216. package/dist/src/compiled/@vercel/sandbox-drives/index.d.ts +0 -14
  217. package/dist/src/compiled/@vercel/sandbox-drives/index.js +0 -9
  218. package/dist/src/compiled/@vercel/sandbox-drives/network-policy.d.ts +0 -169
  219. package/dist/src/compiled/@vercel/sandbox-drives/proxy.d.ts +0 -55
  220. package/dist/src/compiled/@vercel/sandbox-drives/sandbox-user.d.ts +0 -211
  221. package/dist/src/compiled/@vercel/sandbox-drives/sandbox.d.ts +0 -1287
  222. package/dist/src/compiled/@vercel/sandbox-drives/session.d.ts +0 -435
  223. package/dist/src/compiled/@vercel/sandbox-drives/snapshot.d.ts +0 -238
  224. package/dist/src/compiled/@vercel/sandbox-drives/utils/get-credentials.d.ts +0 -21
  225. package/dist/src/compiled/@vercel/sandbox-drives/utils/paginator.d.ts +0 -16
  226. package/dist/src/compiled/@vercel/sandbox-drives/utils/resolveSignal.d.ts +0 -15
  227. package/dist/src/compiled/@vercel/sandbox-drives/utils/sandbox-snapshot.d.ts +0 -11
  228. package/dist/src/compiled/@vercel/sandbox-drives/utils/types.d.ts +0 -11
  229. package/dist/src/compiled/_chunks/node/auth-8aQozzfi.js +0 -2
  230. package/dist/src/compiled/_chunks/node/auth-Bvv0xGTY.js +0 -2
  231. package/dist/src/compiled/_chunks/node/esm-Fqlolk7e.js +0 -7
  232. package/dist/src/compiled/_chunks/node/version-BC6t2Txc.js +0 -1
  233. package/dist/src/compiled/_chunks/node/version-DSQqVZ5T.js +0 -1
  234. package/dist/src/compiled/_chunks/node/xdg-app-paths-F-QHrdza.js +0 -1
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const compiledRemoteAgentNodeSchema=z.object({backing:z.object({kind:z.literal(`resource`),sourcePath:z.string()}).strict(),binding:z.object({backing:z.discriminatedUnion(`kind`,[z.object({externalDependencies:z.array(z.string()).readonly(),extensionScope:z.object({namespace:z.string(),sourceRoot:z.string()}).strict().optional(),kind:z.literal(`filesystem`),sourcePath:z.string()}).strict(),z.object({kind:z.literal(`programmatic`),moduleId:z.string(),registryId:z.string(),revision:z.string(),semanticRevision:z.string().optional()}).strict()]),logicalPath:z.string(),owner:z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`application`)}).strict(),z.object({feature:z.string(),kind:z.literal(`framework`)}).strict(),z.object({kind:z.literal(`extension`),namespace:z.string(),packageName:z.string()}).strict()]),usage:z.object({compile:z.boolean(),runtimeEntry:z.boolean()}).strict()}).strict(),description:z.string(),entryPath:z.string(),exportName:z.string().optional(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),owner:z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`application`)}).strict(),z.object({feature:z.string(),kind:z.literal(`framework`)}).strict(),z.object({kind:z.literal(`extension`),namespace:z.string(),packageName:z.string()}).strict()]),parentNodeId:z.string(),outputSchema:jsonObjectSchema.optional(),path:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string().optional()}).strict();export{compiledRemoteAgentNodeSchema};
1
+ import{z}from"#compiled/zod/index.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const compiledRemoteAgentNodeSchema=z.object({backing:z.object({kind:z.literal(`resource`),sourcePath:z.string()}).strict(),binding:z.object({backing:z.discriminatedUnion(`kind`,[z.object({externalDependencies:z.array(z.string()).readonly(),extensionScope:z.object({namespace:z.string(),sourceRoot:z.string()}).strict().optional(),kind:z.literal(`filesystem`),sourcePath:z.string()}).strict(),z.object({kind:z.literal(`programmatic`),moduleId:z.string(),registryId:z.string(),revision:z.string(),semanticRevision:z.string().optional()}).strict()]),logicalPath:z.string(),owner:z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`application`)}).strict(),z.object({feature:z.string(),kind:z.literal(`framework`)}).strict(),z.object({kind:z.literal(`extension`),namespace:z.string(),packageName:z.string()}).strict()]),usage:z.object({compile:z.boolean(),runtimeEntry:z.boolean()}).strict()}).strict(),description:z.string(),entryPath:z.string(),exportName:z.string().optional(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),owner:z.discriminatedUnion(`kind`,[z.object({kind:z.literal(`application`)}).strict(),z.object({feature:z.string(),kind:z.literal(`framework`)}).strict(),z.object({kind:z.literal(`extension`),namespace:z.string(),packageName:z.string()}).strict()]),parentNodeId:z.string(),outputSchema:jsonObjectSchema.optional(),path:z.string(),rootPath:z.string(),tool:z.boolean().optional(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string().optional()}).strict();export{compiledRemoteAgentNodeSchema};
@@ -144,6 +144,7 @@ export declare function instantiateProgrammaticTemplate(input: {
144
144
  }): AgentModuleCandidate;
145
145
  export declare function composeAgentModuleCandidates(candidates: readonly AgentSourceCandidate[]): ComposedAgentModuleCandidates;
146
146
  export declare function disableComposedCandidate(input: {
147
+ readonly allowUnmatched?: boolean;
147
148
  readonly candidate: AgentSourceCandidate;
148
149
  readonly composed: ComposedAgentModuleCandidates;
149
150
  }): ComposedAgentModuleCandidates;
@@ -1 +1 @@
1
- import{isAbsolute,posix}from"node:path";import{getSupportedModuleBaseName,normalizeLogicalPath,stripLogicalPathExtension}from"#discover/filesystem.js";import{parseJsonObject}from"#shared/json.js";function memoizeModuleNamespaceFactories(e){return Object.freeze(Object.fromEntries(Object.entries(e).map(([e,t])=>{if(typeof t!=`function`)return[e,t];let n;return[e,new Proxy(t,{apply(e,t,r){return r.length>0?Reflect.apply(e,t,r):(n??=Promise.resolve().then(()=>Reflect.apply(e,t,r)),n)}})]})))}var ImmutableProgrammaticSourceMap=class{#e;constructor(e){this.#e=new Map(e),Object.freeze(this)}get size(){return this.#e.size}get[Symbol.toStringTag](){return`ImmutableProgrammaticSourceMap`}[Symbol.iterator](){return this.#e[Symbol.iterator]()}entries(){return this.#e.entries()}forEach(e,t){this.#e.forEach((n,r)=>e.call(t,n,r,this))}get(e){return this.#e.get(e)}has(e){return this.#e.has(e)}keys(){return this.#e.keys()}values(){return this.#e.values()}};function isAgentModuleCandidate(e){return e.backing.kind!==`resource`}const LAYER_PRECEDENCE={"framework-default":0,"extension-package":1,"extension-override":2,application:3},FORM_PRECEDENCE={derived:0,direct:1},registeredProgrammaticTemplates=new WeakSet;function defineProgrammaticAgentSource(e){let t=expectNonEmpty(e.id,`Programmatic agent source id`),n=expectNonEmpty(e.revision,`Programmatic agent source "${t}" revision`),r=new Set,i=e.modules.map(e=>{let n=validateProgrammaticLogicalPath(e.logicalPath);if(r.has(n))throw Error(`Programmatic agent source "${t}" declares "${n}" more than once.`);r.add(n);let i=e.semanticRevision===void 0?void 0:expectNonEmpty(e.semanticRevision,`Programmatic module "${t}:${n}" semanticRevision`);return Object.freeze({exportName:e.exportName,loadNamespace:e.loadNamespace,logicalPath:n,semanticRevision:i})});return Object.freeze({id:t,modules:Object.freeze(i),revision:n})}function createAgentSourceRegistry(e,t={}){let n=new Map,r=new Map,addSource=e=>{let t=defineProgrammaticAgentSource(e);if(n.has(t.id))throw Error(`Programmatic agent source id "${t.id}" is registered more than once.`);return n.set(t.id,t),t},i=e.map(e=>{let t=addSource(e.source);return Object.freeze({applyTo:e.applyTo,source:t})});for(let e of t.templates??[]){let t=addSource(e);if(t.modules.length!==1)throw Error(`Programmatic template source "${t.id}" must register exactly one module.`);let n=Object.freeze({module:t.modules[0],source:t});registeredProgrammaticTemplates.add(n),r.set(t.id,n)}return Object.freeze({registrations:Object.freeze(i),sources:new ImmutableProgrammaticSourceMap(n),templates:new ImmutableProgrammaticSourceMap(r)})}function createProgrammaticModuleCandidates(e){return e.registration.source.modules.map(t=>{let n=`${e.registration.source.id}:${t.logicalPath}`;return Object.freeze({backing:Object.freeze({kind:`programmatic`,moduleId:t.logicalPath,registryId:e.registration.source.id,revision:e.registration.source.revision,semanticRevision:t.semanticRevision}),exportName:t.exportName,form:`direct`,layer:e.layer,logicalPath:t.logicalPath,nodeId:e.nodeId,owner:e.owner,sourceId:n})})}function instantiateProgrammaticTemplate(e){if(!registeredProgrammaticTemplates.has(e.template))throw Error(`Derived programmatic modules require a registered template.`);let t=validateProgrammaticLogicalPath(e.logicalPath),n=expectNonEmpty(e.anchor.sourceId,`Derived programmatic module anchor source id`),r=`${e.template.source.id}:${t}:from:${n}`;if(!Object.values(e.dependencies).some(e=>e.sourceId===n))throw Error(`Derived programmatic module "${r}" must include its anchor source as a dependency.`);let i=Object.freeze(Object.fromEntries(Object.entries(e.dependencies).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>{if(expectNonEmpty(t,`Derived programmatic module dependency alias`),n.nodeId!==e.anchor.nodeId)throw Error(`Derived programmatic module "${r}" cannot depend on source "${n.sourceId}" from another node.`);return[t,n.sourceId]}))),a=Object.freeze(parseJsonObject(e.parameters??{}));return Object.freeze({backing:Object.freeze({dependencies:i,kind:`programmatic`,moduleId:e.template.module.logicalPath,parameters:a,registryId:e.template.source.id,revision:e.template.source.revision,semanticRevision:e.template.module.semanticRevision}),exportName:e.template.module.exportName,form:`derived`,layer:e.anchor.layer,logicalPath:t,nodeId:e.anchor.nodeId,owner:e.owner,sourceId:r})}function composeAgentModuleCandidates(e){let t=new Map,n=new Set;for(let r of e){if(n.has(r.sourceId))throw Error(`Agent source id "${r.sourceId}" is declared more than once in node "${r.nodeId}".`);n.add(r.sourceId);let e=canonicalSourceSlot(r.logicalPath),i=t.get(e)??[];i.push(r),t.set(e,i)}let r=new Map,i=[];for(let[e,n]of[...t].sort(([e],[t])=>e.localeCompare(t))){let t=new Set;for(let r of n){let n=`${r.layer}:${r.form}`;if(t.has(n))throw Error(`Agent source slot "${e}" has more than one ${r.layer} ${r.form} candidate.`);t.add(n)}let a=[...n].sort((e,t)=>LAYER_PRECEDENCE[t.layer]-LAYER_PRECEDENCE[e.layer]||FORM_PRECEDENCE[t.form]-FORM_PRECEDENCE[e.form]),o=a[0];r.set(e,o);for(let e of a.slice(1))i.push({kind:`shadowed`,source:describeAgentSourceCandidate(e),winnerSourceId:o.sourceId})}return validateSelectedCandidateDependencies(r),{composition:{entries:Object.freeze(i)},selected:r}}function disableComposedCandidate(e){let t=canonicalSourceSlot(e.candidate.logicalPath),n=new Map(e.composed.selected);if(n.get(t)?.sourceId!==e.candidate.sourceId)throw Error(`Only the selected source for "${t}" can disable that slot.`);if(!e.composed.composition.entries.some(t=>t.kind===`shadowed`&&t.winnerSourceId===e.candidate.sourceId))throw Error(`Source "${e.candidate.logicalPath}" disables a slot with no lower-precedence source.`);return n.delete(t),{composition:{entries:Object.freeze([...e.composed.composition.entries,{kind:`disabled`,source:describeAgentSourceCandidate(e.candidate)}])},selected:n}}function createAgentModuleBinding(e){return Object.freeze({backing:e.backing,logicalPath:e.logicalPath,owner:e.owner})}async function loadProgrammaticModuleNamespace(e){let t=e.registries.map(t=>t.sources.get(e.backing.registryId)).filter(e=>e!==void 0);if(t.length!==1)throw Error(`Expected exactly one registered programmatic source "${e.backing.registryId}", found ${t.length}.`);let n=t[0];if(n.revision!==e.backing.revision)throw Error(`Programmatic source "${n.id}" revision mismatch: artifact requires "${e.backing.revision}", registry provides "${n.revision}".`);let r=n.modules.find(t=>t.logicalPath===e.backing.moduleId);if(r===void 0)throw Error(`Programmatic source "${n.id}" does not register module "${e.backing.moduleId}".`);if(r.semanticRevision!==e.backing.semanticRevision)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" semantic revision does not match the compiled binding.`);let i=Object.fromEntries(Object.entries(e.backing.dependencies??{}).map(([t,i])=>{let a=e.dependencyNamespaces?.[t];if(a===void 0)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" requires unresolved binding "${i}" as dependency "${t}".`);return[t,a]})),a=await r.loadNamespace({dependencies:Object.freeze(i),parameters:Object.freeze(e.backing.parameters??{})});if(typeof a!=`object`||!a)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" loader must return a module namespace object.`);return a}function canonicalModuleSlot(e){return validateProgrammaticLogicalPath(e),canonicalSourceSlot(e)}function canonicalSourceSlot(e){let t=normalizeLogicalPath(e);if(t.length===0||t===`.`||t.startsWith(`../`)||t.includes(`/../`)||posix.normalize(t)!==t)throw Error(`Agent source logical path "${e}" is invalid.`);let n=stripLogicalPathExtension(t),r=n.match(/^connections\/([^/]+)\/connection$/);if(r!==null)return`connections/${r[1]}`;if(n===`sandbox/sandbox`)return`sandbox`;let i=n.match(/^skills\/([^/]+)\/SKILL$/);return i===null?n:`skills/${i[1]}`}function validateProgrammaticLogicalPath(e){if(e.length===0||isAbsolute(e)||e.includes(`\\`))throw Error(`Programmatic module logical path "${e}" must be a relative POSIX path.`);let t=normalizeLogicalPath(e);if(t===`.`||t.startsWith(`../`)||t.includes(`/../`)||posix.normalize(t)!==t)throw Error(`Programmatic module logical path "${e}" may not traverse directories.`);let n=t.split(`/`),r=n.at(-1);if(getSupportedModuleBaseName(r)===null)throw Error(`Programmatic module logical path "${e}" must use a supported JavaScript or TypeScript extension.`);let i=n[0],a=stripLogicalPathExtension(t);if(!(n.length===1&&[`agent`,`memory`,`sandbox`,`instrumentation`].includes(a)||i===`sandbox`&&n.length===2&&getSupportedModuleBaseName(r)===`sandbox`||[`channels`,`connections`,`hooks`,`instructions`,`memory`,`schedules`,`skills`,`tools`].includes(i)&&n.length>=2))throw Error(`Programmatic module logical path "${e}" does not select an eve module slot.`);return t}function describeAgentSourceCandidate(e){return Object.freeze({backing:e.backing,form:e.form,layer:e.layer,logicalPath:e.logicalPath,owner:e.owner,sourceId:e.sourceId})}function validateSelectedCandidateDependencies(e){let t=new Set([...e.values()].map(e=>e.sourceId));for(let n of e.values())if(n.backing.kind===`programmatic`){for(let e of Object.values(n.backing.dependencies??{}))if(!t.has(e))throw Error(`Derived programmatic source "${n.sourceId}" depends on unselected source "${e}".`)}}function expectNonEmpty(e,t){if(e.trim().length===0)throw Error(`${t} must be non-empty.`);return e}export{canonicalModuleSlot,canonicalSourceSlot,composeAgentModuleCandidates,createAgentModuleBinding,createAgentSourceRegistry,createProgrammaticModuleCandidates,defineProgrammaticAgentSource,describeAgentSourceCandidate,disableComposedCandidate,instantiateProgrammaticTemplate,isAgentModuleCandidate,loadProgrammaticModuleNamespace,memoizeModuleNamespaceFactories,validateProgrammaticLogicalPath};
1
+ import{isAbsolute,posix}from"node:path";import{getSupportedModuleBaseName,normalizeLogicalPath,stripLogicalPathExtension}from"#discover/filesystem.js";import{parseJsonObject}from"#shared/json.js";function memoizeModuleNamespaceFactories(e){return Object.freeze(Object.fromEntries(Object.entries(e).map(([e,t])=>{if(typeof t!=`function`)return[e,t];let n;return[e,new Proxy(t,{apply(e,t,r){return r.length>0?Reflect.apply(e,t,r):(n??=Promise.resolve().then(()=>Reflect.apply(e,t,r)),n)}})]})))}var ImmutableProgrammaticSourceMap=class{#e;constructor(e){this.#e=new Map(e),Object.freeze(this)}get size(){return this.#e.size}get[Symbol.toStringTag](){return`ImmutableProgrammaticSourceMap`}[Symbol.iterator](){return this.#e[Symbol.iterator]()}entries(){return this.#e.entries()}forEach(e,t){this.#e.forEach((n,r)=>e.call(t,n,r,this))}get(e){return this.#e.get(e)}has(e){return this.#e.has(e)}keys(){return this.#e.keys()}values(){return this.#e.values()}};function isAgentModuleCandidate(e){return e.backing.kind!==`resource`}const LAYER_PRECEDENCE={"framework-default":0,"extension-package":1,"extension-override":2,application:3},FORM_PRECEDENCE={derived:0,direct:1},registeredProgrammaticTemplates=new WeakSet;function defineProgrammaticAgentSource(e){let t=expectNonEmpty(e.id,`Programmatic agent source id`),n=expectNonEmpty(e.revision,`Programmatic agent source "${t}" revision`),r=new Set,i=e.modules.map(e=>{let n=validateProgrammaticLogicalPath(e.logicalPath);if(r.has(n))throw Error(`Programmatic agent source "${t}" declares "${n}" more than once.`);r.add(n);let i=e.semanticRevision===void 0?void 0:expectNonEmpty(e.semanticRevision,`Programmatic module "${t}:${n}" semanticRevision`);return Object.freeze({exportName:e.exportName,loadNamespace:e.loadNamespace,logicalPath:n,semanticRevision:i})});return Object.freeze({id:t,modules:Object.freeze(i),revision:n})}function createAgentSourceRegistry(e,t={}){let n=new Map,r=new Map,addSource=e=>{let t=defineProgrammaticAgentSource(e);if(n.has(t.id))throw Error(`Programmatic agent source id "${t.id}" is registered more than once.`);return n.set(t.id,t),t},i=e.map(e=>{let t=addSource(e.source);return Object.freeze({applyTo:e.applyTo,source:t})});for(let e of t.templates??[]){let t=addSource(e);if(t.modules.length!==1)throw Error(`Programmatic template source "${t.id}" must register exactly one module.`);let n=Object.freeze({module:t.modules[0],source:t});registeredProgrammaticTemplates.add(n),r.set(t.id,n)}return Object.freeze({registrations:Object.freeze(i),sources:new ImmutableProgrammaticSourceMap(n),templates:new ImmutableProgrammaticSourceMap(r)})}function createProgrammaticModuleCandidates(e){return e.registration.source.modules.map(t=>{let n=`${e.registration.source.id}:${t.logicalPath}`;return Object.freeze({backing:Object.freeze({kind:`programmatic`,moduleId:t.logicalPath,registryId:e.registration.source.id,revision:e.registration.source.revision,semanticRevision:t.semanticRevision}),exportName:t.exportName,form:`direct`,layer:e.layer,logicalPath:t.logicalPath,nodeId:e.nodeId,owner:e.owner,sourceId:n})})}function instantiateProgrammaticTemplate(e){if(!registeredProgrammaticTemplates.has(e.template))throw Error(`Derived programmatic modules require a registered template.`);let t=validateProgrammaticLogicalPath(e.logicalPath),n=expectNonEmpty(e.anchor.sourceId,`Derived programmatic module anchor source id`),r=`${e.template.source.id}:${t}:from:${n}`;if(!Object.values(e.dependencies).some(e=>e.sourceId===n))throw Error(`Derived programmatic module "${r}" must include its anchor source as a dependency.`);let i=Object.freeze(Object.fromEntries(Object.entries(e.dependencies).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>{if(expectNonEmpty(t,`Derived programmatic module dependency alias`),n.nodeId!==e.anchor.nodeId)throw Error(`Derived programmatic module "${r}" cannot depend on source "${n.sourceId}" from another node.`);return[t,n.sourceId]}))),a=Object.freeze(parseJsonObject(e.parameters??{}));return Object.freeze({backing:Object.freeze({dependencies:i,kind:`programmatic`,moduleId:e.template.module.logicalPath,parameters:a,registryId:e.template.source.id,revision:e.template.source.revision,semanticRevision:e.template.module.semanticRevision}),exportName:e.template.module.exportName,form:`derived`,layer:e.anchor.layer,logicalPath:t,nodeId:e.anchor.nodeId,owner:e.owner,sourceId:r})}function composeAgentModuleCandidates(e){let t=new Map,n=new Set;for(let r of e){if(n.has(r.sourceId))throw Error(`Agent source id "${r.sourceId}" is declared more than once in node "${r.nodeId}".`);n.add(r.sourceId);let e=canonicalSourceSlot(r.logicalPath),i=t.get(e)??[];i.push(r),t.set(e,i)}let r=new Map,i=[];for(let[e,n]of[...t].sort(([e],[t])=>e.localeCompare(t))){let t=new Set;for(let r of n){let n=`${r.layer}:${r.form}`;if(t.has(n))throw Error(`Agent source slot "${e}" has more than one ${r.layer} ${r.form} candidate.`);t.add(n)}let a=[...n].sort((e,t)=>LAYER_PRECEDENCE[t.layer]-LAYER_PRECEDENCE[e.layer]||FORM_PRECEDENCE[t.form]-FORM_PRECEDENCE[e.form]),o=a[0];r.set(e,o);for(let e of a.slice(1))i.push({kind:`shadowed`,source:describeAgentSourceCandidate(e),winnerSourceId:o.sourceId})}return validateSelectedCandidateDependencies(r),{composition:{entries:Object.freeze(i)},selected:r}}function disableComposedCandidate(e){let t=canonicalSourceSlot(e.candidate.logicalPath),n=new Map(e.composed.selected);if(n.get(t)?.sourceId!==e.candidate.sourceId)throw Error(`Only the selected source for "${t}" can disable that slot.`);if(!e.composed.composition.entries.some(t=>t.kind===`shadowed`&&t.winnerSourceId===e.candidate.sourceId)&&e.allowUnmatched!==!0)throw Error(`Source "${e.candidate.logicalPath}" disables a slot with no lower-precedence source.`);return n.delete(t),{composition:{entries:Object.freeze([...e.composed.composition.entries,{kind:`disabled`,source:describeAgentSourceCandidate(e.candidate)}])},selected:n}}function createAgentModuleBinding(e){return Object.freeze({backing:e.backing,logicalPath:e.logicalPath,owner:e.owner})}async function loadProgrammaticModuleNamespace(e){let t=e.registries.map(t=>t.sources.get(e.backing.registryId)).filter(e=>e!==void 0);if(t.length!==1)throw Error(`Expected exactly one registered programmatic source "${e.backing.registryId}", found ${t.length}.`);let n=t[0];if(n.revision!==e.backing.revision)throw Error(`Programmatic source "${n.id}" revision mismatch: artifact requires "${e.backing.revision}", registry provides "${n.revision}".`);let r=n.modules.find(t=>t.logicalPath===e.backing.moduleId);if(r===void 0)throw Error(`Programmatic source "${n.id}" does not register module "${e.backing.moduleId}".`);if(r.semanticRevision!==e.backing.semanticRevision)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" semantic revision does not match the compiled binding.`);let i=Object.fromEntries(Object.entries(e.backing.dependencies??{}).map(([t,i])=>{let a=e.dependencyNamespaces?.[t];if(a===void 0)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" requires unresolved binding "${i}" as dependency "${t}".`);return[t,a]})),a=await r.loadNamespace({dependencies:Object.freeze(i),parameters:Object.freeze(e.backing.parameters??{})});if(typeof a!=`object`||!a)throw Error(`Programmatic module "${n.id}:${r.logicalPath}" loader must return a module namespace object.`);return a}function canonicalModuleSlot(e){return validateProgrammaticLogicalPath(e),canonicalSourceSlot(e)}function canonicalSourceSlot(e){let t=normalizeLogicalPath(e);if(t.length===0||t===`.`||t.startsWith(`../`)||t.includes(`/../`)||posix.normalize(t)!==t)throw Error(`Agent source logical path "${e}" is invalid.`);let n=stripLogicalPathExtension(t),r=n.match(/^connections\/([^/]+)\/connection$/);if(r!==null)return`connections/${r[1]}`;if(n===`sandbox/sandbox`)return`sandbox`;let i=n.match(/^skills\/([^/]+)\/SKILL$/);return i===null?n:`skills/${i[1]}`}function validateProgrammaticLogicalPath(e){if(e.length===0||isAbsolute(e)||e.includes(`\\`))throw Error(`Programmatic module logical path "${e}" must be a relative POSIX path.`);let t=normalizeLogicalPath(e);if(t===`.`||t.startsWith(`../`)||t.includes(`/../`)||posix.normalize(t)!==t)throw Error(`Programmatic module logical path "${e}" may not traverse directories.`);let n=t.split(`/`),r=n.at(-1);if(getSupportedModuleBaseName(r)===null)throw Error(`Programmatic module logical path "${e}" must use a supported JavaScript or TypeScript extension.`);let i=n[0],a=stripLogicalPathExtension(t);if(!(n.length===1&&[`agent`,`memory`,`sandbox`,`instrumentation`].includes(a)||i===`sandbox`&&n.length===2&&getSupportedModuleBaseName(r)===`sandbox`||[`channels`,`connections`,`hooks`,`instructions`,`memory`,`schedules`,`skills`,`tools`].includes(i)&&n.length>=2))throw Error(`Programmatic module logical path "${e}" does not select an eve module slot.`);return t}function describeAgentSourceCandidate(e){return Object.freeze({backing:e.backing,form:e.form,layer:e.layer,logicalPath:e.logicalPath,owner:e.owner,sourceId:e.sourceId})}function validateSelectedCandidateDependencies(e){let t=new Set([...e.values()].map(e=>e.sourceId));for(let n of e.values())if(n.backing.kind===`programmatic`){for(let e of Object.values(n.backing.dependencies??{}))if(!t.has(e))throw Error(`Derived programmatic source "${n.sourceId}" depends on unselected source "${e}".`)}}function expectNonEmpty(e,t){if(e.trim().length===0)throw Error(`${t} must be non-empty.`);return e}export{canonicalModuleSlot,canonicalSourceSlot,composeAgentModuleCandidates,createAgentModuleBinding,createAgentSourceRegistry,createProgrammaticModuleCandidates,defineProgrammaticAgentSource,describeAgentSourceCandidate,disableComposedCandidate,instantiateProgrammaticTemplate,isAgentModuleCandidate,loadProgrammaticModuleNamespace,memoizeModuleNamespaceFactories,validateProgrammaticLogicalPath};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{SessionDynamicToolMetadataKey,SessionIdKey,StepDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toInputSchema,toOutputSchema}from"#tools/schema.js";import{isCurrentDynamicToolMetadata}from"#context/dynamic-tool-metadata.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";import{callDurableDynamicCallback,lookupDurableDynamicCallback}from"#tools/durable-callbacks.js";const log=createLogger(`dynamic-tools`);function missingCallbackError(e,t){return Error(`Dynamic tool "${e.name}" cannot replay its ${t} callback because it is not registered in this process. The tool was removed or renamed since this call was parked, or its resolver did not run. Restore the tool definition or start a new session.`)}function buildReplayedApproval(e,t){let n=e.callbacks.approvalRequest;if(n===void 0)return;let r=lookupDurableDynamicCallback(t,`approvalRequest`),i=r===void 0?async()=>(log.error(missingCallbackError(e,`approvalRequest`).message),`user-approval`):async e=>await callDurableDynamicCallback(r,n.closure,e),a=e.callbacks.approvalResponse;if(a===void 0)return i;let o=lookupDurableDynamicCallback(t,`approvalResponse`);return{request:i,response:o===void 0?async()=>{let t=missingCallbackError(e,`approvalResponse`);return log.error(t.message),{reason:t.message,status:`rejected`}}:async e=>await callDurableDynamicCallback(o,a.closure,e)}}function replayDynamicTools(e,t){if(e.length>0&&t.sessionId.length===0)throw Error(`Dynamic tool replay requires a session id.`);return e.map(e=>{let n={...e,...t},r=e.callbacks.approvalKey,i=r===void 0?void 0:lookupDurableDynamicCallback(n,`approvalKey`),a=e.callbacks.execute,o=lookupDurableDynamicCallback(n,`execute`),s=bindDynamicCallback(e,n,`labelComplete`,e.callbacks.label?.complete),c=bindDynamicCallback(e,n,`labelDelta`,e.callbacks.label?.delta),l=bindDynamicCallback(e,n,`labelStart`,e.callbacks.label?.start),u=bindDynamicCallback(e,n,`toModelOutput`,e.callbacks.toModelOutput),d={description:e.description,execute:e.execution===`background`?createToolExecuteWithAuth({execution:`background`,scope:e.name,execute:(t,n,r)=>{if(o===void 0)throw missingCallbackError(e,`execute`);return callDurableDynamicCallback(o,a.closure,t,n,r)}}):createToolExecuteWithAuth({scope:e.name,execute:(t,n)=>{if(o===void 0)throw missingCallbackError(e,`execute`);return callDurableDynamicCallback(o,a.closure,t,n)}}),inputSchema:toInputSchema(e.inputSchema),name:e.name,execution:e.execution,approval:buildReplayedApproval(e,n),...r===void 0?{}:{approvalKey:t=>{if(i===void 0)throw missingCallbackError(e,`approvalKey`);let n=callDurableDynamicCallback(i,r.closure,t);if(typeof n!=`string`)throw Error(`Dynamic tool "${e.name}" approvalKey callback must return a string.`);return n}},outputSchema:toOutputSchema(e.outputSchema)};return(s!==void 0||c!==void 0||l!==void 0)&&(d.label={complete:s,delta:c,start:l}),u!==void 0&&(d.toModelOutput=u),d})}function bindDynamicCallback(e,t,n,r){if(r===void 0)return;let i=lookupDurableDynamicCallback(t,n);return(...t)=>{if(i===void 0)throw missingCallbackError(e,n);return callDurableDynamicCallback(i,r.closure,...t)}}function requireCurrentDynamicToolMetadata(e){let t=e.find(e=>!isCurrentDynamicToolMetadata(e));if(t!==void 0)throw Error(`Dynamic tool "${t.name}" reached replay before its persisted metadata was converted to the current schema.`);return e}function buildResponseAuthorizationTools(e){let t=new Map;for(let n of e.context===void 0?[]:buildDynamicTools(e.context))t.has(n.name)||t.set(n.name,n);for(let[n,r]of e.authoredTools)t.has(n)||t.set(n,r);return t}function buildDynamicTools(e){let t=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(StepDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`step`}),n=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(TurnDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`turn`}),r=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(SessionDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`session`});return[...t,...n,...r]}export{buildDynamicTools,buildResponseAuthorizationTools,replayDynamicTools};
1
+ import{createLogger}from"#internal/logging.js";import{SessionDynamicToolMetadataKey,SessionIdKey,StepDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toInputSchema,toOutputSchema}from"#tools/schema.js";import{isCurrentDynamicToolMetadata}from"#context/dynamic-tool-metadata.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";import{callDurableDynamicCallback,lookupDurableDynamicCallback}from"#tools/durable-callbacks.js";import{hasSchemaValidator}from"#tools/durable-schema.js";const log=createLogger(`dynamic-tools`);function missingCallbackError(e,t){return Error(`Dynamic tool "${e.name}" cannot replay its ${t} callback because it is not registered in this process. The tool was removed or renamed since this call was parked, or its resolver did not run. Restore the tool definition or start a new session.`)}function buildReplayedApproval(e,t){let n=e.callbacks.approvalRequest;if(n===void 0)return;let r=lookupDurableDynamicCallback(t,`approvalRequest`),i=r===void 0?async()=>(log.error(missingCallbackError(e,`approvalRequest`).message),`user-approval`):async e=>await callDurableDynamicCallback(r,n.closure,e),a=e.callbacks.approvalResponse;if(a===void 0)return i;let o=lookupDurableDynamicCallback(t,`approvalResponse`);return{request:i,response:o===void 0?async()=>{let t=missingCallbackError(e,`approvalResponse`);return log.error(t.message),{reason:t.message,status:`rejected`}}:async e=>await callDurableDynamicCallback(o,a.closure,e)}}function replayDynamicTools(e,t){if(e.length>0&&t.sessionId.length===0)throw Error(`Dynamic tool replay requires a session id.`);return e.map(e=>{let n={...e,...t},r=e.callbacks.approvalKey,i=r===void 0?void 0:lookupDurableDynamicCallback(n,`approvalKey`),a=e.callbacks.execute,o=lookupDurableDynamicCallback(n,`execute`),s=bindDynamicCallback(e,n,`labelComplete`,e.callbacks.label?.complete),c=bindDynamicCallback(e,n,`labelDelta`,e.callbacks.label?.delta),l=bindDynamicCallback(e,n,`labelStart`,e.callbacks.label?.start),u=bindDynamicCallback(e,n,`toModelOutput`,e.callbacks.toModelOutput),d={description:e.description,execute:e.execution===`background`?createToolExecuteWithAuth({execution:`background`,scope:e.name,execute:(t,n,r)=>{if(o===void 0)throw missingCallbackError(e,`execute`);return callDurableDynamicCallback(o,a.closure,t,n,r)}}):createToolExecuteWithAuth({scope:e.name,execute:(t,n)=>{if(o===void 0)throw missingCallbackError(e,`execute`);return callDurableDynamicCallback(o,a.closure,t,n)}}),inputSchema:replayDynamicToolSchema(e,n,`inputSchema`),name:e.name,execution:e.execution,approval:buildReplayedApproval(e,n),...r===void 0?{}:{approvalKey:t=>{if(i===void 0)throw missingCallbackError(e,`approvalKey`);let n=callDurableDynamicCallback(i,r.closure,t);if(typeof n!=`string`)throw Error(`Dynamic tool "${e.name}" approvalKey callback must return a string.`);return n}},outputSchema:replayDynamicToolSchema(e,n,`outputSchema`)};return(s!==void 0||c!==void 0||l!==void 0)&&(d.label={complete:s,delta:c,start:l}),u!==void 0&&(d.toModelOutput=u),d})}function replayDynamicToolSchema(e,t,n){let r=e[n];if(r===void 0)return;let i=e.callbacks[n];if(i===void 0)return n===`inputSchema`?toInputSchema(r):toOutputSchema(r);let a=lookupDurableDynamicCallback(t,n),o;return{"~standard":{version:1,vendor:`eve`,jsonSchema:{input:()=>structuredClone(r),output:()=>structuredClone(r)},validate:async t=>{if(a===void 0)throw missingCallbackError(e,n);return o??=Promise.resolve(callDurableDynamicCallback(a,i.closure)).then(t=>{if(hasSchemaValidator(t))return t;if(typeof t!=`object`||!t)throw Error(`Dynamic tool "${e.name}" ${n} factory did not return a schema.`);return n===`inputSchema`?toInputSchema(t):toOutputSchema(t)}),(await o)[`~standard`].validate(t)}}}}function bindDynamicCallback(e,t,n,r){if(r===void 0)return;let i=lookupDurableDynamicCallback(t,n);return(...t)=>{if(i===void 0)throw missingCallbackError(e,n);return callDurableDynamicCallback(i,r.closure,...t)}}function requireCurrentDynamicToolMetadata(e){let t=e.find(e=>!isCurrentDynamicToolMetadata(e));if(t!==void 0)throw Error(`Dynamic tool "${t.name}" reached replay before its persisted metadata was converted to the current schema.`);return e}function buildResponseAuthorizationTools(e){let t=new Map;for(let n of e.context===void 0?[]:buildDynamicTools(e.context))t.has(n.name)||t.set(n.name,n);for(let[n,r]of e.authoredTools)t.has(n)||t.set(n,r);return t}function buildDynamicTools(e){let t=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(StepDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`step`}),n=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(TurnDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`turn`}),r=replayDynamicTools(requireCurrentDynamicToolMetadata(e.get(SessionDynamicToolMetadataKey)??[]),{sessionId:e.get(SessionIdKey)??``,scope:`session`});return[...t,...n,...r]}export{buildDynamicTools,buildResponseAuthorizationTools,replayDynamicTools};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicSubagentSelectionsKey,TurnDynamicSubagentSelectionsKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{createPreparedWorkflowToolHarnessDefinition}from"#execution/tools/workflow/background.js";import{createPreparedRuntimeSubagentTool}from"#runtime/subagents/registry.js";import{normalizeDynamicSubagentAgentConfig}from"#runtime/subagents/dynamic-agent-config.js";import{normalizeDynamicRemoteAgentConfig}from"#runtime/subagents/dynamic-remote-agent-config.js";const log=createLogger(`dynamic-subagents`),ALLOWED_DYNAMIC_SUBAGENT_EVENTS=new Set([`session.started`,`turn.started`]);async function resolveSelections(e){let t=await Promise.allSettled(e.resolvers.map(async t=>{let n=t.events[e.event.type];if(n===void 0)return[t.nodeId,null];let r=await n(e.event,buildResolveContext(e.ctx,e.messages));if(r==null)return[t.nodeId,null];if(isRemoteAgentDefinition(r)){let e=await normalizeDynamicRemoteAgentConfig({name:t.name,value:r}),n=createPreparedRuntimeSubagentTool({description:e.description,kind:`remote`,logicalPath:t.logicalPath,name:t.name,nodeId:t.nodeId,outputSchema:e.outputSchema,path:e.path,sourceId:t.sourceId,sourceKind:t.sourceKind,url:e.url});return[t.nodeId,{kind:`remote`,prepared:n,remoteAgent:e}]}let i=await normalizeDynamicSubagentAgentConfig({name:t.name,state:e.ctx,value:r}),a=createPreparedRuntimeSubagentTool({description:i.description,kind:`subagent`,logicalPath:t.logicalPath,name:t.name,nodeId:t.nodeId,sourceId:t.sourceId,sourceKind:t.sourceKind});return[t.nodeId,{agentConfig:i,kind:`subagent`,prepared:a}]})),n={};for(let r=0;r<t.length;r+=1){let i=t[r],a=e.resolvers[r];if(i.status===`rejected`){log.error(`Dynamic subagent resolver (${e.event.type}) threw — omitting subagent.`,{error:toErrorMessage(i.reason),subagentName:a.name}),n[a.nodeId]=null;continue}n[i.value[0]]=i.value[1]}return n}function isRemoteAgentDefinition(e){return typeof e==`object`&&!!e&&e.kind===`remote`}async function dispatchDynamicSubagentEvent(e){if(!ALLOWED_DYNAMIC_SUBAGENT_EVENTS.has(e.event.type))return;let t=e.resolvers.filter(t=>t.eventNames.includes(e.event.type)),n=await resolveSelections({...e,resolvers:t});e.event.type===`session.started`?e.ctx.set(SessionDynamicSubagentSelectionsKey,n):e.ctx.set(TurnDynamicSubagentSelectionsKey,n)}async function refreshDynamicSessionSubagentsForRuntimeRevision(e){if(e.ctx.get(SessionDynamicSubagentRuntimeRevisionKey)===e.runtimeRevision)return;let t=e.resolvers.filter(e=>e.eventNames.includes(`session.started`)),n=await resolveSelections({...e,resolvers:t});e.ctx.set(SessionDynamicSubagentSelectionsKey,n),e.ctx.set(SessionDynamicSubagentRuntimeRevisionKey,e.runtimeRevision)}function buildDynamicSubagentTools(e){let t=e.get(SessionDynamicSubagentSelectionsKey)??{},n=e.get(TurnDynamicSubagentSelectionsKey)??{},r={...t,...n},i=[],a=new Set;for(let e of Object.values(r))if(e!==null){if(a.has(e.prepared.name))throw Error(`Found multiple active dynamic subagents named "${e.prepared.name}". Subagent names must be unique at runtime.`);a.add(e.prepared.name),i.push(createPreparedWorkflowToolHarnessDefinition(e.prepared))}return i}function getDynamicSubagentSelection(e,t){let n=e.get(TurnDynamicSubagentSelectionsKey)??{};return Object.hasOwn(n,t)?n[t]??void 0:(e.get(SessionDynamicSubagentSelectionsKey)??{})[t]??void 0}export{buildDynamicSubagentTools,dispatchDynamicSubagentEvent,getDynamicSubagentSelection,refreshDynamicSessionSubagentsForRuntimeRevision};
1
+ import{createLogger}from"#internal/logging.js";import{SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicSubagentSelectionsKey,TurnDynamicSubagentSelectionsKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{createPreparedWorkflowToolHarnessDefinition}from"#execution/tools/workflow/background.js";import{createPreparedRuntimeSubagentTool}from"#runtime/subagents/registry.js";import{normalizeDynamicSubagentAgentConfig}from"#runtime/subagents/dynamic-agent-config.js";import{normalizeDynamicRemoteAgentConfig}from"#runtime/subagents/dynamic-remote-agent-config.js";const log=createLogger(`dynamic-subagents`),ALLOWED_DYNAMIC_SUBAGENT_EVENTS=new Set([`session.started`,`turn.started`]);async function resolveSelections(e){let t=await Promise.allSettled(e.resolvers.map(async t=>{let n=t.events[e.event.type];if(n===void 0)return[t.nodeId,null];let r=await n(e.event,buildResolveContext(e.ctx,e.messages));if(r==null)return[t.nodeId,null];if(isRemoteAgentDefinition(r)){let e=await normalizeDynamicRemoteAgentConfig({name:t.name,value:r}),n=t.tool===!1?{...e,tool:!1}:e,i=createPreparedRuntimeSubagentTool({description:n.description,kind:`remote`,logicalPath:t.logicalPath,name:t.name,nodeId:t.nodeId,outputSchema:n.outputSchema,path:n.path,sourceId:t.sourceId,sourceKind:t.sourceKind,tool:n.tool,url:n.url});return[t.nodeId,{kind:`remote`,prepared:i,remoteAgent:n}]}let i=await normalizeDynamicSubagentAgentConfig({name:t.name,state:e.ctx,value:r}),a=t.tool===!1?{...i,tool:!1}:i,o=createPreparedRuntimeSubagentTool({description:a.description,kind:`subagent`,logicalPath:t.logicalPath,name:t.name,nodeId:t.nodeId,sourceId:t.sourceId,sourceKind:t.sourceKind,tool:a.tool});return[t.nodeId,{agentConfig:a,kind:`subagent`,prepared:o}]})),n={};for(let r=0;r<t.length;r+=1){let i=t[r],a=e.resolvers[r];if(i.status===`rejected`){log.error(`Dynamic subagent resolver (${e.event.type}) threw — omitting subagent.`,{error:toErrorMessage(i.reason),subagentName:a.name}),n[a.nodeId]=null;continue}n[i.value[0]]=i.value[1]}return n}function isRemoteAgentDefinition(e){return typeof e==`object`&&!!e&&e.kind===`remote`}async function dispatchDynamicSubagentEvent(e){if(!ALLOWED_DYNAMIC_SUBAGENT_EVENTS.has(e.event.type))return;let t=e.resolvers.filter(t=>t.eventNames.includes(e.event.type)),n=await resolveSelections({...e,resolvers:t});e.event.type===`session.started`?e.ctx.set(SessionDynamicSubagentSelectionsKey,n):e.ctx.set(TurnDynamicSubagentSelectionsKey,n)}async function refreshDynamicSessionSubagentsForRuntimeRevision(e){if(e.ctx.get(SessionDynamicSubagentRuntimeRevisionKey)===e.runtimeRevision)return;let t=e.resolvers.filter(e=>e.eventNames.includes(`session.started`)),n=await resolveSelections({...e,resolvers:t});e.ctx.set(SessionDynamicSubagentSelectionsKey,n),e.ctx.set(SessionDynamicSubagentRuntimeRevisionKey,e.runtimeRevision)}function buildDynamicSubagentTools(e){let t=e.get(SessionDynamicSubagentSelectionsKey)??{},n=e.get(TurnDynamicSubagentSelectionsKey)??{},r={...t,...n},i=[],a=new Set;for(let e of Object.values(r))if(e!==null){if(a.has(e.prepared.name))throw Error(`Found multiple active dynamic subagents named "${e.prepared.name}". Subagent names must be unique at runtime.`);a.add(e.prepared.name),(e.kind===`subagent`?e.agentConfig.tool!==!1:e.remoteAgent.tool!==!1)&&i.push(createPreparedWorkflowToolHarnessDefinition(e.prepared))}return i}function getDynamicSubagentSelection(e,t){let n=e.get(TurnDynamicSubagentSelectionsKey)??{};return Object.hasOwn(n,t)?n[t]??void 0:(e.get(SessionDynamicSubagentSelectionsKey)??{})[t]??void 0}export{buildDynamicSubagentTools,dispatchDynamicSubagentEvent,getDynamicSubagentSelection,refreshDynamicSessionSubagentsForRuntimeRevision};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{SessionDynamicToolMetadataKey,SessionDynamicToolRuntimeRevisionKey,SessionIdKey,StepDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{serializeInputSchema,serializeOutputSchema}from"#tools/schema.js";import{parseJsonObject}from"#shared/json.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS}from"#dynamic/definition.js";import{isCurrentDynamicToolMetadata,toCurrentDynamicToolMetadataList}from"#context/dynamic-tool-metadata.js";import{clearDurableDynamicCallbacks,hasUnregisteredDurableDynamicCallbacks,readDurableDynamicToolCallbacks,registerDurableDynamicCallback}from"#tools/durable-callbacks.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{isWorkflowToolDefinition}from"#tools/workflow-definition.js";import{replayDynamicTools}from"#context/build-dynamic-tools.js";import{isBrandedToolEntry}from"#tools/dynamic.js";const log=createLogger(`dynamic-tools`);function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n);if(r.length===0)return[];if(t){let t=r[0];return[{name:e.slug,entryKey:t,entry:n[t]}]}let i=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;return r.map(e=>({entry:n[e],entryKey:e,name:`${i}${e}`}))}function replayDynamicSessionTools(e,t,n){return replayDynamicTools(e,{sessionId:n,scope:`session`})}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;case`step.started`:return StepDynamicToolMetadataKey;default:return}}function readDynamicToolResult(e,t){let assertOrdinaryTool=t=>{if(isWorkflowToolDefinition(t))throw Error(`Dynamic tool resolver "${e.logicalPath}" cannot return defineWorkflowTool(). Workflow tools must be static tools; use defineTool() for dynamic entries.`)};if(assertOrdinaryTool(t),isBrandedToolEntry(t))return{entries:{_single:t},isSingle:!0};if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`Dynamic tool resolver "${e.logicalPath}" must return defineTool(), a map of defineTool() values, or null.`);let n={};for(let[r,i]of Object.entries(t)){if(assertOrdinaryTool(i),!isBrandedToolEntry(i))throw Error(`Dynamic tool resolver "${e.logicalPath}" returned "${r}" without defineTool(). Wrap every dynamic tool entry in defineTool().`);n[r]=i}return{entries:n,isSingle:!1}}function validateReference(e){if(e.stamped===void 0){if(e.required)throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" does not have a durable descriptor. Author the callback inline in transformed source or use an eve durable callback helper.`);return}let t=Object.keys(e.stamped).filter(e=>e!==`closure`&&e!==`callback`);if(t.includes(`stepId`))throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" was persisted by a pre-release eve version that identified callbacks by build offset. Start a new session to re-resolve it.`);if(t.length>0)throw Error(`Dynamic tool "${e.name}" has invalid ${e.phase} callback metadata: unknown key(s) ${t.join(`, `)}.`);if(typeof e.stamped.callback!=`function`)throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" does not have a durable descriptor. Author the callback inline in transformed source or use an eve durable callback helper.`);let n;try{n=parseJsonObject(e.stamped.closure)}catch(t){throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" has a non-serializable capture. ${toErrorMessage(t)}`)}return registerDurableDynamicCallback({callback:e.stamped.callback,phase:e.phase,owner:e.owner}),{closure:n}}function validateDurableDynamicToolCallbacks(e,t,n){let r=readDurableDynamicToolCallbacks(t)??{},i=Object.keys(r).filter(e=>e!==`execute`&&e!==`label`&&e!==`approvalKey`&&e!==`approvalRequest`&&e!==`approvalResponse`&&e!==`toModelOutput`);if(i.length>0)throw Error(`Dynamic tool "${e}" has unknown durable callback phase(s): ${i.join(`, `)}.`);let a=t.approval!==void 0,o=t.approval!==void 0&&typeof t.approval!=`function`&&t.approval.response!==void 0,s=validateReference({name:e,owner:n,phase:`execute`,stamped:r.execute,required:!0}),c=validateReference({name:e,owner:n,phase:`labelComplete`,stamped:r.label?.complete,required:!1}),l=validateReference({name:e,owner:n,phase:`labelDelta`,stamped:r.label?.delta,required:!1}),u=validateReference({name:e,owner:n,phase:`labelStart`,stamped:r.label?.start,required:!1}),d=validateReference({name:e,owner:n,phase:`approvalKey`,stamped:r.approvalKey,required:t.approvalKey!==void 0}),f=validateReference({name:e,owner:n,phase:`approvalRequest`,stamped:r.approvalRequest,required:a}),p=validateReference({name:e,owner:n,phase:`approvalResponse`,stamped:r.approvalResponse,required:o}),m=validateReference({name:e,owner:n,phase:`toModelOutput`,stamped:r.toModelOutput,required:t.toModelOutput!==void 0}),h={execute:s};return(c!==void 0||l!==void 0||u!==void 0)&&(h.label={complete:c,delta:l,start:u}),d!==void 0&&(h.approvalKey=d),f!==void 0&&(h.approvalRequest=f),p!==void 0&&(h.approvalResponse=p),m!==void 0&&(h.toModelOutput=m),h}function createMetadata(e){return{callbacks:validateDurableDynamicToolCallbacks(e.name,e.entry,{sessionId:e.sessionId,scope:e.scope,resolverSlug:e.resolver.slug,entryKey:e.entryKey,name:e.name}),description:e.entry.description,execution:e.entry.execution===`background`?`background`:void 0,entryKey:e.entryKey,inputSchema:serializeInputSchema(e.entry.inputSchema),name:e.name,outputSchema:serializeOutputSchema(e.entry.outputSchema),resolverSlug:e.resolver.slug}}async function resolveToolsFromEvent(e,t,n,r){let i=e.require(SessionIdKey),a=n.type.split(`.`)[0],o=await Promise.allSettled(t.map(async t=>{let o=t.events[n.type];if(o===void 0)return null;clearDurableDynamicCallbacks(i,{scope:a,resolverSlug:t.slug});try{let s=await o(n,buildResolveContext(e,r));if(s==null)return null;let{entries:c,isSingle:l}=readDynamicToolResult(t,s);return{metadata:qualifyDynamicToolNames(t,l,c).map(({name:e,entryKey:n,entry:r})=>createMetadata({entry:r,entryKey:n,name:e,resolver:t,sessionId:i,scope:a})),resolver:t}}catch(e){throw clearDurableDynamicCallbacks(i,{scope:a,resolverSlug:t.slug}),e}})),s=[],c=new Map;for(let e of o){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) failed — skipping its complete result.`,{error:toErrorMessage(e.reason)});continue}if(e.value!==null){for(let t of e.value.metadata){let n=c.get(t.name);if(n!==void 0&&n!==e.value.resolver.slug)throw Error(`Dynamic tool "${t.name}" from resolver "${e.value.resolver.slug}" collides with dynamic resolver "${n}". Namespace the map key manually.`);c.set(t.name,e.value.resolver.slug)}s.push(...e.value.metadata)}}return{metadata:s}}const resolvedStepTools=new WeakMap;function stepCoordinate(e){return`${e.data.turnId}:${String(e.data.stepIndex)}`}function storeResolvedStepTools(e){e.ctx.set(StepDynamicToolMetadataKey,e.metadata);let t=stepCoordinate(e.event);resolvedStepTools.set(e.ctx,{coordinate:t,metadata:e.metadata})}async function resolveStepDynamicTools(e){let t=stepCoordinate(e.event),n=resolvedStepTools.get(e.ctx);if(n?.coordinate===t){e.ctx.set(StepDynamicToolMetadataKey,n.metadata);return}let r=e.resolvers.filter(e=>e.eventNames.includes(`step.started`)),{metadata:i}=r.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,r,e.event,e.messages);storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:i})}async function preparePersistedStepDynamicToolMetadata(e){let t=e.ctx.get(StepDynamicToolMetadataKey)??[],n=t.filter(isCurrentDynamicToolMetadata);if(n.length===t.length&&!hasUnregisteredDurableDynamicCallbacks(n,{sessionId:e.ctx.require(SessionIdKey),scope:`step`})){n.length>0&&storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:n});return}await resolveStepDynamicTools(e);let r=e.ctx.get(StepDynamicToolMetadataKey)??[];storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:toCurrentDynamicToolMetadataList(t,r.filter(isCurrentDynamicToolMetadata))})}async function dispatchDynamicToolEvent(e){if(e.event.type===`session.completed`){let t=e.ctx.get(SessionIdKey);t!==void 0&&clearDurableDynamicCallbacks(t);return}if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(e.event.type))return;if(e.event.type===`step.started`){await resolveStepDynamicTools({...e,event:e.event});return}e.event.type===`turn.started`&&e.ctx.set(StepDynamicToolMetadataKey,[]);let t=e.resolvers.filter(t=>t.eventNames.includes(e.event.type)),{metadata:n}=t.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,t,e.event,e.messages),r=durableKeyForEvent(e.event.type);if(r===void 0)return;if(e.event.type===`session.started`){e.ctx.set(SessionDynamicToolMetadataKey,n);return}let i=new Set(t.map(e=>e.slug)),a=(e.ctx.get(r)??[]).filter(e=>!i.has(e.resolverSlug));e.ctx.set(r,[...a,...n])}async function refreshDynamicSessionToolsForRuntimeRevision(e){let t=e.ctx.get(SessionDynamicToolMetadataKey)??[],n=t.filter(isCurrentDynamicToolMetadata),r=n.length!==t.length,i=e.ctx.get(SessionDynamicToolRuntimeRevisionKey)!==e.runtimeRevision;if(!i&&!r&&!hasUnregisteredDurableDynamicCallbacks(n,{sessionId:e.ctx.require(SessionIdKey),scope:`session`}))return;let a=e.resolvers.filter(e=>e.eventNames.includes(`session.started`)),{metadata:o}=a.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,a,e.event,e.messages);e.ctx.set(SessionDynamicToolMetadataKey,i?o:toCurrentDynamicToolMetadataList(t,o)),e.ctx.set(SessionDynamicToolRuntimeRevisionKey,e.runtimeRevision)}async function rebindMissingCompiledDynamicToolCallbacks(e){let t=e.ctx.get(TurnDynamicToolMetadataKey)??[],n=t.filter(t=>!isCurrentDynamicToolMetadata(t)||hasUnregisteredDurableDynamicCallbacks([t],{sessionId:e.ctx.require(SessionIdKey),scope:`turn`}));if(n.length===0)return;let r=new Set(n.map(e=>e.resolverSlug)),i=new Set(t.filter(e=>!isCurrentDynamicToolMetadata(e)).map(e=>e.resolverSlug)),a=e.resolvers.filter(e=>r.has(e.slug)&&(i.has(e.slug)||e.rebindMissingCallbacks===!0));if(a.length===0){e.ctx.set(TurnDynamicToolMetadataKey,toCurrentDynamicToolMetadataList(t));return}let o=await contextStorage.run(e.ctx,async()=>await resolveToolsFromEvent(e.ctx,a,e.event,e.messages)),s=toCurrentDynamicToolMetadataList(t,o.metadata);e.ctx.set(TurnDynamicToolMetadataKey,s);let c=s.filter(t=>n.some(e=>e.resolverSlug===t.resolverSlug&&e.name===t.name)&&hasUnregisteredDurableDynamicCallbacks([t],{sessionId:e.ctx.require(SessionIdKey),scope:`turn`}));if(c.length>0)throw Error(`Dynamic tool callback rebind did not restore: ${c.map(e=>e.name).join(`, `)}. The tool may have been renamed or removed.`)}export{dispatchDynamicToolEvent,preparePersistedStepDynamicToolMetadata,rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision,replayDynamicSessionTools,resolveStepDynamicTools,validateDurableDynamicToolCallbacks};
1
+ import{createLogger}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{SessionDynamicToolMetadataKey,SessionDynamicToolRuntimeRevisionKey,SessionIdKey,StepDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{serializeInputSchema,serializeOutputSchema}from"#tools/schema.js";import{parseJsonObject}from"#shared/json.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS}from"#dynamic/definition.js";import{isCurrentDynamicToolMetadata,toCurrentDynamicToolMetadataList}from"#context/dynamic-tool-metadata.js";import{clearDurableDynamicCallbacks,hasUnregisteredDurableDynamicCallbacks,readDurableDynamicToolCallbacks,registerDurableDynamicCallback}from"#tools/durable-callbacks.js";import{hasSchemaValidator}from"#tools/durable-schema.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{isWorkflowToolDefinition}from"#tools/workflow-definition.js";import{replayDynamicTools}from"#context/build-dynamic-tools.js";import{isBrandedToolEntry}from"#tools/dynamic.js";const log=createLogger(`dynamic-tools`);function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n);if(r.length===0)return[];if(t){let t=r[0];return[{name:e.slug,entryKey:t,entry:n[t]}]}let i=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;return r.map(e=>({entry:n[e],entryKey:e,name:`${i}${e}`}))}function replayDynamicSessionTools(e,t,n){return replayDynamicTools(e,{sessionId:n,scope:`session`})}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;case`step.started`:return StepDynamicToolMetadataKey;default:return}}function readDynamicToolResult(e,t){let assertOrdinaryTool=t=>{if(isWorkflowToolDefinition(t))throw Error(`Dynamic tool resolver "${e.logicalPath}" cannot return defineWorkflowTool(). Workflow tools must be static tools; use defineTool() for dynamic entries.`)};if(assertOrdinaryTool(t),isBrandedToolEntry(t))return{entries:{_single:t},isSingle:!0};if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`Dynamic tool resolver "${e.logicalPath}" must return defineTool(), a map of defineTool() values, or null.`);let n={};for(let[r,i]of Object.entries(t)){if(assertOrdinaryTool(i),!isBrandedToolEntry(i))throw Error(`Dynamic tool resolver "${e.logicalPath}" returned "${r}" without defineTool(). Wrap every dynamic tool entry in defineTool().`);n[r]=i}return{entries:n,isSingle:!1}}function validateReference(e){let t=e.phase===`inputSchema`||e.phase===`outputSchema`,n=t?`Write the schema expression inline in defineTool() or use defineDurableSchema() for a provider package.`:`Author the callback inline in transformed source or use an eve durable callback helper.`;if(e.stamped===void 0){if(e.required)throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" does not have a durable descriptor. `+n);return}let r=Object.keys(e.stamped).filter(e=>e!==`closure`&&e!==`callback`);if(r.includes(`stepId`))throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" was persisted by a pre-release eve version that identified callbacks by build offset. Start a new session to re-resolve it.`);if(r.length>0)throw Error(`Dynamic tool "${e.name}" has invalid ${e.phase} callback metadata: unknown key(s) ${r.join(`, `)}.`);if(typeof e.stamped.callback!=`function`)throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" does not have a durable descriptor. `+n);let i;try{i=parseJsonObject(e.stamped.closure)}catch(n){throw Error(`Dynamic tool "${e.name}" callback "${e.phase}" has a non-serializable capture. ${toErrorMessage(n)}`+(t?` Inline the schema construction or reference a stable module-level schema; put only JSON data in its closure.`:``))}return registerDurableDynamicCallback({callback:e.stamped.callback,phase:e.phase,owner:e.owner}),{closure:i}}function validateDurableDynamicToolCallbacks(e,t,n){let r=readDurableDynamicToolCallbacks(t)??{},i=Object.keys(r).filter(e=>e!==`execute`&&e!==`inputSchema`&&e!==`outputSchema`&&e!==`label`&&e!==`approvalKey`&&e!==`approvalRequest`&&e!==`approvalResponse`&&e!==`toModelOutput`);if(i.length>0)throw Error(`Dynamic tool "${e}" has unknown durable callback phase(s): ${i.join(`, `)}.`);let a=t.approval!==void 0,o=t.approval!==void 0&&typeof t.approval!=`function`&&t.approval.response!==void 0,s=validateReference({name:e,owner:n,phase:`execute`,stamped:r.execute,required:!0}),c=validateReference({name:e,owner:n,phase:`labelComplete`,stamped:r.label?.complete,required:!1}),l=validateReference({name:e,owner:n,phase:`labelDelta`,stamped:r.label?.delta,required:!1}),u=validateReference({name:e,owner:n,phase:`labelStart`,stamped:r.label?.start,required:!1}),d=validateReference({name:e,owner:n,phase:`approvalKey`,stamped:r.approvalKey,required:t.approvalKey!==void 0}),f=validateReference({name:e,owner:n,phase:`approvalRequest`,stamped:r.approvalRequest,required:a}),p=validateReference({name:e,owner:n,phase:`approvalResponse`,stamped:r.approvalResponse,required:o}),m=validateReference({name:e,owner:n,phase:`toModelOutput`,stamped:r.toModelOutput,required:t.toModelOutput!==void 0}),h=validateReference({name:e,owner:n,phase:`inputSchema`,stamped:r.inputSchema,required:hasSchemaValidator(t.inputSchema)}),g=validateReference({name:e,owner:n,phase:`outputSchema`,stamped:r.outputSchema,required:hasSchemaValidator(t.outputSchema)}),_={execute:s};return h!==void 0&&(_.inputSchema=h),g!==void 0&&(_.outputSchema=g),(c!==void 0||l!==void 0||u!==void 0)&&(_.label={complete:c,delta:l,start:u}),d!==void 0&&(_.approvalKey=d),f!==void 0&&(_.approvalRequest=f),p!==void 0&&(_.approvalResponse=p),m!==void 0&&(_.toModelOutput=m),_}function createMetadata(e){return{callbacks:validateDurableDynamicToolCallbacks(e.name,e.entry,{sessionId:e.sessionId,scope:e.scope,resolverSlug:e.resolver.slug,entryKey:e.entryKey,name:e.name}),description:e.entry.description,execution:e.entry.execution===`background`?`background`:void 0,entryKey:e.entryKey,inputSchema:serializeInputSchema(e.entry.inputSchema),name:e.name,outputSchema:serializeOutputSchema(e.entry.outputSchema),resolverSlug:e.resolver.slug}}async function resolveToolsFromEvent(e,t,n,r){let i=e.require(SessionIdKey),a=n.type.split(`.`)[0],o=await Promise.allSettled(t.map(async t=>{let o=t.events[n.type];if(o===void 0)return null;clearDurableDynamicCallbacks(i,{scope:a,resolverSlug:t.slug});try{let s=await o(n,buildResolveContext(e,r));if(s==null)return null;let{entries:c,isSingle:l}=readDynamicToolResult(t,s);return{metadata:qualifyDynamicToolNames(t,l,c).map(({name:e,entryKey:n,entry:r})=>createMetadata({entry:r,entryKey:n,name:e,resolver:t,sessionId:i,scope:a})),resolver:t}}catch(e){throw clearDurableDynamicCallbacks(i,{scope:a,resolverSlug:t.slug}),e}})),s=[],c=new Map;for(let e of o){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) failed — skipping its complete result.`,{error:toErrorMessage(e.reason)});continue}if(e.value!==null){for(let t of e.value.metadata){let n=c.get(t.name);if(n!==void 0&&n!==e.value.resolver.slug)throw Error(`Dynamic tool "${t.name}" from resolver "${e.value.resolver.slug}" collides with dynamic resolver "${n}". Namespace the map key manually.`);c.set(t.name,e.value.resolver.slug)}s.push(...e.value.metadata)}}return{metadata:s}}const resolvedStepTools=new WeakMap;function stepCoordinate(e){return`${e.data.turnId}:${String(e.data.stepIndex)}`}function storeResolvedStepTools(e){e.ctx.set(StepDynamicToolMetadataKey,e.metadata);let t=stepCoordinate(e.event);resolvedStepTools.set(e.ctx,{coordinate:t,metadata:e.metadata})}async function resolveStepDynamicTools(e){let t=stepCoordinate(e.event),n=resolvedStepTools.get(e.ctx);if(n?.coordinate===t){e.ctx.set(StepDynamicToolMetadataKey,n.metadata);return}let r=e.resolvers.filter(e=>e.eventNames.includes(`step.started`)),{metadata:i}=r.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,r,e.event,e.messages);storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:i})}async function preparePersistedStepDynamicToolMetadata(e){let t=e.ctx.get(StepDynamicToolMetadataKey)??[],n=t.filter(isCurrentDynamicToolMetadata);if(n.length===t.length&&!hasUnregisteredDurableDynamicCallbacks(n,{sessionId:e.ctx.require(SessionIdKey),scope:`step`})){n.length>0&&storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:n});return}await resolveStepDynamicTools(e);let r=e.ctx.get(StepDynamicToolMetadataKey)??[];storeResolvedStepTools({ctx:e.ctx,event:e.event,metadata:toCurrentDynamicToolMetadataList(t,r.filter(isCurrentDynamicToolMetadata))})}async function dispatchDynamicToolEvent(e){if(e.event.type===`session.completed`){let t=e.ctx.get(SessionIdKey);t!==void 0&&clearDurableDynamicCallbacks(t);return}if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(e.event.type))return;if(e.event.type===`step.started`){await resolveStepDynamicTools({...e,event:e.event});return}e.event.type===`turn.started`&&e.ctx.set(StepDynamicToolMetadataKey,[]);let t=e.resolvers.filter(t=>t.eventNames.includes(e.event.type)),{metadata:n}=t.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,t,e.event,e.messages),r=durableKeyForEvent(e.event.type);if(r===void 0)return;if(e.event.type===`session.started`){e.ctx.set(SessionDynamicToolMetadataKey,n);return}let i=new Set(t.map(e=>e.slug)),a=(e.ctx.get(r)??[]).filter(e=>!i.has(e.resolverSlug));e.ctx.set(r,[...a,...n])}async function refreshDynamicSessionToolsForRuntimeRevision(e){let t=e.ctx.get(SessionDynamicToolMetadataKey)??[],n=t.filter(isCurrentDynamicToolMetadata),r=n.length!==t.length,i=e.ctx.get(SessionDynamicToolRuntimeRevisionKey)!==e.runtimeRevision;if(!i&&!r&&!hasUnregisteredDurableDynamicCallbacks(n,{sessionId:e.ctx.require(SessionIdKey),scope:`session`}))return;let a=e.resolvers.filter(e=>e.eventNames.includes(`session.started`)),{metadata:o}=a.length===0?{metadata:[]}:await resolveToolsFromEvent(e.ctx,a,e.event,e.messages);e.ctx.set(SessionDynamicToolMetadataKey,i?o:toCurrentDynamicToolMetadataList(t,o)),e.ctx.set(SessionDynamicToolRuntimeRevisionKey,e.runtimeRevision)}async function rebindMissingCompiledDynamicToolCallbacks(e){let t=e.ctx.get(TurnDynamicToolMetadataKey)??[],n=t.filter(t=>!isCurrentDynamicToolMetadata(t)||hasUnregisteredDurableDynamicCallbacks([t],{sessionId:e.ctx.require(SessionIdKey),scope:`turn`}));if(n.length===0)return;let r=new Set(n.map(e=>e.resolverSlug)),i=new Set(t.filter(e=>!isCurrentDynamicToolMetadata(e)).map(e=>e.resolverSlug)),a=e.resolvers.filter(e=>r.has(e.slug)&&(i.has(e.slug)||e.rebindMissingCallbacks===!0));if(a.length===0){e.ctx.set(TurnDynamicToolMetadataKey,toCurrentDynamicToolMetadataList(t));return}let o=await contextStorage.run(e.ctx,async()=>await resolveToolsFromEvent(e.ctx,a,e.event,e.messages)),s=toCurrentDynamicToolMetadataList(t,o.metadata);e.ctx.set(TurnDynamicToolMetadataKey,s);let c=s.filter(t=>n.some(e=>e.resolverSlug===t.resolverSlug&&e.name===t.name)&&hasUnregisteredDurableDynamicCallbacks([t],{sessionId:e.ctx.require(SessionIdKey),scope:`turn`}));if(c.length>0)throw Error(`Dynamic tool callback rebind did not restore: ${c.map(e=>e.name).join(`, `)}. The tool may have been renamed or removed.`)}export{dispatchDynamicToolEvent,preparePersistedStepDynamicToolMetadata,rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision,replayDynamicSessionTools,resolveStepDynamicTools,validateDurableDynamicToolCallbacks};
@@ -1 +1 @@
1
- import{loadContext}from"#context/container.js";import{TurnMemoryLocksKey}from"#context/keys.js";import{parseJsonObject}from"#shared/json.js";import{defineDynamic}from"#dynamic/definition.js";import{stampDurableDynamicToolCallbacks}from"#tools/durable-callbacks.js";import{TOOL_SLUG_PATTERN}from"#discover/grammar.js";import{isBrandedToolEntry}from"#tools/dynamic.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{markDynamicCallbackRebind}from"#internal/dynamic-tool-rebind.js";function createMemoryToolDynamicDefinition(e,t){return markDynamicCallbackRebind(defineDynamic({events:{"turn.started":async(n,r)=>{let i=loadContext().get(TurnMemoryLocksKey)?.[t];if(i===void 0||e.provider.tools===void 0)return null;let a={...r,memory:{scope:i.scope,slot:t},turn:i.turn},o=await e.provider.tools(a);if(o===null)return null;if(typeof o!=`object`||Array.isArray(o))throw Error(`Memory slot "${t}" provider.tools() must return a tool map or null.`);return Object.fromEntries(Object.entries(o).map(([n,r])=>{let i=`${t}__${n}`;if(!TOOL_SLUG_PATTERN.test(i))throw Error(`Memory provider tool name "${i}" must start with an ASCII letter, contain only letters, digits, underscores, or dashes, and be at most 64 characters.`);if(!isBrandedToolEntry(r))throw Error(`Memory provider tool "${i}" must be created with defineTool().`);let o=e.description===void 0?r.description:`${e.description}\n\n${r.description}`,s={...r,description:o};return stampDurableDynamicToolCallbacks(s,createProviderToolCallbacks({context:a,definition:e,key:n,tool:r})),[i,s]}))}}}))}function createProviderToolCallbacks(e){let t=parseJsonObject({context:e.context,key:e.key}),loadTool=async t=>{let n=t.key,r=t.context;if(typeof n!=`string`||typeof r!=`object`||!r)throw Error(`Memory provider tool callback has an invalid durable closure.`);let i=(await e.definition.provider.tools?.(readMemoryToolsContext(r)))?.[n];if(i===void 0||!isBrandedToolEntry(i))throw Error(`Memory provider tool "${n}" was removed or renamed.`);return i},n={execute:{callback:async(e,t,n)=>await(await loadTool(e)).execute(t,n),closure:t}};return e.tool.approval!==void 0&&(n.approvalRequest={callback:async(e,t)=>await resolveApprovalPolicy((await loadTool(e)).approval)(t),closure:t},typeof e.tool.approval!=`function`&&e.tool.approval.response!==void 0&&(n.approvalResponse={callback:async(t,n)=>{let r=(await loadTool(t)).approval;if(r===void 0||typeof r==`function`||r.response===void 0)throw Error(`Memory provider tool "${e.key}" approval response was removed.`);return await r.response(n)},closure:t})),e.tool.toModelOutput!==void 0&&(n.toModelOutput={callback:async(e,t)=>await(await loadTool(e)).toModelOutput(t),closure:t}),n}function readMemoryToolsContext(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Memory provider tool callback has an invalid durable context.`);let t=e;if(typeof t.channel!=`object`||t.channel===null||typeof t.memory!=`object`||t.memory===null||!Array.isArray(t.messages)||typeof t.session!=`object`||t.session===null||typeof t.turn!=`object`||t.turn===null)throw Error(`Memory provider tool callback has an invalid durable context.`);return t}export{createMemoryToolDynamicDefinition};
1
+ import{loadContext}from"#context/container.js";import{TurnMemoryLocksKey}from"#context/keys.js";import{parseJsonObject}from"#shared/json.js";import{defineDynamic}from"#dynamic/definition.js";import{stampDurableDynamicToolCallbacks}from"#tools/durable-callbacks.js";import{TOOL_SLUG_PATTERN}from"#discover/grammar.js";import{isBrandedToolEntry}from"#tools/dynamic.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{markDynamicCallbackRebind}from"#internal/dynamic-tool-rebind.js";function createMemoryToolDynamicDefinition(e,t){return markDynamicCallbackRebind(defineDynamic({events:{"turn.started":async(n,r)=>{let i=loadContext().get(TurnMemoryLocksKey)?.[t];if(i===void 0||e.provider.tools===void 0)return null;let a={...r,memory:{scope:i.scope,slot:t},turn:i.turn},o=await e.provider.tools(a);if(o===null)return null;if(typeof o!=`object`||Array.isArray(o))throw Error(`Memory slot "${t}" provider.tools() must return a tool map or null.`);return Object.fromEntries(Object.entries(o).map(([n,r])=>{let i=`${t}__${n}`;if(!TOOL_SLUG_PATTERN.test(i))throw Error(`Memory provider tool name "${i}" must start with an ASCII letter, contain only letters, digits, underscores, or dashes, and be at most 64 characters.`);if(!isBrandedToolEntry(r))throw Error(`Memory provider tool "${i}" must be created with defineTool().`);let o=e.description===void 0?r.description:`${e.description}\n\n${r.description}`,s={...r,description:o};return stampDurableDynamicToolCallbacks(s,createProviderToolCallbacks({context:a,definition:e,key:n,tool:r})),[i,s]}))}}}))}function createProviderToolCallbacks(e){let t=parseJsonObject({context:e.context,key:e.key}),loadTool=async t=>{let n=t.key,r=t.context;if(typeof n!=`string`||typeof r!=`object`||!r)throw Error(`Memory provider tool callback has an invalid durable closure.`);let i=(await e.definition.provider.tools?.(readMemoryToolsContext(r)))?.[n];if(i===void 0||!isBrandedToolEntry(i))throw Error(`Memory provider tool "${n}" was removed or renamed.`);return i},n={execute:{callback:async(e,t,n)=>await(await loadTool(e)).execute(t,n),closure:t}};for(let r of[`inputSchema`,`outputSchema`])e.tool[r]!==void 0&&(n[r]={callback:async e=>(await loadTool(e))[r],closure:t});return e.tool.approval!==void 0&&(n.approvalRequest={callback:async(e,t)=>await resolveApprovalPolicy((await loadTool(e)).approval)(t),closure:t},typeof e.tool.approval!=`function`&&e.tool.approval.response!==void 0&&(n.approvalResponse={callback:async(t,n)=>{let r=(await loadTool(t)).approval;if(r===void 0||typeof r==`function`||r.response===void 0)throw Error(`Memory provider tool "${e.key}" approval response was removed.`);return await r.response(n)},closure:t})),e.tool.toModelOutput!==void 0&&(n.toModelOutput={callback:async(e,t)=>await(await loadTool(e)).toModelOutput(t),closure:t}),n}function readMemoryToolsContext(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Memory provider tool callback has an invalid durable context.`);let t=e;if(typeof t.channel!=`object`||t.channel===null||typeof t.memory!=`object`||t.memory===null||!Array.isArray(t.messages)||typeof t.session!=`object`||t.session===null||typeof t.turn!=`object`||t.turn===null)throw Error(`Memory provider tool callback has an invalid durable context.`);return t}export{createMemoryToolDynamicDefinition};
@@ -1,4 +1,4 @@
1
- import { EvalSessionManager } from "#evals/session.js";
1
+ import { EvalSessionManager } from "#evals/session-manager.js";
2
2
  import { AssertionCollector } from "#evals/assertions/collector.js";
3
3
  import type { EveEvalContext, EveEvalJudgeConfig, EveEvalTargetHandle } from "#evals/types.js";
4
4
  /**
@@ -1 +1 @@
1
- import"#evals/assertions/collector.js";import"#evals/session.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(e){let t=e.collector,n=``,primary=()=>e.manager.primary,replyMessage=()=>e.manager.lastTurnSession()?.lastTurn?.message??null,r=buildJudgeContext({collector:t,getReply:replyMessage,getInput:()=>n,judge:e.judge});return{context:{get events(){return primary().events},get transcript(){return primary().transcript},get pendingInputRequests(){return primary().pendingInputRequests},get state(){return primary().state},get sessionId(){return primary().sessionId},cancel:()=>primary().cancel(),requireInputRequest:e=>primary().requireInputRequest(e),respond:(e,t)=>primary().respond(e,t),startRespond:(e,t)=>primary().startRespond(e,t),respondAll:e=>primary().respondAll(e),send:(e,t)=>(n=typeof e==`string`?e:``,primary().send(e,t)),start:(e,t)=>(n=e,primary().start(e,t)),sendFile:(e,t,r)=>(n=e,primary().sendFile(e,t,r)),signal:e.signal,target:e.target,get reply(){return replyMessage()},log:e.log,sleep:t=>sleep(t,e.signal),newSession:()=>e.manager.newSession(),...createScopedAssertions(t,{timing:`final`,select:e=>e}),check:(e,n)=>recordCheck(t,e,n),require:(e,n)=>requireCheck(t,e,n),skip:n=>{throw n.trim().length===0?Error(`skip() requires a non-empty reason.`):t.hasEntries||e.manager.hasActivity()?Error(`skip() must be called before sending messages or recording assertions.`):new EvalSkipped(n)},judge:r},collector:t}}async function requireCheck(e,t,n){let r=n.gate(n.threshold);if(!await e.recordRequirement({name:r.name,threshold:r.threshold,score:()=>evaluateAssertion(r,t)}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:()=>evaluateAssertion(n,t)})}async function evaluateAssertion(e,t){return e.evaluate===void 0?{score:await e.score(t)}:await e.evaluate(t)}function sleep(e=1e3,t){if(!Number.isFinite(e)||e<0)throw Error(`sleep() duration must be a non-negative finite number.`);return t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(n,e);t?.addEventListener(`abort`,()=>{clearTimeout(i),r(t.reason)},{once:!0})})}export{createEvalContext};
1
+ import"#evals/assertions/collector.js";import"#evals/session-manager.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(e){let t=e.collector,n=buildJudgeContext({collector:t,getReply:()=>e.manager.lastTurnSession()?.lastTurn?.message??null,getInput:()=>e.manager.lastTurnSession()?.lastInput??``,judge:e.judge});return{context:{session:t=>e.manager.session(t),send:(t,n)=>e.manager.send(t,n),signal:e.signal,target:e.target,log:e.log,sleep:t=>sleep(t,e.signal),...createScopedAssertions(t,{timing:`final`,select:e=>e}),check:(e,n)=>recordCheck(t,e,n),require:(e,n)=>requireCheck(t,e,n),skip:n=>{throw n.trim().length===0?Error(`skip() requires a non-empty reason.`):t.hasEntries||e.manager.hasActivity()?Error(`skip() must be called before creating sessions, sending messages, or recording assertions.`):new EvalSkipped(n)},judge:n},collector:t}}async function requireCheck(e,t,n){let r=n.gate(n.threshold);if(!await e.recordRequirement({name:r.name,threshold:r.threshold,score:()=>evaluateAssertion(r,t)}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:()=>evaluateAssertion(n,t)})}async function evaluateAssertion(e,t){return e.evaluate===void 0?{score:await e.score(t)}:await e.evaluate(t)}function sleep(e=1e3,t){if(!Number.isFinite(e)||e<0)throw Error(`sleep() duration must be a non-negative finite number.`);return t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(n,e);t?.addEventListener(`abort`,()=>{clearTimeout(i),r(t.reason)},{once:!0})})}export{createEvalContext};
@@ -1,7 +1,7 @@
1
1
  import type { EveEvalDefinition, EveEvalInput } from "#evals/types.js";
2
2
  /**
3
3
  * Defines one eve eval. Each eval file is exactly one case: an imperative
4
- * `test(t)` function that drives the agent (`t.send`, `t.respond`, …) and
4
+ * `test(t)` function that drives the agent (`t.session`, `t.send`, …) and
5
5
  * asserts on what it produced (`t.succeeded()`, `t.check(...)`,
6
6
  * `t.judge.autoevals.*`). Organize related evals with directory nesting under
7
7
  * `evals/`, or default-export an array of evals to fan one file out over a
@@ -1 +1 @@
1
- function defineEval(e){return validateEvalInput(e),{...e,_tag:`EveEval`}}function validateEvalInput(e){if(`id`in e)throw Error("Eval must not specify `id`. Eval identity is derived from the file path under evals/.");if(`name`in e)throw Error("Eval must not specify `name`. Eval identity is derived from the file path under evals/.");if(rejectLegacyKey(e,`input`,"Send the prompt inside `test`: `async test(t) { await t.send(...) }`."),rejectLegacyKey(e,`run`,"Rename `run` to `test`; it receives the same context `t`."),rejectLegacyKey(e,`checks`,"Assert inline inside `test` (e.g. `t.succeeded()`, `t.calledTool(...)`)."),rejectLegacyKey(e,`scores`,"Use soft assertions inside `test`: `t.check(...).atLeast(n)` or `t.judge.autoevals.*`."),rejectLegacyKey(e,`expected`,"Pass the reference value to the assertion (e.g. `t.check(t.reply, includes(value))`)."),rejectLegacyKey(e,`thresholds`,"Put the threshold on the assertion: `.atLeast(n)`."),rejectLegacyKey(e,`parseOutput`,"Read the value you want inside `test` and assert on it directly."),rejectLegacyKey(e,`model`,"Rename `model` to `judge: { model }`."),rejectLegacyKey(e,`modelOptions`,"Move it under `judge: { model, modelOptions }`."),rejectLegacyKey(e,`cases`,"Each eval file is one case; default-export an array of `defineEval(...)` for datasets."),rejectLegacyKey(e,`requires`,`Point real-model evals at credentialed targets directly; dev-only routes are enforced from the live target.`),typeof e.test!=`function`)throw Error("Eval requires a `test(t)` function.");if(e.timeoutMs!==void 0&&(e.timeoutMs<0||!Number.isFinite(e.timeoutMs)))throw Error("Eval `timeoutMs` must be a non-negative finite number.")}function rejectLegacyKey(e,t,n){if(t in e)throw Error(`Eval \`${t}\` is no longer supported. ${n}`)}export{defineEval};
1
+ function defineEval(e){return validateEvalInput(e),{...e,_tag:`EveEval`}}function validateEvalInput(e){if(`id`in e)throw Error("Eval must not specify `id`. Eval identity is derived from the file path under evals/.");if(`name`in e)throw Error("Eval must not specify `name`. Eval identity is derived from the file path under evals/.");if(rejectLegacyKey(e,`input`,"Send the prompt inside `test`: `async test(t) { await t.send(...) }`."),rejectLegacyKey(e,`run`,"Rename `run` to `test`; it receives the same context `t`."),rejectLegacyKey(e,`checks`,"Assert inline inside `test` (e.g. `t.succeeded()`, `t.calledTool(...)`)."),rejectLegacyKey(e,`scores`,"Use soft assertions inside `test`: `t.check(...).atLeast(n)` or `t.judge.autoevals.*`."),rejectLegacyKey(e,`expected`,"Pass the reference value to the assertion (e.g. `t.check(turn.message, includes(value))`)."),rejectLegacyKey(e,`thresholds`,"Put the threshold on the assertion: `.atLeast(n)`."),rejectLegacyKey(e,`parseOutput`,"Read the value you want inside `test` and assert on it directly."),rejectLegacyKey(e,`model`,"Rename `model` to `judge: { model }`."),rejectLegacyKey(e,`modelOptions`,"Move it under `judge: { model, modelOptions }`."),rejectLegacyKey(e,`cases`,"Each eval file is one case; default-export an array of `defineEval(...)` for datasets."),rejectLegacyKey(e,`requires`,`Point real-model evals at credentialed targets directly; dev-only routes are enforced from the live target.`),typeof e.test!=`function`)throw Error("Eval requires a `test(t)` function.");if(e.timeoutMs!==void 0&&(e.timeoutMs<0||!Number.isFinite(e.timeoutMs)))throw Error("Eval `timeoutMs` must be a non-negative finite number.")}function rejectLegacyKey(e,t,n){if(t in e)throw Error(`Eval \`${t}\` is no longer supported. ${n}`)}export{defineEval};
@@ -1 +1 @@
1
- import{EveEvalTurnFailedError}from"#evals/session.js";import{defineEval}from"#evals/define-eval.js";import{defineEvalConfig}from"#evals/define-eval-config.js";import{mockModel}from"#evals/mock-model.js";export{EveEvalTurnFailedError,defineEval,defineEvalConfig,mockModel};
1
+ import{defineEval}from"#evals/define-eval.js";import{defineEvalConfig}from"#evals/define-eval-config.js";import{EveEvalTurnFailedError}from"#evals/session.js";import{mockModel}from"#evals/mock-model.js";export{EveEvalTurnFailedError,defineEval,defineEvalConfig,mockModel};
@@ -2,7 +2,7 @@ import type { AssertionCollector } from "#evals/assertions/collector.js";
2
2
  import type { EveEvalJudgeConfig, JudgeContext } from "#evals/types.js";
3
3
  /**
4
4
  * Dependencies the judge namespace closes over: where to record assertions,
5
- * how to resolve the default graded value (`t.reply`) and the original prompt
5
+ * how to resolve the default graded value (the most recently settled turn) and the original prompt
6
6
  * (the autoevals `input`), and the eval/config judge model.
7
7
  */
8
8
  export interface JudgeDeps {
@@ -1,6 +1,6 @@
1
1
  import type { Client } from "#client/client.js";
2
2
  import type { AssertionResult, EveEval, EveEvalTargetHandle, EveEvalTaskResult } from "#evals/types.js";
3
- import { type EvalSessionStartedEvent } from "#evals/session.js";
3
+ import type { EvalSessionStartedEvent } from "#evals/session.js";
4
4
  /**
5
5
  * Options for executing one eval's task.
6
6
  */
@@ -1 +1 @@
1
- import{toErrorMessage}from"#shared/errors.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{scopeEvalTargetHandle}from"#evals/target.js";import{EvalSessionManager}from"#evals/session.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";import{createEmptyDerivedFacts}from"#evals/runner/derive-run-facts.js";import{createEvalContext}from"#evals/context.js";async function executeTask(e){let{client:t,evaluation:n,target:r,timeoutMs:i}=e,a=i===void 0?neverAbortSignal():AbortSignal.timeout(i),o=new AssertionCollector,s=new EvalSessionManager({client:t,collector:o,onSessionStart:e.onSessionStart,signal:a}),c=scopeEvalTargetHandle(r,{sessions:s}),l=[],{context:u}=createEvalContext({collector:o,manager:s,target:c,signal:a,judge:n.judge,log:t=>{l.push(t),e.onLog?.(t)}}),d,f;try{await runUntilAborted(n.test(u),a)}catch(e){e instanceof EvalSkipped?f=e.reason:e instanceof EvalRequirementFailed||(d=toErrorMessage(e))}if(i!==void 0&&a.aborted){let e=(await s.cleanup(AbortSignal.timeout(5e3))).flatMap(e=>e.status===`rejected`?[toErrorMessage(e.reason)]:[]);if(e.length>0){let t=`Eval timeout cleanup failed: ${e.join(`; `)}`;d=d===void 0?t:`${d}\n${t}`}}let p=buildTaskResult({logs:l,sessions:s.snapshots(),turn:s.lastTurnSession()?.lastTurn});return{result:p,assertions:await o.finalize(p),error:d,skipReason:f}}function buildTaskResult(e){let t=e.sessions.flatMap(e=>e.events),n=e.turn?.message??null;return{output:e.turn?.data===void 0?n:e.turn.data,finalMessage:n,sessionId:selectPrimarySessionId(e.sessions),status:e.turn?.status??`completed`,events:t,logs:e.logs,derived:combineDerivedFacts(e.sessions),sessions:e.sessions,runtimeIdentity:extractRuntimeIdentity(t),traceContexts:collectTraceContexts(e.sessions)}}function collectTraceContexts(e){return e.flatMap(e=>{let t=e.sessionId;return t===void 0?[]:e.traceContexts.map(n=>({...n,primary:e.primary,sessionId:t}))})}function combineDerivedFacts(e){if(e.length===0)return createEmptyDerivedFacts();let t=e.flatMap(e=>e.derived.toolCalls),n=e.flatMap(e=>e.derived.subagentCalls),r=e.flatMap(e=>e.derived.inputRequests),i=e.find(e=>e.derived.failureCode!==void 0)?.derived.failureCode;return{toolCalls:t,toolCallCount:t.length,subagentCalls:n,subagentCallCount:n.length,inputRequests:r,parked:e.some(e=>e.derived.parked),messageCount:sum(e,e=>e.derived.messageCount),reasoningBlockCount:sum(e,e=>e.derived.reasoningBlockCount),failureCode:i}}function selectPrimarySessionId(e){return e.find(e=>e.primary)?.sessionId??e[0]?.sessionId}function extractRuntimeIdentity(e){for(let t of e)if(t.type===`session.started`&&t.data.runtime!==void 0)return t.data.runtime}function sum(e,t){return e.reduce((e,n)=>e+t(n),0)}function neverAbortSignal(){return new AbortController().signal}async function runUntilAborted(e,t){t.throwIfAborted();let onAbort,n=new Promise((e,n)=>{onAbort=()=>n(t.reason),t.addEventListener(`abort`,onAbort,{once:!0})});try{await Promise.race([e,n])}finally{onAbort!==void 0&&t.removeEventListener(`abort`,onAbort)}}export{executeTask};
1
+ import{toErrorMessage}from"#shared/errors.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{scopeEvalTargetHandle}from"#evals/target.js";import{EvalSessionManager}from"#evals/session-manager.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";import{createEmptyDerivedFacts}from"#evals/runner/derive-run-facts.js";import{createEvalContext}from"#evals/context.js";async function executeTask(e){let{client:t,evaluation:n,target:r,timeoutMs:i}=e,a=i===void 0?neverAbortSignal():AbortSignal.timeout(i),o=new AssertionCollector,s=new EvalSessionManager({client:t,collector:o,onSessionStart:e.onSessionStart,signal:a}),c=scopeEvalTargetHandle(r,{sessions:s}),l=[],{context:u}=createEvalContext({collector:o,manager:s,target:c,signal:a,judge:n.judge,log:t=>{l.push(t),e.onLog?.(t)}}),d,f;try{await runUntilAborted(n.test(u),a)}catch(e){e instanceof EvalSkipped?f=e.reason:e instanceof EvalRequirementFailed||(d=toErrorMessage(e))}if(i!==void 0&&a.aborted){let e=(await s.cleanup(AbortSignal.timeout(5e3))).flatMap(e=>e.status===`rejected`?[toErrorMessage(e.reason)]:[]);if(e.length>0){let t=`Eval timeout cleanup failed: ${e.join(`; `)}`;d=d===void 0?t:`${d}\n${t}`}}let p=buildTaskResult({logs:l,sessions:s.snapshots(),turn:s.lastTurnSession()?.lastTurn});return{result:p,assertions:await o.finalize(p),error:d,skipReason:f}}function buildTaskResult(e){let t=e.sessions.flatMap(e=>e.events),n=e.turn?.message??null;return{output:e.turn?.data===void 0?n:e.turn.data,finalMessage:n,sessionId:selectPrimarySessionId(e.sessions),status:e.turn?.status??`completed`,events:t,logs:e.logs,derived:combineDerivedFacts(e.sessions),sessions:e.sessions,runtimeIdentity:extractRuntimeIdentity(t),traceContexts:collectTraceContexts(e.sessions)}}function collectTraceContexts(e){return e.flatMap(e=>{let t=e.sessionId;return t===void 0?[]:e.traceContexts.map(n=>({...n,primary:e.primary,sessionId:t}))})}function combineDerivedFacts(e){if(e.length===0)return createEmptyDerivedFacts();let t=e.flatMap(e=>e.derived.toolCalls),n=e.flatMap(e=>e.derived.subagentCalls),r=e.flatMap(e=>e.derived.inputRequests),i=e.find(e=>e.derived.failureCode!==void 0)?.derived.failureCode;return{toolCalls:t,toolCallCount:t.length,subagentCalls:n,subagentCallCount:n.length,inputRequests:r,parked:e.some(e=>e.derived.parked),messageCount:sum(e,e=>e.derived.messageCount),reasoningBlockCount:sum(e,e=>e.derived.reasoningBlockCount),failureCode:i}}function selectPrimarySessionId(e){return e.find(e=>e.primary)?.sessionId??e[0]?.sessionId}function extractRuntimeIdentity(e){for(let t of e)if(t.type===`session.started`&&t.data.runtime!==void 0)return t.data.runtime}function sum(e,t){return e.reduce((e,n)=>e+t(n),0)}function neverAbortSignal(){return new AbortController().signal}async function runUntilAborted(e,t){t.throwIfAborted();let onAbort,n=new Promise((e,n)=>{onAbort=()=>n(t.reason),t.addEventListener(`abort`,onAbort,{once:!0})});try{await Promise.race([e,n])}finally{onAbort!==void 0&&t.removeEventListener(`abort`,onAbort)}}export{executeTask};
@@ -0,0 +1,27 @@
1
+ import type { CreateSessionOptions, SendTurnInput, SendTurnOptions } from "#client/types.js";
2
+ import type { Client } from "#client/client.js";
3
+ import { AssertionCollector } from "#evals/assertions/collector.js";
4
+ import { EvalSessionDriver, type EvalSessionStartedEvent } from "#evals/session.js";
5
+ import type { EveEvalLiveTurn, EveEvalSessionResult } from "#evals/types.js";
6
+ export declare class EvalSessionManager {
7
+ #private;
8
+ constructor(input: {
9
+ readonly client: Client;
10
+ readonly collector?: AssertionCollector;
11
+ readonly onSessionStart?: (event: EvalSessionStartedEvent) => void;
12
+ readonly signal?: AbortSignal;
13
+ });
14
+ session(options?: CreateSessionOptions): Promise<EvalSessionDriver>;
15
+ send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<import("#evals/types.js").EveEvalTurn>;
16
+ attachSession(sessionId: string, options?: {
17
+ readonly startIndex?: number;
18
+ }): Promise<EvalSessionDriver>;
19
+ watchTurn(sessionId: string, options?: {
20
+ readonly startIndex?: number;
21
+ }): EveEvalLiveTurn;
22
+ snapshots(): readonly EveEvalSessionResult[];
23
+ lastTurnSession(): EvalSessionDriver | undefined;
24
+ hasActivity(): boolean;
25
+ /** @internal */
26
+ cleanup(signal: AbortSignal): Promise<readonly PromiseSettledResult<void>[]>;
27
+ }
@@ -0,0 +1 @@
1
+ import{AssertionCollector}from"#evals/assertions/collector.js";import{EvalSessionDriver}from"#evals/session.js";import{cleanupEvalSessions}from"#evals/session-cleanup.js";var EvalSessionManager=class{#e;#t;#n;#r;#i=[];#a;constructor(e){this.#e=e.client,this.#n=e.collector??new AssertionCollector,this.#r=e.onSessionStart,this.#t=e.signal}async session(e={}){let{session:t}=await this.#e.sessions.create({...e,signal:e.signal??this.#t});return this.#o(t)}async send(e,t={}){let{session:n,response:r}=await this.#e.sessions.create({turnPolicy:`queue`,...t,message:e,signal:t.signal??this.#t});return await this.#o(n).consume(r,e).result()}async attachSession(e,t){let n=this.#s(e,t);return await n.readTurn(t),n}watchTurn(e,t){return this.#s(e,t).watchTurn(t)}snapshots(){return this.#i.map(e=>e.snapshot())}lastTurnSession(){return this.#a}hasActivity(){return this.#i.length>0}async cleanup(e){return await cleanupEvalSessions(this.#i,e)}#o(e){let t=new EvalSessionDriver({collector:this.#n,onSessionStart:this.#r,onTurn:e=>{this.#a=e},primary:this.#i.length===0,session:e,signal:this.#t});return this.#i.push(t),t}#s(e,t){return this.#o(this.#e.sessions.attach(e,{streamIndex:t?.startIndex??0}))}};export{EvalSessionManager};
@@ -1,4 +1,3 @@
1
- import type { Client } from "#client/client.js";
2
1
  import type { ClientSession } from "#client/session.js";
3
2
  import type { CancelSessionResult, ClientSessionState, SendTurnInput, SendTurnOptions } from "#client/types.js";
4
3
  import type { MessageStreamEvent, RuntimeTraceContext, TurnFailureStreamEvent } from "#protocol/message.js";
@@ -25,19 +24,20 @@ export interface EvalSessionStartedEvent {
25
24
  export declare class EvalSessionDriver implements EveEvalSession {
26
25
  #private;
27
26
  constructor(input: {
28
- readonly client: Client;
29
27
  readonly collector: AssertionCollector;
30
28
  readonly onSessionStart?: (event: EvalSessionStartedEvent) => void;
31
29
  readonly primary: boolean;
32
- readonly session?: ClientSession;
30
+ readonly session: ClientSession;
31
+ readonly onTurn: (session: EvalSessionDriver) => void;
33
32
  readonly signal?: AbortSignal;
34
33
  });
35
34
  get events(): readonly MessageStreamEvent[];
36
35
  get transcript(): string;
36
+ get lastInput(): string;
37
37
  get lastTurn(): EveEvalTurn | undefined;
38
38
  get pendingInputRequests(): readonly InputRequest[];
39
- get sessionId(): string | undefined;
40
- get state(): ClientSessionState | undefined;
39
+ get sessionId(): string;
40
+ get state(): ClientSessionState;
41
41
  cancel(): Promise<CancelSessionResult>;
42
42
  /** @internal */
43
43
  cleanup(signal: AbortSignal): Promise<void>;
@@ -47,34 +47,14 @@ export declare class EvalSessionDriver implements EveEvalSession {
47
47
  respondAll(optionId: string): Promise<EveEvalTurn>;
48
48
  send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<EveEvalTurn>;
49
49
  start(message: string, options?: SendTurnOptions): Promise<EveEvalLiveTurn>;
50
+ /** @internal */
51
+ consume(events: AsyncIterable<MessageStreamEvent>, message?: SendTurnInput["message"]): EveEvalLiveTurn;
50
52
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
51
53
  readTurn(options?: {
52
54
  readonly startIndex?: number;
53
55
  }): Promise<EveEvalTurn>;
54
56
  watchTurn(options?: {
55
57
  readonly startIndex?: number;
56
- }, sessionId?: string): EveEvalLiveTurn;
57
- snapshot(): EveEvalSessionResult;
58
- }
59
- export declare class EvalSessionManager {
60
- #private;
61
- constructor(input: {
62
- readonly client: Client;
63
- readonly collector?: AssertionCollector;
64
- readonly onSessionStart?: (event: EvalSessionStartedEvent) => void;
65
- readonly signal?: AbortSignal;
66
- });
67
- get primary(): EvalSessionDriver;
68
- newSession(): EvalSessionDriver;
69
- attachSession(sessionId: string, options?: {
70
- readonly startIndex?: number;
71
- }): Promise<EvalSessionDriver>;
72
- watchTurn(sessionId: string, options?: {
73
- readonly startIndex?: number;
74
58
  }): EveEvalLiveTurn;
75
- snapshots(): readonly EveEvalSessionResult[];
76
- lastTurnSession(): EvalSessionDriver | undefined;
77
- hasActivity(): boolean;
78
- /** @internal */
79
- cleanup(signal: AbortSignal): Promise<readonly PromiseSettledResult<void>[]>;
59
+ snapshot(): EveEvalSessionResult;
80
60
  }
@@ -1 +1,2 @@
1
- import{readFile}from"node:fs/promises";import{basename}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{cleanupEvalSessions}from"#evals/session-cleanup.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n;#r;#i=[];#a;#o;#s=[];#c=new Set;#l;#u=!1;#d=[];constructor(e){this.#e=e.client,this.#r=e.collector,this.#o=e.onSessionStart,this.#a=e.primary,this.#t=e.session,this.#n=e.signal,Object.assign(this,createScopedAssertions(this.#r,{timing:`snapshot`,select:()=>this.#g()}),createOutputAssertions(this.#r,{timing:`snapshot`,select:()=>this.#g()}))}get events(){return this.#i}get transcript(){return formatEvalTranscript(this.#i)}get lastTurn(){return this.#l}get pendingInputRequests(){return this.#d}get sessionId(){return this.#t?.state.sessionId??this.#l?.sessionId}get state(){return this.#t?.state}async cancel(){if(this.#t===void 0)throw Error(`Eval session has not started.`);return await this.#t.cancel()}async cleanup(e){this.#t!==void 0&&await this.#t.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#d.length===0&&this.#_(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#d.filter(t=>inputRequestMatches(t,e));return(this.#d.length!==1||t.length!==1)&&this.#_(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#d.length} pending request(s)`),this.#r.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#f({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#f({...t,inputResponses:e})}async respondAll(e){let t=this.#d;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#f({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#f({turnPolicy:`queue`,...t,message:e})}async#f(e){let t=attachSignal(e,this.#n),n;if(this.#t===void 0){if(t.message===void 0)throw Error(`Eval session has not started.`);let e=await this.#e.sessions.create({...t,message:t.message});this.#t=e.session,n=e.response}else{let{inputResponses:e,message:r,...i}=t;n=e===void 0?await this.#t.send(r,i):await this.#t.respond(e,i)}return new EvalLiveTurn({events:n,observe:e=>this.#p(n.sessionId,e),record:e=>this.#h(n.sessionId,e),session:this,sessionId:n.sessionId})}async sendFile(e,t,n){let r=await readFile(t),i=createTextWithFileContent({bytes:r,filename:basename(t),mediaType:n??inferMediaType(t),text:e});return await this.send(i)}async readTurn(e){let t=this.sessionId;return await this.watchTurn(e,requireSessionId(t)).result()}watchTurn(e,t=requireSessionId(this.sessionId)){if(this.#t===void 0)throw Error(`Eval session has not started.`);return new EvalLiveTurn({events:this.#t.stream({signal:this.#n,startIndex:e?.startIndex}),observe:e=>this.#p(t,e),record:e=>this.#h(t,e),session:this,sessionId:t})}snapshot(){let e=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:e}),events:[...this.#i],primary:this.#a,sessionId:e,state:this.#t?.state,traceContexts:[...this.#s]}}#p(e,t){if(t.type!==`session.started`&&t.type!==`turn.started`)return;let n=t.data.trace;if(n===void 0)return;let r=`${n.traceId}:${n.spanId}`;this.#c.has(r)||(this.#c.add(r),this.#s.push(n),!this.#u&&(this.#u=!0,this.#o?.({primary:this.#a,sessionId:e,startedAt:t.meta.at,traceContext:n})))}#m(e){this.#i.push(...e.events),this.#d=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#r,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#l=n,n}#h(e,t){let n=summarizeTurnEvents(t);return this.#m({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#g(){let e=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:e}),events:[...this.#i],output:outputOf(this.#l),status:this.#l?.status??`completed`}}#_(e,t){throw this.#r.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.observe,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t,n){try{let r=!1;for await(let n of e)if(this.#t.push(n),t(n),this.#a(n),isTurnFailureEvent(n)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${n.type}).`)),isCurrentTurnBoundaryEvent(n)){r=!0,this.#o(Error(`Session ${this.sessionId} reached ${n.type} before the expected event.`));break}if(!r)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return n(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}},EvalSessionManager=class{#e;#t;#n;#r;#i=[];#a;constructor(e){this.#e=e.client,this.#n=e.collector??new AssertionCollector,this.#r=e.onSessionStart,this.#t=e.signal}get primary(){return this.#a??=this.#o(!0),this.#a}newSession(){return this.#o(!1)}async attachSession(e,t){let n=this.#s(e,t);return await n.readTurn(t),n}watchTurn(e,t){return this.#s(e,t).watchTurn(t,e)}snapshots(){return this.#i.map(e=>e.snapshot())}lastTurnSession(){return this.#a?.lastTurn===void 0?this.#i.find(e=>e.lastTurn!==void 0):this.#a}hasActivity(){return this.#i.length>0}async cleanup(e){return await cleanupEvalSessions(this.#i,e)}#o(e){let t=new EvalSessionDriver({client:this.#e,collector:this.#n,onSessionStart:this.#r,primary:e,signal:this.#t});return this.#i.push(t),t}#s(e,t){let n=new EvalSessionDriver({client:this.#e,collector:this.#n,onSessionStart:this.#r,primary:!1,session:this.#e.sessions.attach(e,{streamIndex:t?.startIndex??0}),signal:this.#t});return this.#i.push(n),n}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function requireSessionId(e){if(e===void 0)throw Error(`Eval session produced a turn without a session id.`);return e}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}export{EvalSessionDriver,EvalSessionManager,EveEvalTurnFailedError};
1
+ import{readFile}from"node:fs/promises";import{basename}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n=``;#r;#i;#a=[];#o;#s;#c=[];#l=new Set;#u;#d=!1;#f=[];constructor(e){this.#i=e.collector,this.#s=e.onSessionStart,this.#o=e.primary,this.#e=e.session,this.#t=e.onTurn,this.#r=e.signal,Object.assign(this,createScopedAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}),createOutputAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}))}get events(){return this.#a}get transcript(){return formatEvalTranscript(this.#a)}get lastInput(){return this.#n}get lastTurn(){return this.#u}get pendingInputRequests(){return this.#f}get sessionId(){return this.#e.state.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}async cleanup(e){await this.#e.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#f.length===0&&this.#v(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#f.filter(t=>inputRequestMatches(t,e));return(this.#f.length!==1||t.length!==1)&&this.#v(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#f.length} pending request(s)`),this.#i.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#p({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#p({...t,inputResponses:e})}async respondAll(e){let t=this.#f;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#p({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#p({turnPolicy:`queue`,...t,message:e})}async#p(e){let{inputResponses:t,message:n,...r}=attachSignal(e,this.#r),i=t===void 0?await this.#e.send(n,r):await this.#e.respond(t,r);return this.consume(i,n)}consume(e,t){let n=this.sessionId;return new EvalLiveTurn({events:e,observe:e=>this.#m(n,e),record:e=>(t!==void 0&&(this.#n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
+ `)),this.#g(n,e)),session:this,sessionId:n})}async sendFile(e,t,n){let r=await readFile(t),i=createTextWithFileContent({bytes:r,filename:basename(t),mediaType:n??inferMediaType(t),text:e});return await this.send(i)}async readTurn(e){return await this.watchTurn(e).result()}watchTurn(e){return this.consume(this.#e.stream({signal:this.#r,startIndex:e?.startIndex}))}snapshot(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],primary:this.#o,sessionId:e,state:this.#e.state,traceContexts:[...this.#c]}}#m(e,t){if(t.type!==`session.started`&&t.type!==`turn.started`)return;let n=t.data.trace;if(n===void 0)return;let r=`${n.traceId}:${n.spanId}`;this.#l.has(r)||(this.#l.add(r),this.#c.push(n),!this.#d&&(this.#d=!0,this.#s?.({primary:this.#o,sessionId:e,startedAt:t.meta.at,traceContext:n})))}#h(e){this.#a.push(...e.events),this.#f=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#i,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,session:this,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#u=n,this.#t(this),n}#g(e,t){let n=summarizeTurnEvents(t);return this.#h({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#_(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],output:outputOf(this.#u),status:this.#u?.status??`completed`}}#v(e,t){throw this.#i.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.observe,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t,n){try{let r=!1;for await(let n of e)if(this.#t.push(n),t(n),this.#a(n),isTurnFailureEvent(n)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${n.type}).`)),isCurrentTurnBoundaryEvent(n)){r=!0,this.#o(Error(`Session ${this.sessionId} reached ${n.type} before the expected event.`));break}if(!r)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return n(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;session;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.session=e.session,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}export{EvalSessionDriver,EveEvalTurnFailedError};
@@ -1,5 +1,5 @@
1
1
  import { Client } from "#client/client.js";
2
- import { EvalSessionManager } from "#evals/session.js";
2
+ import { EvalSessionManager } from "#evals/session-manager.js";
3
3
  import type { EveEvalTargetCapabilities, EveEvalTargetHandle } from "#evals/types.js";
4
4
  export declare function resolveEvalTargetHandle(input: {
5
5
  readonly client: Client;
@@ -1 +1 @@
1
- import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);return createEvalTargetHandle({capabilities:capabilitiesFromInfo(t),client:e.client,kind:e.kind,url:e.url})}function createEvalTargetHandle(e){return createHandle({capabilities:e.capabilities,client:e.client,kind:e.kind,sessions:void 0,url:e.url})}function scopeEvalTargetHandle(e,t){return createHandle({capabilities:e.capabilities,client:void 0,delegate:e,kind:e.kind,sessions:t.sessions,url:e.url})}function createHandle(e){let t=e.delegate,n=e.client,fetchTarget=async(e,r)=>{if(t!==void 0)return await t.fetch(e,r);if(n===void 0)throw Error(`Eval target cannot fetch without a client.`);return await n.fetch(e,r)};return{capabilities:e.capabilities,kind:e.kind,url:e.url,async attachSession(r,i){if(e.sessions!==void 0)return await e.sessions.attachSession(r,i);if(t!==void 0)return await t.attachSession(r,i);if(n===void 0)throw Error(`Eval target cannot attach sessions without a client.`);return await new EvalSessionManager({client:n}).attachSession(r,i)},watchTurn(r,i){if(e.sessions!==void 0)return e.sessions.watchTurn(r,i);if(t!==void 0)return t.watchTurn(r,i);if(n===void 0)throw Error(`Eval target cannot watch sessions without a client.`);return new EvalSessionManager({client:n}).watchTurn(r,i)},async dispatchSchedule(t){if(!e.capabilities.devRoutes)throw Error(`target.dispatchSchedule() requires a target with dev routes enabled.`);let n=await fetchTarget(createEveDevDispatchSchedulePath(t),{method:`POST`});if(!n.ok){let e=await readResponseBodySafely(n);throw Error(`Schedule dispatch failed: ${n.status} ${n.statusText}`+(e.length>0?`, ${e}`:``))}return parseScheduleDispatchResult(await n.json())},async fetch(e,t){return await fetchTarget(e,t)}}}function capabilitiesFromInfo(e){return{devRoutes:e.capabilities?.devRoutes??e.mode===`development`}}function matchesExpectedAgentName(e,t){return t===e||t===stripNpmPackageScope(e)}async function waitForTargetHealth(e,t){let n=Date.now()+6e4,r;for(;Date.now()<n;)try{await e.health();return}catch(e){r=toErrorMessage(e),await setTimeout(250)}throw Error(`Timed out waiting for eval target health at ${t}.`+(r===void 0?``:` Last error: ${r}`))}function assertAgentInfoShape(e,t){if(e.kind!==`eve-agent-info`||e.version!==4)throw Error(`Eval target ${t} returned an unrecognized /eve/v1/info payload.`)}function parseScheduleDispatchResult(e){if(typeof e!=`object`||!e||!(`scheduleId`in e)||typeof e.scheduleId!=`string`||!(`sessionIds`in e)||!Array.isArray(e.sessionIds)||e.sessionIds.some(e=>typeof e!=`string`))throw Error(`Schedule dispatch returned an unexpected response shape: ${JSON.stringify(e)}`);return{scheduleId:e.scheduleId,sessionIds:[...e.sessionIds]}}async function readResponseBodySafely(e){try{return(await e.text()).trim()}catch{return``}}export{createEvalTargetHandle,resolveEvalTargetHandle,scopeEvalTargetHandle};
1
+ import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session-manager.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);return createEvalTargetHandle({capabilities:capabilitiesFromInfo(t),client:e.client,kind:e.kind,url:e.url})}function createEvalTargetHandle(e){return createHandle({capabilities:e.capabilities,client:e.client,kind:e.kind,sessions:void 0,url:e.url})}function scopeEvalTargetHandle(e,t){return createHandle({capabilities:e.capabilities,client:void 0,delegate:e,kind:e.kind,sessions:t.sessions,url:e.url})}function createHandle(e){let t=e.delegate,n=e.client,fetchTarget=async(e,r)=>{if(t!==void 0)return await t.fetch(e,r);if(n===void 0)throw Error(`Eval target cannot fetch without a client.`);return await n.fetch(e,r)};return{capabilities:e.capabilities,kind:e.kind,url:e.url,async attachSession(r,i){if(e.sessions!==void 0)return await e.sessions.attachSession(r,i);if(t!==void 0)return await t.attachSession(r,i);if(n===void 0)throw Error(`Eval target cannot attach sessions without a client.`);return await new EvalSessionManager({client:n}).attachSession(r,i)},watchTurn(r,i){if(e.sessions!==void 0)return e.sessions.watchTurn(r,i);if(t!==void 0)return t.watchTurn(r,i);if(n===void 0)throw Error(`Eval target cannot watch sessions without a client.`);return new EvalSessionManager({client:n}).watchTurn(r,i)},async dispatchSchedule(t){if(!e.capabilities.devRoutes)throw Error(`target.dispatchSchedule() requires a target with dev routes enabled.`);let n=await fetchTarget(createEveDevDispatchSchedulePath(t),{method:`POST`});if(!n.ok){let e=await readResponseBodySafely(n);throw Error(`Schedule dispatch failed: ${n.status} ${n.statusText}`+(e.length>0?`, ${e}`:``))}return parseScheduleDispatchResult(await n.json())},async fetch(e,t){return await fetchTarget(e,t)}}}function capabilitiesFromInfo(e){return{devRoutes:e.capabilities?.devRoutes??e.mode===`development`}}function matchesExpectedAgentName(e,t){return t===e||t===stripNpmPackageScope(e)}async function waitForTargetHealth(e,t){let n=Date.now()+6e4,r;for(;Date.now()<n;)try{await e.health();return}catch(e){r=toErrorMessage(e),await setTimeout(250)}throw Error(`Timed out waiting for eval target health at ${t}.`+(r===void 0?``:` Last error: ${r}`))}function assertAgentInfoShape(e,t){if(e.kind!==`eve-agent-info`||e.version!==4)throw Error(`Eval target ${t} returned an unrecognized /eve/v1/info payload.`)}function parseScheduleDispatchResult(e){if(typeof e!=`object`||!e||!(`scheduleId`in e)||typeof e.scheduleId!=`string`||!(`sessionIds`in e)||!Array.isArray(e.sessionIds)||e.sessionIds.some(e=>typeof e!=`string`))throw Error(`Schedule dispatch returned an unexpected response shape: ${JSON.stringify(e)}`);return{scheduleId:e.scheduleId,sessionIds:[...e.sessionIds]}}async function readResponseBodySafely(e){try{return(await e.text()).trim()}catch{return``}}export{createEvalTargetHandle,resolveEvalTargetHandle,scopeEvalTargetHandle};
@@ -1,7 +1,7 @@
1
1
  import type { LanguageModel } from "ai";
2
2
  import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
3
3
  import type { RuntimeIdentity, RuntimeTraceContext, MessageStreamEvent } from "#protocol/message.js";
4
- import type { CancelSessionResult, ClientSessionState, SendTurnInput, SendTurnOptions } from "#client/types.js";
4
+ import type { CancelSessionResult, ClientSessionState, CreateSessionOptions, SendTurnInput, SendTurnOptions } from "#client/types.js";
5
5
  import type { InputRequest, InputResponse } from "#shared/input.js";
6
6
  import type { JsonObject, JsonValue } from "#shared/json.js";
7
7
  import type { AgentModelOptionsDefinition } from "#shared/agent-definition.js";
@@ -240,7 +240,7 @@ export interface EveEvalLiveTurn {
240
240
  /** Wait until the live stream emits one typed event matching `options`. */
241
241
  waitForEvent<TType extends MessageStreamEvent["type"]>(type: TType, options?: EveEvalWaitForEventOptions<TType>): Promise<EveEvalStreamEvent<TType>>;
242
242
  }
243
- /** Operations and state shared by the primary eval context and independent sessions. */
243
+ /** Operations and state belonging to one accepted session. */
244
244
  export interface EveEvalSessionDriver {
245
245
  /** All events observed on this session so far. */
246
246
  readonly events: readonly MessageStreamEvent[];
@@ -252,9 +252,9 @@ export interface EveEvalSessionDriver {
252
252
  /** Input requests left pending by the last parked turn. */
253
253
  readonly pendingInputRequests: readonly InputRequest[];
254
254
  /** Serializable cursor for resuming this session. */
255
- readonly state: ClientSessionState | undefined;
256
- /** eve session id after the first successful send. */
257
- readonly sessionId: string | undefined;
255
+ readonly state: ClientSessionState;
256
+ /** Durable session id, available when the session is returned. */
257
+ readonly sessionId: string;
258
258
  /** Request cooperative cancellation of this session's active turn. */
259
259
  cancel(): Promise<CancelSessionResult>;
260
260
  /** Require exactly one pending input request matching `filter`, or abort dependent control flow. */
@@ -272,7 +272,7 @@ export interface EveEvalSessionDriver {
272
272
  /** Send one text turn with a local file attached as a data URL. */
273
273
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
274
274
  }
275
- /** Driver for one independent session, exposed by `t.newSession()` and target attachment helpers. */
275
+ /** One accepted session, exposed by `t.session()`, turns, and target attachment helpers. */
276
276
  export interface EveEvalSession extends EveEvalSessionDriver, EveEvalAssertions, EveEvalOutputAssertions {
277
277
  }
278
278
  /**
@@ -283,6 +283,8 @@ export interface EveEvalTurn extends EveEvalAssertions, EveEvalOutputAssertions
283
283
  readonly events: readonly MessageStreamEvent[];
284
284
  readonly inputRequests: readonly InputRequest[];
285
285
  readonly message: string | undefined;
286
+ /** Session that owns this turn; use it for follow-up messages. */
287
+ readonly session: EveEvalSession;
286
288
  readonly sessionId: string;
287
289
  readonly status: "completed" | "failed" | "waiting";
288
290
  readonly toolCalls: readonly EveEvalToolCall[];
@@ -304,7 +306,7 @@ export interface EveEvalJudgeConfig {
304
306
  * Per-call options for `t.judge.autoevals.*` assertions.
305
307
  */
306
308
  export interface JudgeOpts {
307
- /** Value to grade. Defaults to the final assistant message (`t.reply`). */
309
+ /** Value to grade. Defaults to the most recently settled turn’s assistant message. */
308
310
  readonly on?: unknown;
309
311
  /** Judge model for this call only; overrides the eval/config judge model. */
310
312
  readonly model?: LanguageModel;
@@ -330,26 +332,28 @@ export interface JudgeContext {
330
332
  readonly autoevals: AutoevalsJudges;
331
333
  }
332
334
  /**
333
- * The single context passed to an eval's `test(t)` function. It drives the
334
- * primary session, carries the run-level
335
- * and value-level assertion vocabulary, and exposes `judge` for LLM-as-judge.
335
+ * The context passed to `test(t)`. Creates independent sessions and carries
336
+ * run-level assertions, value-level assertions, and model-backed judges.
336
337
  *
337
338
  * Scoped assertions (`succeeded`, `calledTool`, …) record an entry evaluated
338
339
  * after the test body; `check`, `require`, and `judge` evaluate explicit values.
339
340
  */
340
- export interface EveEvalContext extends EveEvalSessionDriver, EveEvalAssertions {
341
+ export interface EveEvalContext extends EveEvalAssertions {
341
342
  /** Eval timeout signal. */
342
343
  readonly signal: AbortSignal;
343
344
  /** Current target under test. */
344
345
  readonly target: EveEvalTargetHandle;
345
- /** The primary session's last assistant message, or null. */
346
- readonly reply: string | null;
347
346
  /** Structured eval log hook. */
348
347
  log(message: string): void;
349
348
  /** Pause the eval task, defaulting to 1 second, while respecting the eval timeout signal. */
350
349
  sleep(ms?: number): Promise<void>;
351
- /** Create an additional independent session against the same target. */
352
- newSession(): EveEvalSession;
350
+ /**
351
+ * Create a new session without starting a turn or reading events. Resolves on
352
+ * acceptance with a definite session id and cursor. Every call creates a session.
353
+ */
354
+ session(options?: CreateSessionOptions): Promise<EveEvalSession>;
355
+ /** Create a new session with its first message and wait for the turn to settle. */
356
+ send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<EveEvalTurn>;
353
357
  /** Apply a value-level assertion (from `eve/evals/expect`) to a value. */
354
358
  check(value: unknown, assertion: Assertion): AssertionHandle;
355
359
  /** Record an immediate gate and abort dependent control flow when it fails. */
@@ -0,0 +1,24 @@
1
+ import type { UserContent } from "ai";
2
+ import type { ActivityObserverConfig, SessionCallback, SessionCapabilities } from "#channel/types.js";
3
+ import type { JsonObject } from "#shared/json.js";
4
+ import type { RunMode } from "#shared/run-mode.js";
5
+ export interface ParsedCreateBody {
6
+ activityObserver?: ActivityObserverConfig;
7
+ callback?: SessionCallback;
8
+ capabilities?: SessionCapabilities;
9
+ message?: string | UserContent;
10
+ mode?: RunMode;
11
+ context?: readonly string[];
12
+ operationId?: string;
13
+ outputSchema?: JsonObject;
14
+ }
15
+ /** Enforces the fields that only make sense when creation also starts a turn. */
16
+ export declare function validateMessageFreeCreate(input: {
17
+ readonly activityObserver: ActivityObserverConfig | undefined;
18
+ readonly callback: SessionCallback | undefined;
19
+ readonly hasClientContext: boolean;
20
+ readonly hasMessageField: boolean;
21
+ readonly message: string | UserContent | undefined;
22
+ readonly mode: RunMode | undefined;
23
+ readonly outputSchema: JsonObject | undefined;
24
+ }): Response | undefined;
@@ -0,0 +1 @@
1
+ function validateMessageFreeCreate(e){if(e.hasMessageField&&e.message===void 0)return Response.json({error:`Expected 'message' to be non-empty when provided.`,ok:!1},{status:400});if(e.message===void 0){if(e.mode===`task`)return Response.json({error:`Task sessions require a non-empty 'message'.`,ok:!1},{status:400});if(e.hasClientContext||e.callback!==void 0||e.activityObserver!==void 0||e.outputSchema!==void 0)return Response.json({error:`Creating a session without a message does not accept 'clientContext', 'callback', 'activityObserver', or 'outputSchema'.`,ok:!1},{status:400})}}export{validateMessageFreeCreate};