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.
- package/CHANGELOG.md +28 -0
- package/dist/src/approval/definition.d.ts +2 -0
- package/dist/src/channel/session.d.ts +2 -0
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +8 -1
- package/dist/src/chunks/{use-eve-agent-X0asmJg-.js → use-eve-agent-Dmc6sX4d.js} +558 -233
- package/dist/src/chunks/{use-eve-agent-CxWcZCsU.js → use-eve-agent-jSR8P4nK.js} +565 -235
- package/dist/src/cli/dev/tui/runner.d.ts +4 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/client/eve-agent-projection.d.ts +10 -0
- package/dist/src/client/eve-agent-projection.js +1 -0
- package/dist/src/client/eve-agent-store-helpers.d.ts +6 -2
- package/dist/src/client/eve-agent-store-helpers.js +2 -2
- package/dist/src/client/eve-agent-store-state.d.ts +54 -1
- package/dist/src/client/eve-agent-store.d.ts +12 -82
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +2 -2
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-response.d.ts +5 -1
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/ndjson.d.ts +1 -0
- package/dist/src/client/ndjson.js +2 -2
- package/dist/src/client/open-stream.d.ts +4 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-event-stream.d.ts +30 -0
- package/dist/src/client/session-event-stream.js +1 -0
- package/dist/src/client/session-utils.d.ts +2 -1
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +14 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +8 -2
- package/dist/src/client/sessions.js +1 -1
- package/dist/src/client/types.d.ts +7 -0
- package/dist/src/compiled/.vendor-stamp.json +2 -3
- package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +88 -1
- package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +1 -1
- package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +41 -1
- package/dist/src/compiled/@vercel/sandbox/constants.d.ts +3 -3
- package/dist/src/compiled/@vercel/{sandbox-drives → sandbox}/drive.d.ts +13 -2
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +3 -2
- package/dist/src/compiled/@vercel/sandbox/index.js +15 -9
- package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +40 -5
- package/dist/src/compiled/_chunks/node/auth-DDrvYko5.js +2 -0
- package/dist/src/compiled/_chunks/node/version-C__MqbLM.js +1 -0
- package/dist/src/compiler/default-tool-policy.d.ts +3 -1
- package/dist/src/compiler/default-tool-policy.js +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +16 -16
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +8 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest-helpers.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-subagent.d.ts +1 -0
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/remote-agent-node.d.ts +1 -0
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/compiler/source-graph.d.ts +1 -0
- package/dist/src/compiler/source-graph.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/memory-tools.js +1 -1
- package/dist/src/evals/context.d.ts +1 -1
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/define-eval.d.ts +1 -1
- package/dist/src/evals/define-eval.js +1 -1
- package/dist/src/evals/index.js +1 -1
- package/dist/src/evals/judge.d.ts +1 -1
- package/dist/src/evals/runner/execute-task.d.ts +1 -1
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/session-manager.d.ts +27 -0
- package/dist/src/evals/session-manager.js +1 -0
- package/dist/src/evals/session.d.ts +8 -28
- package/dist/src/evals/session.js +2 -1
- package/dist/src/evals/target.d.ts +1 -1
- package/dist/src/evals/target.js +1 -1
- package/dist/src/evals/types.d.ts +19 -15
- package/dist/src/eve-channel/create-request.d.ts +24 -0
- package/dist/src/eve-channel/create-request.js +1 -0
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/request.d.ts +3 -12
- package/dist/src/eve-channel/request.js +2 -2
- package/dist/src/eve-channel/types.d.ts +4 -2
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.d.ts +3 -3
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +1 -4
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +1 -2
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/program.d.ts +2 -0
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/session-inbox/protocol.js +1 -1
- package/dist/src/execution/tools/connection-search.js +1 -1
- package/dist/src/execution/tools/sleep-workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/experimental/evaluate/auto-model.js +2 -2
- package/dist/src/experimental/evaluate/evaluate.d.ts +7 -0
- package/dist/src/experimental/evaluate/evaluate.js +1 -0
- package/dist/src/framework/sources/registry.js +1 -1
- package/dist/src/harness/compaction.d.ts +3 -3
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/request-envelope.d.ts +11 -0
- package/dist/src/harness/request-envelope.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/tools.d.ts +1 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/instrumentation/prepare-trace-context.d.ts +2 -1
- package/dist/src/instrumentation/prepare-trace-context.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-module-loader.d.ts +4 -1
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/bundler/nitro-rolldown.d.ts +2 -0
- package/dist/src/internal/nitro/host/build-extension.js +1 -1
- package/dist/src/internal/nitro/host/extension-capability-requirements.d.ts +1 -0
- package/dist/src/internal/nitro/host/extension-capability-requirements.js +1 -1
- package/dist/src/internal/nitro/host/extension-distribution.d.ts +1 -1
- package/dist/src/internal/nitro/host/extension-distribution.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/public/definitions/connections/mcp.d.ts +1 -0
- package/dist/src/public/definitions/connections/openapi.d.ts +1 -0
- package/dist/src/public/definitions/remote-agent.d.ts +5 -0
- package/dist/src/public/definitions/workspace-agent.d.ts +5 -0
- package/dist/src/public/definitions/workspace-agent.js +1 -1
- package/dist/src/public/experimental/evaluate/index.d.ts +1 -0
- package/dist/src/public/experimental/evaluate/index.js +1 -1
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +1 -1
- package/dist/src/public/sandbox/vercel.d.ts +1 -1
- package/dist/src/public/sandbox/vercel.js +1 -1
- package/dist/src/public/tools/approval/index.d.ts +2 -1
- package/dist/src/public/tools/approval/index.js +1 -1
- package/dist/src/public/tools/index.d.ts +1 -0
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/react/use-eve-agent.d.ts +4 -0
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +1 -0
- package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.d.ts +1 -0
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/subagents/registry.d.ts +5 -2
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -0
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +9 -0
- package/dist/src/subagents/handle-dispatch.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +4 -0
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/approval/policies.d.ts +18 -0
- package/dist/src/tools/approval/policies.js +1 -1
- package/dist/src/tools/definition.d.ts +6 -3
- package/dist/src/tools/definition.js +1 -1
- package/dist/src/tools/durable-callbacks.d.ts +8 -2
- package/dist/src/tools/durable-callbacks.js +1 -1
- package/dist/src/tools/durable-schema.d.ts +16 -0
- package/dist/src/tools/durable-schema.js +1 -0
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +4 -0
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +1 -0
- package/docs/channels/eve.mdx +20 -10
- package/docs/concepts/context-control.md +4 -0
- package/docs/concepts/sessions-runs-and-streaming.md +18 -3
- package/docs/connections/mcp.mdx +2 -2
- package/docs/connections/overview.mdx +1 -1
- package/docs/evals/assertions.mdx +6 -6
- package/docs/evals/cases.mdx +59 -23
- package/docs/evals/judge.mdx +10 -8
- package/docs/evals/overview.mdx +6 -6
- package/docs/evals/reporters.mdx +1 -1
- package/docs/evals/targets.mdx +5 -0
- package/docs/guides/client/messages.mdx +5 -5
- package/docs/guides/client/overview.mdx +15 -1
- package/docs/guides/dynamic-capabilities.md +22 -0
- package/docs/guides/evaluate.md +78 -3
- package/docs/guides/frontend/overview.mdx +54 -5
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +13 -8
- package/docs/guides/frontend/use-eve-agent-vue.mdx +13 -8
- package/docs/guides/remote-agents.md +2 -1
- package/docs/reference/typescript-api.md +38 -37
- package/docs/subagents/index.mdx +25 -8
- package/docs/tools/human-in-the-loop.md +27 -5
- package/docs/tools/overview.mdx +2 -2
- package/docs/tools/workflows.mdx +2 -3
- package/package.json +2 -3
- package/dist/src/compiled/@vercel/sandbox-drives/LICENSE +0 -201
- package/dist/src/compiled/@vercel/sandbox-drives/_async-retry.d.ts +0 -8
- package/dist/src/compiled/@vercel/sandbox-drives/_workflow-serde.d.ts +0 -5
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/api-client.d.ts +0 -1815
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/api-error.d.ts +0 -29
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/base-client.d.ts +0 -39
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/file-writer.d.ts +0 -66
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/index.d.ts +0 -2
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/validators.d.ts +0 -932
- package/dist/src/compiled/@vercel/sandbox-drives/api-client/with-retry.d.ts +0 -10
- package/dist/src/compiled/@vercel/sandbox-drives/auth/error.d.ts +0 -15
- package/dist/src/compiled/@vercel/sandbox-drives/auth/file.d.ts +0 -18
- package/dist/src/compiled/@vercel/sandbox-drives/auth/index.d.ts +0 -6
- package/dist/src/compiled/@vercel/sandbox-drives/auth/oauth.d.ts +0 -111
- package/dist/src/compiled/@vercel/sandbox-drives/auth/poll-for-token.d.ts +0 -28
- package/dist/src/compiled/@vercel/sandbox-drives/auth/project.d.ts +0 -40
- package/dist/src/compiled/@vercel/sandbox-drives/command.d.ts +0 -292
- package/dist/src/compiled/@vercel/sandbox-drives/constants.d.ts +0 -15
- package/dist/src/compiled/@vercel/sandbox-drives/execution-context.d.ts +0 -116
- package/dist/src/compiled/@vercel/sandbox-drives/filesystem.d.ts +0 -258
- package/dist/src/compiled/@vercel/sandbox-drives/index.d.ts +0 -14
- package/dist/src/compiled/@vercel/sandbox-drives/index.js +0 -9
- package/dist/src/compiled/@vercel/sandbox-drives/network-policy.d.ts +0 -169
- package/dist/src/compiled/@vercel/sandbox-drives/proxy.d.ts +0 -55
- package/dist/src/compiled/@vercel/sandbox-drives/sandbox-user.d.ts +0 -211
- package/dist/src/compiled/@vercel/sandbox-drives/sandbox.d.ts +0 -1287
- package/dist/src/compiled/@vercel/sandbox-drives/session.d.ts +0 -435
- package/dist/src/compiled/@vercel/sandbox-drives/snapshot.d.ts +0 -238
- package/dist/src/compiled/@vercel/sandbox-drives/utils/get-credentials.d.ts +0 -21
- package/dist/src/compiled/@vercel/sandbox-drives/utils/paginator.d.ts +0 -16
- package/dist/src/compiled/@vercel/sandbox-drives/utils/resolveSignal.d.ts +0 -15
- package/dist/src/compiled/@vercel/sandbox-drives/utils/sandbox-snapshot.d.ts +0 -11
- package/dist/src/compiled/@vercel/sandbox-drives/utils/types.d.ts +0 -11
- package/dist/src/compiled/_chunks/node/auth-8aQozzfi.js +0 -2
- package/dist/src/compiled/_chunks/node/auth-Bvv0xGTY.js +0 -2
- package/dist/src/compiled/_chunks/node/esm-Fqlolk7e.js +0 -7
- package/dist/src/compiled/_chunks/node/version-BC6t2Txc.js +0 -1
- package/dist/src/compiled/_chunks/node/version-DSQqVZ5T.js +0 -1
- 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:
|
|
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:
|
|
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
|
|
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.
|
|
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(
|
|
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};
|
package/dist/src/evals/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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 (
|
|
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 {
|
|
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
|
|
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
|
|
40
|
-
get state(): ClientSessionState
|
|
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
|
-
|
|
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
|
|
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;
|
package/dist/src/evals/target.js
CHANGED
|
@@ -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
|
|
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
|
|
256
|
-
/**
|
|
257
|
-
readonly sessionId: string
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
334
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
352
|
-
|
|
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};
|