eve 0.84.0 → 0.84.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/src/channel/cross-channel-receive.d.ts +4 -1
  3. package/dist/src/channel/cross-channel-receive.js +1 -1
  4. package/dist/src/channel/delivery.js +1 -1
  5. package/dist/src/channel/session.js +1 -1
  6. package/dist/src/channel/types.d.ts +2 -0
  7. package/dist/src/chunks/{use-eve-agent-BbbguIdB.js → use-eve-agent-DMeP0JOF.js} +26 -10
  8. package/dist/src/chunks/{use-eve-agent-DWjyzplb.js → use-eve-agent-DP5Rso9C.js} +26 -10
  9. package/dist/src/cli/commands/init.js +1 -1
  10. package/dist/src/client/delivery.d.ts +2 -0
  11. package/dist/src/client/delivery.js +1 -1
  12. package/dist/src/client/optimistic-message-submissions.js +1 -1
  13. package/dist/src/client/session-store.js +1 -1
  14. package/dist/src/client/session.js +1 -1
  15. package/dist/src/client/sessions.d.ts +1 -0
  16. package/dist/src/client/sessions.js +1 -1
  17. package/dist/src/client/types.d.ts +2 -0
  18. package/dist/src/compiled/.vendor-stamp.json +2 -2
  19. package/dist/src/compiled/@chat-adapter/slack/index.js +13 -13
  20. package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +75 -0
  21. package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +4 -0
  22. package/dist/src/compiled/@vercel/sandbox/command.d.ts +78 -0
  23. package/dist/src/compiled/@vercel/sandbox/drive.d.ts +41 -1
  24. package/dist/src/compiled/@vercel/sandbox/index.js +13 -13
  25. package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +35 -4
  26. package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +18 -4
  27. package/dist/src/compiled/@vercel/sandbox/session.d.ts +29 -3
  28. package/dist/src/compiled/@vercel/sandbox/utils/pipe-stdin.d.ts +19 -0
  29. package/dist/src/compiled/_chunks/client/{core-CspsxXR-.js → core-BsvaaMUJ.js} +1 -1
  30. package/dist/src/compiled/_chunks/node/{auth-Dztlx9pE.js → auth-v5pS3mLo.js} +1 -1
  31. package/dist/src/compiled/_chunks/node/is-stream-DsuQX_bd.js +1 -0
  32. package/dist/src/compiled/_chunks/node/token-DHGH-jVc.js +1 -0
  33. package/dist/src/compiled/_chunks/node/token-util-BH2pw9Qm.js +25 -0
  34. package/dist/src/compiled/_chunks/node/token-util-CcvxNv76.js +1 -0
  35. package/dist/src/compiled/_chunks/node/version-C2PfNyEv.js +1 -0
  36. package/dist/src/compiled/zod/index.js +1 -1
  37. package/dist/src/compiled/zod/v4/core.js +1 -1
  38. package/dist/src/compiled/zod-validation-error/index.js +1 -1
  39. package/dist/src/compiler/artifacts.d.ts +1 -0
  40. package/dist/src/compiler/artifacts.js +1 -1
  41. package/dist/src/compiler/manifest.d.ts +2 -2
  42. package/dist/src/compiler/manifest.js +1 -1
  43. package/dist/src/compiler/model-catalog.d.ts +8 -18
  44. package/dist/src/compiler/model-catalog.js +1 -1
  45. package/dist/src/compiler/normalize-agent-config.js +1 -1
  46. package/dist/src/compiler/normalize-manifest-types.d.ts +3 -0
  47. package/dist/src/compiler/normalize-manifest.js +1 -1
  48. package/dist/src/context/keys.d.ts +0 -8
  49. package/dist/src/context/keys.js +1 -1
  50. package/dist/src/eve-channel/index.js +1 -1
  51. package/dist/src/eve-channel/request.d.ts +1 -0
  52. package/dist/src/eve-channel/request.js +1 -1
  53. package/dist/src/eve-channel/support.js +1 -1
  54. package/dist/src/execution/agent-sessions/steps.js +1 -1
  55. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  56. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +2 -0
  57. package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
  58. package/dist/src/execution/sandbox/bindings/docker-connection.js +1 -1
  59. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  60. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  61. package/dist/src/execution/sandbox/multiplexed-command.d.ts +11 -1
  62. package/dist/src/execution/sandbox/multiplexed-command.js +1 -1
  63. package/dist/src/execution/sandbox/session.js +1 -1
  64. package/dist/src/execution/session-inbox/address.d.ts +1 -0
  65. package/dist/src/execution/session-inbox/handle.d.ts +7 -0
  66. package/dist/src/execution/session-inbox/handle.js +1 -0
  67. package/dist/src/execution/session-inbox/owner.d.ts +4 -4
  68. package/dist/src/execution/session-inbox/owner.js +1 -1
  69. package/dist/src/execution/session-inbox/resume.d.ts +1 -0
  70. package/dist/src/execution/session-inbox/resume.js +1 -1
  71. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  72. package/dist/src/execution/workflow-runtime.js +1 -1
  73. package/dist/src/harness/model-call/call.d.ts +3 -1
  74. package/dist/src/harness/model-call/call.js +1 -1
  75. package/dist/src/harness/model-call/run.js +1 -1
  76. package/dist/src/harness/semantic-errors/rules/gateway.js +1 -1
  77. package/dist/src/internal/application/compiled-artifacts.d.ts +2 -0
  78. package/dist/src/internal/application/compiled-artifacts.js +2 -2
  79. package/dist/src/internal/application/optional-package-install.js +1 -1
  80. package/dist/src/internal/application/stamped-package-version.js +1 -1
  81. package/dist/src/internal/model-catalog.d.ts +39 -16
  82. package/dist/src/internal/model-catalog.js +1 -1
  83. package/dist/src/internal/nitro/host/dev-build-host.js +1 -1
  84. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  85. package/dist/src/protocol/delivery.d.ts +1 -0
  86. package/dist/src/public/nuxt/module.js +1 -1
  87. package/dist/src/reactions/kinds/model.js +1 -1
  88. package/dist/src/reactions/kinds/subagent.js +1 -1
  89. package/dist/src/runtime/agent/resolve-model.d.ts +3 -4
  90. package/dist/src/runtime/agent/resolve-model.js +1 -1
  91. package/dist/src/runtime/loaders/artifact-paths.d.ts +1 -0
  92. package/dist/src/runtime/loaders/artifact-paths.js +1 -1
  93. package/dist/src/runtime/loaders/bundled-artifacts.d.ts +2 -0
  94. package/dist/src/runtime/loaders/bundled-artifacts.js +1 -1
  95. package/dist/src/runtime/loaders/model-metadata.d.ts +4 -0
  96. package/dist/src/runtime/loaders/model-metadata.js +1 -0
  97. package/dist/src/runtime/resolve-agent.js +1 -1
  98. package/dist/src/runtime/sessions/compiled-agent-cache.d.ts +3 -0
  99. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  100. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +2 -2
  101. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  102. package/dist/src/runtime/subagents/workflow.js +1 -1
  103. package/dist/src/sandbox/provider.d.ts +2 -0
  104. package/dist/src/setup/flows/model-source-change.js +1 -1
  105. package/dist/src/setup/scaffold/create/project.js +1 -1
  106. package/dist/src/shared/agent-definition.d.ts +0 -1
  107. package/dist/src/shared/sandbox-session.d.ts +4 -0
  108. package/dist/src/svelte/index.js +1 -1
  109. package/dist/src/svelte/use-eve-agent.js +1 -1
  110. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  111. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  112. package/dist/src/vue/index.js +1 -1
  113. package/dist/src/vue/use-eve-agent.js +1 -1
  114. package/docs/agent-config.md +5 -4
  115. package/docs/concepts/default-harness.md +6 -0
  116. package/docs/evals/judge.mdx +13 -0
  117. package/docs/guides/client/overview.mdx +23 -1
  118. package/docs/reference/cli.md +1 -1
  119. package/docs/sandbox/custom-providers.mdx +1 -1
  120. package/docs/sandbox/index.mdx +1 -1
  121. package/docs/tools/workflows.mdx +4 -0
  122. package/package.json +2 -2
  123. package/dist/src/compiled/_chunks/node/token-Bedbhv5z.js +0 -1
  124. package/dist/src/compiled/_chunks/node/token-util-DpJNusVS.js +0 -1
  125. package/dist/src/compiled/_chunks/node/token-util-DwHQ2a3c.js +0 -1
  126. package/dist/src/compiled/_chunks/node/version-C__MqbLM.js +0 -1
  127. package/dist/src/runtime/agent/model-catalog.d.ts +0 -10
  128. package/dist/src/runtime/agent/model-catalog.js +0 -1
@@ -1,2 +1,2 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{EVE_SESSION_ID_HEADER}from"#protocol/session-http.js";import{defaultEveAuth}from"#eve-channel/types.js";import{workflowEntryReference}from"#execution/workflow-runtime.js";const log=createLogger(`eve.channel`);function healthResponse(){return Response.json({ok:!0,status:`ready`,workflowId:workflowEntryReference.workflowId})}function sessionCommandErrorResponse(e){if(SessionNotActiveError.is(e))return Response.json({ok:!1,code:e.retryable?`session_not_ready`:`session_not_active`,error:e.retryable?`The session is not ready to accept messages yet.`:`The session is no longer active.`},{headers:{"cache-control":`no-store`},status:409});if(!SessionStrandedError.is(e))return;let t={code:`session_stranded`,error:`This session is no longer available.`,ok:!1};return e.owner.eveVersion!==void 0&&(t.eveVersion=e.owner.eveVersion),Response.json(t,{headers:{"cache-control":`no-store`},status:409})}function deliveryResponse(e){return Response.json({ok:!0,sessionId:e.sessionId,deliveryId:e.deliveryId},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.sessionId},status:202})}async function findRemoteAgentBinding(e){let t=await e.parent.getChildBinding?.(e.childSessionId);if(t===void 0||t.callId!==e.callId||t.streamPath!==e.childStreamPath)return;let n={name:t.name,url:t.url};return t.resolverId!==void 0&&(n.resolverId=t.resolverId),t.dynamicBinding!==void 0&&(n.dynamicBinding=t.dynamicBinding),t.earlierProtocol!==void 0&&(n.earlierProtocol=t.earlierProtocol),n}async function resolveOnMessage(e){let t=e.config.onMessage??defaultOnMessage,n;try{let r={caller:e.auth,clientContext:e.clientContext,request:e.request};if(n=await t({eve:e.sessionId===void 0?e.invocation===void 0?r:{...r,invocation:e.invocation}:{...r,sessionId:e.sessionId}},e.message),n==null)throw TypeError(`eveChannel onMessage must return an auth result.`)}catch(t){let n=logError(log,`onMessage handler failed`,t,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:n,ok:!1},{status:500})}return{auth:n.auth,clientContext:resolveTurnClientContext(n.clientContext,e.clientContext),context:n.context,history:n.history,title:n.title}}function resolveTurnClientContext(e,t){let n=e===void 0?toContextEntries(t).map(e=>`Client context:
1
+ import{createLogger,logError}from"#internal/logging.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{EVE_SESSION_ID_HEADER}from"#protocol/session-http.js";import{defaultEveAuth}from"#eve-channel/types.js";import{workflowEntryReference}from"#execution/workflow-runtime.js";const log=createLogger(`eve.channel`);function healthResponse(){return Response.json({ok:!0,status:`ready`,workflowId:workflowEntryReference.workflowId})}function sessionCommandErrorResponse(e){if(SessionNotActiveError.is(e))return Response.json({ok:!1,code:e.retryable?`session_not_ready`:`session_not_active`,error:e.retryable?`The session is not ready to accept messages yet.`:`The session is no longer active.`},{headers:{"cache-control":`no-store`},status:409});if(!SessionStrandedError.is(e))return;let t={code:`session_stranded`,error:`This session is no longer available.`,ok:!1};return e.owner.eveVersion!==void 0&&(t.eveVersion=e.owner.eveVersion),Response.json(t,{headers:{"cache-control":`no-store`},status:409})}function deliveryResponse(e){return Response.json({ok:!0,sessionId:e.sessionId,deliveryId:e.deliveryId,inbox:e.inbox},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.sessionId},status:202})}async function findRemoteAgentBinding(e){let t=await e.parent.getChildBinding?.(e.childSessionId);if(t===void 0||t.callId!==e.callId||t.streamPath!==e.childStreamPath)return;let n={name:t.name,url:t.url};return t.resolverId!==void 0&&(n.resolverId=t.resolverId),t.dynamicBinding!==void 0&&(n.dynamicBinding=t.dynamicBinding),t.earlierProtocol!==void 0&&(n.earlierProtocol=t.earlierProtocol),n}async function resolveOnMessage(e){let t=e.config.onMessage??defaultOnMessage,n;try{let r={caller:e.auth,clientContext:e.clientContext,request:e.request};if(n=await t({eve:e.sessionId===void 0?e.invocation===void 0?r:{...r,invocation:e.invocation}:{...r,sessionId:e.sessionId}},e.message),n==null)throw TypeError(`eveChannel onMessage must return an auth result.`)}catch(t){let n=logError(log,`onMessage handler failed`,t,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:n,ok:!1},{status:500})}return{auth:n.auth,clientContext:resolveTurnClientContext(n.clientContext,e.clientContext),context:n.context,history:n.history,title:n.title}}function resolveTurnClientContext(e,t){let n=e===void 0?toContextEntries(t).map(e=>`Client context:
2
2
  ${e}`):toContextEntries(e);return n.length===0?void 0:n}function toContextEntries(e){return e===void 0||e===``?[]:typeof e==`string`?[e]:Array.isArray(e)?e:[JSON.stringify(e)]}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}export{deliveryResponse,findRemoteAgentBinding,healthResponse,resolveOnMessage,resolveTurnClientContext,sessionCommandErrorResponse};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{ContextContainer,contextStorage}from"#context/container.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import{resumeHook}from"#internal/workflow/runtime.js";import{agentDelegation}from"#tracing/eve/delegation.js";import{createWorkflowRuntime,dispatchWorkflowSessionCommand,resolveContinuation,waitForCommandHookOwner,waitForSessionInbox}from"#execution/workflow-runtime.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{FatalError,getStepMetadata,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl,resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{remoteAgentCredentials}from"#execution/agent-sessions/remote-credentials.js";import{resolveAgentAction,resolveAgentStartTarget}from"#execution/agent-sessions/target.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{InvalidRuntimeModelSelectionError,resolveRuntimeModelSelection}from"#runtime/agent/resolve-model.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});if(e.model!==void 0&&i.kind===`remote`)throw new FatalError(`ctx.agent("${e.name}", { model }) cannot override a remote agent's model. Configure the model on the receiving agent.`);let a=e.model===void 0?void 0:await normalizeRuntimeOverrides(e.name,e.model),o={auth:e.auth,bundle:n,context:t,key:e.key,replyTo:e.replyTo,runtimeOverrides:a};return await agentDelegation.resume({context:t,agentName:r.name},()=>i.kind===`remote`?startRemoteSession({...o,target:i}):startLocalSession({...o,target:i}))}async function normalizeRuntimeOverrides(e,t){try{return{model:(await resolveRuntimeModelSelection({durability:`durable`,selection:t,state:new ContextContainer})).reference}}catch(t){throw t instanceof InvalidRuntimeModelSelectionError?new FatalError(`ctx.agent("${e}", { model }) could not resolve the model selection: ${toErrorMessage(t)}`):t}}async function sendAgentSessionMessageStep(e){"use step";let{address:t,context:n}=e;if(t.kind===`remote`){let r=await resolveSessionRemote(n,t);return await continueRemoteAgentSession({auth:e.auth.current,callback:{callId:n.parent.callId,subagentName:t.name,token:e.replyTo,url:createWorkflowCallbackUrl(t.callbackBaseUrl,createEveCallbackRoutePath(e.replyTo))},earlierProtocol:t.earlierProtocol,idempotencyKey:agentDeliveryId(`send`,t.sessionId),message:e.message,outputSchema:e.outputSchema,remote:r,sessionId:t.sessionId})}let r=agentDeliveryId(`send`,t.sessionId),i=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`,delivery:{channelKind:`subagent`,channelName:`subagent`,deliveryId:r},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});if(i.status!==`accepted`)throw Error(`Agent "${t.name}" can no longer receive messages; its session ended.`);return{deliveryId:r,sessionId:i.sessionId}}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`,deliveryId:agentDeliveryId(`cancel`,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 stopLateAgentSessionStep(e){"use step";if(e.address.kind===`remote`){await endAgentSession(e);return}let{sessionId:t}=e.address;try{await resumeHook(sessionInboxHookToken(sessionCommandHookToken(t)),{kind:`reset`,reason:RUN_FINISHED_REASON,deliveryId:agentDeliveryId(`reset`,t)})}catch(e){logError(log,`could not stop late child; cleanup is best effort`,e,{sessionId:t})}}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,deliveryId:agentDeliveryId(`reset`,t.sessionId)})}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,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({agentSessionRuntimeOverrides:e.runtimeOverrides,compiledArtifactsSource:n.compiledArtifactsSource,dynamicSubagentAgentConfig:i.dynamicSubagentAgentConfig,nodeId:a.nodeId}),l=r.toolStubs;l!==void 0&&(l={...l,agentPath:stubToolPath(l,a.name)});let u=`agent-session:${e.key}:initial`,d=(await contextStorage.run(new ContextContainer({localDevRequest:r.localDevRequest}),()=>c.createSession({...s,delivery:{channelKind:`subagent`,channelName:`subagent`,deliveryId:u},toolStubs:l}))).sessionId;return getStepMetadata().attempt>1&&({runId:d}=await waitForCommandHookOwner(sessionInboxHookToken(o))),{address:{continuationToken:o,kind:`local`,name:a.name,nodeId:a.nodeId,sessionId:d},deliveryId:u}}async function startRemoteSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,o=bindingFor(r,a.nodeId),s=resolveRemoteAgentForAction({credentials:i.dynamicRemoteAgent===void 0?void 0:await credentialsOf(n,a.nodeId,o,{name:a.remoteAgentName,url:i.dynamicRemoteAgent.url}),dynamicRemoteAgent:i.dynamicRemoteAgent,nodeId:a.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:a.remoteAgentName}),c=resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),l=await startRemoteAgentSession({action:a,auth:t.current,callbackBaseUrl:c,capabilities:r.capabilities,initiatorAuth:t.initiator,operationId:`agent-session:${e.key}`,originAudience:r.trace.originAudience,parent:createParentContext(r,e.replyTo),remote:s,session:{continuationToken:e.replyTo}}),u={callbackBaseUrl:c,kind:`remote`,forwardPrincipal:s.forwardPrincipal,name:a.remoteAgentName,nodeId:a.nodeId,resolverId:a.nodeId,sessionId:l.sessionId,url:s.url};return o!==void 0&&(u.dynamicBinding=o),l.earlierProtocol!==void 0&&(u.earlierProtocol=l.earlierProtocol),l.deliveryId===void 0?{address:u}:{address:u,deliveryId:l.deliveryId}}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({credentials:await credentialsOf(n,t.nodeId,t.dynamicBinding,t),dynamicRemoteAgent:r?.kind===`remote`?r.remoteAgent:void 0,nodeId:t.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:t.name}),url:t.url}}function bindingFor(e,t){let n=e.dynamicSelections[t];return n?.kind===`remote`&&n.remoteAgent.credentials===!0?n.binding:void 0}async function credentialsOf(e,t,n,r){if(n!==void 0)return await remoteAgentCredentials({binding:n,destination:r,nodeId:t,resolvers:e.subagentRegistry.dynamicResolvers})}async function loadAgentSessionBundle(e){return await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.bundle.source),nodeId:e.bundle.nodeId})}function agentDeliveryId(e,t){return`agent-session:${getWorkflowMetadata().workflowRunId}:${getStepMetadata().stepId}:${t}:${e}`}export{cancelAgentSessionTurnStep,endAgentSessionsStep,openAgentSessionStep,sendAgentSessionMessageStep,stopLateAgentSessionStep};
1
+ import{createLogger,logError}from"#internal/logging.js";import{SessionStrandedError}from"#channel/session-stranded-error.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{ContextContainer,contextStorage}from"#context/container.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import{resumeHook}from"#internal/workflow/runtime.js";import{agentDelegation}from"#tracing/eve/delegation.js";import{createWorkflowRuntime,dispatchWorkflowSessionCommand,resolveContinuation,waitForCommandHookOwner,waitForSessionInbox}from"#execution/workflow-runtime.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{FatalError,getStepMetadata,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl,resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{remoteAgentCredentials}from"#execution/agent-sessions/remote-credentials.js";import{resolveAgentAction,resolveAgentStartTarget}from"#execution/agent-sessions/target.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{InvalidRuntimeModelSelectionError,resolveRuntimeModelSelection}from"#runtime/agent/resolve-model.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});if(e.model!==void 0&&i.kind===`remote`)throw new FatalError(`ctx.agent("${e.name}", { model }) cannot override a remote agent's model. Configure the model on the receiving agent.`);let a=e.model===void 0?void 0:await normalizeRuntimeOverrides({bundle:n,model:e.model,name:e.name}),o={auth:e.auth,bundle:n,context:t,key:e.key,replyTo:e.replyTo,runtimeOverrides:a};return await agentDelegation.resume({context:t,agentName:r.name},()=>i.kind===`remote`?startRemoteSession({...o,target:i}):startLocalSession({...o,target:i}))}async function normalizeRuntimeOverrides({bundle:e,model:t,name:n}){try{return{model:(await resolveRuntimeModelSelection({durability:`durable`,modelMetadata:e.modelMetadata,selection:t})).reference}}catch(e){throw e instanceof InvalidRuntimeModelSelectionError?new FatalError(`ctx.agent("${n}", { model }) could not resolve the model selection: ${toErrorMessage(e)}`):e}}async function sendAgentSessionMessageStep(e){"use step";let{address:t,context:n}=e;if(t.kind===`remote`){let r=await resolveSessionRemote(n,t);return await continueRemoteAgentSession({auth:e.auth.current,callback:{callId:n.parent.callId,subagentName:t.name,token:e.replyTo,url:createWorkflowCallbackUrl(t.callbackBaseUrl,createEveCallbackRoutePath(e.replyTo))},earlierProtocol:t.earlierProtocol,idempotencyKey:agentDeliveryId(`send`,t.sessionId),message:e.message,outputSchema:e.outputSchema,remote:r,sessionId:t.sessionId})}let r=agentDeliveryId(`send`,t.sessionId),i=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`,delivery:{channelKind:`subagent`,channelName:`subagent`,deliveryId:r},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});if(i.status!==`accepted`)throw Error(`Agent "${t.name}" can no longer receive messages; its session ended.`);return{deliveryId:r,sessionId:i.sessionId}}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`,deliveryId:agentDeliveryId(`cancel`,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 stopLateAgentSessionStep(e){"use step";if(e.address.kind===`remote`){await endAgentSession(e);return}let{sessionId:t}=e.address;try{await resumeHook(sessionInboxHookToken(sessionCommandHookToken(t)),{kind:`reset`,reason:RUN_FINISHED_REASON,deliveryId:agentDeliveryId(`reset`,t)})}catch(e){logError(log,`could not stop late child; cleanup is best effort`,e,{sessionId:t})}}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,deliveryId:agentDeliveryId(`reset`,t.sessionId)})}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,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({agentSessionRuntimeOverrides:e.runtimeOverrides,compiledArtifactsSource:n.compiledArtifactsSource,dynamicSubagentAgentConfig:i.dynamicSubagentAgentConfig,nodeId:a.nodeId}),l=r.toolStubs;l!==void 0&&(l={...l,agentPath:stubToolPath(l,a.name)});let u=`agent-session:${e.key}:initial`,d=(await contextStorage.run(new ContextContainer({localDevRequest:r.localDevRequest}),()=>c.createSession({...s,delivery:{channelKind:`subagent`,channelName:`subagent`,deliveryId:u},toolStubs:l}))).sessionId;return getStepMetadata().attempt>1&&({runId:d}=await waitForCommandHookOwner(sessionInboxHookToken(o))),{address:{continuationToken:o,kind:`local`,name:a.name,nodeId:a.nodeId,sessionId:d},deliveryId:u}}async function startRemoteSession(e){let{auth:t,bundle:n,context:r,target:i}=e,{action:a}=i,o=bindingFor(r,a.nodeId),s=resolveRemoteAgentForAction({credentials:i.dynamicRemoteAgent===void 0?void 0:await credentialsOf(n,a.nodeId,o,{name:a.remoteAgentName,url:i.dynamicRemoteAgent.url}),dynamicRemoteAgent:i.dynamicRemoteAgent,nodeId:a.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:a.remoteAgentName}),c=resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),l=await startRemoteAgentSession({action:a,auth:t.current,callbackBaseUrl:c,capabilities:r.capabilities,initiatorAuth:t.initiator,operationId:`agent-session:${e.key}`,originAudience:r.trace.originAudience,parent:createParentContext(r,e.replyTo),remote:s,session:{continuationToken:e.replyTo}}),u={callbackBaseUrl:c,kind:`remote`,forwardPrincipal:s.forwardPrincipal,name:a.remoteAgentName,nodeId:a.nodeId,resolverId:a.nodeId,sessionId:l.sessionId,url:s.url};return o!==void 0&&(u.dynamicBinding=o),l.earlierProtocol!==void 0&&(u.earlierProtocol=l.earlierProtocol),l.deliveryId===void 0?{address:u}:{address:u,deliveryId:l.deliveryId}}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({credentials:await credentialsOf(n,t.nodeId,t.dynamicBinding,t),dynamicRemoteAgent:r?.kind===`remote`?r.remoteAgent:void 0,nodeId:t.nodeId,registry:n.subagentRegistry.subagentsByNodeId,remoteAgentName:t.name}),url:t.url}}function bindingFor(e,t){let n=e.dynamicSelections[t];return n?.kind===`remote`&&n.remoteAgent.credentials===!0?n.binding:void 0}async function credentialsOf(e,t,n,r){if(n!==void 0)return await remoteAgentCredentials({binding:n,destination:r,nodeId:t,resolvers:e.subagentRegistry.dynamicResolvers})}async function loadAgentSessionBundle(e){return await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.bundle.source),nodeId:e.bundle.nodeId})}function agentDeliveryId(e,t){return`agent-session:${getWorkflowMetadata().workflowRunId}:${getStepMetadata().stepId}:${t}:${e}`}export{cancelAgentSessionTurnStep,endAgentSessionsStep,openAgentSessionStep,sendAgentSessionMessageStep,stopLateAgentSessionStep};
@@ -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.84.0//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.84.1//runWorkflowProgramTask`;export{runWorkflowProgramTask};
@@ -24,6 +24,7 @@ export interface DockerRunOptions {
24
24
  * shape so the sandbox engine can adapt it directly.
25
25
  */
26
26
  export interface DockerProcess {
27
+ readonly stdin?: WritableStream<Uint8Array>;
27
28
  readonly stdout: ReadableStream<Uint8Array>;
28
29
  readonly stderr: ReadableStream<Uint8Array>;
29
30
  wait(): Promise<{
@@ -42,6 +43,7 @@ export interface DockerCli {
42
43
  /** Spawns `docker <args>` with streaming stdout/stderr. */
43
44
  stream(args: readonly string[], options?: {
44
45
  readonly signal?: AbortSignal;
46
+ readonly stdin?: boolean;
45
47
  }): DockerProcess;
46
48
  }
47
49
  /**
@@ -1,2 +1,2 @@
1
- import{Readable}from"node:stream";import{spawn,spawnSync}from"node:child_process";var DockerUnavailableError=class extends Error{hint="Install and start Docker Desktop, OrbStack, Colima, or another runtime exposing a Docker-compatible `docker` CLI (or point EVE_DOCKER_PATH at one, e.g. Podman). Alternatively use the dependency-free JustBashSandbox, VercelSandbox, or DefaultSandbox to pick by availability.";constructor(e){super("The Docker sandbox provider requires Docker, but the `docker` CLI was not found.",{cause:e}),this.name=`DockerUnavailableError`}},DockerDaemonUnavailableError=class extends Error{hint="Start Docker Desktop (or your Docker-compatible runtime) and retry. Alternatively use the dependency-free JustBashSandbox (installed automatically by `eve dev`, or `pnpm add -D just-bash`), VercelSandbox, or DefaultSandbox to pick by availability.";constructor(e){super(`The Docker sandbox provider requires a running Docker daemon, but it is not reachable. Docker reported: ${e}`),this.name=`DockerDaemonUnavailableError`}};async function assertDockerDaemonAvailable(e){let t=await e.run([`version`,`--format`,`{{.Server.Version}}`]);if(t.exitCode!==0)throw new DockerDaemonUnavailableError(firstLine(t.stderr)||`exit ${t.exitCode}`)}function resolveDockerExecutable(){let e=process.env.EVE_DOCKER_PATH?.trim();return e!==void 0&&e.length>0?e:`docker`}let cachedLinuxDockerAvailability;const LINUX_DOCKER_AVAILABILITY_ENV=`EVE_DEVELOPMENT_LINUX_DOCKER_AVAILABLE`;function isLinuxDockerDaemonAvailableSync(){return cachedLinuxDockerAvailability??=readAdoptedAvailability()??probeLinuxDockerDaemonSync(),cachedLinuxDockerAvailability}function peekLinuxDockerDaemonAvailability(){return cachedLinuxDockerAvailability}function readAdoptedAvailability(){let e=process.env[LINUX_DOCKER_AVAILABILITY_ENV];return e===`1`||e!==`0`&&void 0}function probeLinuxDockerDaemonSync(){try{let e=spawnSync(resolveDockerExecutable(),[`version`,`--format`,`{{.Server.Os}}`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],timeout:5e3});return e.status===0&&e.stdout.trim().toLowerCase()===`linux`}catch{return!1}}function createDockerCli(){return{async run(e,t={}){throwIfAborted(t.signal);let n=spawn(resolveDockerExecutable(),e,{signal:t.signal,stdio:[t.stdin===void 0?`ignore`:`pipe`,`pipe`,`pipe`]}),r=[],i=[];n.stdout?.on(`data`,e=>r.push(e)),n.stderr?.on(`data`,e=>i.push(e)),t.stdin!==void 0&&n.stdin?.end(t.stdin);let a=await new Promise((e,t)=>{n.on(`error`,e=>t(adaptSpawnError(e))),n.on(`close`,t=>e(t??1))}),o=Buffer.concat(r);return{exitCode:a,stderr:Buffer.concat(i).toString(`utf8`),stdout:o.toString(`utf8`),stdoutBytes:o}},stream(e,t={}){throwIfAborted(t.signal);let n=spawn(resolveDockerExecutable(),e,{signal:t.signal,stdio:[`ignore`,`pipe`,`pipe`]}),r=new Promise((e,t)=>{n.on(`error`,e=>t(adaptSpawnError(e))),n.on(`close`,t=>e(t??1))});return r.catch(()=>{}),{stdout:Readable.toWeb(n.stdout),stderr:Readable.toWeb(n.stderr),async wait(){return{exitCode:await r}},async kill(){n.kill(`SIGKILL`),await r.catch(()=>{})}}}}}function adaptSpawnError(e){return e.code===`ENOENT`?new DockerUnavailableError(e):e.code===`ABORT_ERR`?new DOMException(`The operation was aborted.`,`AbortError`):e}function throwIfAborted(e){if(e?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`)}function firstLine(e){return e.split(`
1
+ import{Readable,Writable}from"node:stream";import{spawn,spawnSync}from"node:child_process";var DockerUnavailableError=class extends Error{hint="Install and start Docker Desktop, OrbStack, Colima, or another runtime exposing a Docker-compatible `docker` CLI (or point EVE_DOCKER_PATH at one, e.g. Podman). Alternatively use the dependency-free JustBashSandbox, VercelSandbox, or DefaultSandbox to pick by availability.";constructor(e){super("The Docker sandbox provider requires Docker, but the `docker` CLI was not found.",{cause:e}),this.name=`DockerUnavailableError`}},DockerDaemonUnavailableError=class extends Error{hint="Start Docker Desktop (or your Docker-compatible runtime) and retry. Alternatively use the dependency-free JustBashSandbox (installed automatically by `eve dev`, or `pnpm add -D just-bash`), VercelSandbox, or DefaultSandbox to pick by availability.";constructor(e){super(`The Docker sandbox provider requires a running Docker daemon, but it is not reachable. Docker reported: ${e}`),this.name=`DockerDaemonUnavailableError`}};async function assertDockerDaemonAvailable(e){let t=await e.run([`version`,`--format`,`{{.Server.Version}}`]);if(t.exitCode!==0)throw new DockerDaemonUnavailableError(firstLine(t.stderr)||`exit ${t.exitCode}`)}function resolveDockerExecutable(){let e=process.env.EVE_DOCKER_PATH?.trim();return e!==void 0&&e.length>0?e:`docker`}let cachedLinuxDockerAvailability;const LINUX_DOCKER_AVAILABILITY_ENV=`EVE_DEVELOPMENT_LINUX_DOCKER_AVAILABLE`;function isLinuxDockerDaemonAvailableSync(){return cachedLinuxDockerAvailability??=readAdoptedAvailability()??probeLinuxDockerDaemonSync(),cachedLinuxDockerAvailability}function peekLinuxDockerDaemonAvailability(){return cachedLinuxDockerAvailability}function readAdoptedAvailability(){let e=process.env[LINUX_DOCKER_AVAILABILITY_ENV];return e===`1`||e!==`0`&&void 0}function probeLinuxDockerDaemonSync(){try{let e=spawnSync(resolveDockerExecutable(),[`version`,`--format`,`{{.Server.Os}}`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],timeout:5e3,windowsHide:!0});return e.status===0&&e.stdout.trim().toLowerCase()===`linux`}catch{return!1}}function createDockerCli(){return{async run(e,t={}){throwIfAborted(t.signal);let n=spawn(resolveDockerExecutable(),e,{signal:t.signal,stdio:[t.stdin===void 0?`ignore`:`pipe`,`pipe`,`pipe`],windowsHide:!0}),r=[],i=[];n.stdout?.on(`data`,e=>r.push(e)),n.stderr?.on(`data`,e=>i.push(e)),t.stdin!==void 0&&n.stdin?.end(t.stdin);let a=await new Promise((e,t)=>{n.on(`error`,e=>t(adaptSpawnError(e))),n.on(`close`,t=>e(t??1))}),o=Buffer.concat(r);return{exitCode:a,stderr:Buffer.concat(i).toString(`utf8`),stdout:o.toString(`utf8`),stdoutBytes:o}},stream(e,t={}){throwIfAborted(t.signal);let n=spawn(resolveDockerExecutable(),e,{signal:t.signal,stdio:[`pipe`,`pipe`,`pipe`],windowsHide:!0});t.stdin!==!0&&n.stdin.end();let r=new Promise((e,t)=>{n.on(`error`,e=>t(adaptSpawnError(e))),n.on(`close`,t=>e(t??1))});return r.catch(()=>{}),{stdin:t.stdin===!0?Writable.toWeb(n.stdin):void 0,stdout:Readable.toWeb(n.stdout),stderr:Readable.toWeb(n.stderr),async wait(){return{exitCode:await r}},async kill(){n.kill(`SIGKILL`),await r.catch(()=>{})}}}}}function adaptSpawnError(e){return e.code===`ENOENT`?new DockerUnavailableError(e):e.code===`ABORT_ERR`?new DOMException(`The operation was aborted.`,`AbortError`):e}function throwIfAborted(e){if(e?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`)}function firstLine(e){return e.split(`
2
2
  `,1)[0]?.trim()??``}export{DockerDaemonUnavailableError,DockerUnavailableError,LINUX_DOCKER_AVAILABILITY_ENV,assertDockerDaemonAvailable,createDockerCli,isLinuxDockerDaemonAvailableSync,peekLinuxDockerDaemonAvailability};
@@ -1,2 +1,2 @@
1
1
  import{randomUUID}from"node:crypto";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{dirname}from"node:path/posix";import{stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";const DOCKER_KILL_TREE_SCRIPT=[`pid_file="$1"`,`target="$(cat "$pid_file" 2>/dev/null)" || exit 0`,`[ -n "$target" ] || exit 0`,`kill_tree() {`,` local parent="$1" dir child ppid line`,` for dir in /proc/[0-9]*; do`,' child="${dir#/proc/}"',` ppid=""`,` while IFS= read -r line; do`,` case "$line" in`,' PPid:*) ppid="${line#PPid:}"; ppid="${ppid//[^0-9]/}"; break ;;',` esac`,` done < "$dir/status" 2>/dev/null`,` [ "$ppid" = "$parent" ] && kill_tree "$child"`,` done`,` kill -9 "$parent" 2>/dev/null`,`}`,`kill_tree "$target"`,`rm -f "$pid_file"`,`exit 0`].join(`
2
- `);function createDockerConnection(e){let{cli:t,containerIdentity:n}=e;async function killSpawnTree(e){await t.run([`exec`,n,`bash`,`-c`,DOCKER_KILL_TREE_SCRIPT,`eve-kill-tree`,e]).catch(()=>{})}return{extensions:{setNetworkPolicy:e=>setDockerNetworkPolicy(t,n,e)},async spawn(e){let r=[`exec`,`-w`,e.workingDirectory];for(let[t,n]of Object.entries(e.env))r.push(`-e`,`${t}=${n}`);let i=`/tmp/.eve-sbx-spawn-${randomUUID()}.pid`,a=`echo "$$" > ${shellQuote(i)}; bash -lc ${shellQuote(e.command)}; status=$?; rm -f ${shellQuote(i)}; exit $status`;r.push(n,`bash`,`-c`,a);let o=t.stream(r,{signal:e.signal});return e.signal?.addEventListener(`abort`,()=>void killSpawnTree(i),{once:!0}),{stdout:o.stdout,stderr:o.stderr,async wait(){return await o.wait()},async kill(){await killSpawnTree(i),await o.kill()}}},async readFile(e){let r=shellQuote(e.path),i=await t.run([`exec`,n,`bash`,`-lc`,`if [ -e ${r} ]; then exec cat ${r}; else exit 43; fi`],{signal:e.signal});return i.exitCode===43?null:(expectDockerSuccess(i,`read "${e.path}" from sandbox container`),i.stdoutBytes)},async removePath(e){let r=`${e.recursive===!0?`r`:``}${e.force===!0?`f`:``}`,i=[`exec`,n,`rm`,...r.length>0?[`-${r}`]:[],`--`,e.path],a=await t.run(i,{signal:e.signal});expectDockerSuccess(a,`remove "${e.path}" from sandbox container`)},stop:()=>stopDockerContainerIfRunning(t,n),async writeFiles(e){for(let r of e.files){let i=await t.run([`exec`,`-i`,n,`bash`,`-lc`,`mkdir -p ${shellQuote(dirname(r.path))} && cat > ${shellQuote(r.path)}`],{signal:e.signal,stdin:r.content});expectDockerSuccess(i,`write "${r.path}" into sandbox container`)}}}}export{createDockerConnection};
2
+ `);function createDockerConnection(e){let{cli:t,containerIdentity:n}=e;async function killSpawnTree(e){await t.run([`exec`,n,`bash`,`-c`,DOCKER_KILL_TREE_SCRIPT,`eve-kill-tree`,e]).catch(()=>{})}return{extensions:{setNetworkPolicy:e=>setDockerNetworkPolicy(t,n,e)},async spawn(e){let r=[`exec`,...e.stdin===!0?[`-i`]:[],`-w`,e.workingDirectory];for(let[t,n]of Object.entries(e.env))r.push(`-e`,`${t}=${n}`);let i=`/tmp/.eve-sbx-spawn-${randomUUID()}.pid`,a=`echo "$$" > ${shellQuote(i)}; bash -lc ${shellQuote(e.command)}; status=$?; rm -f ${shellQuote(i)}; exit $status`;r.push(n,`bash`,`-c`,a);let o=t.stream(r,{signal:e.signal,stdin:e.stdin});return e.signal?.addEventListener(`abort`,()=>void killSpawnTree(i),{once:!0}),{stdin:o.stdin,stdout:o.stdout,stderr:o.stderr,async wait(){return await o.wait()},async kill(){await killSpawnTree(i),await o.kill()}}},async readFile(e){let r=shellQuote(e.path),i=await t.run([`exec`,n,`bash`,`-lc`,`if [ -e ${r} ]; then exec cat ${r}; else exit 43; fi`],{signal:e.signal});return i.exitCode===43?null:(expectDockerSuccess(i,`read "${e.path}" from sandbox container`),i.stdoutBytes)},async removePath(e){let r=`${e.recursive===!0?`r`:``}${e.force===!0?`f`:``}`,i=[`exec`,n,`rm`,...r.length>0?[`-${r}`]:[],`--`,e.path],a=await t.run(i,{signal:e.signal});expectDockerSuccess(a,`remove "${e.path}" from sandbox container`)},stop:()=>stopDockerContainerIfRunning(t,n),async writeFiles(e){for(let r of e.files){let i=await t.run([`exec`,`-i`,n,`bash`,`-lc`,`mkdir -p ${shellQuote(dirname(r.path))} && cat > ${shellQuote(r.path)}`],{signal:e.signal,stdin:r.content});expectDockerSuccess(i,`write "${r.path}" into sandbox container`)}}}}export{createDockerConnection};
@@ -1 +1 @@
1
- import{mkdir,readFile,writeFile}from"node:fs/promises";import{isObject}from"#shared/guards.js";import{dirname}from"node:path";import{loadOptionalEnginePackage}from"#internal/application/optional-package-install.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{SANDBOX_AGENT_ENV}from"#public/sandbox/provider.js";import{pathExists}from"#execution/sandbox/bindings/local-provider-utils.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{importOptionalEnginePackage}from"#internal/application/optional-package-import.js";const JUST_BASH_PACKAGE={importModule:async()=>await import(`just-bash`),missingMessage:"The just-bash sandbox provider requires the `just-bash` package, which is not bundled with eve. Install it in your application (for example `pnpm add -D just-bash`), or use DockerSandbox or DefaultSandbox instead.",packageName:`just-bash`};async function installJustBashModule(e){return await loadOptionalEnginePackage({...JUST_BASH_PACKAGE,appRoot:e.appRoot,autoInstall:e.autoInstall,ignoredOptionalDependencies:[`@mongodb-js/zstd`,`node-liblzma`]})}async function importJustBashModule(e){return await importOptionalEnginePackage({...JUST_BASH_PACKAGE,appRoot:e})}async function createBashSandbox(e){let{justBash:t}=e,n=resolveLocalSandboxFilesystemRootPath(e.rootPath),r=resolveLocalSandboxMetadataPath(e.rootPath),i=await readLocalMetadata(r);await mkdir(n,{recursive:!0});let a=new t.ReadWriteFs({allowSymlinks:!0,maxFileReadSize:2**53-1,root:n}),o=a;if(e.filesystem!==void 0)try{o=await e.filesystem({defaultFilesystem:a,resolveProjectPath:t=>e.resolveProjectPath(t),storagePath:e.storagePath,justBash:t})}catch(e){throw Error(`Failed to create the custom just-bash filesystem.`,{cause:e})}await o.mkdir(WORKSPACE_ROOT,{recursive:!0});let s=await t.Sandbox.create({cwd:WORKSPACE_ROOT,customCommands:[t.defineCommand(`realpath`,async(e,t)=>{let n=e.at(-1);if(e.length!==4||e[0]!==`-e`||e[1]!==`-z`||e[2]!==`--`||!n)return{stdout:``,stderr:`realpath: expected -e -z -- path`,exitCode:2};try{let e=await t.fs.realpath(n);return await t.fs.stat(e),{stdout:e+`\0`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`realpath: ${String(e)}`,exitCode:1}}}),...e.customCommands??[]],env:i===null?void 0:{...i.env},fs:o,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureState(){await writeLocalMetadata(r,{env:{...s.bashEnvInstance.getEnv()},version:1})},async readFile({path:e}){try{return await o.readFileBuffer(e)}catch(t){if(!await o.exists(e))return null;throw t}},async removePath(e){await o.rm(e.path,{force:e.force,recursive:e.recursive})},async spawn(e){if(e.signal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=`( cd ${shellQuote(e.workingDirectory)} && {\n${e.command}\n} )`,n=await s.runCommand({args:[t],cmd:`eval`,detached:!0,env:{...SANDBOX_AGENT_ENV,...e.env},signal:e.signal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.type})},async stop(){await s.stop()},async writeFiles({files:e}){for(let t of e)await o.mkdir(dirname(t.path),{recursive:!0}),await o.writeFile(t.path,t.content)}}}function resolveLocalSandboxFilesystemRootPath(e){return`${e}/fs`}function resolveLocalSandboxMetadataPath(e){return`${e}/metadata.json`}async function readLocalMetadata(e){if(!await pathExists(e))return null;let t=JSON.parse(await readFile(e,`utf8`));return!isObject(t)||t.version!==1||!isStringRecord(t.env)?null:{env:t.env,version:1}}async function writeLocalMetadata(e,t){await mkdir(dirname(e),{recursive:!0}),await writeFile(e,`${JSON.stringify(t,null,2)}\n`)}function isStringRecord(e){return isObject(e)&&Object.values(e).every(e=>typeof e==`string`)}export{createBashSandbox,importJustBashModule,installJustBashModule};
1
+ import{mkdir,readFile,writeFile}from"node:fs/promises";import{isObject}from"#shared/guards.js";import{dirname}from"node:path";import{loadOptionalEnginePackage}from"#internal/application/optional-package-install.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{SANDBOX_AGENT_ENV}from"#public/sandbox/provider.js";import{pathExists}from"#execution/sandbox/bindings/local-provider-utils.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{importOptionalEnginePackage}from"#internal/application/optional-package-import.js";const JUST_BASH_PACKAGE={importModule:async()=>await import(`just-bash`),missingMessage:"The just-bash sandbox provider requires the `just-bash` package, which is not bundled with eve. Install it in your application (for example `pnpm add -D just-bash`), or use DockerSandbox or DefaultSandbox instead.",packageName:`just-bash`};async function installJustBashModule(e){return await loadOptionalEnginePackage({...JUST_BASH_PACKAGE,appRoot:e.appRoot,autoInstall:e.autoInstall,ignoredOptionalDependencies:[`@mongodb-js/zstd`,`node-liblzma`]})}async function importJustBashModule(e){return await importOptionalEnginePackage({...JUST_BASH_PACKAGE,appRoot:e})}async function createBashSandbox(e){let{justBash:t}=e,n=resolveLocalSandboxFilesystemRootPath(e.rootPath),r=resolveLocalSandboxMetadataPath(e.rootPath),i=await readLocalMetadata(r);await mkdir(n,{recursive:!0});let a=new t.ReadWriteFs({allowSymlinks:!0,maxFileReadSize:2**53-1,root:n}),o=a;if(e.filesystem!==void 0)try{o=await e.filesystem({defaultFilesystem:a,resolveProjectPath:t=>e.resolveProjectPath(t),storagePath:e.storagePath,justBash:t})}catch(e){throw Error(`Failed to create the custom just-bash filesystem.`,{cause:e})}await o.mkdir(WORKSPACE_ROOT,{recursive:!0});let s=await t.Sandbox.create({cwd:WORKSPACE_ROOT,customCommands:[t.defineCommand(`realpath`,async(e,t)=>{let n=e.at(-1);if(e.length!==4||e[0]!==`-e`||e[1]!==`-z`||e[2]!==`--`||!n)return{stdout:``,stderr:`realpath: expected -e -z -- path`,exitCode:2};try{let e=await t.fs.realpath(n);return await t.fs.stat(e),{stdout:e+`\0`,stderr:``,exitCode:0}}catch(e){return{stdout:``,stderr:`realpath: ${String(e)}`,exitCode:1}}}),...e.customCommands??[]],env:i===null?void 0:{...i.env},fs:o,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureState(){await writeLocalMetadata(r,{env:{...s.bashEnvInstance.getEnv()},version:1})},async readFile({path:e}){try{return await o.readFileBuffer(e)}catch(t){if(!await o.exists(e))return null;throw t}},async removePath(e){await o.rm(e.path,{force:e.force,recursive:e.recursive})},async spawn(e){if(e.signal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);if(e.stdin===!0)throw Error("The just-bash sandbox does not support `stdin` on spawn yet.");let t=`( cd ${shellQuote(e.workingDirectory)} && {\n${e.command}\n} )`,n=await s.runCommand({args:[t],cmd:`eval`,detached:!0,env:{...SANDBOX_AGENT_ENV,...e.env},signal:e.signal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.type})},async stop(){await s.stop()},async writeFiles({files:e}){for(let t of e)await o.mkdir(dirname(t.path),{recursive:!0}),await o.writeFile(t.path,t.content)}}}function resolveLocalSandboxFilesystemRootPath(e){return`${e}/fs`}function resolveLocalSandboxMetadataPath(e){return`${e}/metadata.json`}async function readLocalMetadata(e){if(!await pathExists(e))return null;let t=JSON.parse(await readFile(e,`utf8`));return!isObject(t)||t.version!==1||!isStringRecord(t.env)?null:{env:t.env,version:1}}async function writeLocalMetadata(e,t){await mkdir(dirname(e),{recursive:!0}),await writeFile(e,`${JSON.stringify(t,null,2)}\n`)}function isStringRecord(e){return isObject(e)&&Object.values(e).every(e=>typeof e==`string`)}export{createBashSandbox,importJustBashModule,installJustBashModule};
@@ -1 +1 @@
1
- import{randomBytes}from"node:crypto";import{isObject}from"#shared/guards.js";import{SANDBOX_AGENT_ENV,SandboxSessionGoneError,SandboxTemplateNotProvisionedError}from"#public/sandbox/provider.js";import{VERCEL_EVE_SANDBOX_IMAGE}from"#execution/sandbox/bindings/eve-image.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{invalidPreparedSandboxArtifactError,invalidSandboxSessionStateError}from"#shared/sandbox-recorded-data-error.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{isVercelSandboxMissingError,isVercelSandboxNameConflictError,isVercelSnapshotNotFoundError,isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{getNamedVercelSandbox,isVercelSnapshotCreated}from"#execution/sandbox/bindings/vercel-lookup.js";import{ensureVercelSandboxTags,errorMessage,resolveVercelSandboxTags}from"#execution/sandbox/bindings/vercel-options.js";import{applyInitialVercelNetworkPolicy,createVercelNetworkPolicySetter,ensureVercelSandboxBaseRuntime,toVercelNetworkPolicy,withBaseSetupNetworkPolicy}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-sdk.js";import{deleteNamedVercelSandbox,deleteUnusableVercelSandbox,stopVercelSandbox}from"#execution/sandbox/bindings/vercel-lifecycle.js";import{normalizeVercelReadStream}from"#execution/sandbox/bindings/vercel-read-stream.js";import{withToolSessionRetention}from"#execution/sandbox/bindings/vercel-tool-sessions.js";function createVercelSandbox(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={...e.createOptions,env:{...SANDBOX_AGENT_ENV,...e.createOptions?.env},timeout:e.createOptions?.timeout??DEFAULT_SANDBOX_TIMEOUT_MS},r=e.createSandbox??createVercelEveImageSandbox,i=n.source===void 0&&(n.image??VERCEL_EVE_SANDBOX_IMAGE)===VERCEL_EVE_SANDBOX_IMAGE;return{async onSessionEnd(e,r,{signal:i}){await deleteNamedVercelSandbox({createOptions:n,sandboxModule:await t(),sandboxName:r?.sandboxName??vercelSessionName(e.session.id),signal:i})},async prepare(e){if(e.isEmpty&&n.source===void 0)return{};try{let i=`eve-sbx-tpl-vercel-${e.templateKey({createOptions:vercelIdentityOptions(n),resolvedImage:n.source===void 0?n.image??VERCEL_EVE_SANDBOX_IMAGE:void 0,version:4}).slice(0,32)}`;return{snapshotId:await ensureTemplate({context:e,createOptions:n,createSandbox:r,loadSandboxModule:t,templateKey:i})}}catch(e){throw Error(`Failed to prepare Vercel sandbox snapshot: ${errorMessage(e)}`,{cause:e})}},async resume(e,r,i){requirePreparedVercelTemplate(r);let a=requireVercelSessionState(i),o=await t(),s=await getNamedVercelSandbox({createOptions:n,sandboxModule:o,sandboxName:a.sandboxName});if(s===null)throw new SandboxSessionGoneError(`Vercel sandbox session "${a.sandboxName}" no longer exists.`);return await ensureVercelSandboxBaseRuntime(s),createVercelConnection(s)},async start(e,t,n){let r=vercelSessionName(e.session.id);return{connection:createVercelConnection(await openSession(e,t,n,r)),state:{sandboxName:r,version:3}}},toolSessions:!0};async function openSession(e,a,o,s){let c=requirePreparedVercelTemplate(o),{mounts:l,networkPolicy:u,...d}=a??{},f=e.kind===`tool-session`,p={...n,...d,...u===void 0?{}:{networkPolicy:toVercelNetworkPolicy(u)},env:{...SANDBOX_AGENT_ENV,...d.env??n.env}},m=f?withToolSessionRetention(p):p,h=resolveVercelSandboxTags(m.tags,{sessionId:e.session.id}),g=await t(),_={createOptions:m,createSandbox:r,mounts:l===void 0?void 0:toVercelMounts(l),sandboxModule:g,sessionKey:s,snapshotId:c.snapshotId,tags:h};try{let t=await ensureUsableSession({expired:f?isVercelSnapshotNotFoundError:isVercelSnapshotUnavailableError,inheritsBaseRuntime:c.snapshotId!==void 0&&l===void 0&&i,input:_,session:await ensureSession(_)}),n=m.networkPolicy;if(t.created&&c.snapshotId===void 0&&n!==void 0)try{await applyInitialVercelNetworkPolicy(t.sandbox,n)}catch(n){try{await deleteNamedVercelSandbox({createOptions:m,sandboxModule:g,sandboxName:t.sandbox.name})}catch(t){throw AggregateError([n,t],`Failed to apply network policy and discard Vercel sandbox session "${e.session.id}".`,{cause:n})}throw n}return t.sandbox}catch(t){throw isVercelSnapshotUnavailableError(t)&&c.snapshotId!==void 0?new SandboxTemplateNotProvisionedError({providerName:`vercel`,reason:`The Vercel Sandbox snapshot expired or was deleted.`,templateKey:c.snapshotId}):Error(`Failed to open Vercel sandbox session "${e.session.id}": ${errorMessage(t)}`,{cause:t})}}}function vercelSessionName(e){return`eve-sbx-vercel-${createSandboxProviderIdentity({sessionId:e,version:2}).slice(0,32)}`}function vercelIdentityOptions(e){if(e===void 0)return;let t=new Set([`fetch`,`projectId`,`signal`,`teamId`,`token`]);return Object.fromEntries(Object.entries(e).filter(([e])=>!t.has(e)))}function requireVercelSessionState(e){if(!isObject(e)||e.version!==3||typeof e.sandboxName!=`string`)throw invalidSandboxSessionStateError(`Vercel sandbox`);return{sandboxName:e.sandboxName,version:3}}function requirePreparedVercelTemplate(e){if(!isObject(e)||e.snapshotId!==void 0&&typeof e.snapshotId!=`string`)throw invalidPreparedSandboxArtifactError(`Vercel sandbox`);return e.snapshotId===void 0?{}:{snapshotId:e.snapshotId}}function toVercelMounts(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,`mode`in t?{drive:t.drive,mode:t.mode}:{drive:t.name,mode:`read-write`}]))}async function ensureTemplate(e){let t=await e.loadSandboxModule(),n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:t,sandboxName:e.templateKey}),r=n?.sourceSnapshotId;if(r!==void 0&&await isVercelSnapshotCreated({createOptions:e.createOptions,sandboxModule:t,snapshotId:r}))return e.context.log(`reusing prepared sandbox template`),r;let i=await prepareTemplateSnapshot(e,t);return await publishTemplatePointer(e,t,n,i).catch(t=>{e.context.log(`could not publish sandbox template: ${errorMessage(t)}`)}),i}async function prepareTemplateSnapshot(e,t){let n=await e.createSandbox({sandboxModule:t,createOptions:withBaseSetupNetworkPolicy({...e.createOptions,name:`${e.templateKey}-${randomBytes(4).toString(`hex`)}`,persistent:!1})});try{return e.context.log(`preparing base runtime inside sandbox`),await ensureVercelSandboxBaseRuntime(n),await applyInitialVercelNetworkPolicy(n,e.createOptions.networkPolicy),await e.context.populate(createVercelConnection(n)),await ensureVercelSandboxBaseRuntime(n),(await n.snapshot()).snapshotId}finally{await n.delete().catch(t=>{e.context.log(`could not delete sandbox ${n.name}: ${errorMessage(t)}`)})}}async function publishTemplatePointer(e,t,n,r){if(n!==null)try{await n.delete()}catch(e){if(!isVercelSandboxMissingError(e))throw e}let{image:i,runtime:a,source:o,...s}=e.createOptions,c;try{c=await e.createSandbox({sandboxModule:t,createOptions:{...s,name:e.templateKey,persistent:!1,source:{snapshotId:r,type:`snapshot`}}})}catch(e){if(isVercelSandboxNameConflictError(e))return;throw e}await stopVercelSandbox(c)}async function ensureUsableSession(e){let ensureBaseRuntime=async t=>{t.created&&e.inheritsBaseRuntime||await ensureVercelSandboxBaseRuntime(t.sandbox)};try{return await ensureBaseRuntime(e.session),e.session}catch(t){if(e.session.created||!e.expired(t))throw t}try{await deleteUnusableVercelSandbox({createOptions:e.input.createOptions,sandboxModule:e.input.sandboxModule,sandboxName:e.session.sandbox.name})}catch(e){if(!isVercelSandboxMissingError(e))throw e}let t=await ensureSession(e.input);return await ensureBaseRuntime(t),t}async function ensureSession(e){let t=e.sessionKey,n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:e.sandboxModule,sandboxName:t});if(n!==null)return await ensureVercelSandboxTags(n,e.tags),{created:!1,sandbox:n};let r=createSessionCreateParams(e,t);e.tags!==void 0&&(r.tags=e.tags);try{return{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}catch(n){if(!isVercelSandboxNameConflictError(n))throw n;let r=await getNamedVercelSandbox({...e,sandboxName:t});if(r===null)throw n;return{created:!1,sandbox:r}}}function createSessionCreateParams(e,t){let n={...e.createOptions};if(e.mounts!==void 0&&(n.mounts=e.mounts),e.snapshotId===void 0)return withBaseSetupNetworkPolicy({...n,name:t,persistent:!0});let{image:r,runtime:i,source:a,...o}=n;return{...o,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function createVercelConnection(e){return{extensions:{name:e.name,setNetworkPolicy:createVercelNetworkPolicySetter(e)},async readFile(t){return normalizeVercelReadStream(await e.readFile({path:t.path}))},async removePath(t){await e.fs.rm(t.path,{force:t.force,recursive:t.recursive,signal:t.signal})},async spawn(t){let n=await e.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory,detached:!0,env:t.env,signal:t.signal});return adaptMultiplexedCommandToSandboxProcess({abortSignal:t.signal,command:n,getOutput:e=>e.stream})},async stop(){await stopVercelSandbox(e)},async writeFiles(t){t.files.length!==0&&await e.writeFiles(await resolveVercelWriteFiles(e,t.files,t.signal),{signal:t.signal})}}}async function resolveVercelWriteFiles(e,t,n){let r=[],i=[],a=0;for(let o of t){let t=Buffer.byteLength(o.path)+1;i.length>0&&a+t>65536&&(r.push(...await resolveVercelPaths(e,i,n)),i=[],a=0),i.push(o.path),a+=t}return r.push(...await resolveVercelPaths(e,i,n)),t.map((e,t)=>{let n=r[t];if(n===void 0||!n.startsWith(`/`))throw Error(`Failed to resolve Vercel Sandbox write path: ${e.path}`);return{content:e.content,path:n}})}async function resolveVercelPaths(e,t,n){let r=await e.runCommand({args:[`-m`,`-z`,`--`,...t],cmd:`realpath`,signal:n});if(r.exitCode!==0){let e=(await r.stderr()).trim();throw Error(`Failed to resolve Vercel Sandbox write paths with realpath: ${e}`)}let i=(await r.stdout()).split(`\0`).slice(0,-1);if(i.length!==t.length)throw Error(`Failed to resolve Vercel Sandbox write paths: realpath printed ${i.length} paths for ${t.length} files.`);return i}const DEFAULT_SANDBOX_TIMEOUT_MS=18e5;export{createVercelSandbox};
1
+ import{randomBytes}from"node:crypto";import{isObject}from"#shared/guards.js";import{SANDBOX_AGENT_ENV,SandboxSessionGoneError,SandboxTemplateNotProvisionedError}from"#public/sandbox/provider.js";import{VERCEL_EVE_SANDBOX_IMAGE}from"#execution/sandbox/bindings/eve-image.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{invalidPreparedSandboxArtifactError,invalidSandboxSessionStateError}from"#shared/sandbox-recorded-data-error.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{isVercelSandboxMissingError,isVercelSandboxNameConflictError,isVercelSnapshotNotFoundError,isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{getNamedVercelSandbox,isVercelSnapshotCreated}from"#execution/sandbox/bindings/vercel-lookup.js";import{ensureVercelSandboxTags,errorMessage,resolveVercelSandboxTags}from"#execution/sandbox/bindings/vercel-options.js";import{applyInitialVercelNetworkPolicy,createVercelNetworkPolicySetter,ensureVercelSandboxBaseRuntime,toVercelNetworkPolicy,withBaseSetupNetworkPolicy}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-sdk.js";import{deleteNamedVercelSandbox,deleteUnusableVercelSandbox,stopVercelSandbox}from"#execution/sandbox/bindings/vercel-lifecycle.js";import{normalizeVercelReadStream}from"#execution/sandbox/bindings/vercel-read-stream.js";import{withToolSessionRetention}from"#execution/sandbox/bindings/vercel-tool-sessions.js";function createVercelSandbox(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={...e.createOptions,env:{...SANDBOX_AGENT_ENV,...e.createOptions?.env},timeout:e.createOptions?.timeout??DEFAULT_SANDBOX_TIMEOUT_MS},r=e.createSandbox??createVercelEveImageSandbox,i=n.source===void 0&&(n.image??VERCEL_EVE_SANDBOX_IMAGE)===VERCEL_EVE_SANDBOX_IMAGE;return{async onSessionEnd(e,r,{signal:i}){await deleteNamedVercelSandbox({createOptions:n,sandboxModule:await t(),sandboxName:r?.sandboxName??vercelSessionName(e.session.id),signal:i})},async prepare(e){if(e.isEmpty&&n.source===void 0)return{};try{let i=`eve-sbx-tpl-vercel-${e.templateKey({createOptions:vercelIdentityOptions(n),resolvedImage:n.source===void 0?n.image??VERCEL_EVE_SANDBOX_IMAGE:void 0,version:4}).slice(0,32)}`;return{snapshotId:await ensureTemplate({context:e,createOptions:n,createSandbox:r,loadSandboxModule:t,templateKey:i})}}catch(e){throw Error(`Failed to prepare Vercel sandbox snapshot: ${errorMessage(e)}`,{cause:e})}},async resume(e,r,i){requirePreparedVercelTemplate(r);let a=requireVercelSessionState(i),o=await t(),s=await getNamedVercelSandbox({createOptions:n,sandboxModule:o,sandboxName:a.sandboxName});if(s===null)throw new SandboxSessionGoneError(`Vercel sandbox session "${a.sandboxName}" no longer exists.`);return await ensureVercelSandboxBaseRuntime(s),createVercelConnection(s)},async start(e,t,n){let r=vercelSessionName(e.session.id);return{connection:createVercelConnection(await openSession(e,t,n,r)),state:{sandboxName:r,version:3}}},toolSessions:!0};async function openSession(e,a,o,s){let c=requirePreparedVercelTemplate(o),{mounts:l,networkPolicy:u,...d}=a??{},f=e.kind===`tool-session`,p={...n,...d,...u===void 0?{}:{networkPolicy:toVercelNetworkPolicy(u)},env:{...SANDBOX_AGENT_ENV,...d.env??n.env}},m=f?withToolSessionRetention(p):p,h=resolveVercelSandboxTags(m.tags,{sessionId:e.session.id}),g=await t(),_={createOptions:m,createSandbox:r,mounts:l===void 0?void 0:toVercelMounts(l),sandboxModule:g,sessionKey:s,snapshotId:c.snapshotId,tags:h};try{let t=await ensureUsableSession({expired:f?isVercelSnapshotNotFoundError:isVercelSnapshotUnavailableError,inheritsBaseRuntime:c.snapshotId!==void 0&&l===void 0&&i,input:_,session:await ensureSession(_)}),n=m.networkPolicy;if(t.created&&c.snapshotId===void 0&&n!==void 0)try{await applyInitialVercelNetworkPolicy(t.sandbox,n)}catch(n){try{await deleteNamedVercelSandbox({createOptions:m,sandboxModule:g,sandboxName:t.sandbox.name})}catch(t){throw AggregateError([n,t],`Failed to apply network policy and discard Vercel sandbox session "${e.session.id}".`,{cause:n})}throw n}return t.sandbox}catch(t){throw isVercelSnapshotUnavailableError(t)&&c.snapshotId!==void 0?new SandboxTemplateNotProvisionedError({providerName:`vercel`,reason:`The Vercel Sandbox snapshot expired or was deleted.`,templateKey:c.snapshotId}):Error(`Failed to open Vercel sandbox session "${e.session.id}": ${errorMessage(t)}`,{cause:t})}}}function vercelSessionName(e){return`eve-sbx-vercel-${createSandboxProviderIdentity({sessionId:e,version:2}).slice(0,32)}`}function vercelIdentityOptions(e){if(e===void 0)return;let t=new Set([`fetch`,`projectId`,`signal`,`teamId`,`token`]);return Object.fromEntries(Object.entries(e).filter(([e])=>!t.has(e)))}function requireVercelSessionState(e){if(!isObject(e)||e.version!==3||typeof e.sandboxName!=`string`)throw invalidSandboxSessionStateError(`Vercel sandbox`);return{sandboxName:e.sandboxName,version:3}}function requirePreparedVercelTemplate(e){if(!isObject(e)||e.snapshotId!==void 0&&typeof e.snapshotId!=`string`)throw invalidPreparedSandboxArtifactError(`Vercel sandbox`);return e.snapshotId===void 0?{}:{snapshotId:e.snapshotId}}function toVercelMounts(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,`mode`in t?{drive:t.drive,mode:t.mode}:{drive:t.name,mode:`read-write`}]))}async function ensureTemplate(e){let t=await e.loadSandboxModule(),n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:t,sandboxName:e.templateKey}),r=n?.sourceSnapshotId;if(r!==void 0&&await isVercelSnapshotCreated({createOptions:e.createOptions,sandboxModule:t,snapshotId:r}))return e.context.log(`reusing prepared sandbox template`),r;let i=await prepareTemplateSnapshot(e,t);return await publishTemplatePointer(e,t,n,i).catch(t=>{e.context.log(`could not publish sandbox template: ${errorMessage(t)}`)}),i}async function prepareTemplateSnapshot(e,t){let n=await e.createSandbox({sandboxModule:t,createOptions:withBaseSetupNetworkPolicy({...e.createOptions,name:`${e.templateKey}-${randomBytes(4).toString(`hex`)}`,persistent:!1})});try{return e.context.log(`preparing base runtime inside sandbox`),await ensureVercelSandboxBaseRuntime(n),await applyInitialVercelNetworkPolicy(n,e.createOptions.networkPolicy),await e.context.populate(createVercelConnection(n)),await ensureVercelSandboxBaseRuntime(n),(await n.snapshot()).snapshotId}finally{await n.delete().catch(t=>{e.context.log(`could not delete sandbox ${n.name}: ${errorMessage(t)}`)})}}async function publishTemplatePointer(e,t,n,r){if(n!==null)try{await n.delete()}catch(e){if(!isVercelSandboxMissingError(e))throw e}let{image:i,runtime:a,source:o,...s}=e.createOptions,c;try{c=await e.createSandbox({sandboxModule:t,createOptions:{...s,name:e.templateKey,persistent:!1,source:{snapshotId:r,type:`snapshot`}}})}catch(e){if(isVercelSandboxNameConflictError(e))return;throw e}await stopVercelSandbox(c)}async function ensureUsableSession(e){let ensureBaseRuntime=async t=>{t.created&&e.inheritsBaseRuntime||await ensureVercelSandboxBaseRuntime(t.sandbox)};try{return await ensureBaseRuntime(e.session),e.session}catch(t){if(e.session.created||!e.expired(t))throw t}try{await deleteUnusableVercelSandbox({createOptions:e.input.createOptions,sandboxModule:e.input.sandboxModule,sandboxName:e.session.sandbox.name})}catch(e){if(!isVercelSandboxMissingError(e))throw e}let t=await ensureSession(e.input);return await ensureBaseRuntime(t),t}async function ensureSession(e){let t=e.sessionKey,n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:e.sandboxModule,sandboxName:t});if(n!==null)return await ensureVercelSandboxTags(n,e.tags),{created:!1,sandbox:n};let r=createSessionCreateParams(e,t);e.tags!==void 0&&(r.tags=e.tags);try{return{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}catch(n){if(!isVercelSandboxNameConflictError(n))throw n;let r=await getNamedVercelSandbox({...e,sandboxName:t});if(r===null)throw n;return{created:!1,sandbox:r}}}function createSessionCreateParams(e,t){let n={...e.createOptions};if(e.mounts!==void 0&&(n.mounts=e.mounts),e.snapshotId===void 0)return withBaseSetupNetworkPolicy({...n,name:t,persistent:!0});let{image:r,runtime:i,source:a,...o}=n;return{...o,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function createVercelConnection(e){return{extensions:{name:e.name,setNetworkPolicy:createVercelNetworkPolicySetter(e)},async readFile(t){return normalizeVercelReadStream(await e.readFile({path:t.path}))},async removePath(t){await e.fs.rm(t.path,{force:t.force,recursive:t.recursive,signal:t.signal})},async spawn(t){let n=await e.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory,detached:!0,env:t.env,signal:t.signal,stdin:t.stdin});return adaptMultiplexedCommandToSandboxProcess({abortSignal:t.signal,command:n,getOutput:e=>e.stream,stdin:t.stdin===!0?n:void 0})},async stop(){await stopVercelSandbox(e)},async writeFiles(t){t.files.length!==0&&await e.writeFiles(await resolveVercelWriteFiles(e,t.files,t.signal),{signal:t.signal})}}}async function resolveVercelWriteFiles(e,t,n){let r=[],i=[],a=0;for(let o of t){let t=Buffer.byteLength(o.path)+1;i.length>0&&a+t>65536&&(r.push(...await resolveVercelPaths(e,i,n)),i=[],a=0),i.push(o.path),a+=t}return r.push(...await resolveVercelPaths(e,i,n)),t.map((e,t)=>{let n=r[t];if(n===void 0||!n.startsWith(`/`))throw Error(`Failed to resolve Vercel Sandbox write path: ${e.path}`);return{content:e.content,path:n}})}async function resolveVercelPaths(e,t,n){let r=await e.runCommand({args:[`-m`,`-z`,`--`,...t],cmd:`realpath`,signal:n});if(r.exitCode!==0){let e=(await r.stderr()).trim();throw Error(`Failed to resolve Vercel Sandbox write paths with realpath: ${e}`)}let i=(await r.stdout()).split(`\0`).slice(0,-1);if(i.length!==t.length)throw Error(`Failed to resolve Vercel Sandbox write paths: realpath printed ${i.length} paths for ${t.length} files.`);return i}const DEFAULT_SANDBOX_TIMEOUT_MS=18e5;export{createVercelSandbox};
@@ -13,10 +13,19 @@ interface MultiplexedCommand<Log extends {
13
13
  readonly exitCode: number;
14
14
  }>;
15
15
  }
16
+ interface StdinCommand {
17
+ closeStdin(options: {
18
+ readonly abortSignal?: AbortSignal;
19
+ }): PromiseLike<void>;
20
+ writeStdin(data: Uint8Array, options: {
21
+ readonly abortSignal?: AbortSignal;
22
+ }): PromiseLike<void>;
23
+ }
16
24
  /**
17
25
  * Adapts a detached command with one tagged log iterator to a sandbox process
18
26
  * with independent stdout and stderr streams. Aborting `abortSignal` kills the
19
- * command and rejects `wait()` and both streams.
27
+ * command and rejects `wait()` and both streams. `stdin`, when given, backs
28
+ * the process's writable `stdin` stream.
20
29
  */
21
30
  export declare function adaptMultiplexedCommandToSandboxProcess<Log extends {
22
31
  readonly data: string;
@@ -24,5 +33,6 @@ export declare function adaptMultiplexedCommandToSandboxProcess<Log extends {
24
33
  readonly abortSignal?: AbortSignal;
25
34
  readonly command: MultiplexedCommand<Log>;
26
35
  readonly getOutput: (log: Log) => OutputName;
36
+ readonly stdin?: StdinCommand;
27
37
  }): SandboxProcess;
28
38
  export {};
@@ -1 +1 @@
1
- function createOutputChannel(){let e=!1,t;return{stream:new ReadableStream({cancel(){e=!0},start(e){t=e}}),close(){e||t.close()},enqueue(n){e||t.enqueue(n)},error(n){e||t.error(n)}}}function adaptMultiplexedCommandToSandboxProcess(e){let{abortSignal:t,command:n}=e,r=new TextEncoder,i=createOutputChannel(),a=createOutputChannel(),o={stderr:a,stdout:i},s=(async()=>{try{for await(let i of n.logs({signal:t}))o[e.getOutput(i)].enqueue(r.encode(i.data));i.close(),a.close()}catch(e){let n=t?.aborted?t.reason:e;throw i.error(n),a.error(n),n}})(),c,l,kill=()=>l??=Promise.resolve().then(()=>n.kill()),killOnAbort=()=>void kill().catch(()=>void 0),disarmKill=()=>t?.removeEventListener(`abort`,killOnAbort);return t?.aborted&&killOnAbort(),t?.addEventListener(`abort`,killOnAbort,{once:!0}),s.then(disarmKill,()=>void 0),{stderr:a.stream,stdout:i.stream,wait(){return c??=Promise.resolve().then(async()=>{let e=await n.wait({signal:t});return disarmKill(),await s,{exitCode:e.exitCode}})},kill}}export{adaptMultiplexedCommandToSandboxProcess};
1
+ function createOutputChannel(){let e=!1,t;return{stream:new ReadableStream({cancel(){e=!0},start(e){t=e}}),close(){e||t.close()},enqueue(n){e||t.enqueue(n)},error(n){e||t.error(n)}}}function createStdinStream(e,t){let n;return new WritableStream({start(e){n=AbortSignal.any([...t,e.signal])},async write(t){await e.writeStdin(t,{abortSignal:n})},async close(){await e.closeStdin({abortSignal:n})},async abort(){let n=AbortSignal.any([...t]);n.aborted||await e.closeStdin({abortSignal:n})}})}function adaptMultiplexedCommandToSandboxProcess(e){let{abortSignal:t,command:n}=e,r=new TextEncoder,i=createOutputChannel(),a=createOutputChannel(),o={stderr:a,stdout:i},s=(async()=>{try{for await(let i of n.logs({signal:t}))o[e.getOutput(i)].enqueue(r.encode(i.data));i.close(),a.close()}catch(e){let n=t?.aborted?t.reason:e;throw i.error(n),a.error(n),n}})(),c,l,u=new AbortController,kill=()=>(u.abort(),l??=Promise.resolve().then(()=>n.kill())),killOnAbort=()=>void kill().catch(()=>void 0),disarmKill=()=>t?.removeEventListener(`abort`,killOnAbort);return t?.aborted&&killOnAbort(),t?.addEventListener(`abort`,killOnAbort,{once:!0}),s.then(disarmKill,()=>void 0),{stdin:e.stdin===void 0?void 0:createStdinStream(e.stdin,t===void 0?[u.signal]:[u.signal,t]),stderr:a.stream,stdout:i.stream,wait(){return c??=Promise.resolve().then(async()=>{let e=await n.wait({signal:t});return disarmKill(),await s,{exitCode:e.exitCode}})},kill}}export{adaptMultiplexedCommandToSandboxProcess};
@@ -1,3 +1,3 @@
1
- import{bufferToStream,streamToBuffer}from"./stream-utils.js";import{posix}from"node:path";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";const SANDBOX_AGENT_ENV={AI_AGENT:`eve`};function createConnectionSession(e){let t=e.workspaceRoot??WORKSPACE_ROOT;if(!posix.isAbsolute(t))throw Error(`Sandbox connection workspaceRoot must be an absolute path, but received "${t}".`);let resolveSandboxPath=e=>posix.resolve(t,e);async function read(t){return await e.readFile({signal:t.signal,path:resolveSandboxPath(t.path)})}async function readBytes(e){let t=await read(e);return t===null?null:ArrayBuffer.isView(t)?Buffer.from(t):await streamToBuffer(t)}async function write(t,n){await e.writeFiles({signal:t.signal,files:[{content:n,path:resolveSandboxPath(t.path)}]})}async function spawn(t){return await e.spawn({signal:t.signal,command:t.command,env:t.env??{},workingDirectory:resolveSandboxPath(t.workingDirectory??`.`)})}let n={resolvePath:resolveSandboxPath,async run(e){let t=await spawn(e),[n,r,{exitCode:i}]=await Promise.all([collectStreamToString(t.stdout),collectStreamToString(t.stderr),t.wait()]);return{exitCode:i,stderr:r,stdout:n}},spawn,async readFile(e){let t=await read(e);return t===null||!ArrayBuffer.isView(t)?t:bufferToStream(new Uint8Array(t.buffer,t.byteOffset,t.byteLength))},readBinaryFile:e=>readBytes(e),async readTextFile(e){validateReadTextFileOptions(e);let t=await readBytes(e);return t===null?null:applyLineRange(decodeBytes(t,e.encoding??`utf-8`),e)},async writeFile(e){await write(e,await streamToBuffer(e.content))},async writeBinaryFile(e){await write(e,Buffer.from(e.content))},async writeTextFile(e){let t=e.encoding??`utf-8`;await write(e,Buffer.from(e.content,t))},async writeFiles(t){await e.writeFiles({signal:t.signal,files:t.files.map(e=>({content:e.content,path:resolveSandboxPath(e.path)}))})},async removePath(t){await e.removePath({signal:t.signal,force:t.force,path:resolveSandboxPath(t.path),recursive:t.recursive})}},r=e.extensions??{},i=Object.keys(r).filter(e=>Object.hasOwn(n,e)||e===`delete`||e===`stop`);if(i.length>0)throw Error(`Sandbox connection extensions cannot replace the session members eve provides: ${i.join(`, `)}. Rename them.`);return{...r,...n}}async function collectStreamToString(e){let t=await streamToBuffer(e);return new TextDecoder().decode(t)}function validateReadTextFileOptions(e){let{startLine:t,endLine:n}=e;if(t!==void 0&&(!Number.isInteger(t)||t<1))throw Error(`startLine must be a positive integer (1-based).`);if(n!==void 0&&(!Number.isInteger(n)||n<1))throw Error(`endLine must be a positive integer (1-based).`);if(t!==void 0&&n!==void 0&&t>n)throw Error(`startLine must not be greater than endLine.`)}function splitLinesPreservingEndings(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===`\r`?r+1<e.length&&e[r+1]===`
1
+ import{bufferToStream,streamToBuffer}from"./stream-utils.js";import{posix}from"node:path";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";const SANDBOX_AGENT_ENV={AI_AGENT:`eve`};function createConnectionSession(e){let t=e.workspaceRoot??WORKSPACE_ROOT;if(!posix.isAbsolute(t))throw Error(`Sandbox connection workspaceRoot must be an absolute path, but received "${t}".`);let resolveSandboxPath=e=>posix.resolve(t,e);async function read(t){return await e.readFile({signal:t.signal,path:resolveSandboxPath(t.path)})}async function readBytes(e){let t=await read(e);return t===null?null:ArrayBuffer.isView(t)?Buffer.from(t):await streamToBuffer(t)}async function write(t,n){await e.writeFiles({signal:t.signal,files:[{content:n,path:resolveSandboxPath(t.path)}]})}async function spawn(t){let n=await e.spawn({signal:t.signal,stdin:t.stdin,command:t.command,env:t.env??{},workingDirectory:resolveSandboxPath(t.workingDirectory??`.`)});if(t.stdin===!0&&n.stdin===void 0)throw await Promise.resolve(n.kill()).catch(()=>void 0),Error("This sandbox provider does not support `stdin` on spawn.");return n}let n={resolvePath:resolveSandboxPath,async run(e){let t=await spawn(e),[n,r,{exitCode:i}]=await Promise.all([collectStreamToString(t.stdout),collectStreamToString(t.stderr),t.wait()]);return{exitCode:i,stderr:r,stdout:n}},spawn,async readFile(e){let t=await read(e);return t===null||!ArrayBuffer.isView(t)?t:bufferToStream(new Uint8Array(t.buffer,t.byteOffset,t.byteLength))},readBinaryFile:e=>readBytes(e),async readTextFile(e){validateReadTextFileOptions(e);let t=await readBytes(e);return t===null?null:applyLineRange(decodeBytes(t,e.encoding??`utf-8`),e)},async writeFile(e){await write(e,await streamToBuffer(e.content))},async writeBinaryFile(e){await write(e,Buffer.from(e.content))},async writeTextFile(e){let t=e.encoding??`utf-8`;await write(e,Buffer.from(e.content,t))},async writeFiles(t){await e.writeFiles({signal:t.signal,files:t.files.map(e=>({content:e.content,path:resolveSandboxPath(e.path)}))})},async removePath(t){await e.removePath({signal:t.signal,force:t.force,path:resolveSandboxPath(t.path),recursive:t.recursive})}},r=e.extensions??{},i=Object.keys(r).filter(e=>Object.hasOwn(n,e)||e===`delete`||e===`stop`);if(i.length>0)throw Error(`Sandbox connection extensions cannot replace the session members eve provides: ${i.join(`, `)}. Rename them.`);return{...r,...n}}async function collectStreamToString(e){let t=await streamToBuffer(e);return new TextDecoder().decode(t)}function validateReadTextFileOptions(e){let{startLine:t,endLine:n}=e;if(t!==void 0&&(!Number.isInteger(t)||t<1))throw Error(`startLine must be a positive integer (1-based).`);if(n!==void 0&&(!Number.isInteger(n)||n<1))throw Error(`endLine must be a positive integer (1-based).`);if(t!==void 0&&n!==void 0&&t>n)throw Error(`startLine must not be greater than endLine.`)}function splitLinesPreservingEndings(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===`\r`?r+1<e.length&&e[r+1]===`
2
2
  `?(t.push(e.slice(n,r+2)),n=r+2,r++):(t.push(e.slice(n,r+1)),n=r+1):e[r]===`
3
3
  `&&(t.push(e.slice(n,r+1)),n=r+1);return n<e.length&&t.push(e.slice(n)),t}function applyLineRange(e,t){if(t.startLine===void 0&&t.endLine===void 0)return e;let n=splitLinesPreservingEndings(e),r=n.length,i=t.startLine??1,a=Math.min(t.endLine??r,r);return i>r?``:n.slice(i-1,a).join(``)}function decodeBytes(e,t){return t===`utf-8`||t===`utf8`?new TextDecoder(`utf-8`,{fatal:!0}).decode(e):Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString(t)}export{SANDBOX_AGENT_ENV,createConnectionSession};
@@ -5,6 +5,7 @@ export declare const SESSION_INBOX_SESSION_ID_METADATA_KEY = "sessionId";
5
5
  /** Stable inbox coordinates. The owner and deployment are intentionally absent. */
6
6
  export interface SessionInboxAddress {
7
7
  readonly sessionId: string;
8
+ readonly inbox?: string;
8
9
  }
9
10
  export declare function isSessionInboxAddress(value: unknown): value is SessionInboxAddress;
10
11
  /** Returns whether a token belongs to eve's framework-reserved session namespace. */
@@ -0,0 +1,7 @@
1
+ import type { Hook } from "#internal/workflow/runtime.js";
2
+ type InboxHook = Omit<Hook, "metadata">;
3
+ /** Opaque transport state; never includes user metadata or transient capabilities. */
4
+ export declare function issueInboxHandle(hook: unknown): string | undefined;
5
+ /** Verify the complete descriptor before using its routing or encryption fields. */
6
+ export declare function readInboxHandle(handle: string): InboxHook | undefined;
7
+ export {};
@@ -0,0 +1 @@
1
+ import{createHmac,timingSafeEqual}from"node:crypto";import*as workflowRuntime from"#internal/workflow/runtime.js";const MAX_HANDLE_LENGTH=8192;function parseInboxHook(e){let t=Reflect.get(workflowRuntime,`parseHookResumeHandle`);if(typeof t==`function`)return t(e)}function signingKey(){let e=process.env.EVE_INBOX_HANDLE_SECRET;return e!==void 0&&e.length>=32?e:void 0}function signature(e,t){return createHmac(`sha256`,t).update(`eve:inbox:v1:`).update(e).digest()}function issueInboxHandle(e){let t=signingKey();if(t===void 0)return;let n=parseInboxHook(e);if(n?.resumeContext?.encryptionPublicKey===void 0)return;let r={...n,resumeContext:{...n.resumeContext,traceCarrier:void 0}},i=Buffer.from(JSON.stringify(r)).toString(`base64url`),a=`v1.${i}.${signature(i,t).toString(`base64url`)}`;return a.length<=MAX_HANDLE_LENGTH?a:void 0}function readInboxHandle(e){let t=signingKey();if(t===void 0||e.length>MAX_HANDLE_LENGTH)return;let[n,r,i,a]=e.split(`.`);if(n!==`v1`||r===void 0||i===void 0||a!==void 0)return;let o=signature(r,t),s=Buffer.from(i,`base64url`);if(o.length===s.length&&timingSafeEqual(o,s))try{return parseInboxHook(JSON.parse(Buffer.from(r,`base64url`).toString(`utf8`)))}catch{return}}export{issueInboxHandle,readInboxHandle};
@@ -16,11 +16,11 @@ export declare class StrandedSessionOwnerError extends Error {
16
16
  }
17
17
  /**
18
18
  * The single ingress path into a hook: refuses a session inbox whose owner
19
- * cannot execute before anything is committed, then resumes by token. Any
20
- * other hook resumes unchecked. Resuming by token rather than by the looked-up
21
- * hook keeps Workflow's delivery dedup, which a caller-supplied hook disables.
19
+ * cannot execute before anything is committed. Vercel can reuse a validated
20
+ * inbox handle: Workflow requires its guarded, deduplicated write endpoint.
21
+ * Only a definite refusal falls back to resolving the current token owner.
22
22
  */
23
- export declare function resumeRunnableHook(token: string, payload: unknown): Promise<Awaited<ReturnType<typeof resumeHook>>>;
23
+ export declare function resumeRunnableHook(token: string, payload: unknown, inbox?: string): Promise<Awaited<ReturnType<typeof resumeHook>>>;
24
24
  /**
25
25
  * Throws {@link StrandedSessionOwnerError} when the run holding a physical
26
26
  * session inbox token cannot execute. An unheld token passes: resuming it
@@ -1 +1 @@
1
- import{isSessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{findRetiredOwnerRun,routesToOwnerDeployment}from"#execution/session-inbox/runnable-owner.js";import{DevelopmentRunUnavailableError}from"#internal/workflow/development-run-unavailable-error.js";var StrandedSessionOwnerError=class extends Error{hook;ownerRun;constructor(e,t){super(`Session owner run "${e.runId}" is stranded.`),this.name=`StrandedSessionOwnerError`,this.hook=t,this.ownerRun=e}get ownerRunId(){return this.ownerRun.runId}get eveVersion(){return this.ownerRun.attributes[EVE_VERSION_ATTRIBUTE]}};async function resumeRunnableHook(e,t){return isSessionInboxHookToken(e)&&await assertRunnableSessionInbox(e),await resumeHook(e,t)}async function assertRunnableSessionInbox(e){let t=await getWorld();if(routesToOwnerDeployment(t))return;let n=await findSessionHookHolder(e);n!==void 0&&await assertRunnableOwner(t,n.runId,n.hook)}async function assertRunnableSessionOwner(e){let t=await getWorld();routesToOwnerDeployment(t)||await assertRunnableOwner(t,e.runId,e.hook)}async function findSessionHookHolder(e){try{let t=await getHookByToken(e);return{hook:t,runId:t.runId}}catch(e){if(HookNotFoundError.is(e))return;if(DevelopmentRunUnavailableError.is(e))return{runId:e.runId};throw e}}async function lookupSessionOwnerHook(e){try{return await getHookByToken(e)}catch(e){throw DevelopmentRunUnavailableError.is(e)&&await assertRunnableOwner(await getWorld(),e.runId),e}}async function assertRunnableOwner(e,t,n){let r=await findRetiredOwnerRun(e,t);if(r!==void 0)throw new StrandedSessionOwnerError(r,n)}export{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder,lookupSessionOwnerHook,resumeRunnableHook};
1
+ import{isSessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{readInboxHandle}from"#execution/session-inbox/handle.js";import{findRetiredOwnerRun,routesToOwnerDeployment}from"#execution/session-inbox/runnable-owner.js";import{DevelopmentRunUnavailableError}from"#internal/workflow/development-run-unavailable-error.js";var StrandedSessionOwnerError=class extends Error{hook;ownerRun;constructor(e,t){super(`Session owner run "${e.runId}" is stranded.`),this.name=`StrandedSessionOwnerError`,this.hook=t,this.ownerRun=e}get ownerRunId(){return this.ownerRun.runId}get eveVersion(){return this.ownerRun.attributes[EVE_VERSION_ATTRIBUTE]}};async function resumeRunnableHook(e,t,n){let r=n===void 0?void 0:await getWorld();if(n!==void 0&&n.length<=8192&&r!==void 0&&routesToOwnerDeployment(r)&&r.capabilities!==void 0&&`resolvedHookResume`in r.capabilities&&r.capabilities.resolvedHookResume===!0){let r=readInboxHandle(n),i=r?.token===e?r:void 0;if(i!==void 0)try{return await resumeHook(i,t)}catch(e){if(!HookNotFoundError.is(e))throw e}}return isSessionInboxHookToken(e)&&await assertRunnableSessionInbox(e),await resumeHook(e,t)}async function assertRunnableSessionInbox(e){let t=await getWorld();if(routesToOwnerDeployment(t))return;let n=await findSessionHookHolder(e);n!==void 0&&await assertRunnableOwner(t,n.runId,n.hook)}async function assertRunnableSessionOwner(e){let t=await getWorld();routesToOwnerDeployment(t)||await assertRunnableOwner(t,e.runId,e.hook)}async function findSessionHookHolder(e){try{let t=await getHookByToken(e);return{hook:t,runId:t.runId}}catch(e){if(HookNotFoundError.is(e))return;if(DevelopmentRunUnavailableError.is(e))return{runId:e.runId};throw e}}async function lookupSessionOwnerHook(e){try{return await getHookByToken(e)}catch(e){throw DevelopmentRunUnavailableError.is(e)&&await assertRunnableOwner(await getWorld(),e.runId),e}}async function assertRunnableOwner(e,t,n){let r=await findRetiredOwnerRun(e,t);if(r!==void 0)throw new StrandedSessionOwnerError(r,n)}export{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder,lookupSessionOwnerHook,resumeRunnableHook};
@@ -4,6 +4,7 @@ import type { DeliverHookPayload, SessionCommand, SessionTimeoutHookPayload } fr
4
4
  import { type SessionInboxAddress } from "#execution/session-inbox/address.js";
5
5
  export interface ResumedSessionInboxHook {
6
6
  readonly ownerRunId: string;
7
+ readonly inbox?: string;
7
8
  /** Lazy identity resolution; delivery never needs to decrypt hook metadata. */
8
9
  readonly sessionId: Promise<string>;
9
10
  }
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{SESSION_INBOX_SESSION_ID_METADATA_KEY,isSessionInboxAddress,sessionCommandHookToken,sessionHandoffMarkerToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{assertRunnableSessionOwner,lookupSessionOwnerHook,resumeRunnableHook}from"#execution/session-inbox/owner.js";import{withPreV27Answers}from"#execution/session-inbox/pre-v27.js";import{UnsupportedLegacySessionError,resolveLegacyInbox,resumeLegacyInbox}from"#execution/legacy-session/inbox.js";async function resumeSessionInbox(e,t){t=withPreV27Answers(t);let n=logicalSessionToken(e),r=typeof e==`string`?void 0:e.sessionId,i=Date.now()+5e3;for(;;){let e;try{e=await resumeRunnableHook(sessionInboxHookToken(n),t)}catch(e){if(!HookNotFoundError.is(e))throw e;if(await waitWhileHandoffInProgress(n,i))continue;if(t.kind===`session-failure`||t.kind===`session-prewarm`)throw e;return await resumeLegacyInbox(n,t).catch(rethrowUnsupportedAsNotFound)}let a;return{ownerRunId:e.runId,get sessionId(){return a??=(async()=>{try{return r??requireSessionId(await e.metadata)}catch(e){throw new AcceptedSessionIdentityError(e)}})()}}}}var SessionHandoffPendingError=class extends Error{constructor(e){super(`Session address "${e}" is still changing owners. Nothing was delivered; retry the request.`),this.name=`SessionHandoffPendingError`}},AcceptedSessionIdentityError=class extends Error{constructor(e){super(`Session command accepted, but its session identity could not be resolved.`,{cause:e}),this.name=`AcceptedSessionIdentityError`}};function requireSessionId(e){let t=isObject(e)?e[SESSION_INBOX_SESSION_ID_METADATA_KEY]:void 0;if(typeof t!=`string`||t.length===0)throw Error(`Session hook metadata is missing its session ID.`);return t}async function resolveSessionInbox(e){try{return{sessionId:requireSessionId(await(await getHookByToken(sessionInboxHookToken(e))).metadata)}}catch(t){if(!HookNotFoundError.is(t))throw t;return{sessionId:(await resolveLegacyInbox(e)).sessionId}}}function rethrowUnsupportedAsNotFound(e){throw e instanceof UnsupportedLegacySessionError?new HookNotFoundError(e.message):e}function logicalSessionToken(e){if(typeof e==`string`)return e;if(!isSessionInboxAddress(e))throw Error(`Session inbox target has an invalid address.`);return sessionCommandHookToken(e.sessionId)}async function waitWhileHandoffInProgress(e,t){let n;try{n=await lookupSessionOwnerHook(sessionHandoffMarkerToken(e))}catch(e){if(HookNotFoundError.is(e))return!1;throw e}if(Date.now()>=t)throw await assertRunnableSessionOwner({hook:n,runId:n.runId}),new SessionHandoffPendingError(e);return await new Promise(e=>setTimeout(e,20)),!0}export{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,requireSessionId,resolveSessionInbox,resumeSessionInbox};
1
+ import{isObject}from"#shared/guards.js";import{SESSION_INBOX_SESSION_ID_METADATA_KEY,isSessionInboxAddress,sessionCommandHookToken,sessionHandoffMarkerToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{assertRunnableSessionOwner,lookupSessionOwnerHook,resumeRunnableHook}from"#execution/session-inbox/owner.js";import{issueInboxHandle}from"#execution/session-inbox/handle.js";import{withPreV27Answers}from"#execution/session-inbox/pre-v27.js";import{UnsupportedLegacySessionError,resolveLegacyInbox,resumeLegacyInbox}from"#execution/legacy-session/inbox.js";async function resumeSessionInbox(e,t){t=withPreV27Answers(t);let n=logicalSessionToken(e),r=typeof e==`string`?void 0:e.sessionId,i=Date.now()+5e3;for(;;){let a;try{a=await resumeRunnableHook(sessionInboxHookToken(n),t,typeof e==`string`?void 0:e.inbox)}catch(e){if(!HookNotFoundError.is(e))throw e;if(await waitWhileHandoffInProgress(n,i))continue;if(t.kind===`session-failure`||t.kind===`session-prewarm`)throw e;return await resumeLegacyInbox(n,t).catch(rethrowUnsupportedAsNotFound)}let o;return{ownerRunId:a.runId,inbox:issueInboxHandle(a),get sessionId(){return o??=(async()=>{try{return r??requireSessionId(await a.metadata)}catch(e){throw new AcceptedSessionIdentityError(e)}})()}}}}var SessionHandoffPendingError=class extends Error{constructor(e){super(`Session address "${e}" is still changing owners. Nothing was delivered; retry the request.`),this.name=`SessionHandoffPendingError`}},AcceptedSessionIdentityError=class extends Error{constructor(e){super(`Session command accepted, but its session identity could not be resolved.`,{cause:e}),this.name=`AcceptedSessionIdentityError`}};function requireSessionId(e){let t=isObject(e)?e[SESSION_INBOX_SESSION_ID_METADATA_KEY]:void 0;if(typeof t!=`string`||t.length===0)throw Error(`Session hook metadata is missing its session ID.`);return t}async function resolveSessionInbox(e){try{return{sessionId:requireSessionId(await(await getHookByToken(sessionInboxHookToken(e))).metadata)}}catch(t){if(!HookNotFoundError.is(t))throw t;return{sessionId:(await resolveLegacyInbox(e)).sessionId}}}function rethrowUnsupportedAsNotFound(e){throw e instanceof UnsupportedLegacySessionError?new HookNotFoundError(e.message):e}function logicalSessionToken(e){if(typeof e==`string`)return e;if(!isSessionInboxAddress(e))throw Error(`Session inbox target has an invalid address.`);return sessionCommandHookToken(e.sessionId)}async function waitWhileHandoffInProgress(e,t){let n;try{n=await lookupSessionOwnerHook(sessionHandoffMarkerToken(e))}catch(e){if(HookNotFoundError.is(e))return!1;throw e}if(Date.now()>=t)throw await assertRunnableSessionOwner({hook:n,runId:n.runId}),new SessionHandoffPendingError(e);return await new Promise(e=>setTimeout(e,20)),!0}export{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,requireSessionId,resolveSessionInbox,resumeSessionInbox};
@@ -1 +1 @@
1
- import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{reply:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({signal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.84.0//runAgentRouterTask`;export{runAgentRouterTask};
1
+ import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{reply:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({signal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.84.1//runAgentRouterTask`;export{runAgentRouterTask};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{SessionPredecessorKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{validateToolStubTargets}from"#tool-stubs/validate-targets.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{assertSessionHistoryReadable,readSessionEventHistory,readSessionEventStream,readSessionRecordHistory,readSessionRecords,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder}from"#execution/session-inbox/owner.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{EVE_PREWARM_ATTRIBUTE,EVE_VERSION_ATTRIBUTE,buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{endStrandedSession}from"#execution/session-inbox/end-stranded-session.js";import{SESSION_HOOK_HANDOVER_TIMEOUT_MS,waitForSessionHooksRelease}from"#execution/session-inbox/hook-release.js";import{CONNECTION_EVENT_DELIVERY_WORKFLOW_NAME,CONNECTION_EVENT_WORKFLOW_NAME,SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";import{readRemoteChildBinding}from"#execution/child-binding.js";import{prewarmWorkflowSession}from"#execution/session-prewarm.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/eve/agent-trace-context.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`},connectionEventWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${CONNECTION_EVENT_WORKFLOW_NAME}`},connectionEventDeliveryWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${CONNECTION_EVENT_DELIVERY_WORKFLOW_NAME}`};function createWorkflowRuntime(e){let startSession=async(t,n)=>{validateDeliveryIdempotencyKey(t.idempotencyKey),t.input.message!==void 0&&t.delivery===void 0&&(t={...t,delivery:createChannelDeliveryMetadata({channelKind:t.adapter.kind,channelName:t.channelName??t.adapter.kind,requestId:t.requestId})});let r=t.continuationConflictCommand;r!==void 0&&r.delivery===void 0&&(t={...t,continuationConflictCommand:{...r,delivery:t.delivery}});let i=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId});t.toolStubs!==void 0&&t.toolStubs.rootSessionId===void 0&&validateToolStubTargets(t.toolStubs.rules,i.graph);let a=buildRunContext({agentSessionRuntimeOverrides:e.agentSessionRuntimeOverrides,bundle:i,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t});n!==void 0&&a.set(SessionPredecessorKey,n);let o=resolveEffectiveAgentRuntime(i,a),s=initializeSessionInstrumentation({agentName:o.turnAgent.id,ctx:a}),c=o.limits?.sessionTimeoutMs,l=i.resolvedAgent.config?.experimental?.workflow?.retention??(s.action===`record`&&s.recordInputs&&s.recordOutputs?void 0:0),u=serializeContext(a),d=readParentLineage(u),f={idempotencyKey:t.idempotencyKey,kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:u};t.continuationConflictCommand!==void 0&&(f.continuationConflictCommand=t.continuationConflictCommand),c!==void 0&&(f.sessionTimeoutMs=c),l!==void 0&&(f.retention=l);let p={...d.sessionId===void 0?buildSessionAttributes({serializedContext:u}):buildSubagentRootAttributes({identity:{nodeId:i.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:d.callId,parentSessionId:d.sessionId,parentTurnId:d.turnId,rootSessionId:d.rootSessionId??d.sessionId,serializedContext:u}),[EVE_PREWARM_ATTRIBUTE]:`1`,...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},m;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(p)};l!==void 0&&(e.experimental_retention=l),m=await startWorkflowOnDeployment(workflowEntryReference,[f],f.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let h=m.runId;if(t.idempotencyKey!==void 0&&t.continuationToken!==void 0){let e=await pollUntil(()=>resolveContinuation(t.continuationToken),SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(e===void 0)throw Error(`Delivery accepted, but its session identity is not ready. Retry with the same idempotencyKey.`);h=e.sessionId}let g,getEvents=()=>(g??=readSessionEventStream(h),g);return{get events(){return getEvents()},sessionId:h,...t.delivery!==void 0&&{deliveryId:t.delivery.deliveryId}}};return{async createSession(e){return await startSession(e)},async dispatchContinuation(e){let{continuationToken:t,successor:n}=e,r=identifyCommand(e.command);try{return await dispatchWorkflowCommand(t,r)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;if(r.kind!==`send`||n===void 0)return await settleStrandedCommand(t,r,e);if((r.payload.answers?.length??0)>0)throw sessionStrandedError(e,`Its pending requests can no longer be answered; send a new message to start a fresh session.`);let i=await endStrandedSession(e,t,`message`);return{sessionId:(await startSession({...n,delivery:r.delivery},{sessionId:i})).sessionId,deliveryId:r.delivery?.deliveryId,status:`accepted`}}},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){return t?.follow===!1?readSessionEventHistory(e,t.startIndex,t.signal):(await assertFollowableSession(e),readSessionEventStream(e,t?.startIndex,t?.signal))},async getLineStream(e,t){return t?.follow===!1?readSessionRecordHistory(e,t.startIndex):(await assertFollowableSession(e),readSessionRecords(e,t?.startIndex))},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},async readChildBinding(e,t){return await readRemoteChildBinding(e,t)},async hasRunnableOwner(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await findSessionHookHolder(t);if(n===void 0)return!1;try{return await assertRunnableSessionOwner(n),!0}catch(e){if(e instanceof StrandedSessionOwnerError)return!1;throw e}},resolveContinuation}}async function dispatchWorkflowCommand(e,t){if(t.kind===`prewarm`)return typeof e==`string`?{status:`unsupported`}:await prewarmWorkflowSession(e.sessionId,t.targetDeploymentId);let n;try{let r=await resumeSessionInbox(e,t);n={runId:r.ownerRunId,sessionId:await r.sessionId}}catch(n){if(n instanceof StrandedSessionOwnerError)throw n;let r=t.kind===`send`&&typeof e!=`string`,i={status:`session_not_active`,retryable:!0};if(n instanceof SessionHandoffPendingError){if(r)return i;throw n}if(isInactiveCommandTarget(n))return r&&await isRunActive(e.sessionId)?i:inactiveCommandResult(t);throw logError(log,`failed to dispatch session command`,n,{command:t.kind,token:e}),n}return t.kind===`reset`&&await waitForSessionHooksRelease([sessionCommandHookToken(n.sessionId),logicalSessionToken(e)],{ownerRunId:n.runId,sessionId:n.sessionId}),activeCommandResult(t,n.sessionId)}async function settleStrandedCommand(e,t,n){switch(t.kind){case`reset`:return{previousSessionId:await endStrandedSession(n,e,`reset`,t),status:`reset`};case`send`:case`clear`:throw sessionStrandedError(n);default:return inactiveCommandResult(t)}}async function assertFollowableSession(e){try{await Promise.all([assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(e))),assertSessionHistoryReadable(e)])}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}}function sessionStrandedError(e,t){let n=e.eveVersion===void 0?{}:{eveVersion:e.eveVersion};return new SessionStrandedError(n,describeStrandedSession(n,t))}function activeCommandResult(e,t){return e.kind===`reset`?{previousSessionId:t,status:`reset`}:e.kind===`send`&&e.delivery!==void 0?{sessionId:t,status:`accepted`,deliveryId:e.delivery.deliveryId}:{sessionId:t,status:`accepted`}}function inactiveCommandResult(e){return e.kind===`send`?{status:`session_not_active`}:e.kind===`cancel`?{status:`no_active_turn`}:{status:`no_active_session`}}async function dispatchWorkflowSessionCommand(e){let t={sessionId:e.sessionId},n=identifyCommand(e.command);try{return await dispatchWorkflowCommand(t,n)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;return await settleStrandedCommand(t,n,e)}}async function isRunActive(e){try{let t=await getRun(e).status;return t===`pending`||t===`running`}catch(e){if(isInactiveCommandTarget(e))return!1;throw e}}function isInactiveCommandTarget(e){if(e instanceof AcceptedSessionIdentityError)return!1;if(HookNotFoundError.is(e))return!0;for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function resolveContinuation(e,t){let n;try{n=await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}if(t?.runnable!==!0)return n;try{await assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(n.sessionId)))}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}return n}async function waitForCommandHookOwner(e){let t=await pollUntil(async()=>{try{return normalizeWorkflowHook(await getHookByToken(e))}catch(e){if(!HookNotFoundError.is(e))throw e;return}},SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(t===void 0)throw new HookNotFoundError(e);return t}async function waitForSessionInbox(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await pollUntil(async()=>await findSessionHookHolder(t)!==void 0||!await hasRunEnded(e)&&void 0,SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(n===void 0)throw Error(`Session "${e}" did not start taking commands within ${SESSION_HOOK_HANDOVER_TIMEOUT_MS/1e3} seconds.`);return n}async function pollUntil(e,t){let n=Date.now()+t;for(let t=20;;t=Math.min(t*2,200)){let r=await e();if(r!==void 0||Date.now()>=n)return r;await new Promise(e=>setTimeout(e,t))}}async function hasRunEnded(e){try{let t=await getRun(e).status;return t!==`pending`&&t!==`running`}catch(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t))return!1;if(isInactiveCommandTarget(e))return!0;throw e}}async function startWorkflowOnCurrentDeployment(e,t,n){return await startWorkflowOnDeployment(e,t,await resolveCurrentWorkflowDeploymentId(),n)}async function startWorkflowOnDeployment(e,t,n,r){return await withWorkflowStartContext(async()=>{if(n.length===0||n===`latest`)throw Error(`Workflow starts require an exact deployment id.`);return await start(e,t,{...r,allowReservedAttributes:!0,attributes:{...r?.attributes,[EVE_VERSION_ATTRIBUTE]:EVE_PACKAGE_INFO.version},deploymentId:n})})}async function resolveCurrentWorkflowDeploymentId(){let e=process.env.VERCEL_DEPLOYMENT_ID?.trim()||await(await getWorld()).getDeploymentId();if(e.length===0||e===`latest`)throw Error(`Workflow runtime could not resolve an exact deployment id.`);return e}async function withWorkflowStartContext(e){let t=context.active(),n=isAgentTraceContext(t)?trace.deleteSpan(t):t;return await context.with(n,e)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}function identifyCommand(e){if(e.kind!==`send`||e.delivery!==void 0)return e;let t=e.caller===void 0?e.schedule===void 0?`http`:`schedule`:`subagent`;return{...e,delivery:createChannelDeliveryMetadata({channelKind:t,channelName:t,requestId:e.requestId})}}export{connectionEventDeliveryWorkflowReference,connectionEventWorkflowReference,createWorkflowRuntime,dispatchWorkflowSessionCommand,hasRunEnded,pollUntil,resolveContinuation,sessionTimeoutWorkflowReference,startWorkflowOnCurrentDeployment,startWorkflowOnDeployment,waitForCommandHookOwner,waitForSessionInbox,workflowEntryReference,workflowToolRunWorkflowReference};
1
+ import{createLogger,logError}from"#internal/logging.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{SessionPredecessorKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{validateToolStubTargets}from"#tool-stubs/validate-targets.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{assertSessionHistoryReadable,readSessionEventHistory,readSessionEventStream,readSessionRecordHistory,readSessionRecords,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder}from"#execution/session-inbox/owner.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{EVE_PREWARM_ATTRIBUTE,EVE_VERSION_ATTRIBUTE,buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{endStrandedSession}from"#execution/session-inbox/end-stranded-session.js";import{SESSION_HOOK_HANDOVER_TIMEOUT_MS,waitForSessionHooksRelease}from"#execution/session-inbox/hook-release.js";import{CONNECTION_EVENT_DELIVERY_WORKFLOW_NAME,CONNECTION_EVENT_WORKFLOW_NAME,SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";import{readRemoteChildBinding}from"#execution/child-binding.js";import{prewarmWorkflowSession}from"#execution/session-prewarm.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/eve/agent-trace-context.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`},connectionEventWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${CONNECTION_EVENT_WORKFLOW_NAME}`},connectionEventDeliveryWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${CONNECTION_EVENT_DELIVERY_WORKFLOW_NAME}`};function createWorkflowRuntime(e){let startSession=async(t,n)=>{validateDeliveryIdempotencyKey(t.idempotencyKey),t.input.message!==void 0&&t.delivery===void 0&&(t={...t,delivery:createChannelDeliveryMetadata({channelKind:t.adapter.kind,channelName:t.channelName??t.adapter.kind,requestId:t.requestId})});let r=t.continuationConflictCommand;r!==void 0&&r.delivery===void 0&&(t={...t,continuationConflictCommand:{...r,delivery:t.delivery}});let i=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId});t.toolStubs!==void 0&&t.toolStubs.rootSessionId===void 0&&validateToolStubTargets(t.toolStubs.rules,i.graph);let a=buildRunContext({agentSessionRuntimeOverrides:e.agentSessionRuntimeOverrides,bundle:i,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t});n!==void 0&&a.set(SessionPredecessorKey,n);let o=resolveEffectiveAgentRuntime(i,a),s=initializeSessionInstrumentation({agentName:o.turnAgent.id,ctx:a}),c=o.limits?.sessionTimeoutMs,l=i.resolvedAgent.config?.experimental?.workflow?.retention??(s.action===`record`&&s.recordInputs&&s.recordOutputs?void 0:0),u=serializeContext(a),d=readParentLineage(u),f={idempotencyKey:t.idempotencyKey,kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:u};t.continuationConflictCommand!==void 0&&(f.continuationConflictCommand=t.continuationConflictCommand),c!==void 0&&(f.sessionTimeoutMs=c),l!==void 0&&(f.retention=l);let p={...d.sessionId===void 0?buildSessionAttributes({serializedContext:u}):buildSubagentRootAttributes({identity:{nodeId:i.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:d.callId,parentSessionId:d.sessionId,parentTurnId:d.turnId,rootSessionId:d.rootSessionId??d.sessionId,serializedContext:u}),[EVE_PREWARM_ATTRIBUTE]:`1`,...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},m;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(p)};l!==void 0&&(e.experimental_retention=l),m=await startWorkflowOnDeployment(workflowEntryReference,[f],f.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let h=m.runId;if(t.idempotencyKey!==void 0&&t.continuationToken!==void 0){let e=await pollUntil(()=>resolveContinuation(t.continuationToken),SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(e===void 0)throw Error(`Delivery accepted, but its session identity is not ready. Retry with the same idempotencyKey.`);h=e.sessionId}let g,getEvents=()=>(g??=readSessionEventStream(h),g);return{get events(){return getEvents()},sessionId:h,...t.delivery!==void 0&&{deliveryId:t.delivery.deliveryId}}};return{async createSession(e){return await startSession(e)},async dispatchContinuation(e){let{continuationToken:t,successor:n}=e,r=identifyCommand(e.command);try{return await dispatchWorkflowCommand(t,r)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;if(r.kind!==`send`||n===void 0)return await settleStrandedCommand(t,r,e);if((r.payload.answers?.length??0)>0)throw sessionStrandedError(e,`Its pending requests can no longer be answered; send a new message to start a fresh session.`);let i=await endStrandedSession(e,t,`message`);return{sessionId:(await startSession({...n,delivery:r.delivery},{sessionId:i})).sessionId,deliveryId:r.delivery?.deliveryId,status:`accepted`}}},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){return t?.follow===!1?readSessionEventHistory(e,t.startIndex,t.signal):(await assertFollowableSession(e),readSessionEventStream(e,t?.startIndex,t?.signal))},async getLineStream(e,t){return t?.follow===!1?readSessionRecordHistory(e,t.startIndex):(await assertFollowableSession(e),readSessionRecords(e,t?.startIndex))},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},async readChildBinding(e,t){return await readRemoteChildBinding(e,t)},async hasRunnableOwner(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await findSessionHookHolder(t);if(n===void 0)return!1;try{return await assertRunnableSessionOwner(n),!0}catch(e){if(e instanceof StrandedSessionOwnerError)return!1;throw e}},resolveContinuation}}async function dispatchWorkflowCommand(e,t){if(t.kind===`prewarm`)return typeof e==`string`?{status:`unsupported`}:await prewarmWorkflowSession(e.sessionId,t.targetDeploymentId);let n,r;try{let i=await resumeSessionInbox(e,t);r=i.inbox,n={runId:i.ownerRunId,sessionId:await i.sessionId}}catch(n){if(n instanceof StrandedSessionOwnerError)throw n;let r=t.kind===`send`&&typeof e!=`string`,i={status:`session_not_active`,retryable:!0};if(n instanceof SessionHandoffPendingError){if(r)return i;throw n}if(isInactiveCommandTarget(n))return r&&await isRunActive(e.sessionId)?i:inactiveCommandResult(t);throw logError(log,`failed to dispatch session command`,n,{command:t.kind,token:e}),n}t.kind===`reset`&&await waitForSessionHooksRelease([sessionCommandHookToken(n.sessionId),logicalSessionToken(e)],{ownerRunId:n.runId,sessionId:n.sessionId});let i=activeCommandResult(t,n.sessionId);return i.status===`accepted`?{...i,inbox:r}:i}async function settleStrandedCommand(e,t,n){switch(t.kind){case`reset`:return{previousSessionId:await endStrandedSession(n,e,`reset`,t),status:`reset`};case`send`:case`clear`:throw sessionStrandedError(n);default:return inactiveCommandResult(t)}}async function assertFollowableSession(e){try{await Promise.all([assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(e))),assertSessionHistoryReadable(e)])}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}}function sessionStrandedError(e,t){let n=e.eveVersion===void 0?{}:{eveVersion:e.eveVersion};return new SessionStrandedError(n,describeStrandedSession(n,t))}function activeCommandResult(e,t){return e.kind===`reset`?{previousSessionId:t,status:`reset`}:e.kind===`send`&&e.delivery!==void 0?{sessionId:t,status:`accepted`,deliveryId:e.delivery.deliveryId}:{sessionId:t,status:`accepted`}}function inactiveCommandResult(e){return e.kind===`send`?{status:`session_not_active`}:e.kind===`cancel`?{status:`no_active_turn`}:{status:`no_active_session`}}async function dispatchWorkflowSessionCommand(e){let t={sessionId:e.sessionId,inbox:e.inbox},n=identifyCommand(e.command);try{return await dispatchWorkflowCommand(t,n)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;return await settleStrandedCommand(t,n,e)}}async function isRunActive(e){try{let t=await getRun(e).status;return t===`pending`||t===`running`}catch(e){if(isInactiveCommandTarget(e))return!1;throw e}}function isInactiveCommandTarget(e){if(e instanceof AcceptedSessionIdentityError)return!1;if(HookNotFoundError.is(e))return!0;for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function resolveContinuation(e,t){let n;try{n=await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}if(t?.runnable!==!0)return n;try{await assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(n.sessionId)))}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}return n}async function waitForCommandHookOwner(e){let t=await pollUntil(async()=>{try{return normalizeWorkflowHook(await getHookByToken(e))}catch(e){if(!HookNotFoundError.is(e))throw e;return}},SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(t===void 0)throw new HookNotFoundError(e);return t}async function waitForSessionInbox(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await pollUntil(async()=>await findSessionHookHolder(t)!==void 0||!await hasRunEnded(e)&&void 0,SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(n===void 0)throw Error(`Session "${e}" did not start taking commands within ${SESSION_HOOK_HANDOVER_TIMEOUT_MS/1e3} seconds.`);return n}async function pollUntil(e,t){let n=Date.now()+t;for(let t=20;;t=Math.min(t*2,200)){let r=await e();if(r!==void 0||Date.now()>=n)return r;await new Promise(e=>setTimeout(e,t))}}async function hasRunEnded(e){try{let t=await getRun(e).status;return t!==`pending`&&t!==`running`}catch(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t))return!1;if(isInactiveCommandTarget(e))return!0;throw e}}async function startWorkflowOnCurrentDeployment(e,t,n){return await startWorkflowOnDeployment(e,t,await resolveCurrentWorkflowDeploymentId(),n)}async function startWorkflowOnDeployment(e,t,n,r){return await withWorkflowStartContext(async()=>{if(n.length===0||n===`latest`)throw Error(`Workflow starts require an exact deployment id.`);return await start(e,t,{...r,allowReservedAttributes:!0,attributes:{...r?.attributes,[EVE_VERSION_ATTRIBUTE]:EVE_PACKAGE_INFO.version},deploymentId:n})})}async function resolveCurrentWorkflowDeploymentId(){let e=process.env.VERCEL_DEPLOYMENT_ID?.trim()||await(await getWorld()).getDeploymentId();if(e.length===0||e===`latest`)throw Error(`Workflow runtime could not resolve an exact deployment id.`);return e}async function withWorkflowStartContext(e){let t=context.active(),n=isAgentTraceContext(t)?trace.deleteSpan(t):t;return await context.with(n,e)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}function identifyCommand(e){if(e.kind!==`send`||e.delivery!==void 0)return e;let t=e.caller===void 0?e.schedule===void 0?`http`:`schedule`:`subagent`;return{...e,delivery:createChannelDeliveryMetadata({channelKind:t,channelName:t,requestId:e.requestId})}}export{connectionEventDeliveryWorkflowReference,connectionEventWorkflowReference,createWorkflowRuntime,dispatchWorkflowSessionCommand,hasRunEnded,pollUntil,resolveContinuation,sessionTimeoutWorkflowReference,startWorkflowOnCurrentDeployment,startWorkflowOnDeployment,waitForCommandHookOwner,waitForSessionInbox,workflowEntryReference,workflowToolRunWorkflowReference};
@@ -73,7 +73,9 @@ export declare class ModelCaller {
73
73
  /**
74
74
  * A failed compaction fails the step, whatever recovery the call attempted.
75
75
  * One that left the history over the limit ends the session with its message;
76
- * any other failure throws.
76
+ * any other failure is reported like a failed model call, since its summary
77
+ * call already retried. Rethrowing would make the workflow replay the step and
78
+ * then end the session.
77
79
  */
78
80
  failIfCompactionFailed(): Promise<StepResult | undefined>;
79
81
  /** Steering interrupted the call: the step ends with what it committed, and runs again. */
@@ -1 +1 @@
1
- import{modelCallErrorInfo,reportCompactionFailure}from"./failure.js";import{buildGatewayAttributionHeaders,withGatewayTraceContext}from"./model.js";import{isEmptyModelResponse,recoverModelCall,rethrowNoOutputAsEmptyResponse}from"./recovery.js";import{modelInstructions,requestMessages,withTrailingUserNote}from"./request.js";import{answerSkippedToolCalls,extractToolResultCallIds,withCallResults}from"./response.js";import{ALLOW_RETRY,STOP_RETRY,runModelCallWithRetries}from"./retry.js";import{withUniqueCallIds}from"./unique-call-ids.js";import{prepareModelTools}from"./tools.js";import{extractGatewayCostUsd,extractTokenUsageDelta}from"./usage.js";import{ToolLoopAgent,isStepCount}from"ai";import{createLogger,logError}from"#internal/logging.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{REPLY_TOOL_NAME}from"#protocol/reply-tool.js";import{activeTurnId}from"#harness/session-machine/view.js";import{hydrateSandboxAttachments,moveToolResultFilesToUserMessages}from"#harness/attachment-staging.js";import{workingTaskIds}from"#execution/tasks/model-step.js";import{historyCallNames,toEntryStep,toEntryStream}from"#harness/execute-call.js";import{discardAttempt}from"#harness/session-machine/transitions.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{fact,usageOf}from"#harness/facts.js";import{nextChangeId,nextRunId}from"#protocol/session-projection.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{compactedTurnInput,maybeCompact}from"#harness/compaction/step.js";import{CompactionOverLimitError}from"#harness/compaction/over-limit-error.js";import{estimateTokens}from"#harness/token-estimate.js";import{withoutPromptMeasurement}from"#harness/compaction/engine.js";import{requireSessionModelReference}from"#harness/types.js";import{ContentFilteredModelResponseError,EmptyModelResponseError,ModelStreamStalledError}from"#harness/model-call/errors.js";import{resolveModelProfile}from"#harness/model-profile.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{NO_INLINE_CALLS,executeInlineCalls}from"#harness/call-executor.js";import{emitStreamContent}from"#harness/emission.js";import{estimateRequestEnvelope}from"#harness/request-envelope.js";import{compactPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{buildStepHooks,emitStepActions,readGatewayGenerationId}from"#harness/step-hooks.js";const environment=process.env.NODE_ENV??`unknown`,log=createLogger(`harness.tool-loop`),MODEL_OUTPUT_TIMEOUT_MS=6e5;var ModelCaller=class{profile;attributionHeaders;projectedMessages;turnMessages;request;modelMessages=[];requestEnvelopeTokens=0;interruptedUsage;compactionFailure;attemptIndex=0;started;acceptedOutput=!1;step;prompt;input;constructor(e,t,n){this.step=e,this.prompt=t,this.input=n,this.profile=resolveModelProfile(n.model,requireSessionModelReference(e.session).promptCache),this.attributionHeaders=buildGatewayAttributionHeaders(this.profile,e.config.runtimeIdentity),this.projectedMessages=n.projectedMessages,this.turnMessages=n.turnMessages,this.request=this.buildRequest()}async call(){let e={},t={policies:[()=>this.compactionFailure===void 0?ALLOW_RETRY:STOP_RETRY],onRetry:e=>this.prepareRetry(e),sessionId:this.step.session.sessionId,turnId:this.step.position().turnId};for(;;)try{return await runModelCallWithRetries(()=>this.attempt(e),t,this.input.generation.signal)}catch(n){if(this.compactionFailure!==void 0)throw this.compactionFailure.error;throwIfTurnAborted(this.step.config.abortSignal),this.input.generation.check();let r=recoverModelCall(n,e,t);if(r===void 0)throw n;await this.prepareRetry(n),e=r}}async prepareRetry(e){let{step:t}=this,n=t.position().runId,r=this.started;if(this.started=void 0,n!==void 0){if(this.acceptedOutput){await t.apply(discardAttempt(t.view(),{ending:`retried`,runId:n})),this.acceptedOutput=!1,await this.input.newRun();return}r!==void 0&&await t.apply([fact(`model.retried`,{attempt:r,error:modelCallErrorInfo(e),runId:n})])}}async failIfCompactionFailed(){if(this.compactionFailure===void 0)return;let{error:e}=this.compactionFailure;if(e instanceof CompactionOverLimitError)return reportCompactionFailure(this.step,e);throw e}async steered(){let{step:e}=this;throwIfTurnAborted(e.config.abortSignal),this.input.generation.end(),e.ctx?.set(HistoryStateKey,this.request.historyState);let t=e.position().runId;return t!==void 0&&await e.apply(discardAttempt(e.view(),{ending:`steered`,runId:t,usage:this.interruptedUsage===void 0?void 0:usageOf(this.interruptedUsage)})),{next:e.runStep,session:{...e.session,history:[...this.request.history]},steered:!0}}clearInterruptedUsage(){this.interruptedUsage=void 0}buildRequest(){return requestMessages(this.step,{catalog:this.input.catalog,messages:this.prompt.messages,pendingApprovalsNote:this.input.pendingApprovalsNote,projectedMessages:this.projectedMessages,turnMessages:this.turnMessages})}instructions(e){return modelInstructions({anthropicCache:this.profile.anthropicCache,extraSystemNote:e,session:this.step.session,systemMessages:this.request.systemMessages})}async prepare(e){let t=await prepareModelTools(this.step,{catalog:this.input.catalog,disabledProviderTools:e.disabledProviderTools,profile:this.profile});return this.request=this.buildRequest(),this.requestEnvelopeTokens=await estimateRequestEnvelope({history:this.projectedMessages,instructions:this.instructions(e.extraSystemNote),messages:withTrailingUserNote(this.request.nonSystemMessages,e.trailingUserNote),tools:t}),t}async compact(e,t){let{step:n,prompt:r}=this,{config:i}=n,a;try{let{projection:e}=n.view();if(a=await maybeCompact({abortSignal:i.abortSignal,auth:n.ctx?.get(AuthKey)??null,change:{changeId:nextChangeId(e),summaryRunId:nextRunId(e),turnId:n.position().turnId},ctx:n.ctx,emissionState:n.position(),messages:[...r.messages],model:this.input.model,promptMessages:withClientContext(r),publish:n.publish,view:()=>n.view().projection.view,requestEnvelopeTokens:this.requestEnvelopeTokens,resolveModel:i.resolveModel,runtimeIdentity:i.runtimeIdentity,session:n.session,prepareTelemetry:e=>n.instrumentation?.prepareAttempt({runId:e,attempt:0,turnId:activeTurnId(n.position())}).telemetry,traceContextHeaders:n.instrumentation?.gatewayTraceContextHeaders}),n.session=a.session,a.failure!==void 0)throw a.failure.error}catch(e){throw this.compactionFailure={error:e},e}if(!a.compacted)return t;compactPrompt(n,r,a.messages);let o=compactedTurnInput(r.messages);return this.turnMessages=o===void 0?this.input.turnMessages:[...this.input.turnMessages,o],n.session={...n.session,compaction:withoutPromptMeasurement(n.session.compaction)},this.projectedMessages=projectPrompt(r),await this.prepare(e)}async attempt(e){let{step:t}=this,{generation:n,model:r}=this.input,i=await this.compact(e,await this.prepare(e)),a=this.attemptIndex++;await this.input.startRun(a),this.started=a,this.requestEnvelopeTokens=Math.max(0,this.requestEnvelopeTokens-(estimateTokens(this.request.history)-estimateTokens(this.prompt.messages))),n.begin(),this.modelMessages=await hydrateSandboxAttachments(this.request.nonSystemMessages),this.profile.filesOutsideToolResults&&(this.modelMessages=moveToolResultFilesToUserMessages(this.modelMessages));let o=this.instructions(e.extraSystemNote),s=t.instrumentation?.resolveRuntimeContext({attempt:a,emissionState:t.position(),environment,modelInput:{instructions:o,messages:this.modelMessages},session:t.session})??{};e.retryReason&&(s[`eve.retry.reason`]=e.retryReason);let c=withTrailingUserNote(this.modelMessages,e.trailingUserNote),l=t.position(),u=t.instrumentation?.prepareAttempt({isFrameworkTool:e=>t.frameworkToolNames.has(e),runId:l.runId,attempt:a,runtimeContext:s,stepIndex:l.stepIndex,turnId:activeTurnId(l)}),d=buildStepHooks({auth:t.ctx?.get(AuthKey)??null,profile:this.profile,session:t.session}),f={headers:this.attributionHeaders,instructions:o,model:withUniqueCallIds(withGatewayTraceContext(r,this.profile,this.step.instrumentation?.gatewayTraceContextHeaders),[...Object.keys(t.view().projection.view.calls),...historyCallNames(c).keys()]),onLanguageModelCallEnd:e=>{n.interrupted||(this.interruptedUsage=extractTokenUsageDelta({costUsd:extractGatewayCostUsd(e.providerMetadata),usage:e.usage}))},onError(e){n.interrupted||summarizeKnownError(e.error)?.tags.includes(`config`)!==!0&&logError(log,`tool-loop stream error`,e.error)},onStepEnd:d.onStepEnd,onStepStart:d.onStepStart,prepareStep:d.prepareStep,reasoning:t.session.agent.modelReference?.reasoning??t.session.agent.reasoning,runtimeContext:s,stopWhen:isStepCount(1),telemetry:u?.telemetry,timeout:{chunkMs:MODEL_OUTPUT_TIMEOUT_MS,firstChunkMs:MODEL_OUTPUT_TIMEOUT_MS},tools:i},p=new ToolLoopAgent(f);try{return await this.stream(p,c,d.stepResult,u?.telemetry)}catch(e){if(n.check(),isAbortError(e)&&!n.signal.aborted)throw new ModelStreamStalledError({cause:e});return rethrowNoOutputAsEmptyResponse(e)}}async stream(e,t,n,r){let{step:i}=this,{catalog:a,generation:o}=this.input,s=new Set([REPLY_TOOL_NAME]),c=await e.stream({abortSignal:o.signal,messages:t}),{invalidInputToolCallIds:l,trailingInlineToolResultParts:u}=await emitStreamContent(async(e,t)=>{this.acceptedOutput=!0,await i.publish(e,t)},i.position(),toEntryStream(interruptStreamOnFailure(c.fullStream,o.signal),a.resolve),{excludedActionToolNames:s,held:i.finalReplyOnly&&workingTaskIds(i.session).length>0,finalReplyOnly:i.finalReplyOnly,tools:a,interruptSignal:o.signal});throwIfTurnAborted(i.config.abortSignal),o.check();let[d,f]=toEntryStep(...await Promise.all([n,c.responseMessages]),a.resolve);assertUsableResponse(d,f,{allowEmptyStop:!i.hasDelegatedCaller,hasInlineResults:u.length>0});let p=await this.runInlineCalls(d,t,{excludedCallIds:l,telemetry:r}),m=answerSkippedToolCalls(d,a,l);return await emitStepActions(i.publish,i.position(),d,m),withCallResults({answers:[...u,...m],calls:p,invalidInputToolCallIds:l,responseMessages:f,stepResult:d})}async runInlineCalls(e,t,n){let{finishReason:r}=e;if(r!==`stop`&&r!==`tool-calls`)return NO_INLINE_CALLS;let{step:i}=this,a=await executeInlineCalls({abortSignal:this.input.generation.signal,approvalMemory:this.input.approvalMemory,beforeExecute:()=>this.input.generation.protectToolExecution(),excludedCallIds:n.excludedCallIds??new Set,messages:t,modelCallId:e.callId,publish:i.publish,telemetry:n.telemetry,toolCalls:e.toolCalls??[],tools:this.input.catalog});return throwIfTurnAborted(i.config.abortSignal),a}};function assertUsableResponse(e,t,n){if(e.finishReason===`content-filter`)throw new ContentFilteredModelResponseError(readGatewayGenerationId(e.providerMetadata));if(!(n.allowEmptyStop&&e.finishReason===`stop`)&&isEmptyModelResponse(e)&&extractToolResultCallIds(t).size===0&&!n.hasInlineResults)throw new EmptyModelResponseError}function isAbortError(e){return e instanceof Error&&(e.name===`AbortError`||e.name===`TimeoutError`)}export{ModelCaller};
1
+ import{modelCallErrorInfo,reportCompactionFailure,reportModelCallFailure}from"./failure.js";import{buildGatewayAttributionHeaders,withGatewayTraceContext}from"./model.js";import{isEmptyModelResponse,recoverModelCall,rethrowNoOutputAsEmptyResponse}from"./recovery.js";import{modelInstructions,requestMessages,withTrailingUserNote}from"./request.js";import{answerSkippedToolCalls,extractToolResultCallIds,withCallResults}from"./response.js";import{ALLOW_RETRY,STOP_RETRY,runModelCallWithRetries}from"./retry.js";import{withUniqueCallIds}from"./unique-call-ids.js";import{prepareModelTools}from"./tools.js";import{extractGatewayCostUsd,extractTokenUsageDelta}from"./usage.js";import{ToolLoopAgent,isStepCount}from"ai";import{createLogger,logError}from"#internal/logging.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{REPLY_TOOL_NAME}from"#protocol/reply-tool.js";import{activeTurnId}from"#harness/session-machine/view.js";import{hydrateSandboxAttachments,moveToolResultFilesToUserMessages}from"#harness/attachment-staging.js";import{workingTaskIds}from"#execution/tasks/model-step.js";import{historyCallNames,toEntryStep,toEntryStream}from"#harness/execute-call.js";import{discardAttempt}from"#harness/session-machine/transitions.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{fact,usageOf}from"#harness/facts.js";import{nextChangeId,nextRunId}from"#protocol/session-projection.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{compactedTurnInput,maybeCompact}from"#harness/compaction/step.js";import{CompactionOverLimitError}from"#harness/compaction/over-limit-error.js";import{estimateTokens}from"#harness/token-estimate.js";import{withoutPromptMeasurement}from"#harness/compaction/engine.js";import{requireSessionModelReference}from"#harness/types.js";import{ContentFilteredModelResponseError,EmptyModelResponseError,ModelStreamStalledError}from"#harness/model-call/errors.js";import{resolveModelProfile}from"#harness/model-profile.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{NO_INLINE_CALLS,executeInlineCalls}from"#harness/call-executor.js";import{emitStreamContent}from"#harness/emission.js";import{estimateRequestEnvelope}from"#harness/request-envelope.js";import{compactPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{buildStepHooks,emitStepActions,readGatewayGenerationId}from"#harness/step-hooks.js";const environment=process.env.NODE_ENV??`unknown`,log=createLogger(`harness.tool-loop`),MODEL_OUTPUT_TIMEOUT_MS=6e5;var ModelCaller=class{profile;attributionHeaders;projectedMessages;turnMessages;request;modelMessages=[];requestEnvelopeTokens=0;interruptedUsage;compactionFailure;attemptIndex=0;started;acceptedOutput=!1;step;prompt;input;constructor(e,t,n){this.step=e,this.prompt=t,this.input=n,this.profile=resolveModelProfile(n.model,requireSessionModelReference(e.session).promptCache),this.attributionHeaders=buildGatewayAttributionHeaders(this.profile,e.config.runtimeIdentity),this.projectedMessages=n.projectedMessages,this.turnMessages=n.turnMessages,this.request=this.buildRequest()}async call(){let e={},t={policies:[()=>this.compactionFailure===void 0?ALLOW_RETRY:STOP_RETRY],onRetry:e=>this.prepareRetry(e),sessionId:this.step.session.sessionId,turnId:this.step.position().turnId};for(;;)try{return await runModelCallWithRetries(()=>this.attempt(e),t,this.input.generation.signal)}catch(n){if(this.compactionFailure!==void 0)throw this.compactionFailure.error;throwIfTurnAborted(this.step.config.abortSignal),this.input.generation.check();let r=recoverModelCall(n,e,t);if(r===void 0)throw n;await this.prepareRetry(n),e=r}}async prepareRetry(e){let{step:t}=this,n=t.position().runId,r=this.started;if(this.started=void 0,n!==void 0){if(this.acceptedOutput){await t.apply(discardAttempt(t.view(),{ending:`retried`,runId:n})),this.acceptedOutput=!1,await this.input.newRun();return}r!==void 0&&await t.apply([fact(`model.retried`,{attempt:r,error:modelCallErrorInfo(e),runId:n})])}}async failIfCompactionFailed(){if(this.compactionFailure===void 0)return;let{error:e}=this.compactionFailure;return e instanceof CompactionOverLimitError?reportCompactionFailure(this.step,e):reportModelCallFailure(this.step,e)}async steered(){let{step:e}=this;throwIfTurnAborted(e.config.abortSignal),this.input.generation.end(),e.ctx?.set(HistoryStateKey,this.request.historyState);let t=e.position().runId;return t!==void 0&&await e.apply(discardAttempt(e.view(),{ending:`steered`,runId:t,usage:this.interruptedUsage===void 0?void 0:usageOf(this.interruptedUsage)})),{next:e.runStep,session:{...e.session,history:[...this.request.history]},steered:!0}}clearInterruptedUsage(){this.interruptedUsage=void 0}buildRequest(){return requestMessages(this.step,{catalog:this.input.catalog,messages:this.prompt.messages,pendingApprovalsNote:this.input.pendingApprovalsNote,projectedMessages:this.projectedMessages,turnMessages:this.turnMessages})}instructions(e){return modelInstructions({anthropicCache:this.profile.anthropicCache,extraSystemNote:e,session:this.step.session,systemMessages:this.request.systemMessages})}async prepare(e){let t=await prepareModelTools(this.step,{catalog:this.input.catalog,disabledProviderTools:e.disabledProviderTools,profile:this.profile});return this.request=this.buildRequest(),this.requestEnvelopeTokens=await estimateRequestEnvelope({history:this.projectedMessages,instructions:this.instructions(e.extraSystemNote),messages:withTrailingUserNote(this.request.nonSystemMessages,e.trailingUserNote),tools:t}),t}async compact(e,t){let{step:n,prompt:r}=this,{config:i}=n,a;try{let{projection:e}=n.view();if(a=await maybeCompact({abortSignal:i.abortSignal,auth:n.ctx?.get(AuthKey)??null,change:{changeId:nextChangeId(e),summaryRunId:nextRunId(e),turnId:n.position().turnId},ctx:n.ctx,emissionState:n.position(),messages:[...r.messages],model:this.input.model,promptMessages:withClientContext(r),publish:n.publish,view:()=>n.view().projection.view,requestEnvelopeTokens:this.requestEnvelopeTokens,resolveModel:i.resolveModel,runtimeIdentity:i.runtimeIdentity,session:n.session,prepareTelemetry:e=>n.instrumentation?.prepareAttempt({runId:e,attempt:0,turnId:activeTurnId(n.position())}).telemetry,traceContextHeaders:n.instrumentation?.gatewayTraceContextHeaders}),n.session=a.session,a.failure!==void 0)throw a.failure.error}catch(e){throw this.compactionFailure={error:e},e}if(!a.compacted)return t;compactPrompt(n,r,a.messages);let o=compactedTurnInput(r.messages);return this.turnMessages=o===void 0?this.input.turnMessages:[...this.input.turnMessages,o],n.session={...n.session,compaction:withoutPromptMeasurement(n.session.compaction)},this.projectedMessages=projectPrompt(r),await this.prepare(e)}async attempt(e){let{step:t}=this,{generation:n,model:r}=this.input,i=await this.compact(e,await this.prepare(e)),a=this.attemptIndex++;await this.input.startRun(a),this.started=a,this.requestEnvelopeTokens=Math.max(0,this.requestEnvelopeTokens-(estimateTokens(this.request.history)-estimateTokens(this.prompt.messages))),n.begin(),this.modelMessages=await hydrateSandboxAttachments(this.request.nonSystemMessages),this.profile.filesOutsideToolResults&&(this.modelMessages=moveToolResultFilesToUserMessages(this.modelMessages));let o=this.instructions(e.extraSystemNote),s=t.instrumentation?.resolveRuntimeContext({attempt:a,emissionState:t.position(),environment,modelInput:{instructions:o,messages:this.modelMessages},session:t.session})??{};e.retryReason&&(s[`eve.retry.reason`]=e.retryReason);let c=withTrailingUserNote(this.modelMessages,e.trailingUserNote),l=t.position(),u=t.instrumentation?.prepareAttempt({isFrameworkTool:e=>t.frameworkToolNames.has(e),runId:l.runId,attempt:a,runtimeContext:s,stepIndex:l.stepIndex,turnId:activeTurnId(l)}),d=buildStepHooks({auth:t.ctx?.get(AuthKey)??null,profile:this.profile,session:t.session}),f={headers:this.attributionHeaders,instructions:o,model:withUniqueCallIds(withGatewayTraceContext(r,this.profile,this.step.instrumentation?.gatewayTraceContextHeaders),[...Object.keys(t.view().projection.view.calls),...historyCallNames(c).keys()]),onLanguageModelCallEnd:e=>{n.interrupted||(this.interruptedUsage=extractTokenUsageDelta({costUsd:extractGatewayCostUsd(e.providerMetadata),usage:e.usage}))},onError(e){n.interrupted||summarizeKnownError(e.error)?.tags.includes(`config`)!==!0&&logError(log,`tool-loop stream error`,e.error)},onStepEnd:d.onStepEnd,onStepStart:d.onStepStart,prepareStep:d.prepareStep,reasoning:t.session.agent.modelReference?.reasoning??t.session.agent.reasoning,runtimeContext:s,stopWhen:isStepCount(1),telemetry:u?.telemetry,timeout:{chunkMs:MODEL_OUTPUT_TIMEOUT_MS,firstChunkMs:MODEL_OUTPUT_TIMEOUT_MS},tools:i},p=new ToolLoopAgent(f);try{return await this.stream(p,c,d.stepResult,u?.telemetry)}catch(e){if(n.check(),isAbortError(e)&&!n.signal.aborted)throw new ModelStreamStalledError({cause:e});return rethrowNoOutputAsEmptyResponse(e)}}async stream(e,t,n,r){let{step:i}=this,{catalog:a,generation:o}=this.input,s=new Set([REPLY_TOOL_NAME]),c=await e.stream({abortSignal:o.signal,messages:t}),{invalidInputToolCallIds:l,trailingInlineToolResultParts:u}=await emitStreamContent(async(e,t)=>{this.acceptedOutput=!0,await i.publish(e,t)},i.position(),toEntryStream(interruptStreamOnFailure(c.fullStream,o.signal),a.resolve),{excludedActionToolNames:s,held:i.finalReplyOnly&&workingTaskIds(i.session).length>0,finalReplyOnly:i.finalReplyOnly,tools:a,interruptSignal:o.signal});throwIfTurnAborted(i.config.abortSignal),o.check();let[d,f]=toEntryStep(...await Promise.all([n,c.responseMessages]),a.resolve);assertUsableResponse(d,f,{allowEmptyStop:!i.hasDelegatedCaller,hasInlineResults:u.length>0});let p=await this.runInlineCalls(d,t,{excludedCallIds:l,telemetry:r}),m=answerSkippedToolCalls(d,a,l);return await emitStepActions(i.publish,i.position(),d,m),withCallResults({answers:[...u,...m],calls:p,invalidInputToolCallIds:l,responseMessages:f,stepResult:d})}async runInlineCalls(e,t,n){let{finishReason:r}=e;if(r!==`stop`&&r!==`tool-calls`)return NO_INLINE_CALLS;let{step:i}=this,a=await executeInlineCalls({abortSignal:this.input.generation.signal,approvalMemory:this.input.approvalMemory,beforeExecute:()=>this.input.generation.protectToolExecution(),excludedCallIds:n.excludedCallIds??new Set,messages:t,modelCallId:e.callId,publish:i.publish,telemetry:n.telemetry,toolCalls:e.toolCalls??[],tools:this.input.catalog});return throwIfTurnAborted(i.config.abortSignal),a}};function assertUsableResponse(e,t,n){if(e.finishReason===`content-filter`)throw new ContentFilteredModelResponseError(readGatewayGenerationId(e.providerMetadata));if(!(n.allowEmptyStop&&e.finishReason===`stop`)&&isEmptyModelResponse(e)&&extractToolResultCallIds(t).size===0&&!n.hasInlineResults)throw new EmptyModelResponseError}function isAbortError(e){return e instanceof Error&&(e.name===`AbortError`||e.name===`TimeoutError`)}export{ModelCaller};
@@ -1 +1 @@
1
- import{reportModelCallFailure}from"./failure.js";import{resolveEffectiveRuntimeModel}from"./model.js";import{endsTurnTools,frameworkToolNames}from"./tools.js";import{recordModelUsage}from"./usage.js";import{ModelCaller}from"./call.js";import{HistoryStateKey}from"#context/keys.js";import{activeTurnId}from"#harness/session-machine/view.js";import{enforceBudget,humanInputContext}from"#harness/hitl/index.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{runRequested,runStarted}from"#harness/facts.js";import{nextRunId}from"#protocol/session-projection.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{requireSessionModelReference}from"#harness/types.js";import{buildStepCatalog,recordOfferedCatalogTools}from"#execution/catalog/step-catalog.js";import{buildPrompt,previewPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{handleStepResult}from"#harness/step/after-model.js";import{failBoundaryEvent,failModelSelection,prepareModelCall}from"#harness/step/context.js";async function runModelStep(e,t){let{generation:n}=t,r=await prepareModelCall(e,previewPrompt(e,t.turn));if(r!==void 0)return r;let i=await buildPrompt(e,t.turn),a=await enforceBudget(e,i.messages);if(a!==void 0)return a;let o=await requestRun(e,i);if(`failed`in o)return o.failed;let s=projectPrompt(i),c=!e.hasDelegatedCaller&&e.session.outputSchema===void 0,l=buildStepCatalog({agentTools:e.config.tools,ctx:e.ctx,endsTurn:c,session:e.session});recordOfferedCatalogTools(e.ctx,l),e.frameworkToolNames=frameworkToolNames(l);let{approvalMemory:u,pendingApprovalsNote:d}=humanInputContext(e),f=new ModelCaller(e,i,{approvalMemory:u,catalog:l,generation:n,model:o.model,newRun:async()=>{if(`failed`in await requestRun(e,i))throw Error(`The model run's replacement found no model.`)},startRun:async t=>await startRun(e,t),pendingApprovalsNote:d,projectedMessages:s,turnMessages:t.turn.messages}),p;try{p=await f.call()}catch(t){let r=await f.failIfCompactionFailed();return r===void 0?(throwIfTurnAborted(e.config.abortSignal),n.interrupted?f.steered():reportModelCallFailure(e,t)):r}await recordModelUsage(e,{model:o.model}),f.clearInterruptedUsage();let m;try{n.check(),m=await handleStepResult(e,{catalog:l,durableModelPromptMessageCount:i.clientContext===void 0||i.clientContext.messages.length===0?f.modelMessages.length:void 0,endsTurnTools:endsTurnTools(l,c),promptMessages:f.request.history,requestEnvelopeTokens:f.requestEnvelopeTokens,result:p})}catch(t){if(throwIfTurnAborted(e.config.abortSignal),n.interrupted)return f.steered();throw t}return e.ctx?.set(HistoryStateKey,f.request.historyState),m}async function requestRun(e,t){let{config:n,ctx:r}=e;try{await e.apply([runRequested({turnId:activeTurnId(e.position())},nextRunId(e.view().projection))],validateHarnessModelMessages(withClientContext(t)))}catch(t){return{failed:await failBoundaryEvent(e,t)}}try{let t=await resolveEffectiveRuntimeModel({config:n,ctx:r,session:e.session});return e.session=t.session,{model:t.model}}catch(t){return{failed:await failModelSelection(e,t)}}}async function startRun(e,t){let n=e.position().runId;if(n===void 0)return;let r=requireSessionModelReference(e.session).id;await e.apply([runStarted({attempt:t,modelId:r,runId:n})])}export{runModelStep};
1
+ import{reportModelCallFailure}from"./failure.js";import{resolveEffectiveRuntimeModel}from"./model.js";import{endsTurnTools,frameworkToolNames}from"./tools.js";import{recordModelUsage}from"./usage.js";import{ModelCaller}from"./call.js";import{HistoryStateKey}from"#context/keys.js";import{activeTurnId}from"#harness/session-machine/view.js";import{enforceBudget,humanInputContext}from"#harness/hitl/index.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{runRequested,runStarted}from"#harness/facts.js";import{nextRunId}from"#protocol/session-projection.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{requireSessionModelReference}from"#harness/types.js";import{buildStepCatalog,recordOfferedCatalogTools}from"#execution/catalog/step-catalog.js";import{buildPrompt,previewPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{handleStepResult}from"#harness/step/after-model.js";import{failBoundaryEvent,failModelSelection,prepareModelCall}from"#harness/step/context.js";async function runModelStep(e,t){let{generation:n}=t,r=await prepareModelCall(e,previewPrompt(e,t.turn));if(r!==void 0)return r;let i=await buildPrompt(e,t.turn),a=await enforceBudget(e,i.messages);if(a!==void 0)return a;let o=await requestRun(e,i);if(`failed`in o)return o.failed;let s=projectPrompt(i),c=!e.hasDelegatedCaller&&e.session.outputSchema===void 0,l=buildStepCatalog({agentTools:e.config.tools,ctx:e.ctx,endsTurn:c,session:e.session});recordOfferedCatalogTools(e.ctx,l),e.frameworkToolNames=frameworkToolNames(l);let{approvalMemory:u,pendingApprovalsNote:d}=humanInputContext(e),f=new ModelCaller(e,i,{approvalMemory:u,catalog:l,generation:n,model:o.model,newRun:async()=>{if(`failed`in await requestRun(e,i))throw Error(`The model run's replacement found no model.`)},startRun:async t=>await startRun(e,t),pendingApprovalsNote:d,projectedMessages:s,turnMessages:t.turn.messages}),p;try{p=await f.call()}catch(t){throwIfTurnAborted(e.config.abortSignal);let r=await f.failIfCompactionFailed();return r===void 0?n.interrupted?f.steered():reportModelCallFailure(e,t):r}await recordModelUsage(e,{model:o.model}),f.clearInterruptedUsage();let m;try{n.check(),m=await handleStepResult(e,{catalog:l,durableModelPromptMessageCount:i.clientContext===void 0||i.clientContext.messages.length===0?f.modelMessages.length:void 0,endsTurnTools:endsTurnTools(l,c),promptMessages:f.request.history,requestEnvelopeTokens:f.requestEnvelopeTokens,result:p})}catch(t){if(throwIfTurnAborted(e.config.abortSignal),n.interrupted)return f.steered();throw t}return e.ctx?.set(HistoryStateKey,f.request.historyState),m}async function requestRun(e,t){let{config:n,ctx:r}=e;try{await e.apply([runRequested({turnId:activeTurnId(e.position())},nextRunId(e.view().projection))],validateHarnessModelMessages(withClientContext(t)))}catch(t){return{failed:await failBoundaryEvent(e,t)}}try{let t=await resolveEffectiveRuntimeModel({config:n,ctx:r,session:e.session});return e.session=t.session,{model:t.model}}catch(t){return{failed:await failModelSelection(e,t)}}}async function startRun(e,t){let n=e.position().runId;if(n===void 0)return;let r=requireSessionModelReference(e.session).id;await e.apply([runStarted({attempt:t,modelId:r,runId:n})])}export{runModelStep};
@@ -1 +1 @@
1
- import{allOf,anyOf,messageMatches,nameIs,typeIs}from"../rule.js";const GATEWAY_AUTH_FAILURE_SUMMARY_NAME=`AI Gateway authentication failed`,gatewayAuthenticationFailure=anyOf(nameIs(`GatewayAuthenticationError`),typeIs(`authentication_error`),messageMatches(/AI Gateway authentication/i)),GATEWAY_RULES=[{id:`gateway-billing-required`,name:`AI Gateway billing setup required`,tags:[`gateway`,`config`,`recoverable`],when:messageMatches(/AI Gateway requires a valid credit card on file/),message:e=>e.message,hint:`Add a valid credit card or credits in the Vercel dashboard, then retry.`},{id:`gateway-credit-exhausted`,name:`AI Gateway credit balance exhausted`,tags:[`gateway`,`config`,`recoverable`],when:anyOf(typeIs(`insufficient_funds`),messageMatches(/A positive credit balance is required/i)),message:`AI Gateway requires a positive credit balance to process requests.`,hint:`Add credits in the Vercel dashboard, then retry.`},{id:`gateway-budget-exhausted`,name:`AI Gateway project budget exceeded`,tags:[`gateway`,`config`,`recoverable`],when:anyOf(typeIs(`quota_for_entity_exceeded`),messageMatches(/Project budget exceeded/i)),message:`The AI Gateway project budget has been exceeded.`,hint:`Ask your administrator to increase the project budget, then retry.`},{id:`gateway-free-tier-model-restricted`,name:`Model unavailable on AI Gateway free tier`,tags:[`gateway`,`config`,`recoverable`],when:messageMatches(/Free tier users do not have access to this model/),message:e=>e.message,hint:`Switch to a model available on the free tier or upgrade your Vercel plan, then retry.`},{id:`gateway-free-tier-rate-limited`,name:`AI Gateway free tier rate limit exceeded`,tags:[`gateway`,`recoverable`],when:messageMatches(/Free tier requests on this model are rate-limited/),message:e=>e.message,hint:`Wait for the free-tier limit to reset or upgrade your Vercel plan, then retry.`},{id:`gateway-auth-invalid-api-key`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid API key/i)),message:`AI Gateway rejected the provided API key.`,hint:"Update or unset `AI_GATEWAY_API_KEY` (check your shell profile if you did not set it for this project) — manage keys at https://vercel.com/dashboard/ai/api-keys. Unsetting it falls back to OIDC via `eve link`."},{id:`gateway-auth-invalid-oidc-token`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid OIDC token/i)),message:`AI Gateway rejected the OIDC token.`,hint:"Run `eve link` to refresh `VERCEL_OIDC_TOKEN` in `.env.local`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`gateway-auth-missing-credentials`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:gatewayAuthenticationFailure,message:`AI Gateway received no credentials.`,hint:"Run `eve link` to populate `VERCEL_OIDC_TOKEN`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`model-not-found`,name:`Model not found`,tags:[`gateway`,`config`],when:anyOf(nameIs(`GatewayModelNotFoundError`,`AI_NoSuchModelError`),typeIs(`model_not_found`)),message:`The requested model is not available.`,hint:"Check the model id in `agent.ts` (`model:`) or switch models with `/model` in `eve dev` — browse available models at https://vercel.com/ai-gateway/models."},{id:`gateway-rate-limited`,name:`AI Gateway rate limit exceeded`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayRateLimitError`),typeIs(`rate_limit_exceeded`)),message:`AI Gateway rate-limited the request.`,hint:`Retries are automatic; if it persists, reduce request volume or review your plan limits at https://vercel.com/ai-gateway.`},{id:`gateway-upstream-unavailable`,name:`Model provider unavailable`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayTimeoutError`),typeIs(`timeout_error`,`overloaded_error`)),message:`The model provider is overloaded or timing out upstream of AI Gateway.`,hint:"This is transient — retry shortly, or switch models with `/model` in `eve dev`."}];export{GATEWAY_RULES};
1
+ import{allOf,anyOf,messageMatches,nameIs,typeIs}from"../rule.js";const GATEWAY_AUTH_FAILURE_SUMMARY_NAME=`AI Gateway authentication failed`,gatewayAuthenticationFailure=anyOf(nameIs(`GatewayAuthenticationError`),typeIs(`authentication_error`),messageMatches(/AI Gateway authentication/i)),GATEWAY_RULES=[{id:`gateway-billing-required`,name:`AI Gateway billing setup required`,tags:[`gateway`,`config`,`recoverable`],when:messageMatches(/AI Gateway requires a valid credit card on file/),message:e=>e.message,hint:`Add a valid credit card or credits in the Vercel dashboard, then retry.`},{id:`gateway-credit-check-throttled`,name:`AI Gateway credit check throttled`,tags:[`gateway`,`transient`],when:messageMatches(/credit balance verification is temporarily throttled/i),message:`AI Gateway temporarily throttled its credit balance check.`,hint:`Retries are automatic; if it persists, wait a moment and retry.`},{id:`gateway-credit-exhausted`,name:`AI Gateway credit balance exhausted`,tags:[`gateway`,`config`,`recoverable`],when:anyOf(typeIs(`insufficient_funds`),messageMatches(/A positive credit balance is required/i)),message:`AI Gateway requires a positive credit balance to process requests.`,hint:`Add credits in the Vercel dashboard, then retry.`},{id:`gateway-budget-exhausted`,name:`AI Gateway project budget exceeded`,tags:[`gateway`,`config`,`recoverable`],when:anyOf(typeIs(`quota_for_entity_exceeded`),messageMatches(/Project budget exceeded/i)),message:`The AI Gateway project budget has been exceeded.`,hint:`Ask your administrator to increase the project budget, then retry.`},{id:`gateway-free-tier-model-restricted`,name:`Model unavailable on AI Gateway free tier`,tags:[`gateway`,`config`,`recoverable`],when:messageMatches(/Free tier users do not have access to this model/),message:e=>e.message,hint:`Switch to a model available on the free tier or upgrade your Vercel plan, then retry.`},{id:`gateway-free-tier-rate-limited`,name:`AI Gateway free tier rate limit exceeded`,tags:[`gateway`,`recoverable`],when:messageMatches(/Free tier requests on this model are rate-limited/),message:e=>e.message,hint:`Wait for the free-tier limit to reset or upgrade your Vercel plan, then retry.`},{id:`gateway-auth-invalid-api-key`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid API key/i)),message:`AI Gateway rejected the provided API key.`,hint:"Update or unset `AI_GATEWAY_API_KEY` (check your shell profile if you did not set it for this project) — manage keys at https://vercel.com/dashboard/ai/api-keys. Unsetting it falls back to OIDC via `eve link`."},{id:`gateway-auth-invalid-oidc-token`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid OIDC token/i)),message:`AI Gateway rejected the OIDC token.`,hint:"Run `eve link` to refresh `VERCEL_OIDC_TOKEN` in `.env.local`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`gateway-auth-missing-credentials`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:gatewayAuthenticationFailure,message:`AI Gateway received no credentials.`,hint:"Run `eve link` to populate `VERCEL_OIDC_TOKEN`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`model-not-found`,name:`Model not found`,tags:[`gateway`,`config`],when:anyOf(nameIs(`GatewayModelNotFoundError`,`AI_NoSuchModelError`),typeIs(`model_not_found`)),message:`The requested model is not available.`,hint:"Check the model id in `agent.ts` (`model:`) or switch models with `/model` in `eve dev` — browse available models at https://vercel.com/ai-gateway/models."},{id:`gateway-rate-limited`,name:`AI Gateway rate limit exceeded`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayRateLimitError`),typeIs(`rate_limit_exceeded`)),message:`AI Gateway rate-limited the request.`,hint:`Retries are automatic; if it persists, reduce request volume or review your plan limits at https://vercel.com/ai-gateway.`},{id:`gateway-upstream-unavailable`,name:`Model provider unavailable`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayTimeoutError`),typeIs(`timeout_error`,`overloaded_error`)),message:`The model provider is overloaded or timing out upstream of AI Gateway.`,hint:"This is transient — retry shortly, or switch models with `/model` in `eve dev`."}];export{GATEWAY_RULES};
@@ -1,6 +1,7 @@
1
1
  import type { AuthoredWorkflowModules } from "#internal/workflow-bundle/builder-support.js";
2
2
  import type { CompileMetadata } from "#compiler/artifacts.js";
3
3
  import type { CompileAgentResult } from "#compiler/compile-agent.js";
4
+ import { type ModelMetadata } from "#internal/model-catalog.js";
4
5
  import type { AgentWorkflowWorldDefinition } from "#shared/agent-definition.js";
5
6
  import { type SandboxPreparedArtifactsManifest } from "#shared/sandbox-prepared-artifacts.js";
6
7
  export type BuiltInWorkflowWorldTarget = "local" | "vercel";
@@ -56,6 +57,7 @@ export declare function createCompiledArtifactsBootstrapSource(input: {
56
57
  compileResult: CompileAgentResult;
57
58
  installModulePath: string;
58
59
  metadata: CompileMetadata;
60
+ modelMetadata: ModelMetadata;
59
61
  moduleMapImportPath: string;
60
62
  sandboxPreparedArtifacts: SandboxPreparedArtifactsManifest;
61
63
  }): string;