eve 0.76.3 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/src/channel/adapter.d.ts +13 -4
  3. package/dist/src/channel/channel-address.js +1 -1
  4. package/dist/src/channel/send-input.d.ts +6 -2
  5. package/dist/src/channel/send-input.js +1 -1
  6. package/dist/src/channel/session.js +1 -1
  7. package/dist/src/chunks/{use-eve-agent-BtKWTEpm.js → use-eve-agent-B8brxCk-.js} +46 -28
  8. package/dist/src/chunks/{use-eve-agent-jI6EsYAu.js → use-eve-agent-BSYe_Re7.js} +46 -28
  9. package/dist/src/cli/commands/vercel-non-interactive.d.ts +5 -3
  10. package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
  11. package/dist/src/client/eve-agent-store.d.ts +2 -2
  12. package/dist/src/client/message-response.d.ts +2 -0
  13. package/dist/src/client/message-response.js +1 -1
  14. package/dist/src/client/session.js +1 -1
  15. package/dist/src/compiled/.vendor-stamp.json +9 -9
  16. package/dist/src/compiled/@ai-sdk/anthropic/index.d.ts +6 -1
  17. package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -1
  18. package/dist/src/compiled/@ai-sdk/google/index.d.ts +16 -3
  19. package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
  20. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +681 -348
  21. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  22. package/dist/src/compiled/@ai-sdk/openai/index.d.ts +56 -42
  23. package/dist/src/compiled/@ai-sdk/openai/index.js +5 -3
  24. package/dist/src/compiled/@ai-sdk/otel/index.js +3 -3
  25. package/dist/src/compiled/@ai-sdk/provider/index.d.ts +49 -15
  26. package/dist/src/compiled/@ai-sdk/provider/index.js +1 -1
  27. package/dist/src/compiled/@ai-sdk/provider-utils/index.d.ts +4 -1
  28. package/dist/src/compiled/_chunks/workflow/{dist-DXLdlucM.js → dist-C8k3N3BQ.js} +2 -4
  29. package/dist/src/compiled/_chunks/workflow/dist-DsNhwdzf.js +1 -0
  30. package/dist/src/compiled/_chunks/workflow/experimental-decision-DlvnsBD-.js +3 -0
  31. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  32. package/dist/src/compiler/extension-compatibility.js +1 -1
  33. package/dist/src/compiler/normalize-agent-config.js +1 -1
  34. package/dist/src/context/dynamic-model-lifecycle.js +1 -1
  35. package/dist/src/context/keys.d.ts +16 -0
  36. package/dist/src/context/keys.js +1 -1
  37. package/dist/src/evals/judge.js +1 -1
  38. package/dist/src/eve-channel/index.js +1 -1
  39. package/dist/src/eve-channel/types.d.ts +14 -1
  40. package/dist/src/execution/agent-sessions/steps.d.ts +2 -0
  41. package/dist/src/execution/agent-sessions/steps.js +1 -1
  42. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  43. package/dist/src/execution/catalog/connection-entry.js +1 -1
  44. package/dist/src/execution/catalog/search.js +1 -1
  45. package/dist/src/execution/catalog/step-catalog.d.ts +12 -3
  46. package/dist/src/execution/catalog/step-catalog.js +1 -1
  47. package/dist/src/execution/coordination-dispatch-shared.d.ts +1 -2
  48. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  49. package/dist/src/execution/coordination-dispatch-step.js +1 -1
  50. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  51. package/dist/src/execution/publish-session-events.js +1 -1
  52. package/dist/src/execution/sandbox/bindings/docker-container.js +1 -1
  53. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  54. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  55. package/dist/src/execution/sandbox/bindings/just-bash.d.ts +1 -1
  56. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  57. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  58. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  59. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  60. package/dist/src/execution/sandbox/read-file.d.ts +5 -5
  61. package/dist/src/execution/sandbox/read-file.js +2 -2
  62. package/dist/src/execution/sandbox/session.d.ts +6 -0
  63. package/dist/src/execution/sandbox/session.js +2 -2
  64. package/dist/src/execution/session/active-turn.d.ts +9 -1
  65. package/dist/src/execution/session/active-turn.js +1 -1
  66. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  67. package/dist/src/execution/session/end-sandbox-step.js +1 -1
  68. package/dist/src/execution/session/handoff.d.ts +1 -1
  69. package/dist/src/execution/session/handoff.js +1 -1
  70. package/dist/src/execution/session/next-input.js +1 -1
  71. package/dist/src/execution/session/turn-step.js +1 -1
  72. package/dist/src/execution/session/turn.d.ts +11 -4
  73. package/dist/src/execution/session/turn.js +1 -1
  74. package/dist/src/execution/session-inbox/inbox.d.ts +3 -0
  75. package/dist/src/execution/session-inbox/inbox.js +1 -1
  76. package/dist/src/execution/session-workflow-tool-run.d.ts +14 -12
  77. package/dist/src/execution/session-workflow-tool-run.js +1 -1
  78. package/dist/src/execution/tasks/start.d.ts +14 -1
  79. package/dist/src/execution/tasks/start.js +1 -1
  80. package/dist/src/execution/tasks/steps.d.ts +7 -4
  81. package/dist/src/execution/tasks/steps.js +1 -1
  82. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  83. package/dist/src/execution/tools/workflow/apply-run-messages-step.d.ts +20 -0
  84. package/dist/src/execution/tools/workflow/apply-run-messages-step.js +1 -0
  85. package/dist/src/execution/tools/workflow/ask.d.ts +0 -1
  86. package/dist/src/execution/tools/workflow/ask.js +1 -1
  87. package/dist/src/execution/tools/workflow/interrupt.d.ts +5 -2
  88. package/dist/src/execution/tools/workflow/interrupt.js +1 -1
  89. package/dist/src/execution/tools/workflow/messages.d.ts +14 -0
  90. package/dist/src/execution/tools/workflow/messages.js +1 -1
  91. package/dist/src/execution/tools/workflow/owner.d.ts +18 -6
  92. package/dist/src/execution/tools/workflow/owner.js +1 -1
  93. package/dist/src/execution/tools/workflow/start.d.ts +10 -0
  94. package/dist/src/execution/tools/workflow/start.js +1 -1
  95. package/dist/src/execution/tools/workflow/step.js +1 -1
  96. package/dist/src/execution/tools/workflow/workflow-owner-blocking.d.ts +12 -0
  97. package/dist/src/execution/tools/workflow/workflow-owner-blocking.js +1 -1
  98. package/dist/src/execution/tools/workflow/workflow.js +1 -1
  99. package/dist/src/execution/web-fetch/request.js +1 -1
  100. package/dist/src/execution/workflow-runtime.d.ts +18 -3
  101. package/dist/src/execution/workflow-runtime.js +1 -1
  102. package/dist/src/harness/attachment-staging.d.ts +13 -12
  103. package/dist/src/harness/attachment-staging.js +1 -1
  104. package/dist/src/harness/compaction/step.js +1 -1
  105. package/dist/src/harness/emission.js +1 -1
  106. package/dist/src/harness/hitl/approvals.d.ts +4 -7
  107. package/dist/src/harness/hitl/approvals.js +1 -1
  108. package/dist/src/harness/hitl/approved-calls.d.ts +11 -0
  109. package/dist/src/harness/hitl/approved-calls.js +1 -1
  110. package/dist/src/harness/hitl/candidates.d.ts +0 -4
  111. package/dist/src/harness/hitl/candidates.js +1 -1
  112. package/dist/src/harness/hitl/delivery.d.ts +0 -1
  113. package/dist/src/harness/hitl/delivery.js +1 -1
  114. package/dist/src/harness/hitl/index.d.ts +2 -2
  115. package/dist/src/harness/hitl/index.js +1 -1
  116. package/dist/src/harness/hitl/intake.d.ts +2 -2
  117. package/dist/src/harness/hitl/intake.js +1 -1
  118. package/dist/src/harness/model-call/call.js +1 -1
  119. package/dist/src/harness/model-call/errors.d.ts +10 -0
  120. package/dist/src/harness/model-call/errors.js +1 -1
  121. package/dist/src/harness/model-call/run.js +1 -1
  122. package/dist/src/harness/session-machine/state.d.ts +0 -2
  123. package/dist/src/harness/session-machine/transitions.js +1 -1
  124. package/dist/src/harness/session-machine/view.d.ts +0 -3
  125. package/dist/src/harness/session-machine/view.js +1 -1
  126. package/dist/src/harness/step/after-model.js +1 -1
  127. package/dist/src/harness/token-estimate.js +1 -1
  128. package/dist/src/harness/tool-loop.js +1 -1
  129. package/dist/src/harness/tools.js +1 -1
  130. package/dist/src/internal/application/package.js +1 -1
  131. package/dist/src/internal/application/stamped-package-version.js +1 -1
  132. package/dist/src/internal/attachments/data.d.ts +29 -10
  133. package/dist/src/internal/attachments/data.js +1 -1
  134. package/dist/src/internal/attachments/errors.d.ts +2 -2
  135. package/dist/src/internal/attachments/media-metadata.d.ts +15 -0
  136. package/dist/src/internal/attachments/media-metadata.js +1 -1
  137. package/dist/src/internal/attachments/public-link.d.ts +5 -0
  138. package/dist/src/internal/attachments/public-link.js +1 -0
  139. package/dist/src/internal/attachments/sandbox-refs.d.ts +7 -6
  140. package/dist/src/internal/attachments/sandbox-refs.js +1 -1
  141. package/dist/src/internal/attachments/url-refs.js +1 -1
  142. package/dist/src/protocol/message.d.ts +7 -0
  143. package/dist/src/protocol/message.js +2 -2
  144. package/dist/src/public/channels/attachment-error.d.ts +14 -0
  145. package/dist/src/public/channels/attachment-error.js +1 -0
  146. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
  147. package/dist/src/public/channels/discord/defaults.js +1 -1
  148. package/dist/src/public/channels/github/defaults.js +1 -1
  149. package/dist/src/public/channels/index.d.ts +2 -0
  150. package/dist/src/public/channels/index.js +1 -1
  151. package/dist/src/public/channels/linear/defaults.js +1 -1
  152. package/dist/src/public/channels/slack/api.d.ts +10 -0
  153. package/dist/src/public/channels/slack/api.js +1 -1
  154. package/dist/src/public/channels/slack/approval-cards.js +1 -1
  155. package/dist/src/public/channels/slack/attachments.d.ts +29 -19
  156. package/dist/src/public/channels/slack/attachments.js +1 -1
  157. package/dist/src/public/channels/slack/defaults.js +1 -1
  158. package/dist/src/public/channels/slack/inbound.d.ts +6 -0
  159. package/dist/src/public/channels/slack/inbound.js +1 -1
  160. package/dist/src/public/channels/slack/interaction-cards.d.ts +6 -0
  161. package/dist/src/public/channels/slack/interaction-cards.js +1 -1
  162. package/dist/src/public/channels/slack/interactions.js +1 -1
  163. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  164. package/dist/src/public/channels/teams/defaults.js +1 -1
  165. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  166. package/dist/src/public/channels/telegram/defaults.js +1 -1
  167. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  168. package/dist/src/public/channels/twilio/defaults.js +1 -1
  169. package/dist/src/public/definitions/channel.js +1 -1
  170. package/dist/src/runtime/channels/registry.js +1 -1
  171. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  172. package/dist/src/setup/scaffold/create/project.js +2 -2
  173. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  174. package/dist/src/shared/agent-definition.d.ts +2 -1
  175. package/dist/src/shared/channel-definition.d.ts +16 -4
  176. package/dist/src/svelte/index.d.ts +0 -1
  177. package/dist/src/svelte/index.js +1 -1
  178. package/dist/src/svelte/use-eve-agent.js +1 -1
  179. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  180. package/dist/src/tools/provided/read-file.d.ts +3 -2
  181. package/dist/src/tools/provided/read-file.js +2 -2
  182. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  183. package/dist/src/vue/index.d.ts +0 -1
  184. package/dist/src/vue/index.js +1 -1
  185. package/dist/src/vue/use-eve-agent.js +1 -1
  186. package/docs/agent-config.md +12 -4
  187. package/docs/channels/chat-sdk.mdx +1 -1
  188. package/docs/channels/custom.mdx +30 -3
  189. package/docs/channels/eve.mdx +34 -0
  190. package/docs/channels/slack.mdx +5 -1
  191. package/docs/concepts/built-in-tools.md +10 -10
  192. package/docs/concepts/sessions-runs-and-streaming.md +2 -2
  193. package/docs/evals/overview.mdx +1 -1
  194. package/docs/guides/client/streaming.mdx +1 -1
  195. package/docs/guides/dynamic-capabilities.md +6 -2
  196. package/docs/memory/custom-provider.md +3 -1
  197. package/docs/sandbox/index.mdx +10 -4
  198. package/docs/tools/human-in-the-loop.md +1 -1
  199. package/docs/tools/overview.mdx +1 -1
  200. package/package.json +11 -11
  201. package/dist/src/compiled/_chunks/workflow/experimental-decision-BrfWf6-n.js +0 -3
  202. package/dist/src/context/caller-scope.d.ts +0 -7
  203. package/dist/src/context/caller-scope.js +0 -1
  204. package/dist/src/execution/tools/workflow/emit-workflow-tool-run-report-step.d.ts +0 -13
  205. package/dist/src/execution/tools/workflow/emit-workflow-tool-run-report-step.js +0 -1
  206. package/dist/src/harness/hitl/approved-call-callers.d.ts +0 -14
  207. package/dist/src/harness/hitl/approved-call-callers.js +0 -1
  208. package/dist/src/internal/attachments/refs.d.ts +0 -55
  209. package/dist/src/internal/attachments/refs.js +0 -1
@@ -1 +1 @@
1
- import{isAbsolute,relative,resolve}from"node:path";import{normalizeLogicalPath}from"#discover/filesystem.js";import{toErrorMessage}from"#shared/errors.js";import{parseJsonObject}from"#shared/json.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";import{createCompiledBindingNamespaceLoader}from"#compiler/load-binding-namespace.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{classifyModelRouting}from"#internal/classify-model-routing.js";import{isChatGptModelRouting}from"#shared/chatgpt-model.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";async function compileAgentConfig(e,t,n){let r=n.source,i=formatAgentConfigModulePath(e,r,n.binding),a=normalizeAgentDefinition(Object.hasOwn(n,`definition`)?n.definition:await loadModuleBackedDefinition({binding:n.binding,displayPath:i,kind:`agent config`,loadNamespace:createCompiledBindingNamespaceLoader({appRoot:e.appRoot,bindings:{[r.sourceId]:n.binding},registries:t.registries}),source:r}),`Expected the agent config export "${r.exportName??`default`}" from "${i}" to match the public eve shape.`),o=isDynamicModelDefinition(a.model)?a.model:void 0,s=o===void 0?await normalizeAuthoredModelReference({modelCatalog:t.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:a.modelContextWindowTokens,promptCache:a.modelOptions?.promptCache,providerOptions:a.modelOptions?.providerOptions,source:r,sourcePath:i,value:a.model}):void 0,c={},l={compaction:c,name:e.agentId,source:{...r}};a.defaultTools!==void 0&&(l.defaultTools=a.defaultTools),a.description!==void 0&&(l.description=a.description);let u;o!==void 0&&(u={eventNames:Object.keys(o.events),exportName:r.exportName,sourceKind:`module`,logicalPath:r.logicalPath,sourceId:r.sourceId});let d=normalizeExperimentalDefinition(a.experimental);if(d!==void 0&&(l.experimental=d),a.build!==void 0&&(l.build={externalDependencies:a.build.externalDependencies===void 0?void 0:[...a.build.externalDependencies]}),a.reasoning!==void 0&&(l.reasoning=a.reasoning),a.tool!==void 0&&(l.tool=a.tool),a.limits!==void 0&&(l.limits={maxInputTokensPerSession:a.limits.maxInputTokensPerSession,maxOutputTokensPerSession:a.limits.maxOutputTokensPerSession,maxTokenCostUsdPerSession:a.limits.maxTokenCostUsdPerSession,sessionTimeoutMs:a.limits.sessionTimeoutMs}),a.compaction?.model!==void 0&&(c.model=await normalizeAuthoredModelReference({modelCatalog:t.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:a.compaction.modelContextWindowTokens,providerOptions:a.modelOptions?.providerOptions,source:r,sourcePath:i,value:a.compaction.model})),a.compaction?.thresholdPercent!==void 0&&(c.thresholdPercent=a.compaction.thresholdPercent),u!==void 0)return{...l,dynamicModel:u};if(s===void 0)throw Error(`Expected a static agent model to compile to a concrete model reference.`);return{...l,model:s}}function normalizeExperimentalDefinition(e){if(e===void 0)return;let t={};return e.workflow!==void 0&&(t.workflow={modelCallsPerStep:e.workflow.modelCallsPerStep,retention:e.workflow.retention,world:e.workflow.world}),t}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`){let t=classifyModelRouting(e.value,e.providerOptions);return rejectGatewayPromptCache(e,t),await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions),routing:t},e)}let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let n=e.value,r=n.specificationVersion;if(r!==`v2`&&r!==`v3`&&r!==`v4`||typeof n.provider!=`string`||typeof n.modelId!=`string`||typeof n.doGenerate!=`function`||typeof n.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${e.sourcePath??t.logicalPath}" to provide a valid AI SDK language model.`);let i=classifyModelRouting(n,e.providerOptions);rejectGatewayPromptCache(e,i);let a={id:formatLanguageModelGatewayId(n),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions),routing:i};if(e.promptCache!==void 0&&(a.promptCache=e.promptCache),e.contextWindowTokens===void 0){if(isChatGptModelRouting(a.routing))return{...a,contextWindowTokens:2e5};try{let t=await e.modelCatalog.getByProviderModelId(n.provider,n.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens,maxOutputTokens:t.limits.maxOutputTokens}}catch{}}return await withCompiledRuntimeModelLimits(a,e)}function rejectGatewayPromptCache(e,t){if(e.promptCache!==void 0&&t.kind===`gateway`)throw Error(`${e.sourcePath??`agent.ts`}: modelOptions.promptCache applies only to models eve calls directly, but "${formatLanguageModelGatewayId(e.value)}" routes through AI Gateway, which manages its own prompt caching. Remove promptCache, or configure Gateway caching with providerOptions.gateway.caching.`)}function formatAgentConfigModulePath(e,t,n){return n.backing.kind===`programmatic`?t.logicalPath:normalizeLogicalPath(relative(resolveTopLevelAgentRoot(e),n.backing.sourcePath))}function resolveTopLevelAgentRoot(e){let t=resolve(e.appRoot),n=resolve(t,`agent`);return isPathInsideOrEqual(n,resolve(e.agentRoot))?n:t}function isPathInsideOrEqual(e,t){let n=relative(e,t);return n===``||!n.startsWith(`..`)&&!isAbsolute(n)}async function withCompiledRuntimeModelLimits(e,t){if(t.contextWindowTokens!==void 0)return{...e,contextWindowTokens:t.contextWindowTokens};let n;try{n=await t.modelCatalog.getModelLimits(e.id)}catch(n){throw Error(`Failed to load AI Gateway model metadata for ${t.purpose} "${e.id}". ${toErrorMessage(n)}`)}if(n===null)throw Error(`Cannot compile agent compaction because ${t.purpose} "${e.id}" does not have known AI Gateway context window metadata.`);return{...e,contextWindowTokens:n.contextWindowTokens,maxOutputTokens:n.maxOutputTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,r]of Object.entries(e))t[n]=parseJsonObject(r);return t}export{compileAgentConfig};
1
+ import{isAbsolute,relative,resolve}from"node:path";import{normalizeLogicalPath}from"#discover/filesystem.js";import{toErrorMessage}from"#shared/errors.js";import{parseJsonObject}from"#shared/json.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";import{createCompiledBindingNamespaceLoader}from"#compiler/load-binding-namespace.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{classifyModelRouting}from"#internal/classify-model-routing.js";import{isMockModel}from"#internal/mock-model-identity.js";import{isChatGptModelRouting}from"#shared/chatgpt-model.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";async function compileAgentConfig(e,t,n){let r=n.source,i=formatAgentConfigModulePath(e,r,n.binding),a=normalizeAgentDefinition(Object.hasOwn(n,`definition`)?n.definition:await loadModuleBackedDefinition({binding:n.binding,displayPath:i,kind:`agent config`,loadNamespace:createCompiledBindingNamespaceLoader({appRoot:e.appRoot,bindings:{[r.sourceId]:n.binding},registries:t.registries}),source:r}),`Expected the agent config export "${r.exportName??`default`}" from "${i}" to match the public eve shape.`),o=isDynamicModelDefinition(a.model)?a.model:void 0,s=o===void 0?await normalizeAuthoredModelReference({modelCatalog:t.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:a.modelContextWindowTokens,promptCache:a.modelOptions?.promptCache,providerOptions:a.modelOptions?.providerOptions,source:r,sourcePath:i,value:a.model}):void 0,c={},l={compaction:c,name:e.agentId,source:{...r}};a.defaultTools!==void 0&&(l.defaultTools=a.defaultTools),a.description!==void 0&&(l.description=a.description);let u;o!==void 0&&(u={eventNames:Object.keys(o.events),exportName:r.exportName,sourceKind:`module`,logicalPath:r.logicalPath,sourceId:r.sourceId});let d=normalizeExperimentalDefinition(a.experimental);if(d!==void 0&&(l.experimental=d),a.build!==void 0&&(l.build={externalDependencies:a.build.externalDependencies===void 0?void 0:[...a.build.externalDependencies]}),a.reasoning!==void 0&&(l.reasoning=a.reasoning),a.tool!==void 0&&(l.tool=a.tool),a.limits!==void 0&&(l.limits={maxInputTokensPerSession:a.limits.maxInputTokensPerSession,maxOutputTokensPerSession:a.limits.maxOutputTokensPerSession,maxTokenCostUsdPerSession:a.limits.maxTokenCostUsdPerSession,sessionTimeoutMs:a.limits.sessionTimeoutMs}),a.compaction?.model!==void 0&&(c.model=await normalizeAuthoredModelReference({modelCatalog:t.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:a.compaction.modelContextWindowTokens,providerOptions:a.modelOptions?.providerOptions,source:r,sourcePath:i,value:a.compaction.model})),a.compaction?.thresholdPercent!==void 0&&(c.thresholdPercent=a.compaction.thresholdPercent),u!==void 0)return{...l,dynamicModel:u};if(s===void 0)throw Error(`Expected a static agent model to compile to a concrete model reference.`);return{...l,model:s}}function normalizeExperimentalDefinition(e){if(e===void 0)return;let t={};return e.workflow!==void 0&&(t.workflow={modelCallsPerStep:e.workflow.modelCallsPerStep,retention:e.workflow.retention,world:e.workflow.world}),t}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`){let t=classifyModelRouting(e.value,e.providerOptions);return rejectGatewayPromptCache(e,t),await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions),routing:t},e)}let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let n=e.value,r=n.specificationVersion;if(r!==`v2`&&r!==`v3`&&r!==`v4`||typeof n.provider!=`string`||typeof n.modelId!=`string`||typeof n.doGenerate!=`function`||typeof n.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${e.sourcePath??t.logicalPath}" to provide a valid AI SDK language model.`);let i=classifyModelRouting(n,e.providerOptions);rejectGatewayPromptCache(e,i);let a={id:formatLanguageModelGatewayId(n),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions),routing:i};if(e.promptCache!==void 0&&(a.promptCache=e.promptCache),e.contextWindowTokens===void 0){if(isChatGptModelRouting(a.routing))return{...a,contextWindowTokens:2e5};if(isMockModel(n))return{...a,contextWindowTokens:1e6};try{let t=await e.modelCatalog.getByProviderModelId(n.provider,n.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens,maxOutputTokens:t.limits.maxOutputTokens}}catch{}}return await withCompiledRuntimeModelLimits(a,e)}function rejectGatewayPromptCache(e,t){if(e.promptCache!==void 0&&t.kind===`gateway`)throw Error(`${e.sourcePath??`agent.ts`}: modelOptions.promptCache applies only to models eve calls directly, but "${formatLanguageModelGatewayId(e.value)}" routes through AI Gateway, which manages its own prompt caching. Remove promptCache, or configure Gateway caching with providerOptions.gateway.caching.`)}function formatAgentConfigModulePath(e,t,n){return n.backing.kind===`programmatic`?t.logicalPath:normalizeLogicalPath(relative(resolveTopLevelAgentRoot(e),n.backing.sourcePath))}function resolveTopLevelAgentRoot(e){let t=resolve(e.appRoot),n=resolve(t,`agent`);return isPathInsideOrEqual(n,resolve(e.agentRoot))?n:t}function isPathInsideOrEqual(e,t){let n=relative(e,t);return n===``||!n.startsWith(`..`)&&!isAbsolute(n)}async function withCompiledRuntimeModelLimits(e,t){if(t.contextWindowTokens!==void 0)return{...e,contextWindowTokens:t.contextWindowTokens};let n;try{n=await t.modelCatalog.getModelLimits(e.id)}catch(n){throw Error(`Failed to load AI Gateway model metadata for ${t.purpose} "${e.id}". ${toErrorMessage(n)}`)}if(n===null)throw Error(`Cannot compile agent compaction because ${t.purpose} "${e.id}" does not have known AI Gateway context window metadata.`);return{...e,contextWindowTokens:n.contextWindowTokens,maxOutputTokens:n.maxOutputTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,r]of Object.entries(e))t[n]=parseJsonObject(r);return t}export{compileAgentConfig};
@@ -1 +1 @@
1
- import{LiveStepDynamicModelSelectionKey,SessionDynamicModelReferenceKey,TurnDynamicModelReferenceKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{isMockModel}from"#internal/mock-model-identity.js";import{loadDynamicRuntimeModelDefinition,resolveRuntimeModelSelection,shouldMockAuthoredRuntimeModels}from"#runtime/agent/resolve-model.js";const ALLOWED_DYNAMIC_MODEL_EVENTS=new Set([`session.started`,`turn.started`,`step.started`]),DYNAMIC_MODEL_SELECTION_ERROR_CODE=`EVE_DYNAMIC_MODEL_SELECTION_FAILED`;var DynamicModelSelectionError=class extends Error{code=DYNAMIC_MODEL_SELECTION_ERROR_CODE;name=`DynamicModelSelectionError`;constructor(e){super(toErrorMessage(e),{cause:e})}};function isDynamicModelSelectionError(e){return e instanceof DynamicModelSelectionError||typeof e==`object`&&!!e&&e.code===DYNAMIC_MODEL_SELECTION_ERROR_CODE}function isDynamicModelEventName(e){return ALLOWED_DYNAMIC_MODEL_EVENTS.has(e)}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicModelReferenceKey;case`turn.started`:return TurnDynamicModelReferenceKey;case`step.started`:return}}async function dispatchDynamicModelEvent(e){if(e.dynamicModel!==void 0&&isDynamicModelEventName(e.event.type)&&e.dynamicModel.eventNames.includes(e.event.type)){setSelectionForEvent(e.ctx,e.event.type,null);try{let t=(await loadDynamicRuntimeModelDefinition({dynamicModel:e.dynamicModel,scope:e.scope})).events[e.event.type];if(t===void 0)throw Error(`Dynamic model resolver is missing its compiled "${e.event.type}" handler.`);e.abortSignal?.throwIfAborted();let n=await t(e.event,{...buildResolveContext(e.ctx,e.messages),abortSignal:e.abortSignal});e.abortSignal?.throwIfAborted();let r=await resolveRuntimeModelSelection({durability:e.event.type===`step.started`?`live`:`durable`,selection:n,state:e.ctx});setSelectionForEvent(e.ctx,e.event.type,r)}catch(e){throw isDynamicModelSelectionError(e)?e:new DynamicModelSelectionError(e)}}}function setSelectionForEvent(e,t,n){if(t===`step.started`){let t=n!==null&&n.model!==void 0&&!isMockModel(n.model)&&shouldMockAuthoredRuntimeModels()?{reference:n.reference}:n;e.setVirtualContext(LiveStepDynamicModelSelectionKey,t);return}let r=durableKeyForEvent(t);r!==void 0&&e.set(r,n?.reference??null)}export{DynamicModelSelectionError,dispatchDynamicModelEvent,isDynamicModelSelectionError};
1
+ import{LiveStepDynamicModelSelectionKey,SessionDynamicModelReferenceKey,TurnDynamicModelReferenceKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{isMockModel}from"#internal/mock-model-identity.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{loadDynamicRuntimeModelDefinition,resolveRuntimeModelSelection,shouldMockAuthoredRuntimeModels}from"#runtime/agent/resolve-model.js";const ALLOWED_DYNAMIC_MODEL_EVENTS=new Set([`session.started`,`turn.started`,`step.started`]),DYNAMIC_MODEL_SELECTION_ERROR_CODE=`EVE_DYNAMIC_MODEL_SELECTION_FAILED`;var DynamicModelSelectionError=class extends Error{code=DYNAMIC_MODEL_SELECTION_ERROR_CODE;name=`DynamicModelSelectionError`;constructor(e){super(toErrorMessage(e),{cause:e})}};function isDynamicModelSelectionError(e){return e instanceof DynamicModelSelectionError||typeof e==`object`&&!!e&&e.code===DYNAMIC_MODEL_SELECTION_ERROR_CODE}function isDynamicModelEventName(e){return ALLOWED_DYNAMIC_MODEL_EVENTS.has(e)}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicModelReferenceKey;case`turn.started`:return TurnDynamicModelReferenceKey;case`step.started`:return}}async function dispatchDynamicModelEvent(e){if(e.dynamicModel!==void 0&&isDynamicModelEventName(e.event.type)&&e.dynamicModel.eventNames.includes(e.event.type)){setSelectionForEvent(e.ctx,e.event.type,null);try{let t=(await loadDynamicRuntimeModelDefinition({dynamicModel:e.dynamicModel,scope:e.scope})).events[e.event.type];if(t===void 0)throw Error(`Dynamic model resolver is missing its compiled "${e.event.type}" handler.`);e.abortSignal?.throwIfAborted();let n=await t(e.event,{...buildResolveContext(e.ctx,e.messages),abortSignal:e.abortSignal});e.abortSignal?.throwIfAborted();let r=await resolveRuntimeModelSelection({durability:e.event.type===`step.started`?`live`:`durable`,selection:n,state:e.ctx});setSelectionForEvent(e.ctx,e.event.type,r)}catch(e){throw isDynamicModelSelectionError(e)?e:new DynamicModelSelectionError(e)}}}function setSelectionForEvent(e,t,n){if(t===`step.started`){let t=n!==null&&n.model!==void 0&&!isMockModel(n.model)&&shouldMockAuthoredRuntimeModels()?{reference:n.reference}:n;e.setVirtualContext(LiveStepDynamicModelSelectionKey,t);return}let r=durableKeyForEvent(t);r!==void 0&&e.set(r,n?.reference??null)}export{DynamicModelSelectionError,dispatchDynamicModelEvent,isDynamicModelSelectionError};
@@ -83,6 +83,22 @@ export interface HistoryState {
83
83
  readonly announcements?: Readonly<Record<string, string>>;
84
84
  }
85
85
  export declare const HistoryStateKey: ContextKey<HistoryState>;
86
+ /**
87
+ * The catalog tools a session's tool list has offered. Each stays offered for
88
+ * the rest of the session, so the tool list never drops a catalog tool that
89
+ * earlier calls named. Compaction keeps it, unlike {@link HistoryStateKey}.
90
+ */
91
+ export interface OfferedCatalogTools {
92
+ /** `eve__tool` mentions connected services, and `eve__search` their sign-in entries. */
93
+ readonly connections: boolean;
94
+ /** `eve__search` finds skills. */
95
+ readonly searchableSkills: boolean;
96
+ /** `eve__skill`. */
97
+ readonly skills: boolean;
98
+ /** `eve__tool`. */
99
+ readonly tools: boolean;
100
+ }
101
+ export declare const OfferedCatalogToolsKey: ContextKey<OfferedCatalogTools>;
86
102
  export interface ActiveChannelDelivery {
87
103
  readonly traceSessionId: string;
88
104
  readonly agentName?: string;
@@ -1 +1 @@
1
- import{SESSION_INBOX_CONTEXT_KEY}from"#execution/session-inbox/address.js";import{ContextKey}from"#context/key.js";import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{SESSION_CALLBACK_CONTEXT_KEY_NAME}from"#context/key-names.js";const AuthKey=new ContextKey(`eve.auth`),ToolStubsKey=new ContextKey(STUB_CONTEXT_KEY),InitiatorAuthKey=new ContextKey(`eve.initiatorAuth`),SessionIdKey=new ContextKey(`eve.sessionId`),ConversationIdKey=new ContextKey(`eve.conversationId`),SessionInboxKey=new ContextKey(SESSION_INBOX_CONTEXT_KEY),ContinuationTokenKey=new ContextKey(`eve.continuationToken`),ContinuationHookTokensKey=new ContextKey(`eve.continuationHookTokens`),ChannelRequestIdKey=new ContextKey(`eve.channelRequestId`),LocalDevRequestKey=new ContextKey(`eve.internal.localDevRequest`),OccurrenceIdKey=new ContextKey(`eve.scheduleOccurrenceId`),ScheduleIdKey=new ContextKey(`eve.scheduleId`),ScheduleInstanceKey=new ContextKey(`eve.scheduleInstance`),SessionTitleKey=new ContextKey(`eve.sessionTitle`),ChannelDeliveryKey=new ContextKey(`eve.channelDelivery`),TurnDeliveryIdsKey=new ContextKey(`eve.turnDeliveryIds`),HistoryStateKey=new ContextKey(`eve.historyState`),ActiveChannelDeliveriesKey=new ContextKey(`eve.activeChannelDeliveries`),ChannelInstrumentationKey=new ContextKey(`eve.channelInstrumentation`),ParentSessionKey=new ContextKey(`eve.parentSession`),SessionPredecessorKey=new ContextKey(`eve.sessionPredecessor`),TraceRootKey=new ContextKey(`eve.traceRoot`),ParentTraceContextKey=new ContextKey(`eve.parentTraceContext`),SessionTraceSeedKey=new ContextKey(`eve.sessionTraceSeed`),OtelTraceEnabledKey=new ContextKey(`eve.otelTraceEnabled`),CapabilitiesKey=new ContextKey(`eve.capabilities`),SessionCallbackKey=new ContextKey(SESSION_CALLBACK_CONTEXT_KEY_NAME),LegacyRemoteAgentCallerKey=new ContextKey(`eve.legacyRemoteAgentCaller`),SessionKey=new ContextKey(`eve.session`),SandboxKey=new ContextKey(`eve.sandbox`),SandboxTerminalCleanupKey=new ContextKey(`eve.internal.sandboxTerminalCleanup`),HandleEventKey=new ContextKey(`eve.internal.handleEvent`),StaticModelReferenceKey=new ContextKey(`eve.staticModelReference`),SessionDynamicModelReferenceKey=new ContextKey(`eve.sessionDynamicModelReference`),TurnDynamicModelReferenceKey=new ContextKey(`eve.turnDynamicModelReference`),RuntimeModelMetadataCacheKey=new ContextKey(`eve.runtimeModelMetadataCache`),LiveStepDynamicModelSelectionKey=new ContextKey(`eve.liveStepDynamicModelSelection`),SessionDynamicToolMetadataKey=new ContextKey(`eve.sessionDynamicToolMetadata`),SessionDynamicToolRuntimeRevisionKey=new ContextKey(`eve.sessionDynamicToolRuntimeRevision`),TurnDynamicToolMetadataKey=new ContextKey(`eve.turnDynamicToolMetadata`),TurnMemoryLocksKey=new ContextKey(`eve.memory.turnLocks`),PreparedMemoryPreambleKey=new ContextKey(`eve.memory.preparedPreamble`),PendingMemoryCommitKey=new ContextKey(`eve.memory.pendingCommit`),PreparedMemoryCompactionKey=new ContextKey(`eve.memory.preparedCompaction`),StepDynamicToolMetadataKey=new ContextKey(`eve.stepDynamicToolMetadata`),SessionDynamicSubagentSelectionsKey=new ContextKey(`eve.sessionDynamicSubagentSelections`),TurnDynamicSubagentSelectionsKey=new ContextKey(`eve.turnDynamicSubagentSelections`),SessionDynamicSubagentRuntimeRevisionKey=new ContextKey(`eve.sessionDynamicSubagentRuntimeRevision`),DynamicSubagentAgentConfigKey=new ContextKey(`eve.dynamicSubagentAgentConfig`),DynamicSkillManifestKey=new ContextKey(`eve.dynamicSkillManifest`),DynamicSkillSandboxKey=new ContextKey(`eve.dynamicSkillSandbox`),SessionDynamicInstructionsKey=new ContextKey(`eve.sessionDynamicInstructions`),TurnDynamicInstructionsKey=new ContextKey(`eve.turnDynamicInstructions`),DynamicInstructionResolveMessagesKey=new ContextKey(`eve.dynamicInstructionResolveMessages`),PendingDynamicInstructionUserMessagesKey=new ContextKey(`eve.pendingDynamicInstructionUserMessages`);export{ActiveChannelDeliveriesKey,AuthKey,CapabilitiesKey,ChannelDeliveryKey,ChannelInstrumentationKey,ChannelRequestIdKey,ContinuationHookTokensKey,ContinuationTokenKey,ConversationIdKey,DynamicInstructionResolveMessagesKey,DynamicSkillManifestKey,DynamicSkillSandboxKey,DynamicSubagentAgentConfigKey,HandleEventKey,HistoryStateKey,InitiatorAuthKey,LegacyRemoteAgentCallerKey,LiveStepDynamicModelSelectionKey,LocalDevRequestKey,OccurrenceIdKey,OtelTraceEnabledKey,ParentSessionKey,ParentTraceContextKey,PendingDynamicInstructionUserMessagesKey,PendingMemoryCommitKey,PreparedMemoryCompactionKey,PreparedMemoryPreambleKey,RuntimeModelMetadataCacheKey,SandboxKey,SandboxTerminalCleanupKey,ScheduleIdKey,ScheduleInstanceKey,SessionCallbackKey,SessionDynamicInstructionsKey,SessionDynamicModelReferenceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicSubagentSelectionsKey,SessionDynamicToolMetadataKey,SessionDynamicToolRuntimeRevisionKey,SessionIdKey,SessionInboxKey,SessionKey,SessionPredecessorKey,SessionTitleKey,SessionTraceSeedKey,StaticModelReferenceKey,StepDynamicToolMetadataKey,ToolStubsKey,TraceRootKey,TurnDeliveryIdsKey,TurnDynamicInstructionsKey,TurnDynamicModelReferenceKey,TurnDynamicSubagentSelectionsKey,TurnDynamicToolMetadataKey,TurnMemoryLocksKey};
1
+ import{SESSION_INBOX_CONTEXT_KEY}from"#execution/session-inbox/address.js";import{ContextKey}from"#context/key.js";import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{SESSION_CALLBACK_CONTEXT_KEY_NAME}from"#context/key-names.js";const AuthKey=new ContextKey(`eve.auth`),ToolStubsKey=new ContextKey(STUB_CONTEXT_KEY),InitiatorAuthKey=new ContextKey(`eve.initiatorAuth`),SessionIdKey=new ContextKey(`eve.sessionId`),ConversationIdKey=new ContextKey(`eve.conversationId`),SessionInboxKey=new ContextKey(SESSION_INBOX_CONTEXT_KEY),ContinuationTokenKey=new ContextKey(`eve.continuationToken`),ContinuationHookTokensKey=new ContextKey(`eve.continuationHookTokens`),ChannelRequestIdKey=new ContextKey(`eve.channelRequestId`),LocalDevRequestKey=new ContextKey(`eve.internal.localDevRequest`),OccurrenceIdKey=new ContextKey(`eve.scheduleOccurrenceId`),ScheduleIdKey=new ContextKey(`eve.scheduleId`),ScheduleInstanceKey=new ContextKey(`eve.scheduleInstance`),SessionTitleKey=new ContextKey(`eve.sessionTitle`),ChannelDeliveryKey=new ContextKey(`eve.channelDelivery`),TurnDeliveryIdsKey=new ContextKey(`eve.turnDeliveryIds`),HistoryStateKey=new ContextKey(`eve.historyState`),OfferedCatalogToolsKey=new ContextKey(`eve.offeredCatalogTools`),ActiveChannelDeliveriesKey=new ContextKey(`eve.activeChannelDeliveries`),ChannelInstrumentationKey=new ContextKey(`eve.channelInstrumentation`),ParentSessionKey=new ContextKey(`eve.parentSession`),SessionPredecessorKey=new ContextKey(`eve.sessionPredecessor`),TraceRootKey=new ContextKey(`eve.traceRoot`),ParentTraceContextKey=new ContextKey(`eve.parentTraceContext`),SessionTraceSeedKey=new ContextKey(`eve.sessionTraceSeed`),OtelTraceEnabledKey=new ContextKey(`eve.otelTraceEnabled`),CapabilitiesKey=new ContextKey(`eve.capabilities`),SessionCallbackKey=new ContextKey(SESSION_CALLBACK_CONTEXT_KEY_NAME),LegacyRemoteAgentCallerKey=new ContextKey(`eve.legacyRemoteAgentCaller`),SessionKey=new ContextKey(`eve.session`),SandboxKey=new ContextKey(`eve.sandbox`),SandboxTerminalCleanupKey=new ContextKey(`eve.internal.sandboxTerminalCleanup`),HandleEventKey=new ContextKey(`eve.internal.handleEvent`),StaticModelReferenceKey=new ContextKey(`eve.staticModelReference`),SessionDynamicModelReferenceKey=new ContextKey(`eve.sessionDynamicModelReference`),TurnDynamicModelReferenceKey=new ContextKey(`eve.turnDynamicModelReference`),RuntimeModelMetadataCacheKey=new ContextKey(`eve.runtimeModelMetadataCache`),LiveStepDynamicModelSelectionKey=new ContextKey(`eve.liveStepDynamicModelSelection`),SessionDynamicToolMetadataKey=new ContextKey(`eve.sessionDynamicToolMetadata`),SessionDynamicToolRuntimeRevisionKey=new ContextKey(`eve.sessionDynamicToolRuntimeRevision`),TurnDynamicToolMetadataKey=new ContextKey(`eve.turnDynamicToolMetadata`),TurnMemoryLocksKey=new ContextKey(`eve.memory.turnLocks`),PreparedMemoryPreambleKey=new ContextKey(`eve.memory.preparedPreamble`),PendingMemoryCommitKey=new ContextKey(`eve.memory.pendingCommit`),PreparedMemoryCompactionKey=new ContextKey(`eve.memory.preparedCompaction`),StepDynamicToolMetadataKey=new ContextKey(`eve.stepDynamicToolMetadata`),SessionDynamicSubagentSelectionsKey=new ContextKey(`eve.sessionDynamicSubagentSelections`),TurnDynamicSubagentSelectionsKey=new ContextKey(`eve.turnDynamicSubagentSelections`),SessionDynamicSubagentRuntimeRevisionKey=new ContextKey(`eve.sessionDynamicSubagentRuntimeRevision`),DynamicSubagentAgentConfigKey=new ContextKey(`eve.dynamicSubagentAgentConfig`),DynamicSkillManifestKey=new ContextKey(`eve.dynamicSkillManifest`),DynamicSkillSandboxKey=new ContextKey(`eve.dynamicSkillSandbox`),SessionDynamicInstructionsKey=new ContextKey(`eve.sessionDynamicInstructions`),TurnDynamicInstructionsKey=new ContextKey(`eve.turnDynamicInstructions`),DynamicInstructionResolveMessagesKey=new ContextKey(`eve.dynamicInstructionResolveMessages`),PendingDynamicInstructionUserMessagesKey=new ContextKey(`eve.pendingDynamicInstructionUserMessages`);export{ActiveChannelDeliveriesKey,AuthKey,CapabilitiesKey,ChannelDeliveryKey,ChannelInstrumentationKey,ChannelRequestIdKey,ContinuationHookTokensKey,ContinuationTokenKey,ConversationIdKey,DynamicInstructionResolveMessagesKey,DynamicSkillManifestKey,DynamicSkillSandboxKey,DynamicSubagentAgentConfigKey,HandleEventKey,HistoryStateKey,InitiatorAuthKey,LegacyRemoteAgentCallerKey,LiveStepDynamicModelSelectionKey,LocalDevRequestKey,OccurrenceIdKey,OfferedCatalogToolsKey,OtelTraceEnabledKey,ParentSessionKey,ParentTraceContextKey,PendingDynamicInstructionUserMessagesKey,PendingMemoryCommitKey,PreparedMemoryCompactionKey,PreparedMemoryPreambleKey,RuntimeModelMetadataCacheKey,SandboxKey,SandboxTerminalCleanupKey,ScheduleIdKey,ScheduleInstanceKey,SessionCallbackKey,SessionDynamicInstructionsKey,SessionDynamicModelReferenceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicSubagentSelectionsKey,SessionDynamicToolMetadataKey,SessionDynamicToolRuntimeRevisionKey,SessionIdKey,SessionInboxKey,SessionKey,SessionPredecessorKey,SessionTitleKey,SessionTraceSeedKey,StaticModelReferenceKey,StepDynamicToolMetadataKey,ToolStubsKey,TraceRootKey,TurnDeliveryIdsKey,TurnDynamicInstructionsKey,TurnDynamicModelReferenceKey,TurnDynamicSubagentSelectionsKey,TurnDynamicToolMetadataKey,TurnMemoryLocksKey};
@@ -1,2 +1,2 @@
1
- import{formatDiagnosticValue,toDiagnosticMetadataValue}from"#evals/diagnostics.js";import{decide}from"#ai/decide.js";import{runUntilAborted}from"#evals/abort.js";function buildJudgeContext(e){function judge(t,n){let r=typeof t==`object`&&`questions`in t,i=r?t.questions:{judgment:typeof t==`string`?{type:`boolean`,instructions:t}:t},a=Object.entries(i);if(a.length===0)throw Error(`Judge questions must be a non-empty map.`);let o=r&&t.state!==void 0?t.state:{input:e.getInput(),output:!r&&n?.on!==void 0?n.on:e.getReply()??``},s=n?.model??e.judge?.model,c=n?.modelOptions??e.judge?.modelOptions,l=runUntilAborted((async()=>{let t=structuredClone(o),n=structuredClone(i),r=Object.fromEntries(Object.entries(n).map(([e,t])=>{if(t.type!==`choice`)return[e,t];let{expected:n,...r}=t;if(typeof n!=`string`||!Object.hasOwn(t.criteria,n))throw Error(`Judge question "${e}" expected must name an option in criteria.`);return[e,r]}));return{result:await decide({model:s,state:t,questions:r,providerOptions:c?.providerOptions,abortSignal:e.signal}),state:t,questions:n}})(),e.signal),u=Object.fromEntries(a.map(([t,n])=>[t,e.collector.recordValue({name:`judge.${n.type}${r?`.${t}`:``}`,severity:`soft`,score:async()=>{let{result:e,state:n,questions:i}=await l,a=i[t],o=e.answers[t],s=judgeScore(a,o);return{score:s,message:formatJudgeDetail(n,a,o),metadata:{judge:e.response.modelId,questionId:t,question:a,state:n,answer:o,score:s,usage:e.usage,usageScope:r?`batch`:`assertion`,warnings:e.warnings,rounding:e.rounding,providerMetadata:e.providerMetadata,response:toDiagnosticMetadataValue(e.response)}}}})]));return r?u:u.judgment}return judge}function formatJudgeDetail(e,t,n){return[[`state`,e],[`question`,t],[`answer`,n]].map(([e,t])=>`${e}: ${formatDiagnosticValue(t)}`).join(`
1
+ import{formatDiagnosticValue,toDiagnosticMetadataValue}from"#evals/diagnostics.js";import{decide}from"#ai/decide.js";import{runUntilAborted}from"#evals/abort.js";function buildJudgeContext(e){function judge(t,n){let r=typeof t==`object`&&`questions`in t,i=r?t.questions:{judgment:typeof t==`string`?{type:`boolean`,instructions:t}:t},a=Object.entries(i);if(a.length===0)throw Error(`Judge questions must be a non-empty map.`);let o=r&&t.state!==void 0?t.state:{input:e.getInput(),output:!r&&n?.on!==void 0?n.on:e.getReply()??``},s=n?.model??e.judge?.model,c=n?.modelOptions??e.judge?.modelOptions,l=runUntilAborted((async()=>{let t=structuredClone(o),n=structuredClone(i),r=Object.fromEntries(Object.entries(n).map(([e,t])=>{if(t.type!==`choice`)return[e,t];let{expected:n,...r}=t;if(typeof n!=`string`||!Object.hasOwn(t.criteria,n))throw Error(`Judge question "${e}" expected must name an option in criteria.`);return[e,r]}));return{result:await decide({model:s,state:isJsonArray(t)?[{type:`json`,value:t}]:t,questions:r,providerOptions:c?.providerOptions,abortSignal:e.signal}),state:t,questions:n}})(),e.signal),u=Object.fromEntries(a.map(([t,n])=>[t,e.collector.recordValue({name:`judge.${n.type}${r?`.${t}`:``}`,severity:`soft`,score:async()=>{let{result:e,state:n,questions:i}=await l,a=i[t],o=e.answers[t],s=judgeScore(a,o);return{score:s,message:formatJudgeDetail(n,a,o),metadata:{judge:e.response.modelId,questionId:t,question:a,state:n,answer:o,score:s,usage:e.usage,usageScope:r?`batch`:`assertion`,warnings:e.warnings,rounding:e.rounding,providerMetadata:e.providerMetadata,response:toDiagnosticMetadataValue(e.response)}}}})]));return r?u:u.judgment}return judge}function isJsonArray(e){return Array.isArray(e)}function formatJudgeDetail(e,t,n){return[[`state`,e],[`question`,t],[`answer`,n]].map(([e,t])=>`${e}: ${formatDiagnosticValue(t)}`).join(`
2
2
  `)}function judgeScore(e,t){switch(t.type){case`boolean`:return t.probability;case`score`:if(e.type===`score`)return t.score/(e.criteria.length-1);break;case`choice`:if(e.type===`choice`)return+(t.choice===e.expected)}throw Error(`Decision answer does not match the judge question.`)}export{buildJudgeContext};
@@ -1 +1 @@
1
- import{attachClientContext}from"#internal/client-context.js";import{createLogger,logError}from"#internal/logging.js";import{FAIL_CLOSED_FORWARDED_TRACE_ASSERTION,formatTraceContentCeiling}from"#shared/forwarded-trace-policy.js";import{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SESSION_STUBS_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,EVE_STREAM_CONTROL_VERSION_QUERY,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{DELETE,GET,HEAD,PATCH,POST,PUT,defineChannel}from"#public/definitions/channel.js";import{readMatchedStubRules,readStubFailure}from"#execution/tool-stubs/steps.js";import{InvalidToolStubTargetError}from"#tool-stubs/validate-targets.js";import{getRun}from"#internal/workflow/runtime.js";import{handleExpiredLegacyAuthorization}from"#execution/legacy-session/authorization.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{handleConnectionCallbackRequest}from"#execution/connections/callback-route.js";import{handleSessionCallbackRequest}from"#subagents/callback-route.js";import{WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest}from"#execution/workflow-webhook-route.js";import{readAgentInfoRouteResponse,readRemoteAgentStreamHeadersResolver,readRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{legacyTaskInputRoute}from"#execution/legacy-remote-agent/protocol.js";import{parseTraceparent,readAgentDispatchTraceContext}from"#protocol/traceparent.js";import{readForwardedAudienceBaggage,readForwardedParentSessionBaggage}from"#protocol/baggage.js";import{readConversationBaggage}from"#tracing/conversation-context.js";import{sessionAuthFromResult}from"#channel/auth/result.js";import{routeAuth}from"#public/channels/auth.js";import{defaultEveAudience}from"#eve-channel/audience.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{checkUploadPolicy,createSessionStreamResponse,deriveOperationContinuationToken,parseCancelTurnBody,parseCreateBody,parseIncludeTailIndex,parseJsonRequest,parseOptionalJsonRequest,parseResetBody,parseSessionControlBody,parseSessionMessageBody,parseStartIndex,rejectSessionContinuationToken,requireSessionId}from"#eve-channel/request.js";import{findRemoteAgentBinding,healthResponse,normalizeEveCors,resolveOnMessage,strandedSessionResponse}from"#eve-channel/support.js";export*from"#eve-channel/types.js";const log=createLogger(`eve.channel`);function createdSessionBody(e,t){let n={ok:!0,sessionId:e,status:`accepted`};return t.protocolVersion!==void 0&&(n.protocolVersion=t.protocolVersion),n}function eveChannel(e){let t=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),turnPolicy:e.turnPolicy,audience:t=>{let n=e.audience??defaultEveAudience;return typeof n==`function`?n(t):n},routes:[GET(EVE_HEALTH_ROUTE_PATH,async()=>healthResponse()),HEAD(EVE_HEALTH_ROUTE_PATH,async()=>healthResponse()),GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),GET(`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,handleExpiredLegacyAuthorization),POST(`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,handleExpiredLegacyAuthorization),GET(EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,handleConnectionCallbackRequest),POST(EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,handleConnectionCallbackRequest),POST(EVE_CALLBACK_ROUTE_PATTERN,handleSessionCallbackRequest),POST(legacyTaskInputRoute.path,legacyTaskInputRoute.handler),GET(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),POST(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),PUT(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),PATCH(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),DELETE(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),POST(EVE_SESSION_ROUTE_PATH,async(n,r)=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=sessionAuthFromResult(i),o=await parseOptionalJsonRequest(n);if(o instanceof Response)return o;if(o.stubs!==void 0&&i.allowToolStubs!==!0)return Response.json({ok:!1,error:`Tool stubbing is not permitted for this caller.`},{status:403});let s=rejectSessionContinuationToken(o);if(s!==null)return s;let c=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:a,payload:o});if(c instanceof Response)return c;let l=parseCreateBody(o);if(l instanceof Response)return l;l.callback!==void 0&&l.legacyRemoteAgentCaller!==void 0&&log.info(`serving a remote agent protocol 1 caller`,{callerOrigin:new URL(l.callback.url).origin,forwarder:i.principalId});let u=l.callback===void 0?`absent`:readForwardedParentSessionBaggage(n.headers.get(`baggage`)),d;if(typeof u==`object`){if(u.callId!==l.callback?.callId)log.warn(`ignoring remote parent lineage with a mismatched callback`,{forwarder:i.principalId});else{let t=c.accepted;if(!t&&e.trustedForwarders!==void 0)try{t=await e.trustedForwarders(a,{})}catch(e){let t=logError(log,`trustedForwarders handler failed`,e,{forwarder:i.principalId});return Response.json({error:`trustedForwarders handler failed.`,errorId:t,ok:!1},{status:500})}t?d=u:log.warn(`ignoring remote parent lineage from an untrusted forwarder`,{forwarder:i.principalId})}}else u===`malformed`&&log.warn(`ignoring malformed remote parent lineage`,{forwarder:i.principalId});let f=l.callback===void 0?void 0:parseTraceparent(n.headers.get(`traceparent`)),p=l.callback===void 0?void 0:readAgentDispatchTraceContext(n.headers.get(`tracestate`),f)??f,m=checkUploadPolicy(l,t);if(m!==null)return m;if(l.operationId!==void 0&&c.auth.principalType===`anonymous`)return Response.json({error:`operationId requires an authenticated principal.`,ok:!1},{status:400});let h=l.operationId===void 0?void 0:await deriveOperationContinuationToken({auth:c.auth,operationId:l.operationId});if(h!==void 0){let e=await r.resolveSession(h);if(e!==void 0)return Response.json(createdSessionBody(e.id,l),{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.id},status:202})}let g=f===void 0?`absent`:readForwardedAudienceBaggage(n.headers.get(`baggage`)),_=c.accepted&&f!==void 0&&(f.traceFlags&1)==1?typeof g==`object`?g:g===`malformed`?FAIL_CLOSED_FORWARDED_TRACE_ASSERTION:void 0:void 0,v=p;_!==void 0&&p!==void 0&&(v={...p,forwardedTracePolicy:_}),g===`malformed`?log.warn(`using metadata-only policy for malformed forwarded audience baggage`,{forwarder:i.principalId}):typeof g==`object`&&(_===void 0?log.warn(`ignoring forwarded trace policy without an accepted sampled principal`,{forwarder:i.principalId}):log.info(`accepted forwarded trace policy`,{audience:g.originAudience,ceiling:formatTraceContentCeiling(g.ceiling),forwarder:i.principalId}));let y=l.message===void 0?{auth:c.auth}:await resolveOnMessage({auth:c.auth,config:e,invocation:d===void 0||l.operationId===void 0?void 0:{operationId:l.operationId},message:l.message,request:n});if(y instanceof Response)return y;let b=readRouteSessionCreator(r);if(b===void 0)return Response.json({error:`Session creation requires internal channel dispatch context.`,ok:!1},{status:500});let x;try{x=await b({audienceAuth:a,toolStubs:l.stubs===void 0?void 0:{rules:l.stubs,token:crypto.randomUUID()},auth:y.auth,capabilities:l.capabilities??{requestInput:!0},callback:l.callback,legacyRemoteAgentCaller:l.legacyRemoteAgentCaller,continuationToken:h,initiatorAuth:c.accepted?c.initiatorAuth:void 0,input:attachClientContext({message:l.message,context:y.context,outputSchema:l.outputSchema},l.context),conversationId:l.callback===void 0?void 0:readConversationBaggage(n.headers.get(`baggage`)),parent:d,parentTraceContext:v,traceRoot:d===void 0?void 0:{kind:`own`},title:y.title})}catch(e){if(e instanceof InvalidToolStubTargetError)return Response.json({error:e.message,ok:!1},{status:400});let t=logError(log,`session-create request failed`,e);return Response.json({error:`Failed to create the session.`,errorId:t,ok:!1},{status:500})}return Response.json(createdSessionBody(x.sessionId,l),{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:x.sessionId},status:202})}),POST(EVE_SESSION_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseJsonRequest(n);if(s instanceof Response)return s;let c=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:sessionAuthFromResult(a),payload:s});if(c instanceof Response)return c;let l=parseSessionMessageBody(s);if(l instanceof Response)return l;let u=checkUploadPolicy(l,t);if(u!==null)return u;let d,f,p=c.auth;if(l.message!==void 0){let t=await resolveOnMessage({auth:c.auth,config:e,message:l.message,request:n,sessionId:o});if(t instanceof Response)return t;d=t.context,f=t.title,p=t.auth}let m;try{let e=r(o),t=attachClientContext({auth:p,callback:l.callback,context:d,outputSchema:l.outputSchema,turnPolicy:l.turnPolicy,title:f},l.context);m=l.inputResponses===void 0?await e.send(l.message,t):await e.respond(l.inputResponses,t)}catch(e){let t=strandedSessionResponse(e);if(t!==void 0)return t;let n=logError(log,`session-message request failed`,e,{sessionId:o});return Response.json({error:`Failed to send the session message.`,errorId:n,ok:!1},{status:500})}return m.status===`accepted`?Response.json({ok:!0,sessionId:m.sessionId,status:`accepted`,deliveryId:m.deliveryId},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.sessionId},status:202}):Response.json({code:m.retryable?`session_not_ready`:`session_not_active`,error:m.retryable===!0?`The session is not ready to accept messages yet.`:`The session is no longer active.`,ok:!1},{headers:{"cache-control":`no-store`},status:409})}),POST(EVE_SESSION_CANCEL_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseCancelTurnBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).cancel({turnId:o.turnId})}catch(e){let t=logError(log,`cancel-turn request failed`,e,{sessionId:a});return Response.json({error:`Failed to cancel the turn.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`accepted`?{ok:!0,sessionId:s.sessionId,status:`accepted`}:{ok:!0,status:`no_active_turn`},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_COMPACT_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseSessionControlBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).compact()}catch(e){let t=logError(log,`session-compaction request failed`,e,{sessionId:a});return Response.json({error:`Failed to compact the session.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`accepted`?{ok:!0,sessionId:s.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_CLEAR_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseSessionControlBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).clear()}catch(e){let t=strandedSessionResponse(e);if(t!==void 0)return t;let n=logError(log,`session-clear request failed`,e,{sessionId:a});return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,...s},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_RESET_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseResetBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).reset({reason:o.reason})}catch(e){let t=logError(log,`session-reset request failed`,e,{sessionId:a});return Response.json({error:`Failed to reset the session.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`reset`?{ok:!0,previousSessionId:s.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`}})}),GET(EVE_SESSION_STUBS_ROUTE_PATTERN,async(t,{params:n})=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;if(r.allowToolStubs!==!0)return Response.json({error:`Tool stubbing is not permitted for this caller.`,ok:!1},{status:403});let i=requireSessionId(n);if(i instanceof Response)return i;try{return await getRun(i).exists?Response.json({error:await readStubFailure(i)??null,matchedRuleIds:await readMatchedStubRules(i)},{headers:{"cache-control":`no-store`}}):Response.json({error:`Session not found.`,ok:!1},{status:404})}catch(e){let t=logError(log,`tool-stub verification request failed`,e,{sessionId:i});return Response.json({error:`Failed to verify tool stubs.`,errorId:t,ok:!1},{status:500})}}),GET(EVE_SESSION_STREAM_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);return a instanceof Response?a:await createSessionStreamResponse(t,n(a))}),GET(EVE_SUBAGENT_STREAM_ROUTE_PATTERN,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=n.params.parentSessionId,a=n.params.callId,o=n.params.childSessionId;if(!i||!a||!o)return Response.json({error:`Missing subagent stream coordinates.`,ok:!1},{status:400});let s=parseStartIndex(t);if(s instanceof Response)return s;let c=parseIncludeTailIndex(t),l=createEveSubagentStreamRoutePath({callId:a,childSessionId:o,parentSessionId:i}),u;try{let e=n.attachSession(i),t=await findRemoteAgentBinding({callId:a,childSessionId:o,childStreamPath:l,parent:e});if(t===void 0)throw Error(`Remote subagent binding not found.`);u=t}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let d=readRemoteAgentStreamHeadersResolver(n);if(d===void 0)return Response.json({error:`Subagent stream proxy requires internal channel dispatch context.`,ok:!1},{status:500});let f;try{f=await d(u)}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let p=new URL(createEveSessionStreamRoutePath(o).replace(/^\/+/,``),`${u.url.replace(/\/+$/,``)}/`);s!==void 0&&p.searchParams.set(`startIndex`,String(s));let m=new URL(t.url).searchParams.get(EVE_STREAM_CONTROL_VERSION_QUERY);m!==null&&p.searchParams.set(EVE_STREAM_CONTROL_VERSION_QUERY,m),c&&p.searchParams.set(`includeTailIndex`,`1`);let h=await fetch(p,{cache:`no-store`,headers:f,redirect:`manual`,signal:t.signal}),g=new Headers;for(let e of[`cache-control`,`content-type`,`x-accel-buffering`,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER]){let t=h.headers.get(e);t!==null&&g.set(e,t)}return new Response(h.body,{headers:g,status:h.status,statusText:h.statusText})})],events:e.events})}export{eveChannel};
1
+ import{attachClientContext}from"#internal/client-context.js";import{createLogger,logError}from"#internal/logging.js";import{FAIL_CLOSED_FORWARDED_TRACE_ASSERTION,formatTraceContentCeiling}from"#shared/forwarded-trace-policy.js";import{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SESSION_STUBS_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,EVE_STREAM_CONTROL_VERSION_QUERY,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{DELETE,GET,HEAD,PATCH,POST,PUT,defineChannel}from"#public/definitions/channel.js";import{readMatchedStubRules,readStubFailure}from"#execution/tool-stubs/steps.js";import{InvalidToolStubTargetError}from"#tool-stubs/validate-targets.js";import{getRun}from"#internal/workflow/runtime.js";import{handleExpiredLegacyAuthorization}from"#execution/legacy-session/authorization.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{handleConnectionCallbackRequest}from"#execution/connections/callback-route.js";import{handleSessionCallbackRequest}from"#subagents/callback-route.js";import{WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest}from"#execution/workflow-webhook-route.js";import{readAgentInfoRouteResponse,readRemoteAgentStreamHeadersResolver,readRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{legacyTaskInputRoute}from"#execution/legacy-remote-agent/protocol.js";import{parseTraceparent,readAgentDispatchTraceContext}from"#protocol/traceparent.js";import{readForwardedAudienceBaggage,readForwardedParentSessionBaggage}from"#protocol/baggage.js";import{readConversationBaggage}from"#tracing/conversation-context.js";import{sessionAuthFromResult}from"#channel/auth/result.js";import{routeAuth}from"#public/channels/auth.js";import{defaultEveAudience}from"#eve-channel/audience.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{checkUploadPolicy,createSessionStreamResponse,deriveOperationContinuationToken,parseCancelTurnBody,parseCreateBody,parseIncludeTailIndex,parseJsonRequest,parseOptionalJsonRequest,parseResetBody,parseSessionControlBody,parseSessionMessageBody,parseStartIndex,rejectSessionContinuationToken,requireSessionId}from"#eve-channel/request.js";import{findRemoteAgentBinding,healthResponse,normalizeEveCors,resolveOnMessage,strandedSessionResponse}from"#eve-channel/support.js";export*from"#eve-channel/types.js";const log=createLogger(`eve.channel`);function createdSessionBody(e,t){let n={ok:!0,sessionId:e,status:`accepted`};return t.protocolVersion!==void 0&&(n.protocolVersion=t.protocolVersion),n}function eveChannel(e){let t=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),turnPolicy:e.turnPolicy,audience:t=>{let n=e.audience??defaultEveAudience;return typeof n==`function`?n(t):n},routes:[GET(EVE_HEALTH_ROUTE_PATH,async()=>healthResponse()),HEAD(EVE_HEALTH_ROUTE_PATH,async()=>healthResponse()),GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),GET(`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,handleExpiredLegacyAuthorization),POST(`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,handleExpiredLegacyAuthorization),GET(EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,handleConnectionCallbackRequest),POST(EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,handleConnectionCallbackRequest),POST(EVE_CALLBACK_ROUTE_PATTERN,handleSessionCallbackRequest),POST(legacyTaskInputRoute.path,legacyTaskInputRoute.handler),GET(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),POST(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),PUT(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),PATCH(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),DELETE(WORKFLOW_WEBHOOK_ROUTE_PATTERN,handleWorkflowWebhookRequest),POST(EVE_SESSION_ROUTE_PATH,async(n,r)=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=sessionAuthFromResult(i),o=await parseOptionalJsonRequest(n);if(o instanceof Response)return o;if(o.stubs!==void 0&&i.allowToolStubs!==!0)return Response.json({ok:!1,error:`Tool stubbing is not permitted for this caller.`},{status:403});let s=rejectSessionContinuationToken(o);if(s!==null)return s;let c=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:a,payload:o});if(c instanceof Response)return c;let l=parseCreateBody(o);if(l instanceof Response)return l;l.callback!==void 0&&l.legacyRemoteAgentCaller!==void 0&&log.info(`serving a remote agent protocol 1 caller`,{callerOrigin:new URL(l.callback.url).origin,forwarder:i.principalId});let u=l.callback===void 0?`absent`:readForwardedParentSessionBaggage(n.headers.get(`baggage`)),d;if(typeof u==`object`){if(u.callId!==l.callback?.callId)log.warn(`ignoring remote parent lineage with a mismatched callback`,{forwarder:i.principalId});else{let t=c.accepted;if(!t&&e.trustedForwarders!==void 0)try{t=await e.trustedForwarders(a,{})}catch(e){let t=logError(log,`trustedForwarders handler failed`,e,{forwarder:i.principalId});return Response.json({error:`trustedForwarders handler failed.`,errorId:t,ok:!1},{status:500})}t?d=u:log.warn(`ignoring remote parent lineage from an untrusted forwarder`,{forwarder:i.principalId})}}else u===`malformed`&&log.warn(`ignoring malformed remote parent lineage`,{forwarder:i.principalId});let f=l.callback===void 0?void 0:parseTraceparent(n.headers.get(`traceparent`)),p=l.callback===void 0?void 0:readAgentDispatchTraceContext(n.headers.get(`tracestate`),f)??f,m=checkUploadPolicy(l,t);if(m!==null)return m;if(l.operationId!==void 0&&c.auth.principalType===`anonymous`)return Response.json({error:`operationId requires an authenticated principal.`,ok:!1},{status:400});let h=l.operationId===void 0?void 0:await deriveOperationContinuationToken({auth:c.auth,operationId:l.operationId});if(h!==void 0){let e=await r.resolveSession(h);if(e!==void 0)return Response.json(createdSessionBody(e.id,l),{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.id},status:202})}let g=f===void 0?`absent`:readForwardedAudienceBaggage(n.headers.get(`baggage`)),_=c.accepted&&f!==void 0&&(f.traceFlags&1)==1?typeof g==`object`?g:g===`malformed`?FAIL_CLOSED_FORWARDED_TRACE_ASSERTION:void 0:void 0,v=p;_!==void 0&&p!==void 0&&(v={...p,forwardedTracePolicy:_}),g===`malformed`?log.warn(`using metadata-only policy for malformed forwarded audience baggage`,{forwarder:i.principalId}):typeof g==`object`&&(_===void 0?log.warn(`ignoring forwarded trace policy without an accepted sampled principal`,{forwarder:i.principalId}):log.info(`accepted forwarded trace policy`,{audience:g.originAudience,ceiling:formatTraceContentCeiling(g.ceiling),forwarder:i.principalId}));let y=l.message===void 0?{auth:c.auth}:await resolveOnMessage({auth:c.auth,config:e,invocation:d===void 0||l.operationId===void 0?void 0:{operationId:l.operationId},message:l.message,request:n});if(y instanceof Response)return y;let b=readRouteSessionCreator(r);if(b===void 0)return Response.json({error:`Session creation requires internal channel dispatch context.`,ok:!1},{status:500});let x;try{x=await b({audienceAuth:a,toolStubs:l.stubs===void 0?void 0:{rules:l.stubs,token:crypto.randomUUID()},auth:y.auth,capabilities:l.capabilities??{requestInput:!0},callback:l.callback,legacyRemoteAgentCaller:l.legacyRemoteAgentCaller,continuationToken:h,initiatorAuth:c.accepted?c.initiatorAuth:void 0,input:attachClientContext({message:l.message,context:y.context,outputSchema:l.outputSchema},l.context),conversationId:l.callback===void 0?void 0:readConversationBaggage(n.headers.get(`baggage`)),parent:d,parentTraceContext:v,traceRoot:d===void 0?void 0:{kind:`own`},title:y.title})}catch(e){if(e instanceof InvalidToolStubTargetError)return Response.json({error:e.message,ok:!1},{status:400});let t=logError(log,`session-create request failed`,e);return Response.json({error:`Failed to create the session.`,errorId:t,ok:!1},{status:500})}return Response.json(createdSessionBody(x.sessionId,l),{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:x.sessionId},status:202})}),POST(EVE_SESSION_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseJsonRequest(n);if(s instanceof Response)return s;let c=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:sessionAuthFromResult(a),payload:s});if(c instanceof Response)return c;let l=parseSessionMessageBody(s);if(l instanceof Response)return l;let u=checkUploadPolicy(l,t);if(u!==null)return u;let d,f,p=c.auth;if(l.message!==void 0){let t=await resolveOnMessage({auth:c.auth,config:e,message:l.message,request:n,sessionId:o});if(t instanceof Response)return t;d=t.context,f=t.title,p=t.auth}let m;try{let e=r(o),t=attachClientContext({auth:p,callback:l.callback,context:d,outputSchema:l.outputSchema,turnPolicy:l.turnPolicy,title:f},l.context);m=l.inputResponses===void 0?await e.send(l.message,t):await e.respond(l.inputResponses,t)}catch(e){let t=strandedSessionResponse(e);if(t!==void 0)return t;let n=logError(log,`session-message request failed`,e,{sessionId:o});return Response.json({error:`Failed to send the session message.`,errorId:n,ok:!1},{status:500})}return m.status===`accepted`?Response.json({ok:!0,sessionId:m.sessionId,status:`accepted`,deliveryId:m.deliveryId},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.sessionId},status:202}):Response.json({code:m.retryable?`session_not_ready`:`session_not_active`,error:m.retryable===!0?`The session is not ready to accept messages yet.`:`The session is no longer active.`,ok:!1},{headers:{"cache-control":`no-store`},status:409})}),POST(EVE_SESSION_CANCEL_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseCancelTurnBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).cancel({turnId:o.turnId})}catch(e){let t=logError(log,`cancel-turn request failed`,e,{sessionId:a});return Response.json({error:`Failed to cancel the turn.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`accepted`?{ok:!0,sessionId:s.sessionId,status:`accepted`}:{ok:!0,status:`no_active_turn`},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_COMPACT_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseSessionControlBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).compact()}catch(e){let t=logError(log,`session-compaction request failed`,e,{sessionId:a});return Response.json({error:`Failed to compact the session.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`accepted`?{ok:!0,sessionId:s.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_CLEAR_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseSessionControlBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).clear()}catch(e){let t=strandedSessionResponse(e);if(t!==void 0)return t;let n=logError(log,`session-clear request failed`,e,{sessionId:a});return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,...s},{headers:{"cache-control":`no-store`},status:s.status===`accepted`?202:200})}),POST(EVE_SESSION_RESET_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);if(a instanceof Response)return a;let o=await parseResetBody(t);if(o instanceof Response)return o;let s;try{s=await n(a).reset({reason:o.reason})}catch(e){let t=logError(log,`session-reset request failed`,e,{sessionId:a});return Response.json({error:`Failed to reset the session.`,errorId:t,ok:!1},{status:500})}return Response.json(s.status===`reset`?{ok:!0,previousSessionId:s.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`}})}),GET(EVE_SESSION_STUBS_ROUTE_PATTERN,async(t,{params:n})=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;if(r.allowToolStubs!==!0)return Response.json({error:`Tool stubbing is not permitted for this caller.`,ok:!1},{status:403});let i=requireSessionId(n);if(i instanceof Response)return i;try{return await getRun(i).exists?Response.json({error:await readStubFailure(i)??null,matchedRuleIds:await readMatchedStubRules(i)},{headers:{"cache-control":`no-store`}}):Response.json({error:`Session not found.`,ok:!1},{status:404})}catch(e){let t=logError(log,`tool-stub verification request failed`,e,{sessionId:i});return Response.json({error:`Failed to verify tool stubs.`,errorId:t,ok:!1},{status:500})}}),GET(EVE_SESSION_STREAM_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);return a instanceof Response?a:await createSessionStreamResponse(t,n(a))}),GET(EVE_SUBAGENT_STREAM_ROUTE_PATTERN,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=n.params.parentSessionId,a=n.params.callId,o=n.params.childSessionId;if(!i||!a||!o)return Response.json({error:`Missing subagent stream coordinates.`,ok:!1},{status:400});let s=parseStartIndex(t);if(s instanceof Response)return s;let c=parseIncludeTailIndex(t),l=createEveSubagentStreamRoutePath({callId:a,childSessionId:o,parentSessionId:i}),u;try{let e=n.attachSession(i),t=await findRemoteAgentBinding({callId:a,childSessionId:o,childStreamPath:l,parent:e});if(t===void 0)throw Error(`Remote subagent binding not found.`);u=t}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let d=readRemoteAgentStreamHeadersResolver(n);if(d===void 0)return Response.json({error:`Subagent stream proxy requires internal channel dispatch context.`,ok:!1},{status:500});let f;try{f=await d(u)}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let p=new URL(createEveSessionStreamRoutePath(o).replace(/^\/+/,``),`${u.url.replace(/\/+$/,``)}/`);s!==void 0&&p.searchParams.set(`startIndex`,String(s));let m=new URL(t.url).searchParams.get(EVE_STREAM_CONTROL_VERSION_QUERY);m!==null&&p.searchParams.set(EVE_STREAM_CONTROL_VERSION_QUERY,m),c&&p.searchParams.set(`includeTailIndex`,`1`);let h=await fetch(p,{cache:`no-store`,headers:f,redirect:`manual`,signal:t.signal}),g=new Headers;for(let e of[`cache-control`,`content-type`,`x-accel-buffering`,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER]){let t=h.headers.get(e);t!==null&&g.set(e,t)}return new Response(h.body,{headers:g,status:h.status,statusText:h.statusText})})],events:e.events,fetchFile:e.fetchFile,uploadPolicy:e.uploadPolicy})}export{eveChannel};
@@ -3,6 +3,7 @@ import type { SessionAuthContext, TurnPolicy } from "#channel/types.js";
3
3
  import type { TrustedForwarders } from "#channel/forwarded-principal.js";
4
4
  import type { AuthFn } from "#public/channels/auth.js";
5
5
  import type { UploadPolicyInput } from "#public/channels/upload-policy.js";
6
+ import type { FetchFileFunction } from "#shared/channel-definition.js";
6
7
  import type { AudienceContext, Channel, ChannelContinuationOps, ChannelEvents, ChannelMethod } from "#public/definitions/channel.js";
7
8
  import type { ChannelAudience } from "#shared/channel-audience.js";
8
9
  export type { ForwardedAssertion, TrustedForwarders } from "#channel/forwarded-principal.js";
@@ -124,9 +125,21 @@ export interface EveChannelInput {
124
125
  readonly trustedForwarders?: TrustedForwarders;
125
126
  /**
126
127
  * Attachment policy for inbound file parts. Omit for the framework default (25 MB cap, all media
127
- * types); `"disabled"` rejects every attachment; a partial config is merged onto the default. Violations reject with 413 (too large) or 415 (bad type).
128
+ * types); `"disabled"` rejects every attachment; a partial config is merged onto the default. Violations in the
129
+ * request reject with 413 (too large) or 415 (bad type). eve also checks every file it stages, including URLs, on
130
+ * its final bytes and verified media type; a file that breaks the policy there reaches the model as a note.
128
131
  */
129
132
  readonly uploadPolicy?: UploadPolicyInput;
133
+ /**
134
+ * Loads a file part whose `data` is a URL, such as a browser upload that went
135
+ * to your own storage first. The bytes then skip the request body limit and
136
+ * the workflow start payload, and load inside the workflow step.
137
+ *
138
+ * Return bytes or `{ bytes, mediaType?, filename? }` to stage the file, or
139
+ * `null` when the URL is not yours: eve then downloads a public `https:` URL
140
+ * itself. Fetched bytes must pass {@link uploadPolicy}.
141
+ */
142
+ readonly fetchFile?: FetchFileFunction;
130
143
  /**
131
144
  * Browser CORS policy for the eve HTTP routes. Omit or pass `false` to leave
132
145
  * CORS untouched, pass `true` for fully permissive CORS, or pass an options
@@ -7,6 +7,8 @@ export type AgentSessionAddress = {
7
7
  readonly name: string;
8
8
  readonly nodeId: string;
9
9
  readonly sessionId: string;
10
+ /** Names the session to whichever run holds its inbox. */
11
+ readonly continuationToken: string;
10
12
  } | {
11
13
  readonly callbackBaseUrl: string;
12
14
  readonly kind: "remote";
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{sessionInboxHookToken}from"#execution/session-inbox/address.js";import{ContextContainer,contextStorage}from"#context/container.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{createWorkflowRuntime,dispatchWorkflowSessionCommand,requestWorkflowTurnCancellation,waitForCommandHookOwner}from"#execution/workflow-runtime.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl,resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{resolveAgentAction,resolveAgentStartTarget}from"#execution/agent-sessions/target.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRemoteAgentTurn,continueRemoteAgentSession,resetRemoteAgentSession,resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{buildSubagentRunInput}from"#subagents/tool.js";import{resolveConversationId}from"#shared/conversation-identity.js";import{stubToolPath}from"#tool-stubs/target.js";const log=createLogger(`execution.agent-sessions`),RUN_FINISHED_REASON=`The workflow run that opened this session finished.`;async function openAgentSessionStep(e){"use step";let{context:t}=e,n=await loadAgentSessionBundle(t),r=resolveAgentAction({bundle:n,callId:t.parent.callId,dynamicSelections:t.dynamicSelections,input:{message:e.message,outputSchema:e.outputSchema,target:e.name}}),i=resolveAgentStartTarget({action:r,bundle:n,dynamicSelections:t.dynamicSelections,isRootSession:t.parent.rootSessionId===t.parent.sessionId}),a={auth:e.auth,bundle:n,context:t,key:e.key,replyTo:e.replyTo};return i.kind===`remote`?await startRemoteSession({...a,target:i}):await startLocalSession({...a,target:i})}async function sendAgentSessionMessageStep(e){"use step";let{address:t,context:n}=e;if(t.kind===`remote`){let r=await resolveSessionRemote(n,t);await continueRemoteAgentSession({auth:e.auth.current,callback:{callId:n.parent.callId,subagentName:t.name,token:e.replyTo,url:createWorkflowCallbackUrl(t.callbackBaseUrl,createEveCallbackRoutePath(e.replyTo))},message:e.message,outputSchema:e.outputSchema,remote:r,sessionId:t.sessionId});return}if((await dispatchWorkflowSessionCommand({command:{auth:e.auth.current,schedule:n.schedule,caller:{callId:n.parent.callId,replyTo:{kind:`hook`,token:e.replyTo},subagentName:t.name},kind:`send`,payload:{message:e.message,outputSchema:e.outputSchema}},sessionId:t.sessionId}).catch(e=>{throw SessionStrandedError.is(e)?Error(`Agent "${t.name}" can no longer receive messages: ${e.message}`,{cause:e}):e})).status!==`accepted`)throw Error(`Agent "${t.name}" can no longer receive messages; its session ended.`)}async function cancelAgentSessionTurnStep(e){"use step";let{address:t}=e;try{if(t.kind===`remote`){let n=await resolveSessionRemote(e.context,t);await cancelRemoteAgentTurn({remote:n,sessionId:t.sessionId});return}await requestWorkflowTurnCancellation({sessionId:t.sessionId})}catch(e){logError(log,`failed to cancel an agent session turn`,e,{name:t.name,sessionId:t.sessionId})}}async function endAgentSessionsStep(e){"use step";await Promise.all(e.sessions.map(endAgentSession))}async function endAgentSession({address:e,context:t}){try{if(e.kind===`remote`){let n=await resolveSessionRemote(t,e);await resetRemoteAgentSession({reason:RUN_FINISHED_REASON,remote:n,sessionId:e.sessionId});return}await dispatchWorkflowSessionCommand({command:{kind:`reset`,reason:RUN_FINISHED_REASON},sessionId:e.sessionId})}catch(t){logError(log,`failed to end an agent session`,t,{name:e.name,sessionId:e.sessionId})}}async function startLocalSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,{childContinuationToken:o,runInput:s}=buildSubagentRunInput({action:a,auth:t.current,capabilities:r.capabilities,schedule:r.schedule,channelMetadata:r.channelMetadata,continuationKey:e.key,graph:n.graph,inheritedConversation:r.conversation,initiatorAuth:t.initiator,limits:r.limits,parent:createParentContext(r,e.replyTo),sandboxSessionId:r.sandbox.sessionId,selfAgent:i.source.type===`runtime`,session:{continuationToken:e.replyTo,sandboxState:r.sandbox.state,sessionId:r.parent.sessionId},source:i.source}),c=createWorkflowRuntime({compiledArtifactsSource:n.compiledArtifactsSource,dynamicSubagentAgentConfig:i.dynamicSubagentAgentConfig,nodeId:a.nodeId}),l=r.toolStubs;l!==void 0&&(l={...l,agentPath:stubToolPath(l,a.name)}),await contextStorage.run(new ContextContainer({localDevRequest:r.localDevRequest}),()=>c.createSession({...s,toolStubs:l}));let u=await waitForCommandHookOwner(sessionInboxHookToken(o));return{kind:`local`,name:a.name,nodeId:a.nodeId,sessionId:u.runId}}async function startRemoteSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,o=resolveRemoteAgentForAction({dynamicRemoteAgent:i.dynamicRemoteAgent,nodeId:a.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:a.remoteAgentName}),s=resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),c=await startRemoteAgentSession({action:a,auth:t.current,callbackBaseUrl:s,capabilities:r.capabilities,initiatorAuth:t.initiator,operationId:`agent-session:${e.key}`,originAudience:r.trace.originAudience,parent:createParentContext(r,e.replyTo),remote:o,session:{continuationToken:e.replyTo}});return{callbackBaseUrl:s,kind:`remote`,forwardPrincipal:o.forwardPrincipal,name:a.remoteAgentName,nodeId:a.nodeId,resolverId:i.dynamicRemoteAgent?.credentialsStepId??a.nodeId,sessionId:c.sessionId,url:o.url}}function createParentContext(e,t){return{continuationToken:t,conversationId:e.trace.conversationId??resolveConversationId(e.parent.rootSessionId),lineage:e.parent,originAudience:e.trace.originAudience,traceContext:e.trace.parentTraceContext,traceRoot:e.traceRoot}}async function resolveSessionRemote(e,t){let n=await loadAgentSessionBundle(e),r=e.dynamicSelections[t.nodeId];return{...resolveRemoteAgentForAction({dynamicRemoteAgent:r?.kind===`remote`?r.remoteAgent:void 0,nodeId:t.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:t.name}),url:t.url}}async function loadAgentSessionBundle(e){return await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.bundle.source),nodeId:e.bundle.nodeId})}export{cancelAgentSessionTurnStep,endAgentSessionsStep,openAgentSessionStep,sendAgentSessionMessageStep};
1
+ import{createLogger,logError}from"#internal/logging.js";import{sessionInboxHookToken}from"#execution/session-inbox/address.js";import{ContextContainer,contextStorage}from"#context/container.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{createWorkflowRuntime,dispatchWorkflowSessionCommand,resolveContinuation,waitForCommandHookOwner,waitForSessionInbox}from"#execution/workflow-runtime.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{getStepMetadata,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl,resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{resolveAgentAction,resolveAgentStartTarget}from"#execution/agent-sessions/target.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRemoteAgentTurn,continueRemoteAgentSession,resetRemoteAgentSession,resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{buildSubagentRunInput}from"#subagents/tool.js";import{resolveConversationId}from"#shared/conversation-identity.js";import{stubToolPath}from"#tool-stubs/target.js";const log=createLogger(`execution.agent-sessions`),RUN_FINISHED_REASON=`The workflow run that opened this session finished.`;async function openAgentSessionStep(e){"use step";let{context:t}=e,n=await loadAgentSessionBundle(t),r=resolveAgentAction({bundle:n,callId:t.parent.callId,dynamicSelections:t.dynamicSelections,input:{message:e.message,outputSchema:e.outputSchema,target:e.name}}),i=resolveAgentStartTarget({action:r,bundle:n,dynamicSelections:t.dynamicSelections,isRootSession:t.parent.rootSessionId===t.parent.sessionId}),a={auth:e.auth,bundle:n,context:t,key:e.key,replyTo:e.replyTo};return i.kind===`remote`?await startRemoteSession({...a,target:i}):await startLocalSession({...a,target:i})}async function sendAgentSessionMessageStep(e){"use step";let{address:t,context:n}=e;if(t.kind===`remote`){let r=await resolveSessionRemote(n,t);await continueRemoteAgentSession({auth:e.auth.current,callback:{callId:n.parent.callId,subagentName:t.name,token:e.replyTo,url:createWorkflowCallbackUrl(t.callbackBaseUrl,createEveCallbackRoutePath(e.replyTo))},message:e.message,outputSchema:e.outputSchema,remote:r,sessionId:t.sessionId});return}if((await commandLocalSession({...e,address:t},{auth:e.auth.current,schedule:n.schedule,caller:{callId:n.parent.callId,replyTo:{kind:`hook`,token:e.replyTo},subagentName:t.name},kind:`send`,payload:{message:e.message,outputSchema:e.outputSchema}}).catch(e=>{throw SessionStrandedError.is(e)?Error(`Agent "${t.name}" can no longer receive messages: ${e.message}`,{cause:e}):e})).status!==`accepted`)throw Error(`Agent "${t.name}" can no longer receive messages; its session ended.`)}async function cancelAgentSessionTurnStep(e){"use step";let{address:t}=e;try{if(t.kind===`remote`){let n=await resolveSessionRemote(e.context,t);await cancelRemoteAgentTurn({remote:n,sessionId:t.sessionId});return}await commandLocalSession({...e,address:t},{kind:`cancel`})}catch(e){logError(log,`failed to cancel an agent session turn`,e,{name:t.name,sessionId:t.sessionId})}}async function endAgentSessionsStep(e){"use step";await Promise.all(e.sessions.map(endAgentSession))}async function endAgentSession(e){let{address:t,context:n}=e;try{if(t.kind===`remote`){let e=await resolveSessionRemote(n,t);await resetRemoteAgentSession({reason:RUN_FINISHED_REASON,remote:e,sessionId:t.sessionId});return}await commandLocalSession({...e,address:t},{kind:`reset`,reason:RUN_FINISHED_REASON})}catch(e){logError(log,`failed to end an agent session`,e,{name:t.name,sessionId:t.sessionId})}}async function commandLocalSession(e,t){let{continuationToken:n,sessionId:r}=e.address,i=await dispatchWorkflowSessionCommand({command:t,sessionId:r});if(i.status===`accepted`||i.status===`reset`)return i;let a=await waitForSessionInbox(r)?r:(await resolveContinuation(n))?.sessionId;return a===void 0?i:await dispatchWorkflowSessionCommand({command:t,sessionId:a})}async function startLocalSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,{childContinuationToken:o,runInput:s}=buildSubagentRunInput({action:a,auth:t.current,capabilities:r.capabilities,schedule:r.schedule,channelMetadata:r.channelMetadata,continuationKey:e.key,graph:n.graph,inheritedConversation:r.conversation,initiatorAuth:t.initiator,limits:r.limits,parent:createParentContext(r,e.replyTo),sandboxSessionId:r.sandbox.sessionId,selfAgent:i.source.type===`runtime`,session:{continuationToken:e.replyTo,sandboxState:r.sandbox.state,sessionId:r.parent.sessionId},source:i.source}),c=createWorkflowRuntime({compiledArtifactsSource:n.compiledArtifactsSource,dynamicSubagentAgentConfig:i.dynamicSubagentAgentConfig,nodeId:a.nodeId}),l=r.toolStubs;l!==void 0&&(l={...l,agentPath:stubToolPath(l,a.name)});let u=(await contextStorage.run(new ContextContainer({localDevRequest:r.localDevRequest}),()=>c.createSession({...s,toolStubs:l}))).sessionId;return getStepMetadata().attempt>1&&({runId:u}=await waitForCommandHookOwner(sessionInboxHookToken(o))),{continuationToken:o,kind:`local`,name:a.name,nodeId:a.nodeId,sessionId:u}}async function startRemoteSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,o=resolveRemoteAgentForAction({dynamicRemoteAgent:i.dynamicRemoteAgent,nodeId:a.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:a.remoteAgentName}),s=resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),c=await startRemoteAgentSession({action:a,auth:t.current,callbackBaseUrl:s,capabilities:r.capabilities,initiatorAuth:t.initiator,operationId:`agent-session:${e.key}`,originAudience:r.trace.originAudience,parent:createParentContext(r,e.replyTo),remote:o,session:{continuationToken:e.replyTo}});return{callbackBaseUrl:s,kind:`remote`,forwardPrincipal:o.forwardPrincipal,name:a.remoteAgentName,nodeId:a.nodeId,resolverId:i.dynamicRemoteAgent?.credentialsStepId??a.nodeId,sessionId:c.sessionId,url:o.url}}function createParentContext(e,t){return{continuationToken:t,conversationId:e.trace.conversationId??resolveConversationId(e.parent.rootSessionId),lineage:e.parent,originAudience:e.trace.originAudience,traceContext:e.trace.parentTraceContext,traceRoot:e.traceRoot}}async function resolveSessionRemote(e,t){let n=await loadAgentSessionBundle(e),r=e.dynamicSelections[t.nodeId];return{...resolveRemoteAgentForAction({dynamicRemoteAgent:r?.kind===`remote`?r.remoteAgent:void 0,nodeId:t.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:t.name}),url:t.url}}async function loadAgentSessionBundle(e){return await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.bundle.source),nodeId:e.bundle.nodeId})}export{cancelAgentSessionTurnStep,endAgentSessionsStep,openAgentSessionStep,sendAgentSessionMessageStep};
@@ -1 +1 @@
1
- import{contextStorage}from"#context/container.js";import{appliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{takeDeferredMessage}from"#harness/hitl/index.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";async function cancelledWithoutCheckpoint(e,t,n){let r=appliedSession(e),i=r??t,a=n;if(r!==void 0){let e=takeDeferredMessage(r);i=e.session,e.message!==void 0&&(a={...n,message:e.message})}return await contextStorage.run(e,()=>preserveCancelledTurnMessage(i,a))}async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint?.result.session??await cancelledWithoutCheckpoint(e.ctx,e.initialSession,e.stepInput),r={...e.checkpoint?.serializedContext??e.beforeBatchContext,[AuthKey.name]:t[AuthKey.name],[TurnDeliveryIdsKey.name]:t[TurnDeliveryIdsKey.name]};return{action:`cancelled`,serializedContext:preserveSerializedInstrumentationState(preserveSerializedAgentTraceState(preserveSerializedSessionDynamicModelSelection(r,t),t),t),...createDurableSessionValues(saveSessionProjection(n,e.ctx))}}export{createCancelledModelCallBatchResult};
1
+ import{createLogger}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{appliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,OfferedCatalogToolsKey,SandboxKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{withContextScope}from"#context/run-step.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{takeDeferredMessage}from"#harness/hitl/index.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";const log=createLogger(`execution.cancelled-turn`);async function cancelledWithoutCheckpoint(e,t,n){let r=appliedSession(e),i=r??t,a=n;if(r!==void 0){let e=takeDeferredMessage(r);i=e.session,e.message!==void 0&&(a={...n,message:e.message})}if(e.get(SandboxKey)===void 0&&hasFileParts(a?.message))try{return(await withContextScope(e,i,async e=>({result:void 0,session:await preserveCancelledTurnMessage(e,a)}))).session}catch(t){log.warn(`staging a cancelled turn's attachments failed`,{error:t}),e.clearVirtualContext()}return await contextStorage.run(e,()=>preserveCancelledTurnMessage(i,a))}function hasFileParts(e){return Array.isArray(e)&&e.some(e=>e.type===`file`)}async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint?.result.session??await cancelledWithoutCheckpoint(e.ctx,e.initialSession,e.stepInput),r={...e.checkpoint?.serializedContext??e.beforeBatchContext,[AuthKey.name]:t[AuthKey.name],[OfferedCatalogToolsKey.name]:t[OfferedCatalogToolsKey.name],[TurnDeliveryIdsKey.name]:t[TurnDeliveryIdsKey.name]};return{action:`cancelled`,serializedContext:preserveSerializedInstrumentationState(preserveSerializedAgentTraceState(preserveSerializedSessionDynamicModelSelection(r,t),t),t),...createDurableSessionValues(saveSessionProjection(n,e.ctx))}}export{createCancelledModelCallBatchResult};
@@ -1 +1 @@
1
- import{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage}from"./connection-auth.js";import{closestNames}from"./rank.js";import{connectionToolSignature}from"./signatures.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{displayProperName,displayTitle}from"#shared/display-name.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{defineJsonSchema,refineJsonSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";import{ContextKey}from"#context/key.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{isApprovalRecheck}from"#harness/approval-recheck.js";import{isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{connectionToolModelOutput,toConnectionToolResult}from"#runtime/connections/tool-result.js";const CONNECTION_CHANGED_MESSAGE=`The connection for this tool call changed or is unavailable. Request a new tool call and approval.`,ConnectionApprovalPinsKey=new ContextKey(`eve.connectionApprovalPins`);function instanceKey(e){return e.instanceId??``}function connectionEntry(e,t,n){let r=`${displayProperName(t.connectionName)}: ${displayTitle(n)}`;return{approval:connectionApproval(t),deferred:!0,description:``,execute:(r,i)=>callConnectionTool(e,t,n,r,i),inputSchema:refineJsonSchema({},r=>checkInput(e,t,n,r)),label:{start:()=>r},name:connectionToolName(t.connectionName,n),toModelOutput:connectionToolModelOutput}}function connectionSignInEntry(e,t){let n=displayProperName(t.connectionName),r=`Sign in to use the ${n} tools`;return{deferred:!0,description:t.description===``?`${r}.`:`${r}: ${t.description}`,execute:()=>connect(e,t),inputSchema:defineJsonSchema({type:`object`,properties:{},additionalProperties:!1}),label:{start:()=>`Sign in to ${n}`},name:t.connectionName}}async function connect(e,t){let n=await completeConnectionSignIn(e,t),r=await listConnectionTools(t,n);if(`failure`in r)throw Error(r.failure);if(`authorization`in r)return await n.auth.handleError(r.error,r.authorization);let i=displayProperName(t.connectionName),a=`${SEARCH_TOOL_NAME}({ query: "${t.connectionName}__" })`;return n.scoped!==void 0&&n.auth.isJustAuthorized(n.scoped)?`Signed in to ${i}. Find the ${i} tools with ${a}.`:`The ${i} tools are available. Find them with ${a}.`}async function callConnectionTool(e,t,n,r,i){releaseApprovalPin(i.toolCallId,t);let a=await completeConnectionSignIn(e,t),{auth:o,client:s,scoped:c}=a,l=await listConnectionTools(t,a);if(`failure`in l)throw Error(l.failure);if(`authorization`in l)return await o.handleError(l.error,l.authorization);let u=await checkCall(t,l.tools,n,r);if(`issues`in u)throw Error(issuesMessage(u.issues));let{input:d,tool:f}=u,p;try{p=await s.executeTool(f.name,d,{abortSignal:i.abortSignal,callId:i.toolCallId})}catch(e){if(isConnectionAuthorizationRequiredError(e))return await o.handleError(e,c);throw e}let m=toConnectionToolResult(t.protocol,f,p);if(!m.ok)throw Error(m.error);return m.value}async function checkInput(e,t,n,r){let i;try{i=await listToolMetadata(t.connectionName,e.getClient(t.connectionName))}catch(e){return isConnectionAuthorizationRequiredError(e)?{value:r}:{issues:[{message:listingFailureMessage(t.connectionName,e)}]}}let a=await checkCall(t,i,n,r);return`issues`in a?{issues:a.issues}:{value:a.input}}async function checkCall(e,t,n,r){let i=t.find(e=>e.name===n);if(i===void 0)return{issues:[{message:unknownToolMessage(e,n,t)}]};let a=await defineJsonSchema(i.inputSchema)[`~standard`].validate(isObject(r)?r:{});return a.issues===void 0?{input:a.value,tool:i}:{issues:[...a.issues,{message:`Signature: ${connectionToolSignature(e,i)}`}]}}function issuesMessage(e){return e.map(({message:e,path:t=[]})=>{let n=t.map(e=>String(typeof e==`object`?e.key:e)).join(`.`);return n.length>0?`${n}: ${e}`:e}).join(` `)}function unknownToolMessage(e,t,n){let{connectionName:r}=e,i=closestNames(t,n).map(e=>connectionToolName(r,e));return`Connection "${r}" has no tool named "${t}".${i.length>0?` Closest tools: ${i.join(`, `)}.`:` Find its tools with ${SEARCH_TOOL_NAME}({ query: "${r}__" }).`}`}function connectionApproval(e){let{approval:t}=e;if(t===void 0)return;let n=resolveApprovalPolicy(t),request=t=>requestApproval(e,n,t),r=typeof t==`function`?void 0:t.response;return r===void 0?request:{request,response:t=>authorizeApprovalResponse(e,r,t)}}async function requestApproval(e,t,n){isApprovalRecheck(n)&&!matchesApprovalPin(n.callId,e)&&markApprovalPinChanged(n.callId);let r=await t(n);return!isApprovalRecheck(n)&&parksForApproval(r)&&pinApprovedInstance(n.callId,e),r}function parksForApproval(e){return e===!0||e===`user-approval`||typeof e==`object`&&e.type===`user-approval`}async function authorizeApprovalResponse(e,t,n){return matchesApprovalPin(n.request.callId,e)?await t(n):{reason:CONNECTION_CHANGED_MESSAGE,status:`rejected`}}function pinApprovedInstance(e,t){let n=loadContext();n.get(ConnectionApprovalPinsKey)?.[e]===void 0&&n.set(ConnectionApprovalPinsKey,(n={})=>Object.fromEntries([...Object.entries(n).slice(-49),[e,instanceKey(t)]]))}function matchesApprovalPin(e,t){let n=loadContext().get(ConnectionApprovalPinsKey)?.[e];return n!==void 0&&n===instanceKey(t)}function markApprovalPinChanged(e){loadContext().set(ConnectionApprovalPinsKey,(t={})=>({...t,[e]:`\0changed`}))}function releaseApprovalPin(e,t){let n=loadContext(),r=n.get(ConnectionApprovalPinsKey);if(r?.[e]===void 0)return;let{[e]:i,...a}=r;if(n.set(ConnectionApprovalPinsKey,a),i!==instanceKey(t))throw Error(CONNECTION_CHANGED_MESSAGE)}export{connectionEntry,connectionSignInEntry};
1
+ import{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage}from"./connection-auth.js";import{closestNames}from"./rank.js";import{connectionToolSignature}from"./signatures.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{displayProperName,displayTitle}from"#shared/display-name.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{defineJsonSchema,refineJsonSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";import{ContextKey}from"#context/key.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{isApprovalRecheck}from"#harness/approval-recheck.js";import{isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{connectionToolModelOutput,toConnectionToolResult}from"#runtime/connections/tool-result.js";const CONNECTION_CHANGED_MESSAGE=`The connection for this tool call changed or is unavailable. Request a new tool call and approval.`,ConnectionApprovalPinsKey=new ContextKey(`eve.connectionApprovalPins`);function instanceKey(e){return e.instanceId??``}function connectionEntry(e,t,n){let r=`${displayProperName(t.connectionName)}: ${displayTitle(n)}`;return{approval:connectionApproval(t),deferred:!0,description:``,execute:(r,i)=>callConnectionTool(e,t,n,r,i),inputSchema:refineJsonSchema({},r=>checkInput(e,t,n,r)),label:{start:()=>r},name:connectionToolName(t.connectionName,n),toModelOutput:connectionToolModelOutput}}function connectionSignInEntry(e,t){let n=displayProperName(t.connectionName),r=`Sign in to use the ${n} tools`;return{deferred:!0,description:t.description===``?`${r}.`:`${r}: ${t.description}`,execute:()=>connect(e,t),inputSchema:defineJsonSchema({type:`object`,properties:{},additionalProperties:!1}),label:{start:()=>`Sign in to ${n}`},name:t.connectionName}}async function connect(e,t){let n=await completeConnectionSignIn(e,t),r=await listConnectionTools(t,n);if(`failure`in r)throw Error(r.failure);if(`authorization`in r)return await n.auth.handleError(r.error,r.authorization);let i=displayProperName(t.connectionName),a=`${SEARCH_TOOL_NAME}({ query: "${t.connectionName}__" })`;return n.scoped!==void 0&&n.auth.isJustAuthorized(n.scoped)?`Signed in to ${i}. Find the ${i} tools with ${a}.`:`The ${i} tools are available. Find them with ${a}.`}async function callConnectionTool(e,t,n,r,i){releaseApprovalPin(i.toolCallId,t);let a=await completeConnectionSignIn(e,t),{auth:o,client:s,scoped:c}=a,l=await listConnectionTools(t,a);if(`failure`in l)throw Error(l.failure);if(`authorization`in l)return await o.handleError(l.error,l.authorization);let u=await checkCall(t,l.tools,n,r);if(`issues`in u)throw Error(issuesMessage(u.issues));let{input:d,tool:f}=u,p;try{p=await s.executeTool(f.name,d,{abortSignal:i.abortSignal,callId:i.toolCallId})}catch(e){if(isConnectionAuthorizationRequiredError(e))return await o.handleError(e,c);throw e}let m=toConnectionToolResult(t.protocol,f,p);if(!m.ok)throw Error(m.error);return m.value}async function checkInput(e,t,n,r){let i;try{i=await listToolMetadata(t.connectionName,e.getClient(t.connectionName))}catch(e){return isConnectionAuthorizationRequiredError(e)?{value:r}:{issues:[{message:listingFailureMessage(t.connectionName,e)}]}}let a=await checkCall(t,i,n,r);return`issues`in a?{issues:a.issues}:{value:a.input}}async function checkCall(e,t,n,r){let i=t.find(e=>e.name===n);if(i===void 0)return{issues:[{message:unknownToolMessage(e,n,t)}]};let a=e.toolCall?.providedArguments??{},o=Object.fromEntries(Object.entries(isObject(r)?r:{}).filter(([e])=>!Object.hasOwn(a,e))),s=await defineJsonSchema(i.inputSchema)[`~standard`].validate(o);return s.issues===void 0?{input:s.value,tool:i}:{issues:[...s.issues,{message:`Signature: ${connectionToolSignature(e,i)}`}]}}function issuesMessage(e){return e.map(({message:e,path:t=[]})=>{let n=t.map(e=>String(typeof e==`object`?e.key:e)).join(`.`);return n.length>0?`${n}: ${e}`:e}).join(` `)}function unknownToolMessage(e,t,n){let{connectionName:r}=e,i=closestNames(t,n).map(e=>connectionToolName(r,e));return`Connection "${r}" has no tool named "${t}".${i.length>0?` Closest tools: ${i.join(`, `)}.`:` Find its tools with ${SEARCH_TOOL_NAME}({ query: "${r}__" }).`}`}function connectionApproval(e){let{approval:t}=e;if(t===void 0)return;let n=resolveApprovalPolicy(t),request=t=>requestApproval(e,n,t),r=typeof t==`function`?void 0:t.response;return r===void 0?request:{request,response:t=>authorizeApprovalResponse(e,r,t)}}async function requestApproval(e,t,n){isApprovalRecheck(n)&&!matchesApprovalPin(n.callId,e)&&markApprovalPinChanged(n.callId);let r=await t(n);return!isApprovalRecheck(n)&&parksForApproval(r)&&pinApprovedInstance(n.callId,e),r}function parksForApproval(e){return e===!0||e===`user-approval`||typeof e==`object`&&e.type===`user-approval`}async function authorizeApprovalResponse(e,t,n){return matchesApprovalPin(n.request.callId,e)?await t(n):{reason:CONNECTION_CHANGED_MESSAGE,status:`rejected`}}function pinApprovedInstance(e,t){let n=loadContext();n.get(ConnectionApprovalPinsKey)?.[e]===void 0&&n.set(ConnectionApprovalPinsKey,(n={})=>Object.fromEntries([...Object.entries(n).slice(-49),[e,instanceKey(t)]]))}function matchesApprovalPin(e,t){let n=loadContext().get(ConnectionApprovalPinsKey)?.[e];return n!==void 0&&n===instanceKey(t)}function markApprovalPinChanged(e){loadContext().set(ConnectionApprovalPinsKey,(t={})=>({...t,[e]:`\0changed`}))}function releaseApprovalPin(e,t){let n=loadContext(),r=n.get(ConnectionApprovalPinsKey);if(r?.[e]===void 0)return;let{[e]:i,...a}=r;if(n.set(ConnectionApprovalPinsKey,a),i!==instanceKey(t))throw Error(CONNECTION_CHANGED_MESSAGE)}export{connectionEntry,connectionSignInEntry};
@@ -1 +1 @@
1
- import{completeConnectionSignIn,listConnectionTools,listingFailureMessage}from"./connection-auth.js";import{closestNames,isEmptyQuery,rankCandidates}from"./rank.js";import{connectionToolSignature,entrySignature}from"./signatures.js";import{connectionSignInEntry}from"./connection-entry.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{serializeInputSchema,toInputSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";function searchDescription({connections:e,skills:t,tools:n}){return[`Find your own tools, agents, skills, and connected services by keyword; this searches what you can do, not the web.`,n?`A result with \`tool\` has the exact name, description, and TypeScript signature: call it with ${CALL_TOOL_NAME}({ name, input }).`:void 0,t?`A result with \`skill\` has the name and description: load it with ${SKILL_TOOL_NAME}({ name }).`:void 0,`When you already know a name or connection, from the catalog listing, an earlier result, or an error, search it directly: the exact name, or "<connection>__", which is faster and returns only that connection's tools.`,e?`A connection that needs sign-in appears as a tool named after the connection: calling it with ${CALL_TOOL_NAME}({ name }) asks the user to sign in.`:void 0].filter(e=>e!==void 0).join(` `)}const SEARCH_INPUT_SCHEMA=toInputSchema({type:`object`,properties:{query:{type:`string`,minLength:1,description:`Words describing the capability, such as 'list open issues'; an exact name; or a namespace prefix such as 'linear__', which searches only that connection's tools.`},limit:{type:`integer`,minimum:1,maximum:50,description:`Maximum results, best matches first. Defaults to 10.`}},required:[`query`],additionalProperties:!1}),SEARCH_LABEL={start:e=>`Search tools${labelQuery(e)}`,complete:(e,t)=>{let{results:n,unavailable:r=[]}=t,i=`Searched tools${labelQuery(e)}, found ${n.length===0?`nothing`:String(n.length)}`;if(n.length>0||r.length===0)return i;let a=r.length===1?`connection`:`connections`;return`${i}; ${String(r.length)} ${a} unavailable`}};function labelQuery(e){let t=e.query?.trim();return t?` for “${t}”`:``}function createSearchTool(e){return{description:searchDescription(e.reach),execute:t=>search(e,t),frameworkTool:!0,inputSchema:SEARCH_INPUT_SCHEMA,label:SEARCH_LABEL,name:SEARCH_TOOL_NAME}}async function search(e,t){let n=t.query??``;if(isEmptyQuery(n))throw Error(`${SEARCH_TOOL_NAME} needs at least one word in query, such as a capability ("list open issues") or a name or connection prefix ("linear__").`);let r=parseNamespace(n),inScope=e=>r===void 0||inNamespace(e,r),i=[...e.deferred.map(t=>entryCandidate(t,e.describe)),...e.skills.map(skillCandidate)].filter(e=>inScope(e.fullName)),a=[],{registry:o}=e;if(o!==void 0){let e=o.getConnections().filter(({connectionName:e})=>r===void 0||mayOwnNamespace(e,r)),t=await Promise.all(e.map(e=>searchConnection(o,e)));for(let e of t)`unavailable`in e?a.push(e.unavailable):i.push(...e.candidates.filter(e=>inScope(e.fullName)))}if(r!==void 0&&i.length===0&&a.length===0)throw Error(unknownNamespaceMessage(r,o?.getConnections()??[]));let s=clampInteger(t.limit,1,50,10),c=rankCandidates(n,i).slice(0,s).map(e=>e.result());return a.length>0?{results:c,unavailable:a}:{results:c}}function parseNamespace(e){let t=(e.trim().split(/\s+/u)[0]??``).replace(/^[^A-Za-z0-9_-]+/u,``),n=t.slice(0,Math.max(0,t.lastIndexOf(`__`))).replace(/_+$/u,``);return n===``?void 0:n}function inNamespace(e,t){return e===t||e.startsWith(`${t}__`)}function mayOwnNamespace(e,t){return inNamespace(e,t)||t.startsWith(`${e}__`)}function unknownNamespaceMessage(e,t){if(t.some(({connectionName:t})=>t===e))return`Connection "${e}" has no tools.`;let n=closestNames(e,t.map(({connectionName:e,description:t})=>({description:t,name:e})));return`No entries are named "${e}__…". ${n.length>0?`Closest connections: ${n.join(`, `)}.`:`Find names in the catalog listing or your tool list, or call ${SEARCH_TOOL_NAME} with plain words.`}`}async function searchConnection(e,t){let n=t.connectionName,r;try{r=await listConnectionTools(t,await completeConnectionSignIn(e,t))}catch(e){return{unavailable:{connection:n,error:listingFailureMessage(n,e)}}}return`failure`in r?{unavailable:{connection:n,error:r.failure}}:`authorization`in r?{candidates:[signInCandidate(e,t)]}:{candidates:r.tools.map(e=>toolCandidate(t,e))}}function entryCandidate(e,t){let n=serializeInputSchema(e.inputSchema),r=t(e);return{description:r,inputSchema:n,name:e.name,result:()=>({description:r,signature:entrySignature(e,n),tool:e.name}),fullName:e.name}}function skillCandidate({description:e,name:t,path:n}){return{description:e,fullName:t,name:t,result:()=>({description:e,path:n,skill:t})}}function toolCandidate(e,t){let n=connectionToolName(e.connectionName,t.name);return{connection:{description:e.description,name:e.connectionName},description:t.description,inputSchema:t.inputSchema,name:t.name,result:()=>({description:t.description,signature:connectionToolSignature(e,t),tool:n}),fullName:n}}function signInCandidate(e,t){let n=connectionSignInEntry(e,t);return{description:t.description,name:t.connectionName,result:()=>({description:n.description,signature:entrySignature(n),tool:n.name}),fullName:n.name}}function clampInteger(e,t,n,r){return typeof e!=`number`||!Number.isFinite(e)?r:Math.min(n,Math.max(t,Math.trunc(e)))}export{createSearchTool};
1
+ import{completeConnectionSignIn,listConnectionTools,listingFailureMessage}from"./connection-auth.js";import{closestNames,isEmptyQuery,rankCandidates}from"./rank.js";import{connectionToolSignature,entrySignature}from"./signatures.js";import{connectionSignInEntry}from"./connection-entry.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{serializeInputSchema,toInputSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";function searchDescription({connections:e,skills:t,tools:n}){return[`Search your own catalog for tools, agents, skills, and connected services that aren't in your tool list. Use it when nothing in your tool list fits the request; it doesn't search the web.`,n?`A result with \`tool\` has the exact name, description, and TypeScript signature: call it with ${CALL_TOOL_NAME}({ name, input }).`:void 0,t?`A result with \`skill\` has the name and description: load it with ${SKILL_TOOL_NAME}({ name }).`:void 0,"`searched` counts the entries the query covered, and `remaining` counts the matches past `limit`: when `remaining` is 0, nothing else the query covered matched. Connections under `unavailable` weren't searched.",`When you already know a name or connection, from the catalog listing, an earlier result, or an error, search it directly: the exact name, or "<connection>__", which is faster and returns only that connection's tools.`,e?`A connection that needs sign-in appears as a tool named after the connection: calling it with ${CALL_TOOL_NAME}({ name }) asks the user to sign in. \`searched\` counts its tools only after sign-in.`:void 0].filter(e=>e!==void 0).join(` `)}const SEARCH_INPUT_SCHEMA=toInputSchema({type:`object`,properties:{query:{type:`string`,minLength:1,description:`Words describing the capability, such as 'list open issues'; an exact name; or a namespace prefix such as 'linear__', which searches only that connection's tools.`},limit:{type:`integer`,minimum:1,maximum:50,description:`Maximum results, best matches first. Defaults to 10.`}},required:[`query`],additionalProperties:!1}),SEARCH_LABEL={start:e=>`Search tools${labelQuery(e)}`,complete:(e,t)=>{let{results:n,unavailable:r=[]}=t,i=`Searched tools${labelQuery(e)}, found ${n.length===0?`nothing`:String(n.length)}`;if(n.length>0||r.length===0)return i;let a=r.length===1?`connection`:`connections`;return`${i}; ${String(r.length)} ${a} unavailable`}};function labelQuery(e){let t=e.query?.trim();return t?` for “${t}”`:``}function createSearchTool(e){return{description:searchDescription(e.reach),execute:t=>search(e,t),frameworkTool:!0,inputSchema:SEARCH_INPUT_SCHEMA,label:SEARCH_LABEL,name:SEARCH_TOOL_NAME}}async function search(e,t){let n=t.query??``;if(isEmptyQuery(n))throw Error(`${SEARCH_TOOL_NAME} needs at least one word in query, such as a capability ("list open issues") or a name or connection prefix ("linear__").`);let r=parseNamespace(n),inScope=e=>r===void 0||inNamespace(e,r),i=[...e.deferred.map(t=>entryCandidate(t,e.describe)),...e.skills.map(skillCandidate)].filter(e=>inScope(e.fullName)),a=[],{registry:o}=e;if(o!==void 0){let e=o.getConnections().filter(({connectionName:e})=>r===void 0||mayOwnNamespace(e,r)),t=await Promise.all(e.map(e=>searchConnection(o,e)));for(let e of t)`unavailable`in e?a.push(e.unavailable):i.push(...e.candidates.filter(e=>inScope(e.fullName)))}if(r!==void 0&&i.length===0&&a.length===0)throw Error(unknownNamespaceMessage(r,o?.getConnections()??[]));let s=clampInteger(t.limit,1,50,10),c=rankCandidates(n,i),l=c.slice(0,s).map(e=>e.result()),u={results:l,remaining:c.length-l.length,searched:i.length};return a.length>0?{...u,unavailable:a}:u}function parseNamespace(e){let t=(e.trim().split(/\s+/u)[0]??``).replace(/^[^A-Za-z0-9_-]+/u,``),n=t.slice(0,Math.max(0,t.lastIndexOf(`__`))).replace(/_+$/u,``);return n===``?void 0:n}function inNamespace(e,t){return e===t||e.startsWith(`${t}__`)}function mayOwnNamespace(e,t){return inNamespace(e,t)||t.startsWith(`${e}__`)}function unknownNamespaceMessage(e,t){if(t.some(({connectionName:t})=>t===e))return`Connection "${e}" has no tools.`;let n=closestNames(e,t.map(({connectionName:e,description:t})=>({description:t,name:e})));return`No entries are named "${e}__…". ${n.length>0?`Closest connections: ${n.join(`, `)}.`:`Find names in the catalog listing or your tool list, or call ${SEARCH_TOOL_NAME} with plain words.`}`}async function searchConnection(e,t){let n=t.connectionName,r;try{r=await listConnectionTools(t,await completeConnectionSignIn(e,t))}catch(e){return{unavailable:{connection:n,error:listingFailureMessage(n,e)}}}return`failure`in r?{unavailable:{connection:n,error:r.failure}}:`authorization`in r?{candidates:[signInCandidate(e,t)]}:{candidates:r.tools.map(e=>toolCandidate(t,e))}}function entryCandidate(e,t){let n=serializeInputSchema(e.inputSchema),r=t(e);return{description:r,inputSchema:n,name:e.name,result:()=>({description:r,signature:entrySignature(e,n),tool:e.name}),fullName:e.name}}function skillCandidate({description:e,name:t,path:n}){return{description:e,fullName:t,name:t,result:()=>({description:e,path:n,skill:t})}}function toolCandidate(e,t){let n=connectionToolName(e.connectionName,t.name);return{connection:{description:e.description,name:e.connectionName},description:t.description,inputSchema:t.inputSchema,name:t.name,result:()=>({description:t.description,signature:connectionToolSignature(e,t),tool:n}),fullName:n}}function signInCandidate(e,t){let n=connectionSignInEntry(e,t);return{description:t.description,name:t.connectionName,result:()=>({description:n.description,signature:entrySignature(n),tool:n.name}),fullName:n.name}}function clampInteger(e,t,n,r){return typeof e!=`number`||!Number.isFinite(e)?r:Math.min(n,Math.max(t,Math.trunc(e)))}export{createSearchTool};
@@ -1,18 +1,19 @@
1
1
  /**
2
2
  * The step's catalog: one table of every entry a model step can reach. Direct
3
- * entries go into the model's tool list next to the catalog tools the agent
3
+ * entries go into the model's tool list next to the catalog tools the session
4
4
  * has: `eve__search` finds entries, `eve__tool` calls deferred entries and
5
5
  * connection tools, and `eve__skill` loads skills. A call resolves to its entry
6
6
  * here and then runs exactly as a direct call would, so only model history
7
7
  * ever names a catalog tool.
8
8
  */
9
- import type { ContextReader } from "#context/key.js";
9
+ import type { ContextAccessor, ContextReader } from "#context/key.js";
10
+ import { type OfferedCatalogTools } from "#context/keys.js";
10
11
  import type { HarnessToolDefinition } from "#harness/execute-tool.js";
11
12
  import type { CallResolver, HarnessSession, HarnessToolLookup, HarnessToolMap } from "#harness/types.js";
12
13
  import type { ResolvedConnectionDefinition } from "#runtime/types.js";
13
14
  import { type CatalogSkill } from "./skills.js";
14
15
  export interface StepCatalog extends HarnessToolLookup {
15
- /** The model's tool list: direct entries, then the catalog tools the agent has. */
16
+ /** The model's tool list: direct entries, then the catalog tools the session has. */
16
17
  readonly advertised: HarnessToolMap;
17
18
  readonly connections: readonly ResolvedConnectionDefinition[];
18
19
  /** Entries reached only through `eve__tool`, connection tools aside. */
@@ -21,6 +22,8 @@ export interface StepCatalog extends HarnessToolLookup {
21
22
  readonly entries: HarnessToolMap;
22
23
  /** Every skill the session can load, deferred or not. */
23
24
  readonly skills: ReadonlyMap<string, CatalogSkill>;
25
+ /** The catalog tools the tool list offers; see {@link recordOfferedCatalogTools}. */
26
+ readonly offered: OfferedCatalogTools;
24
27
  /**
25
28
  * Whether the session offers tasks: one of the agent's own tools it sees
26
29
  * starts them, or the agent resolves subagents at runtime. Both are fixed by
@@ -49,3 +52,9 @@ export declare function buildStepCatalog(input: {
49
52
  readonly endsTurn: boolean;
50
53
  readonly session: Pick<HarnessSession, "rootSessionId">;
51
54
  }): StepCatalog;
55
+ /**
56
+ * Keeps the catalog tools `catalog` offers for every later step of the
57
+ * session. The step that calls the model records them; a step rebuilt to
58
+ * resume a parked call only reads them.
59
+ */
60
+ export declare function recordOfferedCatalogTools(ctx: ContextAccessor | undefined, { offered }: StepCatalog): void;
@@ -1 +1 @@
1
- import{closestNames}from"./rank.js";import{entrySignature}from"./signatures.js";import{connectionEntry,connectionSignInEntry}from"./connection-entry.js";import{createSearchTool}from"./search.js";import{createSkillLoader,sessionSkills,unknownSkillMessage}from"./skills.js";import{isObject}from"#shared/guards.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_ENTRY_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{refineJsonSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";import{eveNamespaceReservation}from"#protocol/runtime-tools.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{startsTasks}from"#execution/tasks/tool-entry-point.js";import{buildDynamicSubagentTools}from"#context/dynamic-subagent-lifecycle.js";import{withTaskTools}from"#execution/tasks/model-step.js";import{runEntryCall}from"#harness/execute-call.js";import{checkToolCallInput}from"#harness/tool-call-io.js";const CALL_TOOL_DESCRIPTION=`Call a tool that isn't in your tool list by its exact name from ${SEARCH_TOOL_NAME}, with \`input\` matching its signature.`,SEARCHABLE_SKILL_DESCRIPTION=`Load a skill's instructions when the request clearly matches a listed skill or one ${SEARCH_TOOL_NAME} found, or the user asks for it, then follow them.`;function catalogToolsFor(e,t){let n=t?.resolvedAgent,r=n?.skills??[],i=(n?.dynamicSkillResolvers.length??0)>0,a=(n?.connections??[]).length>0||(n?.dynamicConnectionResolvers?.length??0)>0,o=i||r.some(e=>e.deferred===!0),s=a||e.some(e=>e.deferred===!0)||(n?.dynamicToolResolvers.length??0)>0||(t?.subagentRegistry.dynamicResolvers.length??0)>0;return{connections:a,search:s||o,searchableSkills:o,skills:r.length>0||i,tools:s}}function buildStepCatalog(e){let visible=t=>isVisible(t,e.session),t=e.ctx?.get(BundleKey),n=catalogToolsFor([...e.agentTools.values()].filter(visible),t),r=(t?.subagentRegistry.dynamicResolvers.length??0)>0||[...e.agentTools.values()].some(e=>visible(e)&&startsTasks(e)),i=stepEntries(e,visible),a=r?withTaskTools(i):i,o=new Map,s=new Map;for(let[e,t]of a)(t.deferred===!0?s:o).set(e,t);let c=e.ctx?.get(ConnectionRegistryKey),l=c?.getConnections()??[],u=sessionSkills(e.ctx),d=createSkillLoader(u),f=new Map(o),toolEntry=e=>a.get(e)??f.get(e)??(c===void 0?void 0:connectionEntryNamed(e,c,l)),describe=t=>describeEntry(t,e.endsTurn),p={advertised:f,connections:l,deferred:s,describe,entries:a,get:e=>e===SKILL_ENTRY_NAME?d:toolEntry(e),offersTasks:r,resolve:e=>{if(e.toolName===CALL_TOOL_NAME&&n.tools){let t=targetName(e.input),n=t===void 0?void 0:toolEntry(t);return t===void 0||n===void 0||!callableByName(n)?void 0:{call:asEntryCall(e,t),definition:n}}if(e.toolName===SKILL_TOOL_NAME&&n.skills){let t=targetName(e.input);return t===void 0||!u.has(t)?void 0:{call:{...e,input:{name:t},toolName:SKILL_ENTRY_NAME},definition:d}}let t=f.get(e.toolName);return t===void 0?void 0:{call:e,definition:t}},skills:u};if(n.search){let e=createSearchTool({deferred:[...s.values()],describe,reach:{connections:n.connections,skills:n.searchableSkills,tools:n.tools},registry:c,skills:[...u.values()].filter(e=>e.deferred)});f.set(e.name,e)}return n.tools&&f.set(CALL_TOOL_NAME,createCallTool(p,toolEntry,n)),n.skills&&f.set(SKILL_TOOL_NAME,createSkillTool(p,toolEntry,n)),p}function targetName(e){return isObject(e)&&typeof e.name==`string`?e.name:void 0}function asEntryCall(e,t){let n=e.input.input;return{...e,input:n??{},toolName:t}}function describeEntry(e,t){return t&&e.endsTurn===!0?`${e.description}\n\nCalling this tool ends your turn once it succeeds: do not write a reply or call other tools in the same step. If it fails, you will see the error and can continue.`.trimStart():e.description}function stepEntries(e,t){let n=new Map([...e.agentTools].filter(([,e])=>t(e)));if(e.ctx===void 0)return n;for(let r of buildDynamicSubagentTools(e.ctx).filter(t))n.set(r.name,r);let r=new Set;for(let i of buildDynamicTools(e.ctx).filter(t))r.has(i.name)||(r.add(i.name),n.set(i.name,i));return n}function isVisible(e,t){return e.rootOnly!==!0&&e.availableInSubagents!==!1&&e.behavior?.availability.includes(`root-session`)!==!0||t.rootSessionId===void 0}function connectionEntryNamed(e,t,n){for(let r of n){if(e===r.connectionName)return connectionSignInEntry(t,r);let n=connectionToolName(r.connectionName,``);if(e.length>n.length&&e.startsWith(n))return connectionEntry(t,r,e.slice(n.length))}}function createCallTool(e,t,n){return{description:n.connections?`${CALL_TOOL_DESCRIPTION} Prefer connected services over web search or general knowledge when a request relates to them.`:CALL_TOOL_DESCRIPTION,execute:(t,n)=>runResolved(e,{input:t,toolName:CALL_TOOL_NAME},n),frameworkTool:!0,inputSchema:refineJsonSchema({type:`object`,properties:{name:{type:`string`,description:`The tool's exact name, as ${SEARCH_TOOL_NAME} returns it.`},input:{type:`object`,description:`Arguments matching the tool's signature. Defaults to {}.`}},required:[`name`],additionalProperties:!1},n=>resolveToolInput(e,t,n)),name:CALL_TOOL_NAME}}function createSkillTool(e,t,n){return{description:n.searchableSkills?SEARCHABLE_SKILL_DESCRIPTION:`Load a skill's instructions when the request clearly matches one of your listed skills or the user asks for it, then follow them.`,execute:(t,n)=>runResolved(e,{input:t,toolName:SKILL_TOOL_NAME},n),frameworkTool:!0,inputSchema:refineJsonSchema({type:`object`,properties:{name:{type:`string`,description:n.searchableSkills?`The skill's name, from your listed skills or ${SEARCH_TOOL_NAME}.`:`The skill's name, from your listed skills.`}},required:[`name`],additionalProperties:!1},async r=>resolveSkillInput(e,t,r.name,n)),name:SKILL_TOOL_NAME}}function runResolved(e,t,n){let r=e.resolve(t);if(r===void 0)throw Error(`A ${t.toolName} call ran without a resolved entry.`);return runEntryCall(r,n)}function callableByName(e){return e.deferred===!0||eveNamespaceReservation(e.name)===void 0&&(e.execute!==void 0||e.workflowId!==void 0)}async function resolveToolInput(e,t,{input:n,name:r}){let i=t(r);if(i===void 0)return failure(`name`,unknownEntryMessage(r,e));if(!callableByName(i))return failure(`name`,`"${r}" is in your tool list; call it directly.`);let a=await checkToolCallInput(i,n,``);if(a.kind===`threw`)throw a.error;return a.kind===`invalid`?{issues:(isConnectionTool(r,e.connections)?a.issues:[...a.issues,{message:`Signature: ${entrySignature(i)}`}]).map(({message:e,path:t=[]})=>({message:e,path:[`input`,...t]}))}:{value:{input:a.value,name:r}}}function resolveSkillInput(e,t,n,r){if(e.skills.has(n))return{value:{name:n}};let i=e.connections.map(e=>e.connectionName),a=i.includes(n)?void 0:t(n);return a===void 0?failure(`name`,unknownSkillMessage(n,e.skills,i,r.searchableSkills)):failure(`name`,a.deferred===!0?`"${n}" is a tool, not a skill; call it with ${CALL_TOOL_NAME}({ name: "${n}" }).`:`"${n}" is a tool in your tool list, not a skill; call it directly.`)}function isConnectionTool(e,t){return t.some(({connectionName:t})=>e.startsWith(connectionToolName(t,``)))}function failure(e,t){return{issues:[{message:t,path:[e]}]}}function unknownEntryMessage(e,t){if(t.skills.has(e))return`"${e}" is a skill; load it with ${SKILL_TOOL_NAME}({ name: "${e}" }).`;let n=[...t.deferred.values()].map(({description:e,name:t})=>({description:e,name:t})),r=closestNames(e,n);return`No tool named "${e}".${r.length>0?` Closest tools: ${r.join(`, `)}.`:` Find tools with ${SEARCH_TOOL_NAME}.`}`}export{buildStepCatalog};
1
+ import{closestNames}from"./rank.js";import{entrySignature}from"./signatures.js";import{connectionEntry,connectionSignInEntry}from"./connection-entry.js";import{createSearchTool}from"./search.js";import{createSkillLoader,sessionSkills,unknownSkillMessage}from"./skills.js";import{isObject}from"#shared/guards.js";import{OfferedCatalogToolsKey}from"#context/keys.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_ENTRY_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{refineJsonSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";import{eveNamespaceReservation}from"#protocol/runtime-tools.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{startsTasks}from"#execution/tasks/tool-entry-point.js";import{buildDynamicSubagentTools}from"#context/dynamic-subagent-lifecycle.js";import{withTaskTools}from"#execution/tasks/model-step.js";import{runEntryCall}from"#harness/execute-call.js";import{checkToolCallInput}from"#harness/tool-call-io.js";const CALL_TOOL_DESCRIPTION=`Call a tool that isn't in your tool list by its exact name from ${SEARCH_TOOL_NAME}, with \`input\` matching its signature.`,SEARCHABLE_SKILL_DESCRIPTION=`Load a skill's instructions when the request clearly matches a listed skill or one ${SEARCH_TOOL_NAME} found, or the user asks for it, then follow them.`;function catalogToolsFor(e){let{offered:t}=e,n=[...e.skills.values()],r=t?.connections===!0||e.connections.length>0,i=t?.searchableSkills===!0||n.some(e=>e.deferred),a=t?.tools===!0||r||e.deferred.size>0;return{connections:r,search:a||i,searchableSkills:i,skills:t?.skills===!0||n.length>0,tools:a}}function buildStepCatalog(e){let visible=t=>isVisible(t,e.session),t=((e.ctx?.get(BundleKey))?.subagentRegistry.dynamicResolvers.length??0)>0||[...e.agentTools.values()].some(e=>visible(e)&&startsTasks(e)),n=stepEntries(e,visible),r=t?withTaskTools(n):n,i=new Map,a=new Map;for(let[e,t]of r)(t.deferred===!0?a:i).set(e,t);let o=e.ctx?.get(ConnectionRegistryKey),s=o?.getConnections()??[],c=sessionSkills(e.ctx),l=catalogToolsFor({connections:s,deferred:a,offered:e.ctx?.get(OfferedCatalogToolsKey),skills:c}),{search:u,...d}=l,f=createSkillLoader(c),p=new Map(i),toolEntry=e=>r.get(e)??p.get(e)??(o===void 0?void 0:connectionEntryNamed(e,o,s)),describe=t=>describeEntry(t,e.endsTurn),m={advertised:p,connections:s,deferred:a,describe,entries:r,get:e=>e===SKILL_ENTRY_NAME?f:toolEntry(e),offered:d,offersTasks:t,resolve:e=>{if(e.toolName===CALL_TOOL_NAME&&l.tools){let t=targetName(e.input),n=t===void 0?void 0:toolEntry(t);return t===void 0||n===void 0||!callableByName(n)?void 0:{call:asEntryCall(e,t),definition:n}}if(e.toolName===SKILL_TOOL_NAME&&l.skills){let t=targetName(e.input);return t===void 0||!c.has(t)?void 0:{call:{...e,input:{name:t},toolName:SKILL_ENTRY_NAME},definition:f}}let t=p.get(e.toolName);return t===void 0?void 0:{call:e,definition:t}},skills:c};if(l.search){let e=createSearchTool({deferred:[...a.values()],describe,reach:{connections:l.connections,skills:l.searchableSkills,tools:l.tools},registry:o,skills:[...c.values()].filter(e=>e.deferred)});p.set(e.name,e)}return l.tools&&p.set(CALL_TOOL_NAME,createCallTool(m,toolEntry,l)),l.skills&&p.set(SKILL_TOOL_NAME,createSkillTool(m,toolEntry,l)),m}function recordOfferedCatalogTools(e,{offered:t}){Object.values(t).includes(!0)&&e?.set(OfferedCatalogToolsKey,t)}function targetName(e){return isObject(e)&&typeof e.name==`string`?e.name:void 0}function asEntryCall(e,t){let n=e.input.input;return{...e,input:n??{},toolName:t}}function describeEntry(e,t){return t&&e.endsTurn===!0?`${e.description}\n\nCalling this tool ends your turn once it succeeds: do not write a reply or call other tools in the same step. If it fails, you will see the error and can continue.`.trimStart():e.description}function stepEntries(e,t){let n=new Map([...e.agentTools].filter(([,e])=>t(e)));if(e.ctx===void 0)return n;for(let r of buildDynamicSubagentTools(e.ctx).filter(t))n.set(r.name,r);let r=new Set;for(let i of buildDynamicTools(e.ctx).filter(t))r.has(i.name)||(r.add(i.name),n.set(i.name,i));return n}function isVisible(e,t){return e.rootOnly!==!0&&e.availableInSubagents!==!1&&e.behavior?.availability.includes(`root-session`)!==!0||t.rootSessionId===void 0}function connectionEntryNamed(e,t,n){for(let r of n){if(e===r.connectionName)return connectionSignInEntry(t,r);let n=connectionToolName(r.connectionName,``);if(e.length>n.length&&e.startsWith(n))return connectionEntry(t,r,e.slice(n.length))}}function createCallTool(e,t,n){return{description:n.connections?`${CALL_TOOL_DESCRIPTION} Prefer connected services over web search or general knowledge when a request relates to them.`:CALL_TOOL_DESCRIPTION,execute:(t,n)=>runResolved(e,{input:t,toolName:CALL_TOOL_NAME},n),frameworkTool:!0,inputSchema:refineJsonSchema({type:`object`,properties:{name:{type:`string`,description:`The tool's exact name, as ${SEARCH_TOOL_NAME} returns it.`},input:{type:`object`,description:`Arguments matching the tool's signature. Defaults to {}.`}},required:[`name`],additionalProperties:!1},n=>resolveToolInput(e,t,n)),name:CALL_TOOL_NAME}}function createSkillTool(e,t,n){return{description:n.searchableSkills?SEARCHABLE_SKILL_DESCRIPTION:`Load a skill's instructions when the request clearly matches one of your listed skills or the user asks for it, then follow them.`,execute:(t,n)=>runResolved(e,{input:t,toolName:SKILL_TOOL_NAME},n),frameworkTool:!0,inputSchema:refineJsonSchema({type:`object`,properties:{name:{type:`string`,description:n.searchableSkills?`The skill's name, from your listed skills or ${SEARCH_TOOL_NAME}.`:`The skill's name, from your listed skills.`}},required:[`name`],additionalProperties:!1},async r=>resolveSkillInput(e,t,r.name,n)),name:SKILL_TOOL_NAME}}function runResolved(e,t,n){let r=e.resolve(t);if(r===void 0)throw Error(`A ${t.toolName} call ran without a resolved entry.`);return runEntryCall(r,n)}function callableByName(e){return e.deferred===!0||eveNamespaceReservation(e.name)===void 0&&(e.execute!==void 0||e.workflowId!==void 0)}async function resolveToolInput(e,t,{input:n,name:r}){let i=t(r);if(i===void 0)return failure(`name`,unknownEntryMessage(r,e));if(!callableByName(i))return failure(`name`,`"${r}" is in your tool list; call it directly.`);let a=await checkToolCallInput(i,n,``);if(a.kind===`threw`)throw a.error;return a.kind===`invalid`?{issues:(isConnectionTool(r,e.connections)?a.issues:[...a.issues,{message:`Signature: ${entrySignature(i)}`}]).map(({message:e,path:t=[]})=>({message:e,path:[`input`,...t]}))}:{value:{input:a.value,name:r}}}function resolveSkillInput(e,t,n,r){if(e.skills.has(n))return{value:{name:n}};let i=e.connections.map(e=>e.connectionName),a=i.includes(n)?void 0:t(n);return a===void 0?failure(`name`,unknownSkillMessage(n,e.skills,i,r.searchableSkills)):failure(`name`,a.deferred===!0?`"${n}" is a tool, not a skill; call it with ${CALL_TOOL_NAME}({ name: "${n}" }).`:`"${n}" is a tool in your tool list, not a skill; call it directly.`)}function isConnectionTool(e,t){return t.some(({connectionName:t})=>e.startsWith(connectionToolName(t,``)))}function failure(e,t){return{issues:[{message:t,path:[e]}]}}function unknownEntryMessage(e,t){if(t.skills.has(e))return`"${e}" is a skill; load it with ${SKILL_TOOL_NAME}({ name: "${e}" }).`;let n=[...t.deferred.values()].map(({description:e,name:t})=>({description:e,name:t})),r=closestNames(e,n);return`No tool named "${e}".${r.length>0?` Closest tools: ${r.join(`, `)}.`:` Find tools with ${SEARCH_TOOL_NAME}.`}`}export{buildStepCatalog,recordOfferedCatalogTools};
@@ -1,4 +1,4 @@
1
- import type { SessionAuthContext } from "#channel/types.js";
1
+ /** Shared owner-side dispatch context preparation. */
2
2
  import { type ChannelAdapter, type ChannelAdapterContext } from "#channel/adapter.js";
3
3
  import { type LocalDevRequestProvenance } from "#context/keys.js";
4
4
  import { ContextContainer } from "#context/container.js";
@@ -61,7 +61,6 @@ export declare function prepareCoordinationDispatch(input: {
61
61
  readonly sessionState: DurableSessionState;
62
62
  }): Promise<PreparedCoordinationDispatch | undefined>;
63
63
  interface DispatchBatch {
64
- readonly approvers?: Readonly<Record<string, SessionAuthContext>>;
65
64
  readonly event: {
66
65
  readonly sequence: number;
67
66
  readonly stepIndex: number;
@@ -1 +1 @@
1
- import{ConversationContextKey}from"#shared/conversation-context.js";import"#channel/adapter.js";import"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey,LocalDevRequestKey,ParentSessionKey,TraceRootKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{activeTurnId,runtimeWait,storedProjection,turnPosition}from"#harness/session-machine/view.js";import"#subagents/tool.js";import{readDurableSession}from"#execution/durable-session-store.js";import{deserializeContext}from"#context/serialize.js";import{readDynamicSubagentSelections}from"#context/dynamic-subagent-lifecycle.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{assertUniqueCoordinationCallIds}from"#harness/coordination.js";import{resolveTraceRootSessionId}from"#shared/trace-root.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{resolveWorkflowAgentMetadata}from"#execution/agent-sessions/metadata.js";async function prepareCoordinationDispatch(e){let t=readDurableSession(e.sessionState),n=runtimeWait(t.state);if(n===void 0)return;let r=n.tasks;if(r.length===0)return;let i=n.event.turnId||activeTurnId(turnPosition(storedProjection(t.state))),a=await deserializeContext(e.serializedContext);return{...await prepareActionDispatch({batch:{approvers:n.approvers,event:{...n.event,turnId:i},requests:r},ctx:a,durableSession:t,plan:()=>r,serializedContext:e.serializedContext}),sessionState:e.sessionState}}async function prepareActionDispatch(e){let{batch:t,durableSession:n}=e;assertUniqueCoordinationCallIds(t.requests);let r=e.ctx,i=r.require(BundleKey),a=resolveEffectiveAgentRuntime(i,r),o=hydrateDurableSession({compactionOverrides:{thresholdPercent:a.thresholdPercent},durable:n,turnAgent:a.turnAgent}),s=r.require(ChannelKey),c=e.plan({bundle:i,ctx:r,requests:t.requests,session:o}),l=resolveActiveSandboxSessionId(s.state,o.sessionId);return{adapter:s,adapterCtx:buildAdapterContext(s,r),auth:r.get(AuthKey)??null,batch:t,bundle:i,capabilities:r.get(CapabilitiesKey),channelMetadata:r.get(ChannelInstrumentationKey),dynamicSubagentSelections:readDynamicSubagentSelections(r),inheritedConversation:r.get(ConversationContextKey),initiatorAuth:r.get(InitiatorAuthKey)??null,localDevRequest:r.get(LocalDevRequestKey),parentSession:r.get(ParentSessionKey),plan:c,sandboxSessionId:l,serializedContext:e.serializedContext,session:o,traceRoot:childTraceRoot(r,o.sessionId),workflowAgents:resolveWorkflowAgentMetadata(r)}}function childTraceRoot(e,t){if(e.get(TraceRootKey)!==void 0)return{kind:`inherited`,sessionId:resolveTraceRootSessionId(e,t)}}function resolveActiveSandboxSessionId(e,t){if(typeof e!=`object`||!e)return t;let n=e.sandboxSessionId;return typeof n==`string`&&n.length>0?n:t}export{prepareActionDispatch,prepareCoordinationDispatch};
1
+ import{ConversationContextKey}from"#shared/conversation-context.js";import"#channel/adapter.js";import"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey,LocalDevRequestKey,ParentSessionKey,TraceRootKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{activeTurnId,runtimeWait,storedProjection,turnPosition}from"#harness/session-machine/view.js";import"#subagents/tool.js";import{readDurableSession}from"#execution/durable-session-store.js";import{deserializeContext}from"#context/serialize.js";import{readDynamicSubagentSelections}from"#context/dynamic-subagent-lifecycle.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{assertUniqueCoordinationCallIds}from"#harness/coordination.js";import{resolveTraceRootSessionId}from"#shared/trace-root.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{resolveWorkflowAgentMetadata}from"#execution/agent-sessions/metadata.js";async function prepareCoordinationDispatch(e){let t=readDurableSession(e.sessionState),n=runtimeWait(t.state);if(n===void 0)return;let r=n.tasks;if(r.length===0)return;let i=n.event.turnId||activeTurnId(turnPosition(storedProjection(t.state))),a=await deserializeContext(e.serializedContext);return{...await prepareActionDispatch({batch:{event:{...n.event,turnId:i},requests:r},ctx:a,durableSession:t,plan:()=>r,serializedContext:e.serializedContext}),sessionState:e.sessionState}}async function prepareActionDispatch(e){let{batch:t,durableSession:n}=e;assertUniqueCoordinationCallIds(t.requests);let r=e.ctx,i=r.require(BundleKey),a=resolveEffectiveAgentRuntime(i,r),o=hydrateDurableSession({compactionOverrides:{thresholdPercent:a.thresholdPercent},durable:n,turnAgent:a.turnAgent}),s=r.require(ChannelKey),c=e.plan({bundle:i,ctx:r,requests:t.requests,session:o}),l=resolveActiveSandboxSessionId(s.state,o.sessionId);return{adapter:s,adapterCtx:buildAdapterContext(s,r),auth:r.get(AuthKey)??null,batch:t,bundle:i,capabilities:r.get(CapabilitiesKey),channelMetadata:r.get(ChannelInstrumentationKey),dynamicSubagentSelections:readDynamicSubagentSelections(r),inheritedConversation:r.get(ConversationContextKey),initiatorAuth:r.get(InitiatorAuthKey)??null,localDevRequest:r.get(LocalDevRequestKey),parentSession:r.get(ParentSessionKey),plan:c,sandboxSessionId:l,serializedContext:e.serializedContext,session:o,traceRoot:childTraceRoot(r,o.sessionId),workflowAgents:resolveWorkflowAgentMetadata(r)}}function childTraceRoot(e,t){if(e.get(TraceRootKey)!==void 0)return{kind:`inherited`,sessionId:resolveTraceRootSessionId(e,t)}}function resolveActiveSandboxSessionId(e,t){if(typeof e!=`object`||!e)return t;let n=e.sandboxSessionId;return typeof n==`string`&&n.length>0?n:t}export{prepareActionDispatch,prepareCoordinationDispatch};
@@ -1 +1 @@
1
- import{storedProjection}from"#harness/session-machine/view.js";import{createDurableSessionState}from"#execution/durable-session-store.js";import{prepareCoordinationDispatch}from"#execution/coordination-dispatch-shared.js";import{publishSessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{startWorkflowTask}from"#execution/tools/workflow/start.js";import{sendToTask,startTaskRun}from"#execution/tasks/start.js";import{captureAgentSessionContext,resolveStepAgentLimits}from"#execution/agent-sessions/context.js";import{sessionView}from"#harness/session-machine/commit.js";import{startTask}from"#harness/session-machine/transitions.js";async function dispatchCoordinationStep(e){"use step";return await withSessionStateDelta(e,dispatchCoordination)}async function dispatchCoordination(e){let t=await prepareCoordinationDispatch({serializedContext:e.serializedContext,sessionState:e.sessionState});if(t===void 0)return{results:[],serializedContext:e.serializedContext,sessionState:e.sessionState};let{batch:n,session:r}=t,i=r,a=[],o=[],s=resolveStepAgentLimits(t);for(let r of t.plan){let c=await dispatchWorkflowCall({agentContext:captureAgentSessionContext(t,r.callId,s),auth:{current:n.approvers?.[r.callId]??t.auth,initiator:t.initiatorAuth},batchEvent:n.event,owner:e.workflowToolRunOwner,parentSession:t.parentSession,session:i,task:r});i=c.session,c.result!==void 0&&a.push(c.result),c.started!==void 0&&o.push(c.started)}return{results:a,...await publishSessionEvents({serializedContext:e.serializedContext,sessionState:i===r?t.sessionState:createDurableSessionState({session:i}),sessionWritable:e.sessionWritable},o.flatMap(e=>startTask(sessionView(storedProjection(i.state),i.state),e).events))}}async function dispatchWorkflowCall(e){let{entry:t}=e.task;switch(t.entryPoint){case`execute`:return await startWorkflowTask(e);case`task`:case`serve`:return await startTaskRun({...e,entry:t});case`receive`:return await sendToTask({...e,taskId:t.taskId})}}export{dispatchCoordinationStep};
1
+ import{storedProjection}from"#harness/session-machine/view.js";import{readTaskTable}from"#execution/tasks/table.js";import{createDurableSessionState}from"#execution/durable-session-store.js";import{prepareCoordinationDispatch}from"#execution/coordination-dispatch-shared.js";import{publishSessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{startWorkflowTask,startWorkflowToolCallRun}from"#execution/tools/workflow/start.js";import{runEntryToStart,sendToTask,startTaskRun,startsEveryRun}from"#execution/tasks/start.js";import{captureAgentSessionContext,resolveStepAgentLimits}from"#execution/agent-sessions/context.js";import{sessionView}from"#harness/session-machine/commit.js";import{startTask}from"#harness/session-machine/transitions.js";async function dispatchCoordinationStep(e){"use step";return await withSessionStateDelta(e,dispatchCoordination)}async function dispatchCoordination(e){let t=await prepareCoordinationDispatch({serializedContext:e.serializedContext,sessionState:e.sessionState});if(t===void 0)return{results:[],serializedContext:e.serializedContext,sessionState:e.sessionState};let{batch:n,session:r}=t,i=r,a=[],o=[],s=resolveStepAgentLimits(t),c=withPrestartedRuns(t.plan.map(i=>({agentContext:captureAgentSessionContext(t,i.callId,s),auth:{current:t.auth,initiator:t.initiatorAuth},batchEvent:n.event,owner:e.workflowToolRunOwner,parentSession:t.parentSession,session:r,task:i})),readTaskTable(r.state));for(let e of c){let t=await dispatchWorkflowCall({...e,session:i});i=t.session,t.result!==void 0&&a.push(t.result),t.started!==void 0&&o.push(t.started)}return{results:a,...await publishSessionEvents({serializedContext:e.serializedContext,sessionState:i===r?t.sessionState:createDurableSessionState({session:i}),sessionWritable:e.sessionWritable},o.flatMap(e=>startTask(sessionView(storedProjection(i.state),i.state),e).events))}}function withPrestartedRuns(e,t){let n=e.map(e=>e.task),r=n.map(e=>runEntryToStart(t,e));return r.filter(e=>e!==void 0).length>1&&startsEveryRun(t,n)?e.map((e,t)=>{let n=r[t];if(n===void 0)return e;let i=startWorkflowToolCallRun(e,n);return i.catch(()=>{}),{...e,prestarted:{entry:n,run:i}}}):e}async function dispatchWorkflowCall(e){let{entry:t}=e.task;switch(t.entryPoint){case`execute`:return await startWorkflowTask(e);case`task`:case`serve`:return await startTaskRun({...e,entry:t});case`receive`:return await sendToTask({...e,taskId:t.taskId})}}export{dispatchCoordinationStep};
@@ -1 +1 @@
1
- import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.76.3//runWorkflowProgramTask`;export{runWorkflowProgramTask};
1
+ import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.78.0//runWorkflowProgramTask`;export{runWorkflowProgramTask};
@@ -1 +1 @@
1
- import"#protocol/session-projection.js";import{createLogger}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,recordPublishedEvent,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,InitiatorAuthKey,ParentSessionKey,SessionKey,TurnDeliveryIdsKey}from"#context/keys.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,turnPosition}from"#harness/session-machine/view.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{dropClosedRecords}from"#harness/session-machine/commit.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{withContextScope}from"#context/run-step.js";import{forwardSessionInput}from"#execution/forward-session-input.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";const log=createLogger(`execution.publish-session-events`);async function publishSessionEvents(e,t){return await publishEventsFromStep(e,`own`,t)}async function relaySessionEvents(e,t){return await publishEventsFromStep(e,`relayed`,t)}async function publishEventsFromStep(e,t,n){if(n.length===0)return{serializedContext:e.serializedContext,sessionState:e.sessionState};let{published:r}=await publishFromSessionStep(await restoreSessionStep(e),{origin:t,async publish(e){for(let t of n)await e(t)}});return r}async function restoreSessionStep(e){return{ctx:await deserializeContext(e.serializedContext),durableSession:readDurableSession(e.sessionState),sessionWritable:e.sessionWritable}}async function publishFromSessionStep(e,t){let{ctx:n}=e,r=await publishInSessionScope(e,t),i=t.updateSession?.(r.session,r.result)??{session:r.session},a=readSessionProjection(n),o=reconcileSessionContinuationToken(n,saveSessionProjection(dropClosedRecords(i.session,a),n));return{published:{serializedContext:serializeContext(n),sessionState:createDurableSessionState({session:o}),...`history`in o&&{history:o.history}},result:i.result}}async function publishInSessionScope(e,t){let{ctx:n}=e;enterSessionProjection(n,e.durableSession.state);let r=resolveEffectiveAgentRuntime(n.require(BundleKey),n),i=hydrateDurableSession({compactionOverrides:{thresholdPercent:r.thresholdPercent},durable:e.durableSession,turnAgent:r.turnAgent}),a=e.history===void 0?i:{...i,history:validateHarnessModelMessages(e.history)},o=t.origin===`own`?bindSessionInstrumentation({agentName:r.turnAgent.id,ctx:n,rootSessionId:a.rootSessionId??a.sessionId,sessionId:a.sessionId}):void 0,s=openSessionEventPublisher({ctx:n,inputSource:t.inputSource,origin:t.origin,sessionWritable:e.sessionWritable});try{return await withContextScope(n,a,async e=>{let r=o?.createHandleEvent({handleEvent:s.publish,turnId:activeTurnId(turnPosition(readSessionProjection(n)))})??s.publish;return{result:await t.publish(r,e),session:e}})}finally{await o?.flush(),s.writer.release()}}function openSessionEventPublisher(e){let{ctx:t,origin:n}=e,r=createSessionEventDispatcher(e),i=openSessionEventWriter({deliveryIds:()=>n===`own`?t.get(TurnDeliveryIdsKey):void 0,sessionWritable:e.sessionWritable}),emit=async e=>{let n=await i.write(await r.deliver(e));return recordPublishedEvent(t,n),n};return{dispatcher:r,writer:i,emit,async publish(e){await r.runHooks(await emit(e))}}}function createSessionEventDispatcher(e){let{ctx:t,inputSource:n}=e,r=t.require(ChannelKey),i=buildAdapterContext(r,t);return{adapterCtx:i,async deliver(e){let a=await forwardSessionInput(t,e,n)?e:await callAdapterEventHandler(r,e,n===void 0?i:{...i,inputSource:n});return setChannelContext(t,{...r,state:{...i.state}}),a},async runHooks(e,n){await dispatchStreamEventHooks({cancelTurn:n,ctx:t,event:e,registry:t.require(BundleKey).hookRegistry})}}}function openSessionEventWriter(e){let t=e.sessionWritable.getWriter(),n=!1,release=()=>{n||(n=!0,t.releaseLock())};return{async write(n){let r=stampMessageStreamEvent(n,e.deliveryIds());return await t.write(encodeMessageStreamEvent(r)),r},close:async()=>{await t.close(),release()},release}}function readSessionProjection(e){return currentProjection(e)}async function publishTerminalSessionEvent(e){let t=e.serializedContext[`eve.sessionId`]??``,n={errorId:e.errorId,sessionId:t},{type:r}=e.event,i,a;try{i=await deserializeContext(e.serializedContext),enterSessionProjection(i,void 0),a=openSessionEventPublisher({ctx:i,origin:`own`,sessionWritable:e.sessionWritable})}catch(t){log.error(`failed to restore context for terminal ${r} event`,{...n,error:t}),await writeUnroutedSessionEvent(e.sessionWritable,e.event).catch(e=>log.error(`failed to write terminal ${r} event`,{...n,error:e}));return}let o=i.get(AuthKey)??null;i.setVirtualContext(SessionKey,{auth:{current:o,initiator:i.get(InitiatorAuthKey)??o},parent:i.get(ParentSessionKey),sessionId:t,turn:e.turn??{id:`turn_0`,sequence:0}});let publish=async e=>{await a.emit(e),await a.writer.close()},s;try{s=bindSessionInstrumentation({agentName:i.require(BundleKey).turnAgent.id,ctx:i,rootSessionId:i.get(ParentSessionKey)?.rootSessionId??t,sessionId:t})}catch(e){log.error(`failed to bind instrumentation for terminal ${r} event`,{...n,error:e})}let c=s?.createHandleEvent({handleEvent:publish,turnId:e.turnId})??publish;try{await contextStorage.run(i,()=>c(e.event))}catch(e){log.error(`failed to publish terminal ${r} event`,{...n,error:e})}finally{a.writer.release();try{await s?.flush()}catch(e){log.error(`failed to flush instrumentation after terminal ${r} event`,{...n,error:e})}}}async function writeUnroutedSessionEvent(e,t){let n=openSessionEventWriter({deliveryIds:()=>void 0,sessionWritable:e});try{await n.write(t),await n.close()}finally{n.release()}}export{openSessionEventPublisher,publishFromSessionStep,publishSessionEvents,publishTerminalSessionEvent,readSessionProjection,relaySessionEvents,restoreSessionStep};
1
+ import"#protocol/session-projection.js";import{createLogger}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,recordPublishedEvent,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,InitiatorAuthKey,ParentSessionKey,SessionKey,TurnDeliveryIdsKey}from"#context/keys.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,turnPosition}from"#harness/session-machine/view.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{withContextScope}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{dropClosedRecords}from"#harness/session-machine/commit.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{forwardSessionInput}from"#execution/forward-session-input.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";const log=createLogger(`execution.publish-session-events`);async function publishSessionEvents(e,t){return await publishEventsFromStep(e,`own`,t)}async function relaySessionEvents(e,t){return await publishEventsFromStep(e,`relayed`,t)}async function publishEventsFromStep(e,t,n){if(n.length===0)return{serializedContext:e.serializedContext,sessionState:e.sessionState};let{published:r}=await publishFromSessionStep(await restoreSessionStep(e),{origin:t,async publish(e){for(let t of n)await e(t)}});return r}async function restoreSessionStep(e){return{ctx:await deserializeContext(e.serializedContext),durableSession:readDurableSession(e.sessionState),sessionWritable:e.sessionWritable}}async function publishFromSessionStep(e,t){let{ctx:n}=e,r=await publishInSessionScope(e,t),i=t.updateSession?.(r.session,r.result)??{session:r.session},a=readSessionProjection(n),o=reconcileSessionContinuationToken(n,saveSessionProjection(dropClosedRecords(i.session,a),n));return{published:{serializedContext:serializeContext(n),sessionState:createDurableSessionState({session:o}),...`history`in o&&{history:o.history}},result:i.result}}async function publishInSessionScope(e,t){let{ctx:n}=e;enterSessionProjection(n,e.durableSession.state);let r=resolveEffectiveAgentRuntime(n.require(BundleKey),n),i=hydrateDurableSession({compactionOverrides:{thresholdPercent:r.thresholdPercent},durable:e.durableSession,turnAgent:r.turnAgent}),a=e.history===void 0?i:{...i,history:validateHarnessModelMessages(e.history)},o=t.origin===`own`?bindSessionInstrumentation({agentName:r.turnAgent.id,ctx:n,rootSessionId:a.rootSessionId??a.sessionId,sessionId:a.sessionId}):void 0,s=openSessionEventPublisher({ctx:n,inputSource:t.inputSource,origin:t.origin,sessionWritable:e.sessionWritable});try{return await withContextScope(n,a,async e=>{let r=o?.createHandleEvent({handleEvent:s.publish,turnId:activeTurnId(turnPosition(readSessionProjection(n)))})??s.publish;return{result:await t.publish(r,e),session:e}})}finally{await o?.flush(),s.writer.release()}}function openSessionEventPublisher(e){let{ctx:t,origin:n}=e,r=createSessionEventDispatcher(e),i=openSessionEventWriter({deliveryIds:()=>n===`own`?t.get(TurnDeliveryIdsKey):void 0,sessionWritable:e.sessionWritable}),emit=async e=>{let n=await i.write(await r.deliver(e));return recordPublishedEvent(t,n),n};return{dispatcher:r,writer:i,emit,async publish(e){await r.runHooks(await emit(e))}}}function createSessionEventDispatcher(e){let{ctx:t,inputSource:n}=e,r=t.require(ChannelKey),i=buildAdapterContext(r,t);return{adapterCtx:i,async deliver(e){let a=await forwardSessionInput(t,e,n)?e:await callAdapterEventHandler(r,e,n===void 0?i:{...i,inputSource:n});return setChannelContext(t,{...r,state:{...i.state}}),a},async runHooks(e,n){await dispatchStreamEventHooks({cancelTurn:n,ctx:t,event:e,registry:t.require(BundleKey).hookRegistry})}}}function openSessionEventWriter(e){let t=e.sessionWritable.getWriter(),n=!1,release=()=>{n||(n=!0,t.releaseLock())};return{async write(n){let r=stampMessageStreamEvent(n,e.deliveryIds());return await t.write(encodeMessageStreamEvent(r)),r},close:async()=>{await t.close(),release()},release}}function readSessionProjection(e){return currentProjection(e)}async function publishTerminalSessionEvent(e){let t=e.serializedContext[`eve.sessionId`]??``,n={errorId:e.errorId,sessionId:t},{type:r}=e.event,i,a;try{i=await deserializeContext(e.serializedContext),enterSessionProjection(i,void 0),a=openSessionEventPublisher({ctx:i,origin:`own`,sessionWritable:e.sessionWritable})}catch(t){log.error(`failed to restore context for terminal ${r} event`,{...n,error:t}),await writeUnroutedSessionEvent(e.sessionWritable,e.event).catch(e=>log.error(`failed to write terminal ${r} event`,{...n,error:e}));return}let o=i.get(AuthKey)??null;i.setVirtualContext(SessionKey,{auth:{current:o,initiator:i.get(InitiatorAuthKey)??o},parent:i.get(ParentSessionKey),sessionId:t,turn:e.turn??{id:`turn_0`,sequence:0}});let publish=async e=>{await a.emit(e),await a.writer.close()},s;try{s=bindSessionInstrumentation({agentName:i.require(BundleKey).turnAgent.id,ctx:i,rootSessionId:i.get(ParentSessionKey)?.rootSessionId??t,sessionId:t})}catch(e){log.error(`failed to bind instrumentation for terminal ${r} event`,{...n,error:e})}let c=s?.createHandleEvent({handleEvent:publish,turnId:e.turnId})??publish;try{await contextStorage.run(i,()=>c(e.event))}catch(e){log.error(`failed to publish terminal ${r} event`,{...n,error:e})}finally{a.writer.release();try{await s?.flush()}catch(e){log.error(`failed to flush instrumentation after terminal ${r} event`,{...n,error:e})}}}async function writeUnroutedSessionEvent(e,t){let n=openSessionEventWriter({deliveryIds:()=>void 0,sessionWritable:e});try{await n.write(t),await n.close()}finally{n.release()}}export{openSessionEventPublisher,publishFromSessionStep,publishSessionEvents,publishTerminalSessionEvent,readSessionProjection,relaySessionEvents,restoreSessionStep};
@@ -1 +1 @@
1
- import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{buildDockerBaseSetupScript}from"#execution/sandbox/bindings/docker-base-setup.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";const DOCKER_SANDBOX_LABEL=`eve.sandbox`,DOCKER_KEEPALIVE_ARGS=[`-c`,`sleep 2147483647`];async function startDockerContainer(e){let t=[`run`,`-d`,`--name`,e.containerName,`--label`,`${DOCKER_SANDBOX_LABEL}=1`,`--label`,`${DOCKER_SANDBOX_LABEL}.role=${e.role}`];for(let[n,r]of Object.entries(withDevelopmentSandboxTags(e.tags)??{}))t.push(`--label`,`${DOCKER_SANDBOX_LABEL}.tag.${n}=${r}`);for(let[n,r]of Object.entries(e.options.env))t.push(`-e`,`${n}=${r}`);e.initialNetworkPolicy===`deny-all`&&t.push(`--network`,`none`),e.resourcesPath!==void 0&&t.push(`--mount`,`type=bind,src=${e.resourcesPath},dst=/eve/resources,readonly`),t.push(`--workdir`,WORKSPACE_ROOT,`--entrypoint`,`/bin/sh`,e.image,...DOCKER_KEEPALIVE_ARGS),expectDockerSuccess(await e.cli.run(t),`start sandbox container "${e.containerName}" from "${e.image}"`)}async function runDockerBaseSetup(e,t){expectDockerSuccess(await e.run([`exec`,`--user`,`root`,t,`/bin/sh`,`-c`,buildDockerBaseSetupScript()]),`prepare base runtime in sandbox container "${t}"`)}async function stopDockerContainerIfRunning(e,t){await e.run([`stop`,`-t`,`0`,t]).catch(()=>{})}export{DOCKER_SANDBOX_LABEL,runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning};
1
+ import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{buildDockerBaseSetupScript}from"#execution/sandbox/bindings/docker-base-setup.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{SANDBOX_AGENT_ENV}from"#execution/sandbox/session.js";const DOCKER_SANDBOX_LABEL=`eve.sandbox`,DOCKER_KEEPALIVE_ARGS=[`-c`,`sleep 2147483647`];async function startDockerContainer(e){let t=[`run`,`-d`,`--name`,e.containerName,`--label`,`${DOCKER_SANDBOX_LABEL}=1`,`--label`,`${DOCKER_SANDBOX_LABEL}.role=${e.role}`];for(let[n,r]of Object.entries(withDevelopmentSandboxTags(e.tags)??{}))t.push(`--label`,`${DOCKER_SANDBOX_LABEL}.tag.${n}=${r}`);for(let[n,r]of Object.entries({...SANDBOX_AGENT_ENV,...e.options.env}))t.push(`-e`,`${n}=${r}`);e.initialNetworkPolicy===`deny-all`&&t.push(`--network`,`none`),e.resourcesPath!==void 0&&t.push(`--mount`,`type=bind,src=${e.resourcesPath},dst=/eve/resources,readonly`),t.push(`--workdir`,WORKSPACE_ROOT,`--entrypoint`,`/bin/sh`,e.image,...DOCKER_KEEPALIVE_ARGS),expectDockerSuccess(await e.cli.run(t),`start sandbox container "${e.containerName}" from "${e.image}"`)}async function runDockerBaseSetup(e,t){expectDockerSuccess(await e.run([`exec`,`--user`,`root`,t,`/bin/sh`,`-c`,buildDockerBaseSetupScript()]),`prepare base runtime in sandbox container "${t}"`)}async function stopDockerContainerIfRunning(e,t){await e.run([`stop`,`-t`,`0`,t]).catch(()=>{})}export{DOCKER_SANDBOX_LABEL,runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning};
@@ -1 +1 @@
1
- import{randomUUID}from"node:crypto";import{toErrorMessage}from"#shared/errors.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,commitDockerTemplateImage,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{buildSandboxDockerfile,dockerfileImageReference,materializeSandboxDockerfile}from"#execution/sandbox/dockerfile.js";import{hydrateSandboxProviderResources,prepareImmutableResources}from"#execution/sandbox/bindings/immutable-resources.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{isSandboxPreparedArtifactRecord,sandboxProviderResourceIdentity}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";const DOCKER_PROVIDER_NAME=`docker`;function createDockerSandboxProvider(e,t){let n=t??createDockerCli(),r=e??{},i=resolveDockerSandboxOptions(r),a=createDockerSandboxOptionsHash(i),o;function ensureDaemon(){return o??=assertDockerDaemonAvailable(n).catch(e=>{throw o=void 0,e}),o}async function inspectContainerRunning(e){let t=await n.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,e]);return t.exitCode===0?t.stdout.trim()===`true`:void 0}async function openDockerSession(e,t,r,a,o){await ensureDaemon();let s=requirePreparedDockerArtifact(r);if(!await dockerImageExists(n,s.imageReference))throw new SandboxTemplateNotProvisionedError({providerName:DOCKER_PROVIDER_NAME,templateKey:s.imageReference});let c=await inspectContainerRunning(a);if(c===void 0){if(!o)throw Error(`Docker sandbox session container "${a}" no longer exists.`);try{await startDockerContainer({cli:n,containerName:a,image:s.imageReference,initialNetworkPolicy:t?.networkPolicy??`allow-all`,options:i,role:`session`,tags:{agent:e.session.id,sessionId:e.session.id}}),c=!0}catch(e){if(c=/is already in use/u.test(toErrorMessage(e))?await inspectContainerRunning(a):void 0,c===void 0)throw e}}c||expectDockerSuccess(await n.run([`start`,a]),`restart sandbox session container "${a}"`);let l=await resolveDockerHandleIdentity(n,a);return{sandbox:buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:l}),e=>setDockerNetworkPolicy(n,l,e)),async onSandboxDelete(){await stopDockerContainerIfRunning(n,l),expectDockerSuccess(await n.run([`rm`,`-f`,l]),`delete sandbox session container "${a}"`)},async onSandboxStop(){await stopDockerContainerIfRunning(n,l)},async onRuntimeShutdown(){await stopDockerContainerIfRunning(n,l)}}}return{async prepare(e){e.log?.(`checking Docker daemon`),await ensureDaemon();let t=await materializeSandboxDockerfile({files:e.files,storagePath:e.storagePath}),o=createSandboxProviderIdentity({dockerfile:t?.contentHash,optionsHash:a,resources:sandboxProviderResourceIdentity(e.resources),sourceRevision:e.sourceRevision,version:2}).slice(0,24),s={optionsHash:a,templateKey:o},c=dockerTemplateImageReference(s),l=e.resources.source,u=l.kind===`materialized`?await prepareImmutableResources({storagePath:e.storagePath,provider:DOCKER_PROVIDER_NAME,resourcesKey:l.key,sourcePath:l.path}):void 0,d=resolveDockerTemplateMarkerPath(e.storagePath,s);if(e.log?.(`checking cached template image "${c}"`),await dockerImageExists(n,c))return e.log?.(`reusing cached template image`),await touchDockerTemplateMarker(d,c),{imageReference:c};let f=i.image;t===void 0?(e.log?.(`checking base image "${i.image}"`),await ensureDockerBaseImage(n,i)):(f=dockerfileImageReference({dockerfile:t,templateKey:o}),e.log?.(`building sandbox Dockerfile "${t.path}"`),await buildSandboxDockerfile({cli:n,dockerfile:t,imageReference:f}));let p=`${o}-build-${randomUUID().slice(0,8)}`;e.log?.(`starting template build container`),await startDockerContainer({cli:n,containerName:p,image:f,initialNetworkPolicy:`allow-all`,options:i,resourcesPath:u,role:`template-build`});try{let t=await resolveDockerHandleIdentity(n,p);e.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(n,t);let i=buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:t}),e=>setDockerNetworkPolicy(n,t,e));await hydrateSandboxProviderResources({copySkills:!0,log:e.log,resources:e.resources,session:i}),r.prepare!==void 0&&(e.log?.(`running sandbox preparation`),await r.prepare(createLoggingSandboxSession({log:e.log,session:i}))),e.log?.(`stopping template build container`),expectDockerSuccess(await n.run([`stop`,`-t`,`0`,t]),`stop template build container "${p}"`),e.log?.(`committing template image "${c}"`),await commitDockerTemplateImage({cli:n,containerIdentity:t,imageReference:c,templateKey:o})===`reused`&&e.log?.(`reusing concurrently published template image`),await touchDockerTemplateMarker(d,c)}finally{await n.run([`rm`,`-f`,p]).catch(()=>{}),t!==void 0&&await n.run([`rmi`,f]).catch(()=>{})}return{imageReference:c}},async resume(e,t,n){let r=requireDockerSessionState(n);if(r.generation!==dockerGeneration(t,a))throw Error(`Docker sandbox session state is incompatible with this environment.`);return await openDockerSession(e,void 0,t,r.containerName,!1)},async start(e,t,n){let r=dockerSessionName(e.session.id,t,n,a);return{handle:await openDockerSession(e,t,n,r,!0),state:{containerName:r,generation:dockerGeneration(n,a),version:2}}}}}function dockerGeneration(e,t){return createSandboxProviderIdentity({artifact:e,environment:t,version:1})}function dockerSessionName(e,t,n,r){return`eve-sbx-${createSandboxProviderIdentity({artifact:n,environment:r,open:{networkPolicy:t?.networkPolicy},sessionId:e,version:1}).slice(0,32)}`}function requirePreparedDockerArtifact(e){if(!isSandboxPreparedArtifactRecord(e)||typeof e.imageReference!=`string`)throw Error(`Invalid prepared Docker artifact.`);return{imageReference:e.imageReference}}function requireDockerSessionState(e){if(!isSandboxPreparedArtifactRecord(e)||e.version!==2||typeof e.containerName!=`string`||typeof e.generation!=`string`)throw Error(`Invalid Docker sandbox session state.`);return{containerName:e.containerName,generation:e.generation,version:2}}async function resolveDockerHandleIdentity(e,t){let n=await e.run([`container`,`inspect`,`--format`,`{{.Id}}`,t]);expectDockerSuccess(n,`resolve sandbox container identity for "${t}"`);let r=n.stdout.trim();if(r.length===0)throw Error(`Docker returned an empty identity for sandbox container "${t}".`);return r}export{DOCKER_PROVIDER_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxProvider,pruneDockerSandboxTemplates};
1
+ import{randomUUID}from"node:crypto";import{toErrorMessage}from"#shared/errors.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,commitDockerTemplateImage,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{buildSandboxDockerfile,dockerfileImageReference,materializeSandboxDockerfile}from"#execution/sandbox/dockerfile.js";import{hydrateSandboxProviderResources,prepareImmutableResources}from"#execution/sandbox/bindings/immutable-resources.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{isSandboxPreparedArtifactRecord,sandboxProviderResourceIdentity}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";const DOCKER_PROVIDER_NAME=`docker`;function createDockerSandboxProvider(e,t){let n=t??createDockerCli(),r=e??{},i=resolveDockerSandboxOptions(r),a=createDockerSandboxOptionsHash(i),o;function ensureDaemon(){return o??=assertDockerDaemonAvailable(n).catch(e=>{throw o=void 0,e}),o}async function inspectContainerRunning(e){let t=await n.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,e]);return t.exitCode===0?t.stdout.trim()===`true`:void 0}async function openDockerSession(e,t,r,a,o){await ensureDaemon();let s=requirePreparedDockerArtifact(r);if(!await dockerImageExists(n,s.imageReference))throw new SandboxTemplateNotProvisionedError({providerName:DOCKER_PROVIDER_NAME,templateKey:s.imageReference});let c=await inspectContainerRunning(a);if(c===void 0){if(!o)throw Error(`Docker sandbox session container "${a}" no longer exists.`);try{await startDockerContainer({cli:n,containerName:a,image:s.imageReference,initialNetworkPolicy:t?.networkPolicy??`allow-all`,options:i,role:`session`,tags:{agent:e.session.id,sessionId:e.session.id}}),c=!0}catch(e){if(c=/is already in use/u.test(toErrorMessage(e))?await inspectContainerRunning(a):void 0,c===void 0)throw e}}c||expectDockerSuccess(await n.run([`start`,a]),`restart sandbox session container "${a}"`);let l=await resolveDockerHandleIdentity(n,a);return{sandbox:buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:l}),e=>setDockerNetworkPolicy(n,l,e)),async onSandboxDelete(){await stopDockerContainerIfRunning(n,l),expectDockerSuccess(await n.run([`rm`,`-f`,l]),`delete sandbox session container "${a}"`)},async onSandboxStop(){await stopDockerContainerIfRunning(n,l)},async onRuntimeShutdown(){await stopDockerContainerIfRunning(n,l)}}}return{async prepare(e){e.log?.(`checking Docker daemon`),await ensureDaemon();let t=await materializeSandboxDockerfile({files:e.files,storagePath:e.storagePath}),o=createSandboxProviderIdentity({dockerfile:t?.contentHash,optionsHash:a,resources:sandboxProviderResourceIdentity(e.resources),sourceRevision:e.sourceRevision,version:2}).slice(0,24),s={optionsHash:a,templateKey:o},c=dockerTemplateImageReference(s),l=e.resources.source,u=l.kind===`materialized`?await prepareImmutableResources({storagePath:e.storagePath,provider:DOCKER_PROVIDER_NAME,resourcesKey:l.key,sourcePath:l.path}):void 0,d=resolveDockerTemplateMarkerPath(e.storagePath,s);if(e.log?.(`checking cached template image "${c}"`),await dockerImageExists(n,c))return e.log?.(`reusing cached template image`),await touchDockerTemplateMarker(d,c),{imageReference:c};let f=i.image;t===void 0?(e.log?.(`checking base image "${i.image}"`),await ensureDockerBaseImage(n,i)):(f=dockerfileImageReference({dockerfile:t,templateKey:o}),e.log?.(`building sandbox Dockerfile "${t.path}"`),await buildSandboxDockerfile({cli:n,dockerfile:t,imageReference:f}));let p=`${o}-build-${randomUUID().slice(0,8)}`;e.log?.(`starting template build container`),await startDockerContainer({cli:n,containerName:p,image:f,initialNetworkPolicy:`allow-all`,options:i,resourcesPath:u,role:`template-build`});try{let t=await resolveDockerHandleIdentity(n,p);e.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(n,t);let i=buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:t}),e=>setDockerNetworkPolicy(n,t,e));await hydrateSandboxProviderResources({copySkills:!0,log:e.log,resources:e.resources,session:i}),r.prepare!==void 0&&(e.log?.(`running sandbox preparation`),await r.prepare(createLoggingSandboxSession({log:e.log,session:i}))),e.log?.(`stopping template build container`),expectDockerSuccess(await n.run([`stop`,`-t`,`0`,t]),`stop template build container "${p}"`),e.log?.(`committing template image "${c}"`),await commitDockerTemplateImage({cli:n,containerIdentity:t,imageReference:c,templateKey:o})===`reused`&&e.log?.(`reusing concurrently published template image`),await touchDockerTemplateMarker(d,c)}finally{await n.run([`rm`,`-f`,p]).catch(()=>{}),t!==void 0&&await n.run([`rmi`,f]).catch(()=>{})}return{imageReference:c}},async resume(e,t,n){let r=requireDockerSessionState(n);if(r.generation!==dockerGeneration(t,a))throw Error(`Docker sandbox session state is incompatible with this environment.`);return await openDockerSession(e,void 0,t,r.containerName,!1)},async start(e,t,n){let r=dockerSessionName(e.session.id,t,n,a);return{handle:await openDockerSession(e,t,n,r,!0),state:{containerName:r,generation:dockerGeneration(n,a),version:2}}}}}function dockerGeneration(e,t){return createSandboxProviderIdentity({artifact:e,environment:t,version:1})}function dockerSessionName(e,t,n,r){return`eve-sbx-${createSandboxProviderIdentity({artifact:n,environment:r,open:{networkPolicy:t?.networkPolicy},sessionId:e,version:1}).slice(0,32)}`}function requirePreparedDockerArtifact(e){if(!isSandboxPreparedArtifactRecord(e)||typeof e.imageReference!=`string`)throw Error(`Invalid prepared Docker artifact.`);return{imageReference:e.imageReference}}function requireDockerSessionState(e){if(!isSandboxPreparedArtifactRecord(e)||e.version!==2||typeof e.containerName!=`string`||typeof e.generation!=`string`)throw Error(`Invalid Docker sandbox session state.`);return{containerName:e.containerName,generation:e.generation,version:2}}async function resolveDockerHandleIdentity(e,t){let n=await e.run([`container`,`inspect`,`--format`,`{{.Id}}`,t]);expectDockerSuccess(n,`resolve sandbox container identity for "${t}"`);let r=n.stdout.trim();if(r.length===0)throw Error(`Docker returned an empty identity for sandbox container "${t}".`);return r}export{DOCKER_PROVIDER_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxProvider,pruneDockerSandboxTemplates};