eve 0.70.3 → 0.71.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/src/channel/agent-description.d.ts +33 -0
- package/dist/src/channel/agent-description.js +1 -0
- package/dist/src/channel/resolved-prompt.d.ts +12 -0
- package/dist/src/channel/resolved-prompt.js +1 -0
- package/dist/src/channel/routes.d.ts +7 -0
- package/dist/src/channel/tool-eligibility.d.ts +39 -0
- package/dist/src/channel/tool-eligibility.js +1 -0
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +18 -0
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/memory-tools.js +1 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/sandbox/bash.d.ts +34 -11
- package/dist/src/execution/sandbox/bash.js +24 -1
- package/dist/src/execution/sandbox/bindings/docker-session.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +1 -1
- package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/local-provider-utils.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/ensure.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.js +1 -1
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/sandbox/read-file.js +3 -3
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/media-metadata.d.ts +2 -0
- package/dist/src/internal/attachments/media-metadata.js +1 -1
- package/dist/src/internal/authored-definition/source-identity.d.ts +17 -8
- package/dist/src/internal/authored-definition/source-identity.js +1 -1
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/mcp/streamable-http-server.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +9 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
- package/dist/src/public/channels/chat-sdk/input-actions.d.ts +4 -2
- package/dist/src/public/channels/chat-sdk/input-actions.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.d.ts +10 -0
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/teams/defaults.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +8 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/defaults.d.ts +5 -2
- package/dist/src/public/channels/telegram/defaults.js +1 -1
- package/dist/src/public/channels/telegram/hitl.d.ts +23 -1
- package/dist/src/public/channels/telegram/hitl.js +2 -2
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -0
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +1 -0
- package/dist/src/public/tools/result.js +1 -1
- package/dist/src/runtime/resolve-connection.js +1 -1
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +2 -0
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/bash.d.ts +17 -2
- package/dist/src/tools/provided/bash.js +1 -1
- package/dist/src/tools/provided/read-file.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/docs/channels/custom.mdx +1 -0
- package/docs/concepts/built-in-tools.md +18 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/extensions.md +1 -1
- package/docs/guides/hooks.md +2 -0
- package/docs/memory/custom-provider.md +4 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile,writeFile}from"node:fs/promises";import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=2,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:73,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,29,30,31,32,34,35,54,55,63,64,65,66,67,68,69,70,71,72,73],dropped:{14:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,15:`TaskExec replaces stageEffect with send`,16:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,17:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,18:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,19:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,20:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,21:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,22:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,23:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,24:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,25:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,26:`Background tools now use task yield descriptors`,27:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,28:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,33:`ctx.agent now accepts the subagent name as its first argument, derives invocation identity internally, and infers structured output types`,36:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,37:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,38:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,39:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,40:`runWorkflowProgram was made internal; use the workflow factory from eve/tools/workflow`,41:`workflow no longer accepts agents and its options argument is optional; use workflow() or workflow({ maxSubagents })`,42:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,43:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,44:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,45:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,46:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,47:`eve/experimental/evaluate was removed; import evaluate from eve/ai`,48:`eve/experimental/evaluate was removed; import evaluate from eve/ai`,49:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,50:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,51:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,52:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,53:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,56:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,57:`agentRouter() no longer accepts a model-facing outputSchema; structured subagent output is requested only through ctx.agent().`,58:`Workflow tools no longer accept execution or return background task receipts; every call blocks until it settles.`,59:`Workflow tools no longer accept execution or return background task receipts, and every call blocks until it settles. ctx.ask() no longer accepts dismissible and reports a withdrawn request as cancelled, workflow tool contexts carry interruptSignal, and ctx.agent(name) returns a session handle whose send() delivers a message and whose result() resolves the turn; ctx.agent(name, { message, agentId }) and AgentInput were removed. A ctx.ask() question parks the open turn with turn.waiting instead of ending it.`,60:`Workflow tools define exactly one of execute(input, ctx), task(input, ctx), or serve(receive, ctx): a task() call returns a receipt and runs as a task, a serve() call reaches a resumable task through receive() and its model input gains taskId, and stream events gained task.started and task.settled. Agent tools are serve() tools with taskId in place of agentId, and the subagent.* stream events were removed. ctx.interruptSignal and WorkflowTaskContext were removed: a steering message aborts the abortSignal of an execute call the turn waits on.`,61:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,62:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},dynamicTool:{current:70,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,31,32,33,52,54,60,61,62,63,64,65,66,67,68,69,70],dropped:{21:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,24:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,25:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,26:`Background tools now use task yield descriptors`,27:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,28:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,29:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,30:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,34:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,35:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,36:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,37:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,38:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,39:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,40:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,41:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,42:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,43:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,44:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,45:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,46:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,47:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,48:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,49:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,50:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,51:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,53:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,55:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,56:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,57:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`,58:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,59:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},channel:{current:45,supported:[1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,29,31,36,37,38,39,40,41,42,43,44,45],dropped:{12:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,19:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,20:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,21:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,22:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,23:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,24:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,25:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,26:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,27:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,28:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,30:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,32:`Run mode and caller-supplied output schemas were removed from channel operations; sessions always park, and send options, audience inputs, and ConversationContext no longer carry mode, while from().send() and from().respond() no longer accept outputSchema.`,33:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text.`,34:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,35:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},schedule:{current:26,supported:[1,2,3,4,6,7,8,9,10,11,12,13,14,15,18,19,20,21,22,23,24,25,26],dropped:{5:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,16:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,17:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},subagent:{current:29,supported:[3,4,6,7,8,9,10,11,12,13,14,15,16,19,23,24,25,26,27,28,29],dropped:{1:`Persistent subagent sessions are now the default and the experimental opt-in was removed`,2:`Persistent subagent sessions are now the default and the experimental opt-in was removed`,5:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,17:`Removed experimental.instrumentationProviders; instrumentation is now always enabled for root agents.`,18:`Removed experimental.instrumentationProviders; instrumentation is now always enabled for root agents.`,20:`Run mode was removed and agent definitions no longer declare outputSchema; sessions always park, ConversationContext no longer carries mode, and structured output is requested per turn.`,21:`Background task execution was removed: subagent results no longer carry backgroundTask, message.completed always carries text, and experimental.tasks is gone. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,22:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},connection:{current:38,supported:[1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18,19,20,21,22,24,26,32,33,34,35,36,37,38],dropped:{9:`Dynamic connection resolvers no longer receive conversation or channel continuation data`,10:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,25:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,27:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,28:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,29:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`,30:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,31:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},hook:{current:37,supported:[20,21,22,23,25,27,31,32,33,34,35,36,37],dropped:{1:`Model identity moved from session.started runtime metadata to step.started call attribution.`,2:`Model identity moved from session.started runtime metadata to step.started call attribution.`,3:`Model identity moved from session.started runtime metadata to step.started call attribution.`,4:`Model identity moved from session.started runtime metadata to step.started call attribution.`,5:`Model identity moved from session.started runtime metadata to step.started call attribution.`,6:`Model identity moved from session.started runtime metadata to step.started call attribution.`,7:`Model identity moved from session.started runtime metadata to step.started call attribution.`,8:`Model identity moved from session.started runtime metadata to step.started call attribution.`,9:`Model identity moved from session.started runtime metadata to step.started call attribution.`,10:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,11:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,12:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,13:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,14:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,15:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,16:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,17:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,18:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,19:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,24:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,26:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,28:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text.`,29:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,30:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`}},skill:{current:2,supported:[1,2],dropped:{}},dynamicSkill:{current:31,supported:[1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,25,26,27,28,29,30,31],dropped:{13:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,22:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,23:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,24:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},instructions:{current:2,supported:[1,2],dropped:{}},dynamicInstructions:{current:32,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,26,27,28,29,30,31,32],dropped:{14:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,24:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,25:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},config:{current:1,supported:[1],dropped:{}},state:{current:9,supported:[1,2,3,4,5,7,9],dropped:{6:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,8:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`}}},EXTENSION_CAPABILITY_VERSIONS=Object.fromEntries(Object.entries(EXTENSION_CAPABILITY_CONTRACTS).map(([e,t])=>[e,t.current])),EXTENSION_CAPABILITY_SUPPORT=Object.keys(EXTENSION_CAPABILITY_CONTRACTS).reduce((e,t)=>(e[t]=EXTENSION_CAPABILITY_CONTRACTS[t].supported,e),{}),extensionCompatibilityManifestV1Schema=z.object({kind:z.literal(EXTENSION_COMPATIBILITY_MANIFEST_KIND),formatVersion:z.literal(1),builtWithEve:z.string().min(1),requires:z.record(z.string(),z.number().int().positive())}).strict(),extensionCompatibilityManifestV2Schema=extensionCompatibilityManifestV1Schema.extend({formatVersion:z.literal(2),build:z.object({externalDependencies:z.array(z.string().min(1)).readonly()}).strict().optional()}),extensionCompatibilityManifestSchema=z.union([extensionCompatibilityManifestV1Schema,extensionCompatibilityManifestV2Schema]);function serializeExtensionCompatibilityManifest(e){return`${JSON.stringify(e,null,2)}\n`}function parseExtensionCompatibilityManifest(e,t){let n;try{n=JSON.parse(e)}catch(e){throw Error(`Extension compatibility manifest "${t}" is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}let r=extensionCompatibilityManifestSchema.safeParse(n);if(!r.success)throw Error(`Extension compatibility manifest "${t}" is invalid. ${formatValidationError(r.error)}`);return r.data}async function readExtensionCompatibilityManifest(e){return parseExtensionCompatibilityManifest(await readFile(e,`utf8`),e)}async function writeExtensionCompatibilityManifest(e,t){await writeFile(join(e,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),serializeExtensionCompatibilityManifest(t),`utf8`)}function findUnsupportedExtensionCapabilities(e,t=EXTENSION_CAPABILITY_SUPPORT){return Object.entries(e.requires).flatMap(([e,n])=>{let r=Object.hasOwn(t,e)?t[e]??[]:[];return r.includes(n)?[]:[{capability:e,requiredVersion:n,supportedVersions:r}]}).sort((e,t)=>e.capability.localeCompare(t.capability))}export{EXTENSION_CAPABILITY_SUPPORT,EXTENSION_CAPABILITY_VERSIONS,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION,EXTENSION_COMPATIBILITY_MANIFEST_KIND,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest,readExtensionCompatibilityManifest,serializeExtensionCompatibilityManifest,writeExtensionCompatibilityManifest};
|
|
1
|
+
import{readFile,writeFile}from"node:fs/promises";import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=2,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:73,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,29,30,31,32,34,35,54,55,63,64,65,66,67,68,69,70,71,72,73],dropped:{14:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,15:`TaskExec replaces stageEffect with send`,16:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,17:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,18:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,19:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,20:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,21:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,22:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,23:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,24:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,25:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,26:`Background tools now use task yield descriptors`,27:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,28:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,33:`ctx.agent now accepts the subagent name as its first argument, derives invocation identity internally, and infers structured output types`,36:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,37:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,38:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,39:`experimental_workflow and eve/tools/workflow were removed; migrate to the workflow factory from eve/tools/workflow`,40:`runWorkflowProgram was made internal; use the workflow factory from eve/tools/workflow`,41:`workflow no longer accepts agents and its options argument is optional; use workflow() or workflow({ maxSubagents })`,42:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,43:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,44:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,45:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,46:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,47:`eve/experimental/evaluate was removed; import evaluate from eve/ai`,48:`eve/experimental/evaluate was removed; import evaluate from eve/ai`,49:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,50:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,51:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,52:`Background defineTool and TaskExec were removed; use defineWorkflowTool for durable background work.`,53:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,56:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,57:`agentRouter() no longer accepts a model-facing outputSchema; structured subagent output is requested only through ctx.agent().`,58:`Workflow tools no longer accept execution or return background task receipts; every call blocks until it settles.`,59:`Workflow tools no longer accept execution or return background task receipts, and every call blocks until it settles. ctx.ask() no longer accepts dismissible and reports a withdrawn request as cancelled, workflow tool contexts carry interruptSignal, and ctx.agent(name) returns a session handle whose send() delivers a message and whose result() resolves the turn; ctx.agent(name, { message, agentId }) and AgentInput were removed. A ctx.ask() question parks the open turn with turn.waiting instead of ending it.`,60:`Workflow tools define exactly one of execute(input, ctx), task(input, ctx), or serve(receive, ctx): a task() call returns a receipt and runs as a task, a serve() call reaches a resumable task through receive() and its model input gains taskId, and stream events gained task.started and task.settled. Agent tools are serve() tools with taskId in place of agentId, and the subagent.* stream events were removed. ctx.interruptSignal and WorkflowTaskContext were removed: a steering message aborts the abortSignal of an execute call the turn waits on.`,61:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,62:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},dynamicTool:{current:70,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,31,32,33,52,54,60,61,62,63,64,65,66,67,68,69,70],dropped:{21:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,24:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,25:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,26:`Background tools now use task yield descriptors`,27:`TaskExec.delegated was removed; migrate to workflow-backed background tools`,28:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,29:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,30:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,34:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,35:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,36:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,37:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,38:`workflowMaxSubagents was removed with experimental_workflow; configure generated-program limits with the workflow factory`,39:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,40:`Legacy session history migration was removed; user-role messages require current provenance kinds.`,41:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,42:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,43:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,44:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,45:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,46:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,47:`autoModel and eve/experimental/evaluate were removed; import auto from eve/models`,48:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,49:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,50:`Background dynamic tools were removed; use a static defineWorkflowTool for durable background work.`,51:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,53:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,55:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,56:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,57:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`,58:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,59:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},channel:{current:46,supported:[1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,29,31,36,37,38,39,40,41,42,43,44,45,46],dropped:{12:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,19:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,20:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,21:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,22:`Continuation rekey was removed; channel extensions must use additive continuation.alias instead.`,23:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,24:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,25:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,26:`Task views no longer expose executor bindings; background work is owned by workflow runs.`,27:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,28:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,30:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,32:`Run mode and caller-supplied output schemas were removed from channel operations; sessions always park, and send options, audience inputs, and ConversationContext no longer carry mode, while from().send() and from().respond() no longer accept outputSchema.`,33:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text.`,34:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,35:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},schedule:{current:26,supported:[1,2,3,4,6,7,8,9,10,11,12,13,14,15,18,19,20,21,22,23,24,25,26],dropped:{5:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,16:`Background task delivery was removed: sends no longer accept taskDeliveryPolicy and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,17:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},subagent:{current:29,supported:[3,4,6,7,8,9,10,11,12,13,14,15,16,19,23,24,25,26,27,28,29],dropped:{1:`Persistent subagent sessions are now the default and the experimental opt-in was removed`,2:`Persistent subagent sessions are now the default and the experimental opt-in was removed`,5:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,17:`Removed experimental.instrumentationProviders; instrumentation is now always enabled for root agents.`,18:`Removed experimental.instrumentationProviders; instrumentation is now always enabled for root agents.`,20:`Run mode was removed and agent definitions no longer declare outputSchema; sessions always park, ConversationContext no longer carries mode, and structured output is requested per turn.`,21:`Background task execution was removed: subagent results no longer carry backgroundTask, message.completed always carries text, and experimental.tasks is gone. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,22:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},connection:{current:38,supported:[1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18,19,20,21,22,24,26,32,33,34,35,36,37,38],dropped:{9:`Dynamic connection resolvers no longer receive conversation or channel continuation data`,10:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,25:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,27:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,28:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,29:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`,30:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`,31:`Approval response policies now run for Cancel as well as Approve; a policy written for Approve only could reject every Cancel.`}},hook:{current:37,supported:[20,21,22,23,25,27,31,32,33,34,35,36,37],dropped:{1:`Model identity moved from session.started runtime metadata to step.started call attribution.`,2:`Model identity moved from session.started runtime metadata to step.started call attribution.`,3:`Model identity moved from session.started runtime metadata to step.started call attribution.`,4:`Model identity moved from session.started runtime metadata to step.started call attribution.`,5:`Model identity moved from session.started runtime metadata to step.started call attribution.`,6:`Model identity moved from session.started runtime metadata to step.started call attribution.`,7:`Model identity moved from session.started runtime metadata to step.started call attribution.`,8:`Model identity moved from session.started runtime metadata to step.started call attribution.`,9:`Model identity moved from session.started runtime metadata to step.started call attribution.`,10:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,11:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,12:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,13:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,14:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,15:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,16:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,17:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,18:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,19:`The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`,24:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,26:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`,28:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text.`,29:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,30:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event hook events were removed; subscribe to task.started, task.settled, and agent.started.`}},skill:{current:2,supported:[1,2],dropped:{}},dynamicSkill:{current:31,supported:[1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,25,26,27,28,29,30,31],dropped:{13:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,22:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,23:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,24:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},instructions:{current:2,supported:[1,2],dropped:{}},dynamicInstructions:{current:32,supported:[1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,26,27,28,29,30,31,32],dropped:{14:`Message and reasoning append events now expose deltas instead of cumulative snapshots.`,23:`Run mode was removed; sessions always park and ConversationContext no longer carries mode.`,24:`Background task execution was removed: subagent results no longer carry backgroundTask and message.completed always carries text. input.resolved reports outcome "cancelled" when a workflow tool withdraws a ctx.ask() request, and stream events gained agent.started, published when a workflow run opens a ctx.agent session, and turn.waiting, which parks the open turn instead of emitting turn.completed and session.waiting.`,25:`Stream events gained task.started and task.settled, and input.requested, authorization events, and agent.started carry the taskId of the task they come from. The subagent.called, subagent.completed, subagent.started, and subagent.event stream events were removed; agent calls report task.started, task.settled, and agent.started.`}},config:{current:1,supported:[1],dropped:{}},state:{current:9,supported:[1,2,3,4,5,7,9],dropped:{6:`Sandbox sessions no longer expose core identity and mutable networking is provider-specific.`,8:`SandboxSession no longer exposes setNetworkPolicy; pass the configured environment to ctx.getSandbox(environment) to access network policy capabilities`}}},EXTENSION_CAPABILITY_VERSIONS=Object.fromEntries(Object.entries(EXTENSION_CAPABILITY_CONTRACTS).map(([e,t])=>[e,t.current])),EXTENSION_CAPABILITY_SUPPORT=Object.keys(EXTENSION_CAPABILITY_CONTRACTS).reduce((e,t)=>(e[t]=EXTENSION_CAPABILITY_CONTRACTS[t].supported,e),{}),extensionCompatibilityManifestV1Schema=z.object({kind:z.literal(EXTENSION_COMPATIBILITY_MANIFEST_KIND),formatVersion:z.literal(1),builtWithEve:z.string().min(1),requires:z.record(z.string(),z.number().int().positive())}).strict(),extensionCompatibilityManifestV2Schema=extensionCompatibilityManifestV1Schema.extend({formatVersion:z.literal(2),build:z.object({externalDependencies:z.array(z.string().min(1)).readonly()}).strict().optional()}),extensionCompatibilityManifestSchema=z.union([extensionCompatibilityManifestV1Schema,extensionCompatibilityManifestV2Schema]);function serializeExtensionCompatibilityManifest(e){return`${JSON.stringify(e,null,2)}\n`}function parseExtensionCompatibilityManifest(e,t){let n;try{n=JSON.parse(e)}catch(e){throw Error(`Extension compatibility manifest "${t}" is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}let r=extensionCompatibilityManifestSchema.safeParse(n);if(!r.success)throw Error(`Extension compatibility manifest "${t}" is invalid. ${formatValidationError(r.error)}`);return r.data}async function readExtensionCompatibilityManifest(e){return parseExtensionCompatibilityManifest(await readFile(e,`utf8`),e)}async function writeExtensionCompatibilityManifest(e,t){await writeFile(join(e,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),serializeExtensionCompatibilityManifest(t),`utf8`)}function findUnsupportedExtensionCapabilities(e,t=EXTENSION_CAPABILITY_SUPPORT){return Object.entries(e.requires).flatMap(([e,n])=>{let r=Object.hasOwn(t,e)?t[e]??[]:[];return r.includes(n)?[]:[{capability:e,requiredVersion:n,supportedVersions:r}]}).sort((e,t)=>e.capability.localeCompare(t.capability))}export{EXTENSION_CAPABILITY_SUPPORT,EXTENSION_CAPABILITY_VERSIONS,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION,EXTENSION_COMPATIBILITY_MANIFEST_KIND,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest,readExtensionCompatibilityManifest,serializeExtensionCompatibilityManifest,writeExtensionCompatibilityManifest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{loadContext}from"#context/container.js";import{TurnMemoryLocksKey}from"#context/keys.js";import{parseJsonObject}from"#shared/json.js";import{defineDynamic}from"#dynamic/definition.js";import{stampDurableDynamicToolCallbacks}from"#tools/durable-callbacks.js";import{TOOL_SLUG_PATTERN}from"#discover/grammar.js";import{isBrandedToolEntry}from"#tools/dynamic.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{markDynamicCallbackRebind}from"#internal/dynamic-tool-rebind.js";function createMemoryToolDynamicDefinition(e,t){return markDynamicCallbackRebind(defineDynamic({events:{"turn.started":async(n,r)=>{let i=loadContext().get(TurnMemoryLocksKey)?.[t];if(i===void 0||e.provider.tools===void 0)return null;let a={...r,memory:{scope:i.scope,slot:t},turn:i.turn},o=await e.provider.tools(a);if(o===null)return null;if(typeof o!=`object`||Array.isArray(o))throw Error(`Memory slot "${t}" provider.tools() must return a tool map or null.`);return Object.fromEntries(Object.entries(o).map(([n,r])=>{let i=`${t}__${n}`;if(!TOOL_SLUG_PATTERN.test(i))throw Error(`Memory provider tool name "${i}" must start with an ASCII letter, contain only letters, digits, underscores, or dashes, and be at most 64 characters.`);if(!isBrandedToolEntry(r))throw Error(`Memory provider tool "${i}" must be created with defineTool().`);let o=e.description===void 0?r.description:`${e.description}\n\n${r.description}`,s={...r,description:o};return stampDurableDynamicToolCallbacks(s,createProviderToolCallbacks({context:a,definition:e,key:n,tool:r})),[i,s]}))}}}))}function createProviderToolCallbacks(e){let
|
|
1
|
+
import{loadContext}from"#context/container.js";import{TurnMemoryLocksKey}from"#context/keys.js";import{parseJsonObject}from"#shared/json.js";import{defineDynamic}from"#dynamic/definition.js";import{stampDurableDynamicToolCallbacks}from"#tools/durable-callbacks.js";import{TOOL_SLUG_PATTERN}from"#discover/grammar.js";import{isBrandedToolEntry}from"#tools/dynamic.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{markDynamicCallbackRebind}from"#internal/dynamic-tool-rebind.js";function createMemoryToolDynamicDefinition(e,t){return markDynamicCallbackRebind(defineDynamic({events:{"turn.started":async(n,r)=>{let i=loadContext().get(TurnMemoryLocksKey)?.[t];if(i===void 0||e.provider.tools===void 0)return null;let a={...r,memory:{scope:i.scope,slot:t},turn:i.turn},o=await e.provider.tools(a);if(o===null)return null;if(typeof o!=`object`||Array.isArray(o))throw Error(`Memory slot "${t}" provider.tools() must return a tool map or null.`);return Object.fromEntries(Object.entries(o).map(([n,r])=>{let i=`${t}__${n}`;if(!TOOL_SLUG_PATTERN.test(i))throw Error(`Memory provider tool name "${i}" must start with an ASCII letter, contain only letters, digits, underscores, or dashes, and be at most 64 characters.`);if(!isBrandedToolEntry(r))throw Error(`Memory provider tool "${i}" must be created with defineTool().`);let o=e.description===void 0?r.description:`${e.description}\n\n${r.description}`,s={...r,description:o};return stampDurableDynamicToolCallbacks(s,createProviderToolCallbacks({context:a,definition:e,key:n,tool:r})),[i,s]}))}}}))}function createProviderToolCallbacks(e){let{messages:t,...n}=e.context,r=parseJsonObject({context:n,key:e.key}),loadTool=async n=>{let r=n.key,i=n.context;if(typeof r!=`string`||typeof i!=`object`||!i)throw Error(`Memory provider tool callback has an invalid durable closure.`);let a=(await e.definition.provider.tools?.(readMemoryToolsContext({...i,messages:t})))?.[r];if(a===void 0||!isBrandedToolEntry(a))throw Error(`Memory provider tool "${r}" was removed or renamed.`);return a},i={execute:{callback:async(e,t,n)=>await(await loadTool(e)).execute(t,n),closure:r}};for(let t of[`inputSchema`,`outputSchema`])e.tool[t]!==void 0&&(i[t]={callback:async e=>(await loadTool(e))[t],closure:r});return e.tool.approval!==void 0&&(i.approvalRequest={callback:async(e,t)=>await resolveApprovalPolicy((await loadTool(e)).approval)(t),closure:r},typeof e.tool.approval!=`function`&&e.tool.approval.response!==void 0&&(i.approvalResponse={callback:async(t,n)=>{let r=(await loadTool(t)).approval;if(r===void 0||typeof r==`function`||r.response===void 0)throw Error(`Memory provider tool "${e.key}" approval response was removed.`);return await r.response(n)},closure:r})),e.tool.toModelOutput!==void 0&&(i.toModelOutput={callback:async(e,t)=>await(await loadTool(e)).toModelOutput(t),closure:r}),i}function readMemoryToolsContext(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Memory provider tool callback has an invalid durable context.`);let t=e;if(typeof t.channel!=`object`||t.channel===null||typeof t.memory!=`object`||t.memory===null||!Array.isArray(t.messages)||typeof t.session!=`object`||t.session===null||typeof t.turn!=`object`||t.turn===null)throw Error(`Memory provider tool callback has an invalid durable context.`);return t}export{createMemoryToolDynamicDefinition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{ContextContainer}from"#context/container.js";import{resolveKey}from"#context/key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{ContextContainer}from"#context/container.js";import{resolveKey}from"#context/key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{mountedStateKeyName}from"#public/definitions/state.js";const log=createLogger(`context.serialize`),STATE_LAYOUT_KEY=`eve.stateLayout`;function serializeContext(e){let t={};for(let[n,r]of e.entries())try{t[n.name]=n.codec?n.codec.serialize(r):r}catch(e){throw logError(log,`failed to serialize context key`,e,{key:n.name}),e}return(t[BundleKey.name]!==void 0||Object.keys(t).some(e=>e.startsWith(`eve:mount.`)))&&(t[STATE_LAYOUT_KEY]=1),t}async function deserializeContext(e){let t=e,n=new ContextContainer,r=t[BundleKey.name];if(t[STATE_LAYOUT_KEY]!==void 0&&t[STATE_LAYOUT_KEY]!==1||t[STATE_LAYOUT_KEY]===void 0&&Object.keys(t).some(e=>t[e]!==void 0&&e.startsWith(`eve:mount.`)))throw new IncompatibleStateLayoutError;if(r!==void 0){let e=BundleKey.codec;if(e===void 0)throw Error(`Context key "eve.bundle" is missing a codec.`);let i=await e.deserialize(r,n);t[STATE_LAYOUT_KEY]===void 0&&(t=await adoptLegacyStateLayout(t,i)),n.set(BundleKey,i)}for(let[e,r]of Object.entries(t)){if(r===void 0||e===BundleKey.name||e===STATE_LAYOUT_KEY)continue;let t=resolveKey(e);if(t===void 0){log.warn(`dropping unknown context key during deserialization`,{key:e});continue}try{n.set(t,t.codec?await t.codec.deserialize(r,n):r)}catch(t){throw logError(log,`failed to deserialize context key`,t,{key:e}),t}}return n}async function adoptLegacyStateLayout(e,t){let n=await loadCompiledManifest({compiledArtifactsSource:t.compiledArtifactsSource}),r=[n,...n.subagents.map(e=>e.agent)].flatMap(e=>e.extensionMounts),i={};for(let[t,n]of Object.entries(e)){if(n===void 0)continue;if(t===BundleKey.name||resolveKey(t)!==void 0){i[t]=n;continue}let e=r.flatMap(e=>{let n=`${legacyPackageStateNamespace(e.packageName)}.`;if(!t.startsWith(n))return[];let r=mountedStateKeyName(e.mountId,t.slice(n.length));return resolveKey(r)===void 0?[]:[r]});if(e.length>1||e.length===0&&t.startsWith(`eve.`))throw new IncompatibleStateLayoutError(t);i[e[0]??t]=n}return i}function legacyPackageStateNamespace(e){return e.replace(/^@/,``).replace(/[^a-zA-Z0-9._-]+/g,`-`).replace(/^-+|-+$/g,``)||`extension`}var IncompatibleStateLayoutError=class extends Error{constructor(e){super(`Incompatible context state layout${e===void 0?``:` for key "${e}"`}. This deployment cannot read the saved state. Continue this session on its original deployment or start a new session.`),this.name=`IncompatibleStateLayoutError`}};export{IncompatibleStateLayoutError,deserializeContext,serializeContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{contextStorage}from"#context/container.js";import{TurnDeliveryIdsKey}from"#context/keys.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint?.result.session??e.initialSession,r=e.checkpoint===void 0?await contextStorage.run(e.ctx,()=>preserveCancelledTurnMessage(n,e.stepInput)):n,i={...e.checkpoint?.serializedContext??e.beforeBatchContext,[TurnDeliveryIdsKey.name]:t[TurnDeliveryIdsKey.name]};return{action:`cancelled`,serializedContext:preserveSerializedInstrumentationState(preserveSerializedAgentTraceState(preserveSerializedSessionDynamicModelSelection(i,t),t),t),...createDurableSessionValues(r)}}export{createCancelledModelCallBatchResult};
|
|
1
|
+
import{contextStorage}from"#context/container.js";import{AuthKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint?.result.session??e.initialSession,r=e.checkpoint===void 0?await contextStorage.run(e.ctx,()=>preserveCancelledTurnMessage(n,e.stepInput)):n,i={...e.checkpoint?.serializedContext??e.beforeBatchContext,[AuthKey.name]:t[AuthKey.name],[TurnDeliveryIdsKey.name]:t[TurnDeliveryIdsKey.name]};return{action:`cancelled`,serializedContext:preserveSerializedInstrumentationState(preserveSerializedAgentTraceState(preserveSerializedSessionDynamicModelSelection(i,t),t),t),...createDurableSessionValues(r)}}export{createCancelledModelCallBatchResult};
|
|
@@ -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.
|
|
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.71.1//runWorkflowProgramTask`;export{runWorkflowProgramTask};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthKey}from"#context/keys.js";import{createInputResolvedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{readDurableSession,replaceDurableSessionSnapshot}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{relaySessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{getProxyInputRequests,retireProxyInputRequests}from"#harness/proxy-input-requests.js";import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{createTurnWaitingOnInputEvent,routeDeliverPayload}from"#subagents/hitl-proxy.js";import{sendWorkflowAskAnswers,toToolInputResponseResponder}from"#execution/tools/workflow/answer.js";async function routeProxiedDeliverStep(e){"use step";return await withSessionStateDelta(e,routeProxiedDeliver)}async function routeProxiedDeliver(e){let t=getProxyInputRequests(readDurableSession(e.sessionState).state),{delivery:n,serializedContext:r}=await deliverChannelInputResponses({...e,routable:e=>t.has(e.requestId)}),i=readDurableSession(e.sessionState),a=new Map,o=new Map,s,c=!hasDelegatedSessionContext(r)&&n.caller===void 0,l=new Set;for(let[e,t]of n.payloads.entries()){let r=routeDeliverPayload({allowRoute:e=>!l.has(e),payload:t,resolveMessage:c,state:i.state});s??=r.parentAction,r.forSelf!==void 0&&a.set(e,r.forSelf);for(let[t,i]of r.forChildren.entries()){if(i.workflowAsk!==void 0)for(let{requestId:e}of i.resolved.resolutions)l.add(e);let a=JSON.stringify([i.childContinuationToken,i.childSessionInbox?.sessionId??``,i.remote?.sessionId??``,i.resolved.event.sequence,i.resolved.event.stepIndex,i.resolved.event.turnId,i.inputSource??null]),s=o.get(a)??{workflowAsk:i.workflowAsk,remote:i.remote,childContinuationToken:i.childContinuationToken,childSessionInbox:i.childSessionInbox,event:i.resolved.event,metadata:[],payloads:[],resolutions:new Map},c=s.payloads.length;s.payloads.push(i.payload);for(let e of i.resolved.resolutions)s.resolutions.has(e.requestId)||s.resolutions.set(e.requestId,e);if(r.forSelf===void 0&&t===0)for(let t of n.deliveryMetadata??[])t.payloadIndex===e&&s.metadata.push({...t,payloadIndex:c});o.set(a,s)}}let
|
|
1
|
+
import{AuthKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createInputResolvedEvent,createMessageReceivedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{readDurableSession,replaceDurableSessionSnapshot}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{publishSessionEvents,relaySessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{getProxyInputRequests,retireProxyInputRequests}from"#harness/proxy-input-requests.js";import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{createTurnWaitingOnInputEvent,routeDeliverPayload}from"#subagents/hitl-proxy.js";import{sendWorkflowAskAnswers,toToolInputResponseResponder}from"#execution/tools/workflow/answer.js";async function routeProxiedDeliverStep(e){"use step";return await withSessionStateDelta(e,routeProxiedDeliver)}async function routeProxiedDeliver(e){let t=getProxyInputRequests(readDurableSession(e.sessionState).state),{delivery:n,serializedContext:r}=await deliverChannelInputResponses({...e,routable:e=>t.has(e.requestId)}),i=readDurableSession(e.sessionState),a=new Map,o=new Map,s,c=!hasDelegatedSessionContext(r)&&n.caller===void 0,l=new Set,u=[],d=[];for(let[e,t]of n.payloads.entries()){let r=routeDeliverPayload({allowRoute:e=>!l.has(e),payload:t,resolveMessage:c,state:i.state});s??=r.parentAction,r.forSelf!==void 0&&a.set(e,r.forSelf);for(let[t,i]of r.forChildren.entries()){if(i.workflowAsk!==void 0)for(let{requestId:e}of i.resolved.resolutions)l.add(e);if(i.message!==void 0){let{sequence:t,turnId:r}=i.resolved.event;u.push(createMessageReceivedEvent({message:i.message,sequence:t,turnId:r}));for(let t of n.deliveryMetadata??[])t.payloadIndex===e&&d.push(t.deliveryId)}let a=JSON.stringify([i.childContinuationToken,i.childSessionInbox?.sessionId??``,i.remote?.sessionId??``,i.resolved.event.sequence,i.resolved.event.stepIndex,i.resolved.event.turnId,i.inputSource??null]),s=o.get(a)??{workflowAsk:i.workflowAsk,remote:i.remote,childContinuationToken:i.childContinuationToken,childSessionInbox:i.childSessionInbox,event:i.resolved.event,metadata:[],payloads:[],resolutions:new Map},c=s.payloads.length;s.payloads.push(i.payload);for(let e of i.resolved.resolutions)s.resolutions.has(e.requestId)||s.resolutions.set(e.requestId,e);if(r.forSelf===void 0&&t===0)for(let t of n.deliveryMetadata??[])t.payloadIndex===e&&s.metadata.push({...t,payloadIndex:c});o.set(a,s)}}let f=!1,p=[];for(let e of o.values()){if(e.workflowAsk!==void 0){let t=coalesceDeliverPayloads(e.payloads).inputResponses??[];await sendWorkflowAskAnswers(e.workflowAsk,t,toToolInputResponseResponder(n.auth))}else{let t={...n,deliveryMetadata:e.metadata.length===0?void 0:e.metadata,payloads:e.payloads},i=e.remote;if(i!==void 0){let t=await deserializeContext(r),a=await resolveRemoteAgentStreamHeaders({bundle:t.require(BundleKey),name:i.name,resolverId:i.resolverId,url:i.url});await respondToRemoteAgentSession({remote:i,headers:a,auth:n.auth,responses:coalesceDeliverPayloads(e.payloads).inputResponses??[]})}else await resumeSessionInbox(e.childSessionInbox??e.childContinuationToken,t)}e.resolutions.size>0&&p.push(createInputResolvedEvent({resolutions:[...e.resolutions.values()],...e.event})),i=retireProxyInputRequests(i,[...e.resolutions.keys()]),f=!0}p.length>0&&a.size===0&&s===void 0&&getProxyInputRequests(i.state).size>0&&p.push(createTurnWaitingOnInputEvent(i));let m={serializedContext:r,sessionState:f?replaceDurableSessionSnapshot({session:i,state:e.sessionState}):e.sessionState};u.length>0&&(m=await publishSessionEvents({serializedContext:joinTurnDeliveryIds(m.serializedContext,d),sessionState:m.sessionState,sessionWritable:e.sessionWritable},u));let h=await relaySessionEvents({...m,sessionWritable:e.sessionWritable},p);if(s!==void 0)return{...h,...s};let g=[...a].sort(([e],[t])=>e-t),_=g.flatMap(([e],t)=>(n.deliveryMetadata??[]).filter(t=>t.payloadIndex===e).map(e=>({...e,payloadIndex:t}))),v=g.length===0?void 0:{...n,deliveryMetadata:_.length===0?void 0:_,payloads:g.map(([,e])=>e)};return{...h,kind:`continue`,remainder:v}}function joinTurnDeliveryIds(e,t){if(t.length===0)return e;let n=e[TurnDeliveryIdsKey.name]??[];return{...e,[TurnDeliveryIdsKey.name]:[...new Set([...n,...t])]}}async function mapHeldInputResponsesStep(e){"use step";return await withSessionStateDelta(e,async()=>{let t=new Set(e.requestIds),n=await deliverChannelInputResponses({...e,routable:e=>t.has(e.requestId)});return n.delivery===e.delivery?{delivery:void 0}:{delivery:n.delivery,serializedContext:n.serializedContext}})}async function deliverChannelInputResponses(e){let{routable:t}=e;if(!e.delivery.payloads.some(e=>e.inputResponses?.some(e=>!t(e))===!0))return e;let n=await deserializeContext(e.serializedContext),r=n.require(ChannelKey);if(r.deliver===void 0)return e;e.delivery.auth!==void 0&&n.set(AuthKey,e.delivery.auth??null);let i=r.state??{},a=!1,o=[];for(let s of e.delivery.payloads){if(s.inputResponses===void 0){o.push(s);continue}let e=[];for(let o of s.inputResponses){if(t(o)){e.push(o);continue}let c=buildAdapterContext({...r,state:structuredClone(i)},n),l=(await r.deliver({...s,inputResponses:[o],message:void 0},c))?.inputResponses?.filter(t)??[];if(l.length===0){e.push(o);continue}a=!0,i=c.state,e.push(...l)}o.push({...s,inputResponses:e})}if(!a)return e;let s=await deserializeContext(e.serializedContext);return setChannelContext(s,{...r,state:i}),{delivery:{...e.delivery,payloads:o},serializedContext:serializeContext(s)}}export{mapHeldInputResponsesStep,routeProxiedDeliverStep};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
2
|
+
/** How long a `bash` call waits before it leaves the command running in the background. */
|
|
3
|
+
export declare const BASH_YIELD_SECONDS = 30;
|
|
2
4
|
/**
|
|
3
5
|
* Typed input accepted by {@link executeBashOnSandbox}.
|
|
4
6
|
*/
|
|
@@ -6,26 +8,47 @@ export interface BashInput {
|
|
|
6
8
|
readonly command: string;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
11
|
+
* Per-call options for {@link executeBashOnSandbox}.
|
|
10
12
|
*/
|
|
11
|
-
interface
|
|
12
|
-
|
|
13
|
+
export interface BashExecutionOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Stops the command when aborted before the call returns. A command
|
|
16
|
+
* already returned as `running` keeps running.
|
|
17
|
+
*/
|
|
18
|
+
readonly abortSignal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
interface BashStreams {
|
|
13
21
|
readonly stderr: string;
|
|
14
22
|
readonly stdout: string;
|
|
15
23
|
/** True when stdout or stderr was shortened to fit within output limits. */
|
|
16
24
|
readonly truncated: boolean;
|
|
17
25
|
}
|
|
18
26
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
27
|
+
* Structured result returned from {@link executeBashOnSandbox}: the command
|
|
28
|
+
* finished, or it is still running in the background.
|
|
29
|
+
*/
|
|
30
|
+
type BashResult = (BashStreams & {
|
|
31
|
+
readonly status: "completed";
|
|
32
|
+
readonly exitCode: number;
|
|
33
|
+
}) | (BashStreams & {
|
|
34
|
+
readonly status: "running";
|
|
35
|
+
readonly pid: number;
|
|
36
|
+
readonly outputDirectory: string;
|
|
37
|
+
readonly message: string;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Executes one shell command inside the agent's sandbox.
|
|
41
|
+
*
|
|
42
|
+
* A command that finishes within {@link BASH_YIELD_SECONDS} returns its exit
|
|
43
|
+
* code and output. A slower command keeps running in the sandbox as its own
|
|
44
|
+
* process group, writing to files the model reads with later commands, and
|
|
45
|
+
* the call returns its output so far with `status: "running"`. Sandboxes that
|
|
46
|
+
* cannot run background processes, such as `just-bash`, run every command to
|
|
47
|
+
* completion.
|
|
21
48
|
*
|
|
22
49
|
* Both stdout and stderr are tail-truncated to keep the end of the output
|
|
23
50
|
* (where errors and final results typically appear) within the shared
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* Used by the framework `bash` tool and authored wrappers around its
|
|
27
|
-
* exported definition. Centralizing the executor here keeps the error
|
|
28
|
-
* messages and result shape identical across all bash-style tools.
|
|
51
|
+
* output limits.
|
|
29
52
|
*/
|
|
30
|
-
export declare function executeBashOnSandbox(sandbox: SandboxSession, args: BashInput): Promise<BashResult>;
|
|
53
|
+
export declare function executeBashOnSandbox(sandbox: SandboxSession, args: BashInput, options?: BashExecutionOptions): Promise<BashResult>;
|
|
31
54
|
export {};
|
|
@@ -1 +1,24 @@
|
|
|
1
|
-
import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{truncateTail}from"#execution/sandbox/truncate-output.js";async function executeBashOnSandbox(e,t){let
|
|
1
|
+
import{randomUUID}from"node:crypto";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{streamToBuffer}from"#execution/sandbox/stream-utils.js";import{MAX_OUTPUT_BYTES,truncateTail}from"#execution/sandbox/truncate-output.js";const BASH_YIELD_SECONDS=30;async function executeBashOnSandbox(e,t,n={}){let r=formatCommand(t.command);logDevelopmentSandboxCommand(`eve: starting sandbox command: ${r}`);let i=await withDevelopmentSandboxProgress(r,()=>runCommand(e,t.command,n.abortSignal));return logDevelopmentSandboxCommand(i.status===`running`?`eve: sandbox command still running as pid ${i.pid}: ${r}`:`eve: sandbox command finished (exit ${i.exitCode}): ${r}`),i}async function runCommand(e,t,n){n?.throwIfAborted();let r=randomUUID().slice(0,8),i=`/tmp/.eve/jobs/${r}`,a=new AbortController,cancel=()=>{a.abort(n?.reason),Promise.resolve(e.run({command:`kill -TERM -- -"$(cat ${shellQuote(i)}/pid 2>/dev/null)" 2>/dev/null; rm -rf ${shellQuote(i)}`})).catch(()=>{})};n?.addEventListener(`abort`,cancel,{once:!0});try{let n=await e.spawn({abortSignal:a.signal,command:launchCommand(t,i)}),o=Promise.all([readText(n.stdout),readText(n.stderr),n.wait()]).then(([e,t,{exitCode:n}])=>({exitCode:n,stderr:t,stdout:e})),s=await waitUpTo(o,3e4);if(s!==void 0)return completed(s.exitCode,s);let c=await claimRunningJob(e,i,r);if(c===void 0){let e=await o;return completed(e.exitCode,e)}return o.catch(()=>{}),c}finally{n?.removeEventListener(`abort`,cancel)}}function launchCommand(e,t){return[`if command -v bash >/dev/null 2>&1 && kill -0 "$$" 2>/dev/null; then`,` set -- ${shellQuote(t)} ${shellQuote(e)}`,` eval ${shellQuote(`d=$1
|
|
2
|
+
mkdir -p "$d" 2>/dev/null || { eval "$2"; exit; }
|
|
3
|
+
trap 'exit 0' USR1
|
|
4
|
+
echo "$$" > "$d/launcher"
|
|
5
|
+
set -m
|
|
6
|
+
(
|
|
7
|
+
trap : TERM INT
|
|
8
|
+
(eval "$2") > "$d/stdout" 2> "$d/stderr"
|
|
9
|
+
code=$?
|
|
10
|
+
echo "$code" > "$d/exit"
|
|
11
|
+
exit "$code"
|
|
12
|
+
) < /dev/null > /dev/null 2>&1 &
|
|
13
|
+
pid=$!
|
|
14
|
+
set +m
|
|
15
|
+
echo "$pid" > "$d/pid"
|
|
16
|
+
wait "$pid" 2> /dev/null
|
|
17
|
+
code=$?
|
|
18
|
+
mkdir "$d/claimed" 2> /dev/null || exit 0
|
|
19
|
+
cat "$d/stdout"
|
|
20
|
+
cat "$d/stderr" >&2
|
|
21
|
+
rm -rf "$d"
|
|
22
|
+
exit "$code"`)}`,`fi`,`eval ${shellQuote(e)}`].join(`
|
|
23
|
+
`)}async function claimRunningJob(e,t,n){let r=`eve-bash:${n}`,i=await e.run({command:[`cd ${shellQuote(t)} 2>/dev/null && mkdir claimed 2>/dev/null || exit 0`,`kill -USR1 "$(cat launcher)" 2>/dev/null`,`printf '%s %s %s %s\\n' ${r} "$(cat pid)" "$(($(wc -c < stdout)))" "$(($(wc -c < stderr)))"`,`tail -c ${MAX_OUTPUT_BYTES} stdout`,`tail -c ${MAX_OUTPUT_BYTES} stderr >&2`].join(`
|
|
24
|
+
`)}),a=RegExp(`(?:^|\\n)${r} (\\d+) (\\d+) (\\d+)\\n`).exec(i.stdout);if(a===null)return;let o=Number(a[1]),s=i.stdout.slice(a.index+a[0].length),c={stderr:Math.max(0,Number(a[3])-Buffer.byteLength(i.stderr)),stdout:Math.max(0,Number(a[2])-Buffer.byteLength(s))};return{...formatStreams({stderr:i.stderr,stdout:s},c),message:`The command is still running after 30 seconds as process group ${o}; stdout and stderr show its output so far. It keeps writing to ${t}/stdout and ${t}/stderr, and writes its exit code to ${t}/exit when it finishes. Check on it with later commands such as \`tail ${t}/stdout\` or \`cat ${t}/exit\`, and stop it with \`kill -- -${o}\`.`,outputDirectory:t,pid:o,status:`running`}}async function readText(e){return new TextDecoder().decode(await streamToBuffer(e))}async function waitUpTo(e,t){let n;try{return await Promise.race([e,new Promise(e=>{n=setTimeout(()=>e(void 0),t)})])}finally{clearTimeout(n)}}function completed(e,t){return{...formatStreams(t),exitCode:e,status:`completed`}}function formatStreams(e,t={stderr:0,stdout:0}){let n=formatStream(`stdout`,e.stdout,t.stdout),r=formatStream(`stderr`,e.stderr,t.stderr);return{stderr:r.output,stdout:n.output,truncated:n.truncated||r.truncated}}function formatStream(e,t,n){let r=truncateTail(t);return!r.truncated&&n===0?{output:r.output,truncated:!1}:{output:`${n===0?`[${e} truncated: showing last ${r.outputLines} of ${r.totalLines} lines]`:`[${e} truncated: showing last ${r.outputLines} lines; earlier output omitted]`}\n${r.output}`,truncated:!0}}async function withDevelopmentSandboxProgress(e,t){if(!isEveDevEnvironment())return await t();let n=Date.now(),r=setInterval(()=>{logDevelopmentSandboxCommand(`eve: waiting for sandbox command (${Math.round((Date.now()-n)/1e3)}s elapsed): ${e}`)},5e3);r.unref?.();try{return await t()}catch(t){throw logDevelopmentSandboxCommand(`eve: sandbox command failed: ${e}`),t}finally{clearInterval(r)}}function logDevelopmentSandboxCommand(e){isEveDevEnvironment()&&console.log(e)}function formatCommand(e){let t=e.replaceAll(/\s+/g,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}export{BASH_YIELD_SECONDS,executeBashOnSandbox};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{randomUUID}from"node:crypto";import{
|
|
1
|
+
import{randomUUID}from"node:crypto";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{bufferToStream,streamToBuffer}from"#execution/sandbox/stream-utils.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{dirname}from"node:path/posix";import{resolveWorkspacePath}from"#execution/sandbox/bindings/local-provider-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
2
|
`);function createDockerInternalSession(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{resolvePath:resolveWorkspacePath,async spawn(e){let r=[`exec`,`-w`,resolveWorkspacePath(e.workingDirectory??WORKSPACE_ROOT)];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.abortSignal});return e.abortSignal?.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.abortSignal});return i.exitCode===43?null:(expectDockerSuccess(i,`read "${e.path}" from sandbox container`),bufferToStream(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.abortSignal});expectDockerSuccess(a,`remove "${e.path}" from sandbox container`)},async writeFile(e){let r=await streamToBuffer(e.content),i=await t.run([`exec`,`-i`,n,`bash`,`-lc`,`mkdir -p ${shellQuote(dirname(e.path))} && cat > ${shellQuote(e.path)}`],{signal:e.abortSignal,stdin:r});expectDockerSuccess(i,`write "${e.path}" into sandbox container`)}}}export{createDockerInternalSession};
|
|
@@ -26,7 +26,7 @@ export declare function dockerTemplateImageReference(input: {
|
|
|
26
26
|
readonly optionsHash: string;
|
|
27
27
|
readonly templateKey: string;
|
|
28
28
|
}): string;
|
|
29
|
-
export declare function resolveDockerTemplateMarkerPath(
|
|
29
|
+
export declare function resolveDockerTemplateMarkerPath(storagePath: string, input: {
|
|
30
30
|
readonly optionsHash: string;
|
|
31
31
|
readonly templateKey: string;
|
|
32
32
|
}): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdir,readdir,rm,stat,utimes,writeFile}from"node:fs/promises";import"node:fs";import{dirname,join}from"node:path";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL}from"#execution/sandbox/bindings/docker-container.js";import{LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,selectStaleTemplateEntries}from"#execution/sandbox/bindings/local-template-prune.js";const DOCKER_TEMPLATE_IMAGE_REPOSITORY=`eve-sandbox-template`;async function pruneDockerSandboxTemplates(e){let t=e.dockerCli??createDockerCli(),n=resolveDockerTemplateMarkersDirectory(e.appRoot),r;try{r=await readdir(n,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let i=await Promise.all(r.filter(e=>e.isFile()).map(async e=>{let t=join(n,e.name);return{imageTag:e.name,mtimeMs:(await stat(t)).mtimeMs,path:t}})),a=selectStaleTemplateEntries(i,{now:e.now??Date.now(),recentWindowMs:e.recentWindowMs??LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,retainCount:e.retainCount??LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT});for(let e of a){let n=await t.run([`rmi`,dockerTemplateImageReferenceFromTag(e.imageTag)]),r=n.exitCode!==0&&/no such image/i.test(n.stderr);(n.exitCode===0||r)&&await rm(e.path,{force:!0})}}function dockerTemplateImageReference(e){return dockerTemplateImageReferenceFromTag(dockerTemplateImageTag(e))}function dockerTemplateImageReferenceFromTag(e){return`${DOCKER_TEMPLATE_IMAGE_REPOSITORY}:${e}`}function dockerTemplateImageTag(e){return`${e.templateKey.toLowerCase()}-${e.optionsHash}`}function resolveDockerTemplateMarkerPath(e,t){return join(resolveDockerTemplateMarkersDirectory(e),dockerTemplateImageTag(t))}async function touchDockerTemplateMarker(e,t){await mkdir(dirname(e),{recursive:!0});try{let t=new Date;await utimes(e,t,t)}catch{await writeFile(e,`${t}\n`)}}async function dockerImageExists(e,t){return(await e.run([`image`,`inspect`,`--format`,`{{.Id}}`,t])).exitCode===0}async function commitDockerTemplateImage(e){let t=await e.cli.run([`commit`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}=1`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.role=template`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.template-key=${e.templateKey}`,e.containerIdentity,e.imageReference]);return t.exitCode===0?`committed`:(/already(?:\s*|-)?exists/iu.test(`${t.stderr}\n${t.stdout}`)&&await dockerImageExists(e.cli,e.imageReference)||expectDockerSuccess(t,`commit sandbox template image "${e.imageReference}"`),`reused`)}async function ensureDockerBaseImage(e,t){if(t.pullPolicy===`always`){expectDockerSuccess(await e.run([`pull`,t.image]),`pull base image "${t.image}"`);return}if(!await dockerImageExists(e,t.image)){if(t.pullPolicy===`never`)throw Error(`The local sandbox base image "${t.image}" is not present locally and pullPolicy is "never". Pull the image manually or relax the pull policy.`);expectDockerSuccess(await e.run([`pull`,t.image]),`pull base image "${t.image}"`)}}function resolveDockerTemplateMarkersDirectory(e){return join(
|
|
1
|
+
import{mkdir,readdir,rm,stat,utimes,writeFile}from"node:fs/promises";import"node:fs";import{dirname,join}from"node:path";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL}from"#execution/sandbox/bindings/docker-container.js";import{LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,selectStaleTemplateEntries}from"#execution/sandbox/bindings/local-template-prune.js";const DOCKER_TEMPLATE_IMAGE_REPOSITORY=`eve-sandbox-template`;async function pruneDockerSandboxTemplates(e){let t=e.dockerCli??createDockerCli(),n=resolveDockerTemplateMarkersDirectory(resolveSandboxCacheDirectory(e.appRoot)),r;try{r=await readdir(n,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let i=await Promise.all(r.filter(e=>e.isFile()).map(async e=>{let t=join(n,e.name);return{imageTag:e.name,mtimeMs:(await stat(t)).mtimeMs,path:t}})),a=selectStaleTemplateEntries(i,{now:e.now??Date.now(),recentWindowMs:e.recentWindowMs??LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,retainCount:e.retainCount??LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT});for(let e of a){let n=await t.run([`rmi`,dockerTemplateImageReferenceFromTag(e.imageTag)]),r=n.exitCode!==0&&/no such image/i.test(n.stderr);(n.exitCode===0||r)&&await rm(e.path,{force:!0})}}function dockerTemplateImageReference(e){return dockerTemplateImageReferenceFromTag(dockerTemplateImageTag(e))}function dockerTemplateImageReferenceFromTag(e){return`${DOCKER_TEMPLATE_IMAGE_REPOSITORY}:${e}`}function dockerTemplateImageTag(e){return`${e.templateKey.toLowerCase()}-${e.optionsHash}`}function resolveDockerTemplateMarkerPath(e,t){return join(resolveDockerTemplateMarkersDirectory(e),dockerTemplateImageTag(t))}async function touchDockerTemplateMarker(e,t){await mkdir(dirname(e),{recursive:!0});try{let t=new Date;await utimes(e,t,t)}catch{await writeFile(e,`${t}\n`)}}async function dockerImageExists(e,t){return(await e.run([`image`,`inspect`,`--format`,`{{.Id}}`,t])).exitCode===0}async function commitDockerTemplateImage(e){let t=await e.cli.run([`commit`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}=1`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.role=template`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.template-key=${e.templateKey}`,e.containerIdentity,e.imageReference]);return t.exitCode===0?`committed`:(/already(?:\s*|-)?exists/iu.test(`${t.stderr}\n${t.stdout}`)&&await dockerImageExists(e.cli,e.imageReference)||expectDockerSuccess(t,`commit sandbox template image "${e.imageReference}"`),`reused`)}async function ensureDockerBaseImage(e,t){if(t.pullPolicy===`always`){expectDockerSuccess(await e.run([`pull`,t.image]),`pull base image "${t.image}"`);return}if(!await dockerImageExists(e,t.image)){if(t.pullPolicy===`never`)throw Error(`The local sandbox base image "${t.image}" is not present locally and pullPolicy is "never". Pull the image manually or relax the pull policy.`);expectDockerSuccess(await e.run([`pull`,t.image]),`pull base image "${t.image}"`)}}function resolveDockerTemplateMarkersDirectory(e){return join(e,`docker`,`templates`)}export{DOCKER_TEMPLATE_IMAGE_REPOSITORY,commitDockerTemplateImage,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID}from"node:crypto";import{toErrorMessage}from"#shared/errors.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,commitDockerTemplateImage,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{buildSandboxDockerfile,dockerfileImageReference,materializeSandboxDockerfile}from"#execution/sandbox/dockerfile.js";import{hydrateSandboxProviderResources,prepareImmutableResources}from"#execution/sandbox/bindings/immutable-resources.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{isSandboxPreparedArtifactRecord,sandboxProviderResourceIdentity}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";const DOCKER_PROVIDER_NAME=`docker`;function createDockerSandboxProvider(e,t){let n=t??createDockerCli(),r=e??{},i=resolveDockerSandboxOptions(r),a=createDockerSandboxOptionsHash(i),o;function ensureDaemon(){return o??=assertDockerDaemonAvailable(n).catch(e=>{throw o=void 0,e}),o}async function inspectContainerRunning(e){let t=await n.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,e]);return t.exitCode===0?t.stdout.trim()===`true`:void 0}async function openDockerSession(e,t,r,a,o){await ensureDaemon();let s=requirePreparedDockerArtifact(r);if(!await dockerImageExists(n,s.imageReference))throw new SandboxTemplateNotProvisionedError({providerName:DOCKER_PROVIDER_NAME,templateKey:s.imageReference});let c=await inspectContainerRunning(a);if(c===void 0){if(!o)throw Error(`Docker sandbox session container "${a}" no longer exists.`);try{await startDockerContainer({cli:n,containerName:a,image:s.imageReference,initialNetworkPolicy:t?.networkPolicy??`allow-all`,options:i,role:`session`,tags:{agent:e.session.id,sessionId:e.session.id}}),c=!0}catch(e){if(c=/is already in use/u.test(toErrorMessage(e))?await inspectContainerRunning(a):void 0,c===void 0)throw e}}c||expectDockerSuccess(await n.run([`start`,a]),`restart sandbox session container "${a}"`);let l=await resolveDockerHandleIdentity(n,a);return{sandbox:buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:l}),e=>setDockerNetworkPolicy(n,l,e)),async onSessionDelete(){await stopDockerContainerIfRunning(n,l),expectDockerSuccess(await n.run([`rm`,`-f`,l]),`delete sandbox session container "${a}"`)},async onSessionStop(){await stopDockerContainerIfRunning(n,l)},async onRuntimeShutdown(){await stopDockerContainerIfRunning(n,l)}}}return{async prepare(e){e.log?.(`checking Docker daemon`),await ensureDaemon();let t=await materializeSandboxDockerfile({files:e.files,storagePath:e.storagePath}),o=createSandboxProviderIdentity({dockerfile:t?.contentHash,optionsHash:a,resources:sandboxProviderResourceIdentity(e.resources),sourceRevision:e.sourceRevision,version:2}).slice(0,24),s={optionsHash:a,templateKey:o},c=dockerTemplateImageReference(s),l=e.resources.source,u=l.kind===`materialized`?await prepareImmutableResources({storagePath:e.storagePath,provider:DOCKER_PROVIDER_NAME,resourcesKey:l.key,sourcePath:l.path}):void 0,d=resolveDockerTemplateMarkerPath(e.storagePath,s);if(e.log?.(`checking cached template image "${c}"`),await dockerImageExists(n,c))return e.log?.(`reusing cached template image`),await touchDockerTemplateMarker(d,c),{imageReference:c};let f=i.image;t===void 0?(e.log?.(`checking base image "${i.image}"`),await ensureDockerBaseImage(n,i)):(f=dockerfileImageReference({dockerfile:t,templateKey:o}),e.log?.(`building sandbox Dockerfile "${t.path}"`),await buildSandboxDockerfile({cli:n,dockerfile:t,imageReference:f}));let p=`${o}-build-${randomUUID().slice(0,8)}`;e.log?.(`starting template build container`),await startDockerContainer({cli:n,containerName:p,image:f,initialNetworkPolicy:`allow-all`,options:i,resourcesPath:u,role:`template-build`});try{let t=await resolveDockerHandleIdentity(n,p);e.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(n,t);let i=buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:t}),e=>setDockerNetworkPolicy(n,t,e));await hydrateSandboxProviderResources({copySkills:!0,log:e.log,resources:e.resources,session:i}),r.prepare!==void 0&&(e.log?.(`running sandbox preparation`),await r.prepare(createLoggingSandboxSession({log:e.log,session:i}))),e.log?.(`stopping template build container`),expectDockerSuccess(await n.run([`stop`,`-t`,`0`,t]),`stop template build container "${p}"`),e.log?.(`committing template image "${c}"`),await commitDockerTemplateImage({cli:n,containerIdentity:t,imageReference:c,templateKey:o})===`reused`&&e.log?.(`reusing concurrently published template image`),await touchDockerTemplateMarker(d,c)}finally{await n.run([`rm`,`-f`,p]).catch(()=>{})}return{imageReference:c}},async resume(e,t,n){let r=requireDockerSessionState(n);if(r.generation!==dockerGeneration(t,a))throw Error(`Docker sandbox session state is incompatible with this environment.`);return await openDockerSession(e,void 0,t,r.containerName,!1)},async start(e,t,n){let r=dockerSessionName(e.session.id,t,n,a);return{handle:await openDockerSession(e,t,n,r,!0),state:{containerName:r,generation:dockerGeneration(n,a),version:2}}}}}function dockerGeneration(e,t){return createSandboxProviderIdentity({artifact:e,environment:t,version:1})}function dockerSessionName(e,t,n,r){return`eve-sbx-${createSandboxProviderIdentity({artifact:n,environment:r,open:{networkPolicy:t?.networkPolicy},sessionId:e,version:1}).slice(0,32)}`}function requirePreparedDockerArtifact(e){if(!isSandboxPreparedArtifactRecord(e)||typeof e.imageReference!=`string`)throw Error(`Invalid prepared Docker artifact.`);return{imageReference:e.imageReference}}function requireDockerSessionState(e){if(!isSandboxPreparedArtifactRecord(e)||e.version!==2||typeof e.containerName!=`string`||typeof e.generation!=`string`)throw Error(`Invalid Docker sandbox session state.`);return{containerName:e.containerName,generation:e.generation,version:2}}async function resolveDockerHandleIdentity(e,t){let n=await e.run([`container`,`inspect`,`--format`,`{{.Id}}`,t]);expectDockerSuccess(n,`resolve sandbox container identity for "${t}"`);let r=n.stdout.trim();if(r.length===0)throw Error(`Docker returned an empty identity for sandbox container "${t}".`);return r}export{DOCKER_PROVIDER_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxProvider,pruneDockerSandboxTemplates};
|
|
1
|
+
import{randomUUID}from"node:crypto";import{toErrorMessage}from"#shared/errors.js";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{runDockerBaseSetup,startDockerContainer,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,commitDockerTemplateImage,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{buildSandboxDockerfile,dockerfileImageReference,materializeSandboxDockerfile}from"#execution/sandbox/dockerfile.js";import{hydrateSandboxProviderResources,prepareImmutableResources}from"#execution/sandbox/bindings/immutable-resources.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{isSandboxPreparedArtifactRecord,sandboxProviderResourceIdentity}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";const DOCKER_PROVIDER_NAME=`docker`;function createDockerSandboxProvider(e,t){let n=t??createDockerCli(),r=e??{},i=resolveDockerSandboxOptions(r),a=createDockerSandboxOptionsHash(i),o;function ensureDaemon(){return o??=assertDockerDaemonAvailable(n).catch(e=>{throw o=void 0,e}),o}async function inspectContainerRunning(e){let t=await n.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,e]);return t.exitCode===0?t.stdout.trim()===`true`:void 0}async function openDockerSession(e,t,r,a,o){await ensureDaemon();let s=requirePreparedDockerArtifact(r);if(!await dockerImageExists(n,s.imageReference))throw new SandboxTemplateNotProvisionedError({providerName:DOCKER_PROVIDER_NAME,templateKey:s.imageReference});let c=await inspectContainerRunning(a);if(c===void 0){if(!o)throw Error(`Docker sandbox session container "${a}" no longer exists.`);try{await startDockerContainer({cli:n,containerName:a,image:s.imageReference,initialNetworkPolicy:t?.networkPolicy??`allow-all`,options:i,role:`session`,tags:{agent:e.session.id,sessionId:e.session.id}}),c=!0}catch(e){if(c=/is already in use/u.test(toErrorMessage(e))?await inspectContainerRunning(a):void 0,c===void 0)throw e}}c||expectDockerSuccess(await n.run([`start`,a]),`restart sandbox session container "${a}"`);let l=await resolveDockerHandleIdentity(n,a);return{sandbox:buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:l}),e=>setDockerNetworkPolicy(n,l,e)),async onSessionDelete(){await stopDockerContainerIfRunning(n,l),expectDockerSuccess(await n.run([`rm`,`-f`,l]),`delete sandbox session container "${a}"`)},async onSessionStop(){await stopDockerContainerIfRunning(n,l)},async onRuntimeShutdown(){await stopDockerContainerIfRunning(n,l)}}}return{async prepare(e){e.log?.(`checking Docker daemon`),await ensureDaemon();let t=await materializeSandboxDockerfile({files:e.files,storagePath:e.storagePath}),o=createSandboxProviderIdentity({dockerfile:t?.contentHash,optionsHash:a,resources:sandboxProviderResourceIdentity(e.resources),sourceRevision:e.sourceRevision,version:2}).slice(0,24),s={optionsHash:a,templateKey:o},c=dockerTemplateImageReference(s),l=e.resources.source,u=l.kind===`materialized`?await prepareImmutableResources({storagePath:e.storagePath,provider:DOCKER_PROVIDER_NAME,resourcesKey:l.key,sourcePath:l.path}):void 0,d=resolveDockerTemplateMarkerPath(e.storagePath,s);if(e.log?.(`checking cached template image "${c}"`),await dockerImageExists(n,c))return e.log?.(`reusing cached template image`),await touchDockerTemplateMarker(d,c),{imageReference:c};let f=i.image;t===void 0?(e.log?.(`checking base image "${i.image}"`),await ensureDockerBaseImage(n,i)):(f=dockerfileImageReference({dockerfile:t,templateKey:o}),e.log?.(`building sandbox Dockerfile "${t.path}"`),await buildSandboxDockerfile({cli:n,dockerfile:t,imageReference:f}));let p=`${o}-build-${randomUUID().slice(0,8)}`;e.log?.(`starting template build container`),await startDockerContainer({cli:n,containerName:p,image:f,initialNetworkPolicy:`allow-all`,options:i,resourcesPath:u,role:`template-build`});try{let t=await resolveDockerHandleIdentity(n,p);e.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(n,t);let i=buildSandboxSession(createDockerInternalSession({cli:n,containerIdentity:t}),e=>setDockerNetworkPolicy(n,t,e));await hydrateSandboxProviderResources({copySkills:!0,log:e.log,resources:e.resources,session:i}),r.prepare!==void 0&&(e.log?.(`running sandbox preparation`),await r.prepare(createLoggingSandboxSession({log:e.log,session:i}))),e.log?.(`stopping template build container`),expectDockerSuccess(await n.run([`stop`,`-t`,`0`,t]),`stop template build container "${p}"`),e.log?.(`committing template image "${c}"`),await commitDockerTemplateImage({cli:n,containerIdentity:t,imageReference:c,templateKey:o})===`reused`&&e.log?.(`reusing concurrently published template image`),await touchDockerTemplateMarker(d,c)}finally{await n.run([`rm`,`-f`,p]).catch(()=>{}),t!==void 0&&await n.run([`rmi`,f]).catch(()=>{})}return{imageReference:c}},async resume(e,t,n){let r=requireDockerSessionState(n);if(r.generation!==dockerGeneration(t,a))throw Error(`Docker sandbox session state is incompatible with this environment.`);return await openDockerSession(e,void 0,t,r.containerName,!1)},async start(e,t,n){let r=dockerSessionName(e.session.id,t,n,a);return{handle:await openDockerSession(e,t,n,r,!0),state:{containerName:r,generation:dockerGeneration(n,a),version:2}}}}}function dockerGeneration(e,t){return createSandboxProviderIdentity({artifact:e,environment:t,version:1})}function dockerSessionName(e,t,n,r){return`eve-sbx-${createSandboxProviderIdentity({artifact:n,environment:r,open:{networkPolicy:t?.networkPolicy},sessionId:e,version:1}).slice(0,32)}`}function requirePreparedDockerArtifact(e){if(!isSandboxPreparedArtifactRecord(e)||typeof e.imageReference!=`string`)throw Error(`Invalid prepared Docker artifact.`);return{imageReference:e.imageReference}}function requireDockerSessionState(e){if(!isSandboxPreparedArtifactRecord(e)||e.version!==2||typeof e.containerName!=`string`||typeof e.generation!=`string`)throw Error(`Invalid Docker sandbox session state.`);return{containerName:e.containerName,generation:e.generation,version:2}}async function resolveDockerHandleIdentity(e,t){let n=await e.run([`container`,`inspect`,`--format`,`{{.Id}}`,t]);expectDockerSuccess(n,`resolve sandbox container identity for "${t}"`);let r=n.stdout.trim();if(r.length===0)throw Error(`Docker returned an empty identity for sandbox container "${t}".`);return r}export{DOCKER_PROVIDER_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxProvider,pruneDockerSandboxTemplates};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdir,readFile,rm,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{createFileBackedInternalSandboxSession,pathExists}from"#execution/sandbox/bindings/local-provider-utils.js";import{
|
|
1
|
+
import{mkdir,readFile,rm,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{createFileBackedInternalSandboxSession,pathExists}from"#execution/sandbox/bindings/local-provider-utils.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";let justBashModulePromise;async function loadJustBashModule(e){return justBashModulePromise??=e.host.loadOptionalPackage({autoInstall:e.autoInstall,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`,ignoredOptionalDependencies:[`@mongodb-js/zstd`,`node-liblzma`]}).catch(e=>{throw justBashModulePromise=void 0,e}),await justBashModulePromise}async function createBashSandbox(e){let t=await loadJustBashModule({autoInstall:e.autoInstall,host:e.host}),{ReadWriteFs:n,Sandbox:r}=t,i=resolveLocalSandboxFilesystemRootPath(e.rootPath),a=resolveLocalSandboxMetadataPath(e.rootPath),o=await readLocalMetadata(a);await mkdir(i,{recursive:!0});let s=new n({allowSymlinks:!0,maxFileReadSize:2**53-1,root:i}),c=s;if(e.filesystem!==void 0)try{c=await e.filesystem({defaultFilesystem:s,resolveProjectPath:e.host.resolveProjectPath,storagePath:e.storagePath,justBash:t})}catch(e){throw Error(`Failed to create the custom just-bash filesystem.`,{cause:e})}await ensureLocalSandboxDirectories(c);let l=await r.create({cwd:WORKSPACE_ROOT,customCommands:e.customCommands===void 0?void 0:[...e.customCommands],env:o===null?void 0:{...o.env},fs:c,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureState(){return await writeLocalMetadata(a,{env:{...l.bashEnvInstance.getEnv()},version:1}),{rootPath:e.rootPath}},async dispose(){await l.stop()},async readFileBytes(e){let t;try{t=await c.readFileBuffer(e)}catch{return null}return Buffer.from(t)},async removePath(e){await c.rm(e.path,{force:e.force,recursive:e.recursive})},rootPath:e.rootPath,sessionKey:e.sessionKey,async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=e.workingDirectory===void 0?e.command:`( cd ${shellQuote(e.workingDirectory)} && ${e.command} )`,n=await l.runCommand({args:[t],cmd:`eval`,detached:!0,env:e.env,signal:e.abortSignal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.type})},async writeFiles(e){for(let t of e){let e=dirname(t.path);await c.mkdir(e,{recursive:!0}),await c.writeFile(t.path,t.content)}}}}function createJustBashHandle(e){return{sandbox:buildSandboxSession(createFileBackedInternalSandboxSession({sandbox:e})),async onSessionDelete(){await e.dispose(),await rm(e.rootPath,{force:!0,recursive:!0})},async onSessionStop(){await e.dispose()},async onRuntimeShutdown(){await e.dispose()}}}function resolveLocalSandboxFilesystemRootPath(e){return`${e}/fs`}function resolveLocalSandboxMetadataPath(e){return`${e}/metadata.json`}async function ensureLocalSandboxDirectories(e){await e.mkdir(WORKSPACE_ROOT,{recursive:!0})}async function readLocalMetadata(e){if(!await pathExists(e))return null;let t=JSON.parse(await readFile(e,`utf8`));return!isRecord(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 isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isStringRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&Object.values(e).every(e=>typeof e==`string`)}export{createBashSandbox,createJustBashHandle};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID}from"node:crypto";import{access,cp,mkdir,rename,rm,utimes}from"node:fs/promises";import{dirname,join}from"node:path";import{
|
|
1
|
+
import{randomUUID}from"node:crypto";import{access,cp,mkdir,rename,rm,utimes}from"node:fs/promises";import{dirname,join}from"node:path";import{bufferToStream,streamToBuffer}from"#execution/sandbox/stream-utils.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{resolveSandboxModelPath}from"#shared/skill-paths.js";function createFileBackedInternalSandboxSession(e){return{resolvePath:resolveWorkspacePath,async spawn(t){return await e.sandbox.spawn(t)},async readFile(t){let n=await e.sandbox.readFileBytes(t.path);return n===null?null:bufferToStream(n)},async removePath(t){await e.sandbox.removePath(t)},async writeFile(t){let n=await streamToBuffer(t.content);await e.sandbox.writeFiles([{content:n,path:t.path}])}}}function resolveWorkspacePath(e){return e.startsWith(`/`)?e:`${WORKSPACE_ROOT}/${e}`}async function pathExists(e){try{return await access(e),!0}catch{return!1}}async function copyDirectoryAtomically(e,t){let n=`${t}.${randomUUID()}.tmp`;await rm(n,{force:!0,recursive:!0}),await mkdir(dirname(t),{recursive:!0});try{await cp(e,n,{recursive:!0}),await rename(n,t)}catch(e){if(await rm(n,{force:!0,recursive:!0}).catch(()=>{}),await pathExists(t))return;throw e}}async function touchDirectory(e){let t=new Date;await utimes(e,t,t)}function resolveLocalProviderTemplateRootPath(e,t,n){return join(resolveLocalProviderTemplatesDirectory(e,t),n)}function resolveLocalProviderTemplatesDirectory(e,t){return join(e,t,`templates`)}function resolveLocalProviderSessionRootPath(e,t,n){return join(e,t,`sessions`,n)}async function writeSandboxSeedFiles(e,t){for(let n of t){let t=await resolveSandboxModelPath({path:n.path,sandbox:e});typeof n.content==`string`?await e.writeTextFile({content:n.content,path:t}):await e.writeBinaryFile({content:n.content,path:t})}}export{copyDirectoryAtomically,createFileBackedInternalSandboxSession,pathExists,resolveLocalProviderSessionRootPath,resolveLocalProviderTemplateRootPath,resolveLocalProviderTemplatesDirectory,resolveWorkspacePath,touchDirectory,writeSandboxSeedFiles};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{access}from"node:fs/promises";import{posix}from"node:path";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{importInstalledEnginePackage,isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,createMicrosandboxSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{createMicrosandboxWithProgress}from"#execution/sandbox/bindings/microsandbox-create.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";import{isMicrosandboxNotFoundError,isMicrosandboxNotFoundError as isMicrosandboxNotFoundError$1,isMicrosandboxSnapshotSourceRunningError,isMicrosandboxStillRunningError,removeSnapshotIfExists,removeSnapshotIfExists as removeSnapshotIfExists$1,sandboxExists,snapshotExists,snapshotExists as snapshotExists$1}from"#execution/sandbox/bindings/microsandbox-provider-state.js";const MICROSANDBOX_PACKAGE_NAME=`microsandbox`,MICROSANDBOX_INSTALL_SPECIFIER=`${MICROSANDBOX_PACKAGE_NAME}@0.5.5`,MICROSANDBOX_STOP_TIMEOUT_MS=1e4,MICROSANDBOX_HOME=`/home/${MICROSANDBOX_USER}`;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}get name(){return this.#a}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o});let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n})}async detach(){await this.#i.detach().catch(()=>{})}async shutdown(){await this.#i.stop().catch(()=>{}),await this.detach()}async stop(){await this.#i.stop(),await this.detach()}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a);let e=this.#o;e!==void 0&&(await removeSnapshotIfExists$1(this.#e.module,e),this.#o=void 0)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),r=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,r);let i=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:i,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=i,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists$1(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...this.#e.options.env,HOME:MICROSANDBOX_HOME,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(e){let t=this.#i.fs();for(let n of e){let e=posix.dirname(n.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(e)}`,user:MICROSANDBOX_USER}),await t.write(n.path,n.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(n.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{image:this.#e.options.image,networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,log:e.log,module:e.module,name:e.name,networkPolicy:t,options:e.options,resourcesPath:e.resourcesPath,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError$1(t))throw t;return e.metadata.stateSnapshotName===void 0?null:await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists$1(e.module,e.metadata.stateSnapshotName))return null;let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await r.writeMetadata(e.metadataPath,e.metadata.optionsHash),r}const MICROSANDBOX_MISSING_PACKAGE_MESSAGE=`The microsandbox sandbox provider requires the \`microsandbox\` package, which is not bundled with eve. Install it in your application (for example \`pnpm add -D ${MICROSANDBOX_INSTALL_SPECIFIER}\`), or use DockerSandbox or VercelSandbox instead.`;async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>e.host.loadOptionalPackage({autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),installPackageName:MICROSANDBOX_INSTALL_SPECIFIER,missingMessage:MICROSANDBOX_MISSING_PACKAGE_MESSAGE,packageName:MICROSANDBOX_PACKAGE_NAME}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(e){try{let t=await importInstalledEnginePackage({appRoot:e,packageName:MICROSANDBOX_PACKAGE_NAME});return t.isInstalled()?t:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs({...e.options.env,HOME:MICROSANDBOX_HOME}).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.options.image.startsWith(`127.0.0.1:`)&&(t=t.registry(e=>e.insecure())),e.resourcesPath!==void 0&&(t=t.volume(`/eve/resources`,t=>t.bind(e.resourcesPath).readonly())),e.user!==void 0&&(t=t.user(e.user));let n=e.fromSnapshot===void 0?`image "${e.options.image}"`:`snapshot "${e.fromSnapshot}"`;return await createMicrosandboxWithProgress({builder:applyMicrosandboxNetwork(t,e.networkPolicy),errorType:e.module.MicrosandboxError,log:e.log,source:n})}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError$1(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function resolveMicrosandboxLabels(e){return{"eve.provider":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{access}from"node:fs/promises";import{posix}from"node:path";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{importInstalledEnginePackage,isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,createMicrosandboxSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{createMicrosandboxWithProgress}from"#execution/sandbox/bindings/microsandbox-create.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";import{isMicrosandboxNotFoundError,isMicrosandboxNotFoundError as isMicrosandboxNotFoundError$1,isMicrosandboxSnapshotSourceRunningError,isMicrosandboxStillRunningError,removeSnapshotIfExists,removeSnapshotIfExists as removeSnapshotIfExists$1,sandboxExists,snapshotExists,snapshotExists as snapshotExists$1}from"#execution/sandbox/bindings/microsandbox-provider-state.js";const MICROSANDBOX_PACKAGE_NAME=`microsandbox`,MICROSANDBOX_INSTALL_SPECIFIER=`${MICROSANDBOX_PACKAGE_NAME}@0.5.5`,MICROSANDBOX_STOP_TIMEOUT_MS=1e4,MICROSANDBOX_HOME=`/home/${MICROSANDBOX_USER}`;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}get name(){return this.#a}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o});let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n})}async detach(){await this.#i.detach().catch(()=>{})}async shutdown(){await this.#i.stop().catch(()=>{}),await this.detach()}async stop(){await this.#i.stop(),await this.detach()}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a);let e=this.#o;e!==void 0&&(await removeSnapshotIfExists$1(this.#e.module,e),this.#o=void 0)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),r=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,r);let i=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:i,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=i,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists$1(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...this.#e.options.env,HOME:MICROSANDBOX_HOME,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(e){let t=this.#i.fs();for(let n of e){let e=posix.dirname(n.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(e)}`,user:MICROSANDBOX_USER}),await t.write(n.path,n.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(n.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{image:this.#e.options.image,networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,log:e.log,module:e.module,name:e.name,networkPolicy:t,options:e.options,resourcesPath:e.resourcesPath,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError$1(t))throw t;return e.metadata.stateSnapshotName===void 0?null:await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists$1(e.module,e.metadata.stateSnapshotName))return null;let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await r.writeMetadata(e.metadataPath,e.metadata.optionsHash),r}const MICROSANDBOX_MISSING_PACKAGE_MESSAGE=`The microsandbox sandbox provider requires the \`microsandbox\` package, which is not bundled with eve. Install it in your application (for example \`pnpm add -D ${MICROSANDBOX_INSTALL_SPECIFIER}\`), or use DockerSandbox or VercelSandbox instead.`;async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>e.host.loadOptionalPackage({autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),installPackageName:MICROSANDBOX_INSTALL_SPECIFIER,missingMessage:MICROSANDBOX_MISSING_PACKAGE_MESSAGE,packageName:MICROSANDBOX_PACKAGE_NAME}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(e){try{let t=await importInstalledEnginePackage({appRoot:e,packageName:MICROSANDBOX_PACKAGE_NAME});return t.isInstalled()?t:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs({...e.options.env,HOME:MICROSANDBOX_HOME}).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.options.image.startsWith(`127.0.0.1:`)&&(t=t.registry(e=>e.insecure())),e.resourcesPath!==void 0&&(t=t.volume(`/eve/resources`,t=>t.bind(e.resourcesPath).readonly())),e.user!==void 0&&(t=t.user(e.user));let n=e.fromSnapshot===void 0?`image "${e.options.image}"`:`snapshot "${e.fromSnapshot}"`;return await createMicrosandboxWithProgress({builder:applyMicrosandboxNetwork(t,e.networkPolicy),errorType:e.module.MicrosandboxError,log:e.log,source:n})}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError$1(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function resolveMicrosandboxLabels(e){return{"eve.provider":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{streamToBuffer}from"#execution/sandbox/stream-utils.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{VERCEL_EVE_SANDBOX_IMAGE}from"#execution/sandbox/bindings/eve-image.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{createSandboxProviderIdentity}from"#execution/sandbox/provider-identity.js";import{isSandboxPreparedArtifactRecord,providerResourceTargetFiles,sandboxProviderResourceIdentity}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{resolveSandboxModelPath}from"#shared/skill-paths.js";import{isVercelSandboxMissingError,isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{ensureVercelSandboxTags,errorMessage,resolveVercelSandboxTags}from"#execution/sandbox/bindings/vercel-options.js";import{applyInitialVercelNetworkPolicy,createVercelNetworkPolicySetter,ensureVercelSandboxBaseRuntime,withBaseSetupNetworkPolicy}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-sdk.js";import{getNamedVercelSandbox}from"#execution/sandbox/bindings/vercel-lookup.js";import{deleteUnusableVercelSandbox,deleteVercelSandbox,stopVercelSandbox}from"#execution/sandbox/bindings/vercel-lifecycle.js";import{normalizeVercelReadStream}from"#execution/sandbox/bindings/vercel-read-stream.js";function createVercelSandboxProvider(e){let{prepare:t,...n}=e??{};return createVercelSandbox({createOptions:n,prepare:t})}function createVercelSandbox(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n=e.loadDeleteSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),r={timeout:DEFAULT_SANDBOX_TIMEOUT_MS,...e.createOptions},i=e.createSandbox??createVercelEveImageSandbox;async function openSession(e,a,o,s){let c=requirePreparedVercelTemplate(o),{mounts:l,...u}=a??{},d={...r,...u},f=resolveVercelSandboxTags(d.tags,{sessionId:e.session.id}),p=await t(),m={createOptions:d,createSandbox:i,resolveSessionCreateOptions:l===void 0?void 0:async()=>({mounts:l}),sandboxModule:p,sessionKey:s,snapshotId:c.snapshotId,tags:f},h;try{if(h=await ensureSession(m),h=await ensureUsableSession({input:m,loadDeleteSandboxModule:n,session:h}),h.created&&c.snapshotId===void 0&&u.networkPolicy!==void 0)try{await applyInitialVercelNetworkPolicy(h.sandbox,u.networkPolicy)}catch(t){try{await deleteVercelSandbox({createOptions:d,loadDeleteSandboxModule:n,sandbox:h.sandbox})}catch(n){throw AggregateError([t,n],`Failed to apply network policy and discard Vercel sandbox session "${e.session.id}".`,{cause:t})}throw t}}catch(t){throw isVercelSnapshotUnavailableError(t)&&c.snapshotId!==void 0?new SandboxTemplateNotProvisionedError({providerName:`vercel`,templateKey:c.snapshotId}):Error(`Failed to open Vercel sandbox session "${e.session.id}": ${errorMessage(t)}`,{cause:t})}return createHandle({createOptions:d,loadDeleteSandboxModule:n,sandbox:h.sandbox})}return{async prepare(n){let a=providerResourceTargetFiles(n.resources);if(e.skipEmptyPreparation===!0&&e.prepare===void 0&&a.length===0)return{};let o=`eve-sbx-tpl-vercel-${createSandboxProviderIdentity({createOptions:vercelIdentityOptions(r),resolvedImage:r.source===void 0?r.image??VERCEL_EVE_SANDBOX_IMAGE:void 0,resources:sandboxProviderResourceIdentity(n.resources),sourceRevision:n.sourceRevision,version:2}).slice(0,32)}`;try{return{snapshotId:(await ensureTemplateWithUnavailableRetry({createOptions:r,createSandbox:i,loadSandboxModule:t,log:n.log,prepareSandbox:e.prepare,seedFiles:a,templateKey:o})).template.snapshotId}}catch(e){throw Error(`Failed to prepare Vercel sandbox snapshot: ${errorMessage(e)}`,{cause:e})}},async resume(e,i,a){requirePreparedVercelTemplate(i);let o=requireVercelSessionState(a),s=await t(),c=await getNamedVercelSandbox({createOptions:r,sandboxModule:s,sandboxName:o.sandboxName});if(c===null)throw Error(`Vercel sandbox session "${o.sandboxName}" no longer exists.`);return await ensureVercelSandboxBaseRuntime(c),createHandle({createOptions:r,loadDeleteSandboxModule:n,sandbox:c})},async start(e,t,n){let i=vercelSessionName(e.session.id,t,n,r);return{handle:await openSession(e,t,n,i),state:{sandboxName:i,version:3}}}}}function vercelSessionName(e,t,n,r){let i=requirePreparedVercelTemplate(n);return`eve-sbx-vercel-${createSandboxProviderIdentity({artifact:i,createOptions:vercelIdentityOptions(r),options:vercelIdentityOptions(t),sessionId:e,version:1}).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(!isSandboxPreparedArtifactRecord(e)||e.version!==3||typeof e.sandboxName!=`string`)throw Error(`Invalid Vercel sandbox session state.`);return{sandboxName:e.sandboxName,version:3}}function requirePreparedVercelTemplate(e){if(!isSandboxPreparedArtifactRecord(e)||e.snapshotId!==void 0&&typeof e.snapshotId!=`string`)throw Error(`Invalid prepared Vercel sandbox artifact.`);return e.snapshotId===void 0?{}:{snapshotId:e.snapshotId}}async function ensureTemplateWithUnavailableRetry(e){try{return await ensureTemplate(e)}catch(t){if(!isVercelSnapshotUnavailableError(t)&&!isVercelSandboxMissingError(t))throw t;return e.log?.(`cached template disappeared; rebuilding sandbox template`),await ensureTemplate(e)}}async function ensureTemplate(e){let t=await e.loadSandboxModule(),n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:t,sandboxName:e.templateKey}),r=resolveVercelSandboxTags(e.createOptions.tags,e.tags),i=extractAuthorSnapshotId(e.createOptions);n!==null&&isUnprovisionedTerminalTemplateSandbox(n,i)&&(await n.delete(),n=null),n===null?n=await e.createSandbox({sandboxModule:t,createOptions:withBaseSetupNetworkPolicy({...e.createOptions,name:e.templateKey,persistent:!0,tags:r})}):await ensureVercelSandboxTags(n,r);let a=typeof n.currentSnapshotId==`string`&&n.currentSnapshotId.length>0&&n.currentSnapshotId!==i?n.currentSnapshotId:null;if(a!==null)return{template:{sandboxName:n.name,snapshotId:a,templateKey:e.templateKey}};e.log?.(`preparing base runtime inside sandbox`),await ensureVercelSandboxBaseRuntime(n),await applyInitialVercelNetworkPolicy(n,e.createOptions.networkPolicy);let o=buildSandboxSession(createVercelInternalSandboxSession(n),createVercelNetworkPolicySetter(n));await writeVercelSandboxSeedFiles({sandbox:n,seedFiles:e.seedFiles,session:o}),e.log?.(`running sandbox preparation`),await e.prepareSandbox?.(createLoggingSandboxSession({log:e.log,session:o}));let s=await n.snapshot();return{template:{sandboxName:n.name,snapshotId:s.snapshotId,templateKey:e.templateKey}}}async function ensureUsableSession(e){try{return await ensureVercelSandboxBaseRuntime(e.session.sandbox),e.session}catch(t){if(e.session.created||!isVercelSnapshotUnavailableError(t))throw t}await deleteUnusableVercelSandbox({createOptions:e.input.createOptions,loadDeleteSandboxModule:e.loadDeleteSandboxModule,sandbox:e.session.sandbox});let t=await ensureSession(e.input);return await ensureVercelSandboxBaseRuntime(t.sandbox),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,await e.resolveSessionCreateOptions?.());return e.tags!==void 0&&(r.tags=e.tags),{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}function createSessionCreateParams(e,t,n={}){let r={...e.createOptions,...n};if(e.snapshotId===void 0)return withBaseSetupNetworkPolicy({...r,name:t,persistent:!0});let{image:i,runtime:a,source:o,...s}=r;return{...s,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function createHandle(e){let{sandbox:t}=e;return{sandbox:buildSandboxSession(createVercelInternalSandboxSession(t),createVercelNetworkPolicySetter(t)),async onSessionDelete(n){await deleteVercelSandbox({createOptions:e.createOptions,loadDeleteSandboxModule:e.loadDeleteSandboxModule,sandbox:t,signal:n?.abortSignal})},async onSessionStop(){await stopVercelSandbox(t)},async onRuntimeShutdown(){try{await stopVercelSandbox(t)}catch{}}}}function createVercelInternalSandboxSession(e){return{resolvePath:resolveVercelSandboxPath,async spawn(t){let n=await e.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory??WORKSPACE_ROOT,detached:!0,env:t.env,signal:t.abortSignal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.stream})},async readFile(t){return normalizeVercelReadStream(await e.readFile({path:t.path}))},async writeFile(t){let n=await streamToBuffer(t.content),r=await resolveVercelWritePath(e,t.path,t.abortSignal);await e.writeFiles([{content:n,path:r}],{signal:t.abortSignal})},async removePath(t){await e.fs.rm(t.path,{force:t.force,recursive:t.recursive,signal:t.abortSignal})}}}async function writeVercelSandboxSeedFiles(e){if(e.seedFiles.length===0)return;let t=await Promise.all(e.seedFiles.map(async t=>({content:typeof t.content==`string`?Buffer.from(t.content):t.content,path:await resolveSandboxModelPath({path:t.path,sandbox:e.session})})));await e.sandbox.writeFiles(t)}function resolveVercelSandboxPath(e){return e.startsWith(`/`)?e:`${WORKSPACE_ROOT}/${e}`}async function resolveVercelWritePath(e,t,n){let r=await e.runCommand({args:[`-m`,`--`,t],cmd:`realpath`,signal:n}),i=(await r.stdout()).trim();if(r.exitCode!==0||!i.startsWith(`/`)||i.includes(`
|
|
2
2
|
`))throw Error(`Failed to resolve Vercel Sandbox write path: ${t}`);return i}function isUnprovisionedTerminalTemplateSandbox(e,t){let n=e.currentSnapshotId;return typeof n==`string`&&n.length>0&&n!==t?!1:e.status===`aborted`||e.status===`failed`||e.status===`stopped`}function extractAuthorSnapshotId(e){let t=e.source;if(t?.type===`snapshot`&&typeof t.snapshotId==`string`)return t.snapshotId}const DEFAULT_SANDBOX_TIMEOUT_MS=18e5;export{createVercelSandbox,createVercelSandboxProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{contextStorage}from"#context/container.js";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{getSandboxEnvironmentRuntime,runWithSandboxConstructorRuntime}from"#shared/sandbox-environment.js";import{buildCallbackContext,withRuntimeSandboxLifecycle}from"#context/build-callback-context.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{trackActiveSandboxHandle}from"#execution/sandbox/active-handles.js";import{isSandboxPreparedArtifact}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";import{loadSandboxPreparedArtifact}from"#runtime/sandbox/prepared-artifacts.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{ensureDevelopmentSandboxesPrepared}from"#execution/sandbox/development-lazy-prewarm.js";import{createSandboxProviderHost}from"#execution/sandbox/provider-host.js";const pendingSandboxStarts=new Map;async function ensureSandboxAccess(e){let t=e.state?.session
|
|
1
|
+
import{contextStorage}from"#context/container.js";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{getSandboxEnvironmentRuntime,runWithSandboxConstructorRuntime}from"#shared/sandbox-environment.js";import{buildCallbackContext,withRuntimeSandboxLifecycle}from"#context/build-callback-context.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{trackActiveSandboxHandle}from"#execution/sandbox/active-handles.js";import{isSandboxPreparedArtifact}from"#shared/sandbox-provider.js";import{SandboxTemplateNotProvisionedError}from"#shared/sandbox-template-error.js";import{loadSandboxPreparedArtifact}from"#runtime/sandbox/prepared-artifacts.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{ensureDevelopmentSandboxesPrepared}from"#execution/sandbox/development-lazy-prewarm.js";import{createSandboxProviderHost}from"#execution/sandbox/provider-host.js";const pendingSandboxStarts=new Map;async function ensureSandboxAccess(e){let t=e.state?.session?.providerName===void 0?null:e.state.session,n,r,i,a=getRuntimeCompiledArtifactsSandboxAppRoot(e.compiledArtifactsSource)??process.cwd(),o=e.registry.sandbox;if(o===null)return{async captureState(){return{session:t}},async get(){return null},async stop(){}};async function open(n,i,s,c){if(r!==void 0)throw Error(`A sandbox definition can open only one sandbox.`);let l=o.inheritance,u=l?.definition??o.definition;if(u.kind!==`independent`)throw Error(`Sandbox "${u.logicalPath}" has no environment.`);if(s!==u.environment)throw Error(`Sandbox "${u.logicalPath}" selected a different environment.`);if(n!==getSandboxEnvironmentRuntime(u.environment))throw Error(`Sandbox "${u.logicalPath}" selected a different provider.`);if(t!==null)throw Error(`Sandbox "${u.logicalPath}" is already initialized.`);let d=l?.nodeId??e.nodeId,f=await loadSandboxPreparedArtifact({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:d,providerName:n.providerName});if(f===void 0)throw new SandboxTemplateNotProvisionedError({providerName:n.providerName,templateKey:d});let p={host:createSandboxProviderHost(a),session:c,storagePath:resolveSandboxCacheDirectory(a)};r=(async()=>{let e=await n.implementation.start(p,i,f);if(!isSandboxPreparedArtifact(e.state))throw Error(`Sandbox provider "${n.providerName}" returned non-serializable session state.`);return t={providerName:n.providerName,state:e.state,stateProtocolVersion:n.stateProtocolVersion},e.handle})().catch(e=>{throw r=void 0,e});let m=await r;return installHandle(n.providerName,m)}function installHandle(e,t){let r=withRuntimeSandboxLifecycle(t.sandbox,e=>t.onSessionDelete(e),()=>t.onSessionStop());return n={handle:t,providerName:e,sandbox:r},r}async function resumePersisted(n,i){if(t===null)throw Error(`Sandbox session state is missing.`);let s=getSandboxEnvironmentRuntime(n.environment);if(t.providerName!==s.providerName)throw Error(`Sandbox session state belongs to provider "${t.providerName}", not "${s.providerName}".`);if(t.stateProtocolVersion!==s.stateProtocolVersion)throw Error(`Sandbox session state protocol ${t.stateProtocolVersion} is incompatible with provider "${s.providerName}" protocol ${s.stateProtocolVersion}.`);let c=o.inheritance?.nodeId??e.nodeId,l=await loadSandboxPreparedArtifact({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:c,providerName:s.providerName});if(l===void 0)throw new SandboxTemplateNotProvisionedError({providerName:s.providerName,templateKey:c});let u={host:createSandboxProviderHost(a),session:i,storagePath:resolveSandboxCacheDirectory(a)};r=s.implementation.resume(u,l,t.state).catch(e=>{throw r=void 0,e});let d=await r;return installHandle(s.providerName,d),trackActiveSandboxHandle({handle:d,providerName:s.providerName,sessionId:e.sessionId}),d}async function resolveHandle(){let n=o.inheritance,r=n?.definition??o.definition;if(r.kind!==`independent`)throw Error(`Sandbox "${r.logicalPath}" has no resolved parent.`);isEveDevEnvironment()&&e.compiledArtifactsSource.kind===`disk`&&await ensureDevelopmentSandboxesPrepared({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:n?.nodeId??e.nodeId,providerName:getSandboxEnvironmentRuntime(r.environment).providerName});let i={...contextStorage.getStore()===void 0?{auth:{current:null,initiator:null},id:e.sessionId,turn:{id:`sandbox-initialization`,sequence:0}}:buildCallbackContext().session,id:e.sessionId};if(t!==null)return await resumePersisted(r,i);let a=`${n?.nodeId??e.nodeId}\0${e.sessionId}`,s=pendingSandboxStarts.get(a);for(;s!==void 0;){if(t=await s,t!==null)return await resumePersisted(r,i);s=pendingSandboxStarts.get(a)}let c=startHandle(r,i),l=c.then(()=>t,()=>null);pendingSandboxStarts.set(a,l);try{return await c}finally{pendingSandboxStarts.get(a)===l&&pendingSandboxStarts.delete(a)}}async function startHandle(i,a){if(o.inheritance!==void 0)await open(getSandboxEnvironmentRuntime(i.environment),void 0,i.environment,a);else try{let e=await runWithSandboxConstructorRuntime({open:({environment:e,options:t,provider:n})=>open(n,t,e,a)},async()=>i.selector({session:a}));if(n===void 0||e!==n.sandbox)throw Error(`Sandbox "${i.logicalPath}" must return the sandbox it opens.`)}catch(e){let a=n?.handle;if(n=void 0,r=void 0,t=null,a!==void 0)try{await a.onSessionDelete()}catch(t){throw AggregateError([e,t],`Sandbox "${i.logicalPath}" initialization and cleanup both failed.`,{cause:e})}throw e}if(n===void 0)throw Error(`Sandbox "${i.logicalPath}" did not open a provider handle.`);return trackActiveSandboxHandle({handle:n.handle,providerName:n.providerName,sessionId:e.sessionId}),n.handle}function requireHandle(){return i===void 0&&(i=resolveHandle().catch(e=>{throw i=void 0,e})),i}let s=o.inheritance?.definition??o.definition;return{environment:s.kind===`independent`?s.environment:void 0,async captureState(){return r!==void 0&&await r,{session:t}},async delete(a){if(e.ownsSandbox===!1)throw Error(`Only the owning session can delete this sandbox.`);await(await requireHandle()).onSessionDelete(a),n=void 0,r=void 0,t=null,i=void 0},async get(){return await requireHandle(),n?.sandbox??null},async stop(){await(await requireHandle()).onSessionStop(),n=void 0,r=void 0,i=void 0}}}export{ensureSandboxAccess};
|