eve 0.84.0 → 0.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/src/channel/channel-operations.d.ts +2 -18
- package/dist/src/channel/compiled-channel.d.ts +3 -7
- package/dist/src/channel/cross-channel-receive.d.ts +13 -11
- package/dist/src/channel/cross-channel-receive.js +1 -1
- package/dist/src/channel/delivery.js +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/session.d.ts +26 -4
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +2 -0
- package/dist/src/chunks/{use-eve-agent-BbbguIdB.js → use-eve-agent-B2jCfcnG.js} +29 -12
- package/dist/src/chunks/{use-eve-agent-DWjyzplb.js → use-eve-agent-DCLFi26P.js} +29 -12
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/delivery.d.ts +2 -0
- package/dist/src/client/delivery.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/optimistic-message-submissions.js +1 -1
- package/dist/src/client/session-store.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +1 -0
- package/dist/src/client/sessions.js +1 -1
- package/dist/src/client/types.d.ts +7 -4
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@chat-adapter/slack/index.js +13 -13
- package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +75 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +4 -0
- package/dist/src/compiled/@vercel/sandbox/command.d.ts +78 -0
- package/dist/src/compiled/@vercel/sandbox/drive.d.ts +41 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +13 -13
- package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +35 -4
- package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +18 -4
- package/dist/src/compiled/@vercel/sandbox/session.d.ts +29 -3
- package/dist/src/compiled/@vercel/sandbox/utils/pipe-stdin.d.ts +19 -0
- package/dist/src/compiled/_chunks/client/{core-CspsxXR-.js → core-BsvaaMUJ.js} +1 -1
- package/dist/src/compiled/_chunks/node/{auth-Dztlx9pE.js → auth-v5pS3mLo.js} +1 -1
- package/dist/src/compiled/_chunks/node/is-stream-DsuQX_bd.js +1 -0
- package/dist/src/compiled/_chunks/node/token-DHGH-jVc.js +1 -0
- package/dist/src/compiled/_chunks/node/token-util-BH2pw9Qm.js +25 -0
- package/dist/src/compiled/_chunks/node/token-util-CcvxNv76.js +1 -0
- package/dist/src/compiled/_chunks/node/version-C2PfNyEv.js +1 -0
- package/dist/src/compiled/zod/index.js +1 -1
- package/dist/src/compiled/zod/v4/core.js +1 -1
- package/dist/src/compiled/zod-validation-error/index.js +1 -1
- package/dist/src/compiler/artifacts.d.ts +1 -0
- package/dist/src/compiler/artifacts.js +1 -1
- package/dist/src/compiler/manifest.d.ts +2 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/model-catalog.d.ts +8 -18
- package/dist/src/compiler/model-catalog.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest-types.d.ts +3 -0
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/context/keys.d.ts +7 -8
- package/dist/src/context/keys.js +1 -1
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/request.d.ts +1 -0
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/eve-channel/support.js +1 -1
- package/dist/src/execution/agent-sessions/context.d.ts +5 -1
- package/dist/src/execution/agent-sessions/context.js +1 -1
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-session/snapshot.d.ts +1 -2
- package/dist/src/execution/legacy-session/snapshot.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/public-destination.d.ts +3 -0
- package/dist/src/execution/public-destination.js +1 -1
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +2 -0
- package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-connection.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/multiplexed-command.d.ts +11 -1
- package/dist/src/execution/sandbox/multiplexed-command.js +1 -1
- package/dist/src/execution/sandbox/session.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.d.ts +16 -5
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/checkpoint-refusal.d.ts +4 -0
- package/dist/src/execution/session/checkpoint-refusal.js +1 -0
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session/handoff-steps.d.ts +7 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/imported-conversation.d.ts +2 -0
- package/dist/src/execution/session/imported-conversation.js +1 -0
- package/dist/src/execution/session/interrupted-step.js +1 -1
- package/dist/src/execution/session/pre-v27-checkpoint.d.ts +36 -0
- package/dist/src/execution/session/pre-v27-checkpoint.js +1 -0
- package/dist/src/execution/session/program.d.ts +2 -0
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session-callback-request.js +1 -1
- package/dist/src/execution/session-inbox/address.d.ts +1 -0
- package/dist/src/execution/session-inbox/handle.d.ts +7 -0
- package/dist/src/execution/session-inbox/handle.js +1 -0
- package/dist/src/execution/session-inbox/owner.d.ts +4 -4
- package/dist/src/execution/session-inbox/owner.js +1 -1
- package/dist/src/execution/session-inbox/resume.d.ts +1 -0
- package/dist/src/execution/session-inbox/resume.js +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/channel-to.d.ts +12 -0
- package/dist/src/execution/tools/channel-to.js +1 -0
- package/dist/src/execution/tools/workflow/body.d.ts +3 -0
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/step-context.d.ts +5 -0
- package/dist/src/execution/tools/workflow/step-execution.js +1 -1
- package/dist/src/execution/tools/workflow/step.js +1 -1
- package/dist/src/execution/workflow-callback-url.d.ts +2 -3
- package/dist/src/execution/workflow-callback-url.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +3 -1
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/semantic-errors/rules/gateway.js +1 -1
- package/dist/src/harness/session-machine/transitions.js +1 -1
- package/dist/src/internal/application/compiled-artifacts.d.ts +2 -0
- package/dist/src/internal/application/compiled-artifacts.js +2 -2
- package/dist/src/internal/application/optional-package-install.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/attachments/limited-read.d.ts +2 -0
- package/dist/src/internal/attachments/limited-read.js +1 -1
- package/dist/src/internal/attachments/url-refs.js +1 -1
- package/dist/src/internal/capability-error.d.ts +3 -0
- package/dist/src/internal/capability-error.js +1 -0
- package/dist/src/internal/model-catalog.d.ts +39 -16
- package/dist/src/internal/model-catalog.js +1 -1
- package/dist/src/internal/nitro/host/dev-build-host.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/protocol/delivery.d.ts +1 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/linq/inboundContent.js +1 -1
- package/dist/src/public/channels/slack/answers.d.ts +2 -3
- package/dist/src/public/channels/slack/answers.js +1 -1
- package/dist/src/public/channels/slack/api.d.ts +23 -3
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/app-manifest.d.ts +2 -0
- package/dist/src/public/channels/slack/app-manifest.js +1 -1
- package/dist/src/public/channels/slack/auth.d.ts +2 -1
- package/dist/src/public/channels/slack/auth.js +1 -1
- package/dist/src/public/channels/slack/code-channel.d.ts +42 -0
- package/dist/src/public/channels/slack/code-channel.js +1 -0
- package/dist/src/public/channels/slack/defaults.d.ts +7 -3
- package/dist/src/public/channels/slack/defaults.js +3 -3
- package/dist/src/public/channels/slack/hitl.d.ts +7 -17
- package/dist/src/public/channels/slack/hitl.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +4 -3
- package/dist/src/public/channels/slack/index.js +1 -1
- package/dist/src/public/channels/slack/interaction-cards.d.ts +0 -2
- package/dist/src/public/channels/slack/interaction-cards.js +1 -1
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/open-code-channel.d.ts +30 -0
- package/dist/src/public/channels/slack/open-code-channel.js +1 -0
- package/dist/src/public/channels/slack/private-approval-delivery.d.ts +16 -4
- package/dist/src/public/channels/slack/private-approval-delivery.js +1 -1
- package/dist/src/public/channels/slack/renderers.d.ts +58 -6
- package/dist/src/public/channels/slack/renderers.js +1 -1
- package/dist/src/public/channels/slack/reply-delivery.d.ts +4 -0
- package/dist/src/public/channels/slack/reply-delivery.js +1 -1
- package/dist/src/public/channels/slack/request-card-render.d.ts +45 -0
- package/dist/src/public/channels/slack/request-card-render.js +1 -0
- package/dist/src/public/channels/slack/request-cards.d.ts +35 -0
- package/dist/src/public/channels/slack/request-cards.js +3 -0
- package/dist/src/public/channels/slack/sign-in-cancel.d.ts +3 -5
- package/dist/src/public/channels/slack/sign-in-cancel.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +109 -22
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/slack/task-card.d.ts +3 -3
- package/dist/src/public/channels/slack/task-card.js +1 -1
- package/dist/src/public/channels/slack/thread-status.js +1 -1
- package/dist/src/public/channels/teams/api.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/teams/verify.d.ts +9 -5
- package/dist/src/public/channels/teams/verify.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/nuxt/module.js +1 -1
- package/dist/src/public/schedules/subscription.d.ts +10 -1
- package/dist/src/reactions/kinds/model.js +1 -1
- package/dist/src/reactions/kinds/subagent.js +1 -1
- package/dist/src/runtime/agent/resolve-model.d.ts +3 -4
- package/dist/src/runtime/agent/resolve-model.js +1 -1
- package/dist/src/runtime/loaders/artifact-paths.d.ts +1 -0
- package/dist/src/runtime/loaders/artifact-paths.js +1 -1
- package/dist/src/runtime/loaders/bundled-artifacts.d.ts +2 -0
- package/dist/src/runtime/loaders/bundled-artifacts.js +1 -1
- package/dist/src/runtime/loaders/model-metadata.d.ts +4 -0
- package/dist/src/runtime/loaders/model-metadata.js +1 -0
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.d.ts +3 -0
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +2 -2
- package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
- package/dist/src/runtime/subagents/workflow.js +1 -1
- package/dist/src/sandbox/provider.d.ts +2 -0
- package/dist/src/setup/flows/model-source-change.js +1 -1
- package/dist/src/setup/index.d.ts +1 -1
- package/dist/src/setup/primitives/index.d.ts +1 -1
- package/dist/src/setup/primitives/pm/run.d.ts +0 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +0 -1
- package/dist/src/shared/channel-definition.d.ts +4 -4
- package/dist/src/shared/sandbox-session.d.ts +4 -0
- package/dist/src/subagents/adapter.js +1 -1
- package/dist/src/subagents/parent-notification.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/definition.d.ts +21 -0
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/workflow-definition.d.ts +4 -4
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +5 -4
- package/docs/channels/custom.mdx +16 -3
- package/docs/channels/eve.mdx +2 -0
- package/docs/channels/linq.mdx +1 -1
- package/docs/channels/slack.mdx +185 -18
- package/docs/channels/teams.mdx +6 -2
- package/docs/concepts/default-harness.md +6 -0
- package/docs/concepts/upgrade-to-v27-events.md +2 -2
- package/docs/evals/judge.mdx +13 -0
- package/docs/experimental/dynamic-schedules.mdx +2 -2
- package/docs/guides/client/overview.mdx +24 -2
- package/docs/guides/remote-agents.md +8 -0
- package/docs/patterns/fork-conversations-into-new-threads.md +159 -0
- package/docs/patterns/meta.json +1 -0
- package/docs/reference/cli.md +1 -1
- package/docs/sandbox/custom-providers.mdx +1 -1
- package/docs/sandbox/index.mdx +1 -1
- package/docs/schedules.mdx +1 -1
- package/docs/tools/overview.mdx +34 -0
- package/docs/tools/workflows.mdx +51 -5
- package/package.json +2 -2
- package/dist/src/compiled/_chunks/node/token-Bedbhv5z.js +0 -1
- package/dist/src/compiled/_chunks/node/token-util-DpJNusVS.js +0 -1
- package/dist/src/compiled/_chunks/node/token-util-DwHQ2a3c.js +0 -1
- package/dist/src/compiled/_chunks/node/version-C__MqbLM.js +0 -1
- package/dist/src/public/channels/slack/approval-cards.d.ts +0 -25
- package/dist/src/public/channels/slack/approval-cards.js +0 -2
- package/dist/src/runtime/agent/model-catalog.d.ts +0 -10
- package/dist/src/runtime/agent/model-catalog.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var CheckpointRefusal=class extends Error{};function refuse(e){throw new CheckpointRefusal(e)}export{CheckpointRefusal,refuse};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{SESSION_INBOX_CONTEXT_KEY,sessionCommandHookToken}from"#execution/session-inbox/address.js";import{readSerializedSessionSchedule}from"#context/session-schedule.js";import{storedProjection}from"#harness/session-machine/view.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,isHookConflictError}from"#execution/hook-ownership.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";import{createSessionTimeoutControl}from"#execution/session/timeout-control.js";import{prepareSuccessorStep,signalSessionOwnerActivationStep}from"#execution/session/handoff-steps.js";import{
|
|
1
|
+
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{SESSION_INBOX_CONTEXT_KEY,sessionCommandHookToken}from"#execution/session-inbox/address.js";import{readSerializedSessionSchedule}from"#context/session-schedule.js";import{storedProjection}from"#harness/session-machine/view.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,isHookConflictError}from"#execution/hook-ownership.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";import{createSessionTimeoutControl}from"#execution/session/timeout-control.js";import{prepareSuccessorStep,readSessionStreamTailStep,signalSessionOwnerActivationStep}from"#execution/session/handoff-steps.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{createTurnControl}from"#execution/session/turn-control.js";import{HANDOFF_LEASE_RETENTION,handoffLeaseToken,sendSessionHandover}from"#execution/session/handoff.js";import{preV27Projection,withProjection}from"#execution/session/pre-v27-checkpoint.js";import{resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{createSessionStep}from"#execution/create-session-step.js";import{closeSessionStreamStep}from"#execution/close-session-stream-step.js";import{settleContinuationConflictStep}from"#execution/continuation-conflict-step.js";import{migrateSessionCheckpoint}from"#execution/session/checkpoint-migrations.js";import{abandonHandoverIfRunEnds,watchRunEnd}from"#execution/session/run-watch.js";async function workflowEntry(e){"use workflow";let t=e.kind===`initial`?await bootInitialOwner(e,getWorkflowMetadata().workflowRunId):(e.handoffVersion??0)>=3?await bootForcedHandoffOwner(e):await bootReleasedHandoffOwner(e);return t===void 0?{output:``}:{output:(await runPreparedSession(t.session,t.inbox)).output}}function stampSessionIdentity(e,t){return{...e,"eve.sessionId":t,[SESSION_INBOX_CONTEXT_KEY]:{sessionId:t}}}async function prepareInitialOwner(e,t){let n={kind:`owned`,timeoutControl:createSessionTimeoutControl({sessionId:t.sessionId,timeoutMs:t.sessionTimeoutMs}),turnControl:createTurnControl()},r={confirmAfter:t.sessionCreation},[i,a]=await Promise.allSettled([e.claimSessionHook(sessionCommandHookToken(t.sessionId),r),t.continuationToken===``?Promise.resolve():e.claimSessionHook(t.continuationToken,r)]);if(i.status===`rejected`)throw i.reason;if(a.status===`rejected`){if(isHookConflictError(a.reason))return{kind:`alias-conflict`};throw a.reason}return n}function unwrapSettled(e){if(e.status===`rejected`)throw e.reason;return e.value}async function bootInitialOwner(e,t){let n=stampSessionIdentity(e.serializedContext,t),r=getWritable(),i=createSessionInbox(t),a=e.sessionTimeoutMs??DEFAULT_SESSION_TIMEOUT_MS,o=n[`eve.continuationToken`]||``,s=n[`eve.bundle`];try{let c=createSessionStep({agentSessionRuntimeOverrides:n[`eve.agentSessionRuntimeOverrides`],compiledArtifactsSource:s.source,continuationToken:o,dynamicSubagentAgentConfig:n[`eve.dynamicSubagentAgentConfig`],history:e.input.message===void 0?e.input.history:void 0,nodeId:s.nodeId,outputSchema:e.input.outputSchema,rootSessionId:readRootSessionId(n),sessionId:t}),l=prepareInitialOwner(i,{continuationToken:o,sessionCreation:c,sessionId:t,sessionTimeoutMs:a}),u=hasDelegatedSessionContext(n)?resolveInitialTurnCallerStep({serializedContext:n}):Promise.resolve(void 0),[d,f,p]=await Promise.allSettled([c,l,u]),m=unwrapSettled(d),h=unwrapSettled(f);if(h.kind===`alias-conflict`){e.continuationConflictCommand!==void 0&&await settleContinuationConflictStep({command:e.continuationConflictCommand,continuationToken:o}),await i.dispose(),await closeSessionStreamStep({sessionWritable:r});return}let g=unwrapSettled(p);return{inbox:i,session:{admittedDeliveryKeys:e.idempotencyKey===void 0?[]:[e.idempotencyKey],anchor:{kind:`self`},caller:g,capabilities:n[`eve.capabilities`],deploymentId:e.ownerDeploymentId,history:m.history,start:e.input.message===void 0?{kind:`first-message`}:{input:createInitialDelivery(e,n),kind:`turn`},initialTurnControl:h.turnControl,retention:e.retention,serializedContext:n,sessionId:t,sessionState:m.state,sessionTimeoutControl:h.timeoutControl,sessionTimeoutMs:a,sessionWritable:r}}}catch(e){return await i.dispose(),await failSession({error:e,serializedContext:n,sessionId:t,sessionState:void 0,sessionWritable:r})}}async function prepareSuccessor(e,t){let{sessionId:n}=e,r=migrateSessionCheckpoint(e.checkpoint);if(r.kind===`busy`){await signalFailedActivation(e,Error(r.detail),{payloads:[]});return}let i=await prepareSuccessorStep({handoffVersion:e.handoffVersion,migration:r,sessionId:n,...t!==void 0&&{source:t}});if(r.kind===`incompatible`||i.kind===`incompatible`){await signalSessionOwnerActivationStep({activation:{kind:`incompatible`,payloads:[],reason:`checkpoint-version`,runId:getWorkflowMetadata().workflowRunId},token:e.activationToken});return}if(i.kind===`source-gone`){await signalFailedActivation(e,Error(`The session's previous owner no longer holds all of its addresses.`),{payloads:[]});return}if(r.kind===`current`){let{checkpoint:e}=r;return{checkpoint:e,serializedContext:stampSessionIdentity(e.serializedContext,n)}}let{checkpoint:a,turnCount:o}=r.imported;return{checkpoint:a,importedTurnCount:o,serializedContext:stampSessionIdentity(a.serializedContext,n)}}async function placeImportedSession(e,t){if(t.importedTurnCount===void 0)return t;let n=await readSessionStreamTailStep({sessionId:e}),r=preV27Projection(n,t.importedTurnCount);return{...t,checkpoint:withProjection(t.checkpoint,r)}}async function signalFailedActivation(e,t,n){await signalSessionOwnerActivationStep({activation:{error:normalizeSerializableError(t),kind:`failed`,runId:getWorkflowMetadata().workflowRunId,...n},token:e.activationToken})}async function bootForcedHandoffOwner(e){let{attemptKey:t,hookTokens:n,sessionId:r,sourceRunId:i}=e;if(t===void 0||n===void 0||i===void 0){await signalFailedActivation(e,Error(`Session handoff version 3 input is missing attemptKey, hookTokens, or sourceRunId.`),{payloads:[]});return}try{let e=createHook({experimental_minRetention:HANDOFF_LEASE_RETENTION,token:handoffLeaseToken(t)});await claimHookOwnership(e)}catch(t){if(isHookConflictError(t))return;await signalFailedActivation(e,t,{payloads:[]});return}let a;try{a=await prepareSuccessor(e,{hookTokens:n,runId:i})}catch(t){await signalFailedActivation(e,t,{payloads:[]});return}if(a===void 0)return;let o=createSessionInbox(r);try{await o.claimSessionHooks(n,{force:!0,handover:t}),a=await placeImportedSession(r,a)}catch(n){let a=o.claimedTokens.length>0;await signalFailedActivation(e,n,{claimedHooks:a,payloads:[]}),a&&await handBack(o,{attemptKey:t,sessionId:r,sourceRunId:i}),await o.dispose();return}return abandonHandoverIfRunEnds(o,{attemptKey:t,sourceRunId:i}),await startSuccessor(e,o,a)}async function handBack(e,t){let n=watchRunEnd(t.sourceRunId),r=new AbortController;try{if(await Promise.race([e.whenTakenOver(r.signal).then(()=>`taken-back`),n.ended.then(()=>`source-ended`)])===`source-ended`)return}finally{n.stop(),r.abort()}await sendSessionHandover({attemptKey:t.attemptKey,payloads:e.drain(),sessionId:t.sessionId})}async function bootReleasedHandoffOwner(e){let t=createSessionInbox(e.sessionId),n;try{if(n=await prepareSuccessor(e),n===void 0)return;await t.claimSessionHooks(sessionHookTokens({serializedContext:n.serializedContext,sessionState:n.checkpoint.sessionState})),n=await placeImportedSession(e.sessionId,n),await signalSessionOwnerActivationStep({activation:{kind:`active`},token:e.activationToken})}catch(n){await signalFailedActivation(e,n,{payloads:await t.release()});return}return await startSuccessor(e,t,n)}async function startSuccessor(e,t,n){let{sessionId:r}=e,{checkpoint:i,serializedContext:a}=n;return{inbox:t,session:{anchor:{kind:`successor`},admittedDeliveryKeys:i.admittedDeliveryKeys,caller:e.delivery?.caller,capabilities:i.capabilities,compactFirst:n.importedTurnCount!==void 0&&i.history.length>0,deploymentId:e.ownerDeploymentId,history:i.history,start:e.delivery===void 0?storedProjection(i.sessionState.snapshot.session.state).view.session.status===`new`?{kind:`first-message`}:{kind:`parked`}:{input:e.delivery,kind:`turn`},retention:i.retention,serializedContext:a,sessionId:r,sessionState:i.sessionState,sessionTimeoutControl:createSessionTimeoutControl({deadline:e.reason===`prewarm`?e.sessionTimeoutDeadline:void 0,sessionId:r,timeoutMs:i.sessionTimeoutMs}),sessionTimeoutMs:i.sessionTimeoutMs,sessionWritable:e.sessionWritable}}}function createInitialDelivery(e,t){if(e.input.message!==void 0)return{auth:t[`eve.auth`],idempotencyKey:e.idempotencyKey,schedule:readSerializedSessionSchedule(t),deliveryMetadata:t[`eve.channelDelivery`]===void 0?void 0:[{...t[`eve.channelDelivery`],payloadIndex:0}],kind:`deliver`,payloads:[attachClientContext({message:e.input.message,context:e.input.context,history:e.input.history,outputSchema:e.input.outputSchema,state:e.input.state},readClientContext(e.input))],requestId:readChannelRequestId(t)}}workflowEntry.workflowId=`workflow//eve//workflowEntry`;export{bootInitialOwner,workflowEntry};
|
|
@@ -52,7 +52,9 @@ export type SessionCheckpointValidation = {
|
|
|
52
52
|
export declare function prepareSuccessorStep(input: {
|
|
53
53
|
/** Absent for version 1 sources, which predate the field. */
|
|
54
54
|
readonly handoffVersion: number | undefined;
|
|
55
|
-
readonly migration: SessionCheckpointMigration
|
|
55
|
+
readonly migration: Exclude<SessionCheckpointMigration, {
|
|
56
|
+
readonly kind: "busy";
|
|
57
|
+
}>;
|
|
56
58
|
readonly sessionId: string;
|
|
57
59
|
/** Version 3: the run that still holds the session and the addresses it hands over. */
|
|
58
60
|
readonly source?: {
|
|
@@ -114,3 +116,7 @@ export declare function signalSessionAnchorStep(input: {
|
|
|
114
116
|
};
|
|
115
117
|
readonly token: string;
|
|
116
118
|
}): Promise<void>;
|
|
119
|
+
/** The position of the session stream's last line, or `-1` before the first. */
|
|
120
|
+
export declare function readSessionStreamTailStep(input: {
|
|
121
|
+
readonly sessionId: string;
|
|
122
|
+
}): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getWorld,resumeHook}from"#internal/workflow/runtime.js";import{hasRunEnded,startWorkflowOnDeployment,workflowEntryReference}from"#execution/workflow-runtime.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-read.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{findSessionHookHolder}from"#execution/session-inbox/owner.js";import{EVE_PREWARM_ATTRIBUTE,EVE_SESSION_ATTRIBUTE,EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{owningSandboxDefinition}from"#runtime/sandbox/registry.js";import{isRetiredSandboxSessionState,resolvePersistedSandboxSessionState}from"#sandbox/state.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";import{mapWithConcurrency}from"#shared/map-with-concurrency.js";import{isSessionStateIdleForHandoff}from"#execution/session/handoff-state.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";const log=createLogger(`execution.handoff`);async function startSuccessorStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,sessionWritable:i,targetDeploymentId:a,...o}=e,{capabilities:s}=await getWorld();if(s?.hookForceClaim!==!0||s.hookRetention?.active!==!0)return log.warn(`session handoff unavailable: the Workflow world cannot force-claim hooks`,{sessionId:n}),{kind:`unsupported`};if(!isSessionStateIdleForHandoff(r))return{kind:`not-idle`};let c={...o,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:a,sessionWritable:i,sessionId:n};return{kind:`started`,runId:(await startWorkflowOnDeployment(workflowEntryReference,[c],a,r.retention===void 0?void 0:{experimental_retention:r.retention})).runId}}async function hasRunEndedStep(e){"use step";return await hasRunEnded(e.runId)}async function prepareSuccessorStep(e){"use step";let{migration:t}=e,unreadable=t=>(log.warn(`session handoff refused: this deployment cannot read the checkpoint`,{detail:t,readableCheckpointVersion:SESSION_CHECKPOINT_VERSION,sessionId:e.sessionId}),{kind:`incompatible`,reason:`checkpoint-version`});if(t.kind===`incompatible`)return unreadable(t.detail);let{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getWorld,resumeHook}from"#internal/workflow/runtime.js";import{hasRunEnded,startWorkflowOnDeployment,workflowEntryReference}from"#execution/workflow-runtime.js";import{readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-read.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{findSessionHookHolder}from"#execution/session-inbox/owner.js";import{EVE_PREWARM_ATTRIBUTE,EVE_SESSION_ATTRIBUTE,EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{owningSandboxDefinition}from"#runtime/sandbox/registry.js";import{isRetiredSandboxSessionState,resolvePersistedSandboxSessionState}from"#sandbox/state.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";import{mapWithConcurrency}from"#shared/map-with-concurrency.js";import{isSessionStateIdleForHandoff}from"#execution/session/handoff-state.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";const log=createLogger(`execution.handoff`);async function startSuccessorStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,sessionWritable:i,targetDeploymentId:a,...o}=e,{capabilities:s}=await getWorld();if(s?.hookForceClaim!==!0||s.hookRetention?.active!==!0)return log.warn(`session handoff unavailable: the Workflow world cannot force-claim hooks`,{sessionId:n}),{kind:`unsupported`};if(!isSessionStateIdleForHandoff(r))return{kind:`not-idle`};let c={...o,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:a,sessionWritable:i,sessionId:n};return{kind:`started`,runId:(await startWorkflowOnDeployment(workflowEntryReference,[c],a,r.retention===void 0?void 0:{experimental_retention:r.retention})).runId}}async function hasRunEndedStep(e){"use step";return await hasRunEnded(e.runId)}async function prepareSuccessorStep(e){"use step";let{migration:t}=e,unreadable=t=>(log.warn(`session handoff refused: this deployment cannot read the checkpoint`,{detail:t,readableCheckpointVersion:SESSION_CHECKPOINT_VERSION,sessionId:e.sessionId}),{kind:`incompatible`,reason:`checkpoint-version`});if(t.kind===`incompatible`)return unreadable(t.detail);let refuse=e=>{if(t.kind===`pre-v27`)return unreadable(e);throw Error(e)},n=t.kind===`pre-v27`?t.imported.checkpoint:t.checkpoint,r=n.sessionTimeoutMs;if(r!==!1&&(typeof r!=`number`||!Number.isFinite(r)||r<0))return refuse(`Session checkpoint contains an invalid timeout duration.`);let i;try{i=await deserializeContext(n.serializedContext)}catch(e){if(e instanceof IncompatibleStateLayoutError)return unreadable(e.message);throw e}let a=i.require(BundleKey),o=readDurableSession(n.sessionState).sandboxState?.session;if(o!=null&&!isRetiredSandboxSessionState(o)){let e=owningSandboxDefinition(getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox);if(e.kind!==`independent`)return refuse(`Session checkpoint sandbox has no resolved provider.`);let t=getSandboxEnvironmentRuntime(e.environment),n=resolvePersistedSandboxSessionState(o,t);if(n?.providerName!==t.providerName||n.stateProtocolVersion!==t.stateProtocolVersion)return refuse(`Session checkpoint sandbox provider state is incompatible.`)}return isSessionStateIdleForHandoff(n)?e.source!==void 0&&!await holdsEveryAddress(e.source)?{kind:`source-gone`}:(await recordSessionOwner(e.sessionId),(e.handoffVersion??1)<SESSION_HANDOFF_VERSION&&log.info(`session moved from an owner that releases its addresses first`,{handoffVersion:e.handoffVersion??1,sessionId:e.sessionId}),t.kind===`pre-v27`&&log.info(`session handoff accepted from an owner before v27`,{sessionId:e.sessionId}),{kind:`valid`}):refuse(`Session checkpoint contains pending work and cannot be handed off.`)}async function holdsEveryAddress(e){return(await mapWithConcurrency(e.hookTokens,16,e=>findSessionHookHolder(sessionInboxHookToken(e)))).every(t=>t?.runId===e.runId)}async function reportSessionHandoffRetainedStep(e){"use step";log.warn(`session handoff failed; the current owner keeps the session`,{...e,checkpointVersion:SESSION_CHECKPOINT_VERSION})}async function recordSessionOwnerStep(e){"use step";await recordSessionOwner(e.sessionId)}async function recordSessionOwner(e){let{setAttributes:t}=await import(`#compiled/@workflow/core/index.js`);await t({[EVE_SESSION_ATTRIBUTE]:e,[EVE_PREWARM_ATTRIBUTE]:`1`,[EVE_VERSION_ATTRIBUTE]:resolveInstalledPackageInfo().version},{allowReservedAttributes:!0})}async function signalSessionOwnerActivationStep(e){"use step";try{await resumeHook(e.token,e.activation)}catch(e){if(!HookNotFoundError.is(e))throw e}}async function reportSessionTakenOverOutsideAttemptStep(e){"use step";log.error(`session taken over with no handoff attempt open; this run leaves without finalizing`,{sessionId:e.sessionId})}async function reportHandoverPartStuckStep(e){"use step";log.warn(`session handover part keeps failing; the previous owner keeps retrying`,e)}async function sendSessionHandoverPartStep(e){"use step";let t={"eve.handoff.buffered_payload_count":e.bufferedPayloadCount,"eve.handoff.part_index":e.part.index};e.part.index===0&&traceSessionHandover(`forwarding_started`,e.sessionId,e.part.attemptKey,t);try{let n=await resumeHook(sessionInboxHookToken(sessionCommandHookToken(e.sessionId)),{...e.part,kind:`handover`});return traceSessionHandover(e.part.final===!0?`final_submitted`:`part_submitted`,e.sessionId,e.part.attemptKey,{...t,"eve.handoff.destination_run_id":n.runId}),`delivered`}catch(e){if(HookNotFoundError.is(e))return`session-ended`;throw e}}async function signalSessionAnchorStep(e){"use step";await resumeHook(e.token,e.result)}async function readSessionStreamTailStep(e){"use step";return await readSessionStreamTailIndex(e.sessionId)}export{hasRunEndedStep,prepareSuccessorStep,readSessionStreamTailStep,recordSessionOwnerStep,reportHandoverPartStuckStep,reportSessionHandoffRetainedStep,reportSessionTakenOverOutsideAttemptStep,sendSessionHandoverPartStep,signalSessionAnchorStep,signalSessionOwnerActivationStep,startSuccessorStep};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isUserMessageKind,validateHarnessModelMessages}from"#harness/messages.js";function normalizeHistory(e){let t=[],n=new Map,settle=()=>{n.size!==0&&(t.push({role:`tool`,content:[...n].map(([e,t])=>({type:`tool-result`,toolCallId:e,toolName:t,output:{type:`error-text`,value:`Interrupted by the session upgrade. Start this work again if it is still needed.`}}))}),n.clear())};for(let r of e){let e=r;if(e.role===`assistant`&&Array.isArray(e.content))e={...e,content:e.content.filter(e=>e.type!==`tool-approval-request`)};else if(e.role===`tool`&&(e={...e,content:e.content.filter(e=>e.type!==`tool-approval-response`)},e.content.length===0))continue;if(e.role!==`tool`&&settle(),e.role===`assistant`&&Array.isArray(e.content))for(let t of e.content)t.type===`tool-call`&&n.set(t.toolCallId,t.toolName);if(e.role===`tool`)for(let t of e.content)t.type===`tool-result`&&n.delete(t.toolCallId);let i=e.kind;t.push(e.role===`user`&&!isUserMessageKind(i)?{...e,kind:`user`}:e)}return settle(),validateHarnessModelMessages(t)}export{normalizeHistory};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createErrorId,createLogger}from"#internal/logging.js";import{eventsOfLine}from"#protocol/session-lines.js";import{currentProjection,saveSessionProjection}from"#harness/session-machine/current.js";import{rowOf}from"#protocol/session-projection/tree.js";import{serializeContext}from"#context/serialize.js";import{createImportedHistoryMessages}from"#harness/messages.js";import{applyTransition,dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{fail,receive,stopInterruptedSteps}from"#harness/session-machine/transitions.js";import{
|
|
1
|
+
import{createErrorId,createLogger}from"#internal/logging.js";import{eventsOfLine}from"#protocol/session-lines.js";import{currentProjection,saveSessionProjection}from"#harness/session-machine/current.js";import{rowOf}from"#protocol/session-projection/tree.js";import{serializeContext}from"#context/serialize.js";import{createImportedHistoryMessages}from"#harness/messages.js";import{applyTransition,dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{fail,receive,stopInterruptedSteps}from"#harness/session-machine/transitions.js";import{activeTurnIdOf}from"#protocol/session-projection.js";import{controlAdmitted,fact}from"#harness/facts.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{supersede}from"#harness/session-machine/cascade.js";import{preserveStoppedTurnMessage}from"#execution/cancelled-model-call-batch.js";import{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{interruptedAttemptNote}from"#harness/interrupted-attempt.js";import{replaceSessionHistory}from"#harness/compaction/step.js";import{summarizeFailure}from"#execution/failure-summary.js";const log=createLogger(`execution.interrupted-step`);function readInterruptedAttempt(e,t){let n=new Map,r=new Map,i=new Set,a,o=!1,s,call=e=>{let t=n.get(e);return t===void 0&&n.set(e,t={name:``,started:!1}),t};for(let{line:e,position:n}of t)if(`facts`in e)for(let t of eventsOfLine(e,n,e.at))switch(t.type){case`call.requested`:Object.assign(call(t.data.callId),{input:t.data.input,name:t.data.capability.name});break;case`call.started`:call(t.data.callId).started=!0;break;case`call.settled`:call(t.data.callId).outcome=t.data.outcome;break;case`interaction.settled`:i.add(t.data.interactionId);break;case`content.completed`:t.data.kind===`text`&&typeof t.data.value==`string`&&r.set(t.data.partId,t.data.value);break;case`turn.settled`:{let e=(t.data.reply??[]).flatMap(e=>r.get(e)??[]);s={failed:t.data.outcome===`failed`,...e.length>0&&{text:e.join(`
|
|
2
2
|
|
|
3
3
|
`)}};break}case`session.ended`:a=t.data.outcome;break;case`context.settled`:t.data.kind===`clear`&&t.data.outcome===`completed`&&(o=!0)}return{calls:n,cleared:o,sessionEnded:a,settledInteractions:i,settledTurn:s,since:e}}async function recoverInterruptedStep(e){let{attempt:t,ctx:n}=e,r=e.session,publish=async t=>{r=await e.publish(t,r)},view=()=>sessionView(currentProjection(n),r.state),closeAttempt=async e=>{let t=currentProjection(n).view,r=supersede(t,n=>{let r=rowOf(t,n.family,n.id);return r!==void 0&&e(n,r)},`step-interrupted`);r.length>0&&await publish(r)},introduced=e=>e.introducedAt>=t.since,finish=e=>{let t=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(n,e.session),currentProjection(n)),n);return{result:resolveSessionStepResult({...e,session:t},serializeContext(n))}};if(t.sessionEnded!==void 0)return finish({next:{done:!0,isError:t.sessionEnded===`failed`,output:t.settledTurn?.text??``},session:r});if(e.control!==void 0){if(await closeAttempt(({family:e},t)=>(e===`run`||e===`change`)&&introduced(t)),t.cleared){let e=saveTransition(r,{clearsHistory:!0,events:[],signIns:[],turn:{remembered:view().turn.remembered,suspended:[]}});r=replaceSessionHistory(e,[])}let{delivery:i,kind:a}=e.control,o=i===void 0?void 0:currentProjection(n).view.deliveries[i.deliveryId]?.status;return i!==void 0&&o!==`settled`&&await publish([...o===void 0?[controlAdmitted(i,a)]:[],fact(`delivery.settled`,{deliveryId:i.deliveryId,outcome:`failed`,reason:`${a}-interrupted`})]),finish({next:null,session:r})}let{settledTurn:i}=t;if(i!==void 0&&activeTurnIdOf(currentProjection(n))===void 0)return r={...r,history:[...r.history,...createImportedHistoryMessages(e.stepInput?.history??[])]},r=await preserveStoppedTurnMessage(n,r,e.stepInput),i.text!==void 0&&(r={...r,history:[...r.history,{content:i.text,role:`assistant`}]}),finish({next:null,session:r,settledTurn:{isError:i.failed,output:i.text??``}});let a=stopInterruptedSteps(view(),t),o=new Set(view().turn.suspended.filter(e=>!a.turn.suspended.includes(e)).flatMap(e=>e.requests.map(e=>e.interactionId)));await closeAttempt(({family:e,id:n},r)=>{switch(e){case`run`:case`change`:return introduced(r);case`call`:return r.taskId===void 0&&(introduced(r)||t.calls.get(n)?.started===!0);case`interaction`:return!view().relayedRequestIds.has(n)&&(introduced(r)||o.has(n));default:return!1}});let s=activeTurnIdOf(currentProjection(n)),c=s===void 0?0:turnInterruptions(r.state,s)+1;r=saveTransition(r,a);let l=interruptedAttemptNote(t.calls);if(l!==void 0&&(r={...r,history:[...r.history,l]}),e.failed===void 0&&c<=3){let{settledInteractions:n}=t,i=e.stepInput?.answers?.filter(e=>!n.has(e.interactionId));return{session:s===void 0?r:withTurnInterruptions(r,s,c),stepInput:e.stepInput===void 0?void 0:{...e.stepInput,answers:i}}}e.admission.length>0&&await publish(e.admission);let u=(e.stepInput?.deliveries??[]).filter(({deliveryId:e})=>currentProjection(n).view.deliveries[e]?.status===`admitted`);u.length>0&&await publish(receive(view(),{deliveries:u}).events);let d=activeTurnIdOf(currentProjection(n));if(d===void 0)return finish({next:null,session:r});r=await preserveStoppedTurnMessage(n,r,e.stepInput);let f=e.failed===void 0?{code:`STEP_INTERRUPTED`,details:{errorId:createErrorId()},message:`This turn was interrupted too many times to continue.`}:summarizeFailure(e.failed.error,`STEP_FAILED`);return log.error(`turn failed`,{code:f.code,errorId:f.details.errorId,sessionId:r.sessionId,turnId:d}),r=await applyTransition(r,fail(view(),f),publish),finish({next:null,session:r,settledTurn:{isError:!0,output:f.message}})}const INTERRUPTIONS_STATE_KEY=`eve.turn-interruptions`,MAX_TURN_INTERRUPTIONS=3;function turnInterruptions(e,t){let n=e?.[INTERRUPTIONS_STATE_KEY];return n?.turnId===t?n.count:0}function withTurnInterruptions(e,t,n){return{...e,state:{...e.state,[INTERRUPTIONS_STATE_KEY]:{count:n,turnId:t}}}}export{MAX_TURN_INTERRUPTIONS,readInterruptedAttempt,recoverInterruptedStep};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type SessionCheckpoint } from "#execution/session/handoff.js";
|
|
2
|
+
import { type SessionProjection } from "#protocol/session-projection.js";
|
|
3
|
+
export interface PreV27Checkpoint<C = SessionCheckpoint> {
|
|
4
|
+
/** The checkpoint in v27's shape, without its session projection. */
|
|
5
|
+
readonly checkpoint: C;
|
|
6
|
+
/** Turns the earlier owner numbered: the next turn takes the next number. */
|
|
7
|
+
readonly turnCount: number;
|
|
8
|
+
}
|
|
9
|
+
export type PreV27CheckpointImport =
|
|
10
|
+
/** Its checkpoint still unchecked against the current shape. */
|
|
11
|
+
{
|
|
12
|
+
readonly kind: "pre-v27";
|
|
13
|
+
readonly imported: PreV27Checkpoint<Record<string, unknown>>;
|
|
14
|
+
}
|
|
15
|
+
/** Work the earlier owner runs will finish; a later delivery can move the session. */
|
|
16
|
+
| {
|
|
17
|
+
readonly kind: "busy";
|
|
18
|
+
readonly detail: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: "incompatible";
|
|
21
|
+
readonly detail: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function isPreV27CheckpointVersion(version: unknown): version is number;
|
|
24
|
+
/**
|
|
25
|
+
* Reads a pre-v27 checkpoint in v27's shape. Pure, so the session workflow can run it before
|
|
26
|
+
* validation. The earlier owner only hands off an idle session; a task it still tracks keeps the
|
|
27
|
+
* session on that owner.
|
|
28
|
+
*/
|
|
29
|
+
export declare function importPreV27Checkpoint(checkpoint: Readonly<Record<string, unknown>>): PreV27CheckpointImport;
|
|
30
|
+
/**
|
|
31
|
+
* The projection of a session whose earlier lines a v27 writer never folded: it writes after
|
|
32
|
+
* `tailIndex`, and its next turn follows the earlier owner's last. An empty stream has not opened.
|
|
33
|
+
*/
|
|
34
|
+
export declare function preV27Projection(tailIndex: number, turnCount: number): SessionProjection;
|
|
35
|
+
/** The imported checkpoint with its session projection. */
|
|
36
|
+
export declare function withProjection(checkpoint: SessionCheckpoint, projection: SessionProjection): SessionCheckpoint;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{EARLIER_REMOTE_CALLER_CONTEXT_KEY_NAME,SESSION_CALLBACK_CONTEXT_KEY_NAME}from"#context/key-names.js";import{SESSION_PROJECTION_STATE_KEY}from"#harness/session-machine/view.js";import{DURABLE_SESSION_VERSION}from"#execution/durable-session-read.js";import{initialSessionProjection}from"#protocol/session-projection.js";import{normalizeHistory}from"#execution/session/imported-conversation.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";import{CheckpointRefusal,refuse}from"#execution/session/checkpoint-refusal.js";function isPreV27CheckpointVersion(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=10&&e<=17}function importPreV27Checkpoint(e){try{return{kind:`pre-v27`,imported:importCheckpoint(e)}}catch(t){if(!(t instanceof CheckpointRefusal)&&!(t instanceof SessionBusy))throw t;return{kind:t instanceof SessionBusy?`busy`:`incompatible`,detail:`checkpoint version ${String(e.version)}: ${t.message}`}}}function preV27Projection(e,t){let n=initialSessionProjection();return{...n,view:{...n.view,position:e+1,session:{status:e<0?`new`:`open`,turnCount:t,...t>0&&{latestTurnId:`turn_${String(t-1)}`}}}}}function withProjection(e,t){let{sessionState:n}=e,{session:r}=n.snapshot;return{...e,sessionState:{...n,snapshot:{...n.snapshot,session:{...r,state:{...r.state,[SESSION_PROJECTION_STATE_KEY]:t}}}}}}function importCheckpoint(e){let t=readRecord(e,`sessionState`),n=readRecord(readRecord(t,`snapshot`),`session`);typeof t.sessionId!=`string`&&refuse(`session id is missing`);let r=n.state===void 0?{}:readRecord(n,`state`),i=readTurnCount(t,r);if(holdsRunningTask(r[`eve.taskTable`]))throw new SessionBusy(`session holds a running task`);let a=Array.isArray(e.history)?e.history:n.history;Array.isArray(a)||refuse(`session history is missing`);let o=readRecord(e,`serializedContext`),s=o[SESSION_CALLBACK_CONTEXT_KEY_NAME],c=isObject(s)?o[`eve.legacyRemoteAgentCaller`]===void 0?2:1:void 0;return{checkpoint:{admittedDeliveryKeys:Array.isArray(e.admittedDeliveryKeys)?e.admittedDeliveryKeys:[],...c===void 0?e.capabilities!==void 0&&{capabilities:e.capabilities}:{capabilities:{requestInput:!1}},history:importHistory(a),...e.retention!==void 0&&{retention:e.retention},serializedContext:c===void 0?o:{...o,"eve.capabilities":{requestInput:!1},[EARLIER_REMOTE_CALLER_CONTEXT_KEY_NAME]:c},sessionState:{continuationToken:t.continuationToken,hasProxyInputRequests:!1,sessionId:t.sessionId,snapshot:{session:{agent:isObject(n.agent)?n.agent:{system:``},continuationToken:n.continuationToken,sessionId:n.sessionId,...pick(n,[`outputSchema`,`rootSessionId`,`sandboxState`]),state:Object.fromEntries(Object.entries(r).filter(([e])=>!e.startsWith(`eve.`)))}},version:DURABLE_SESSION_VERSION},sessionTimeoutMs:e.sessionTimeoutMs,version:SESSION_CHECKPOINT_VERSION},turnCount:i}}function readTurnCount(e,t){let n=t[SESSION_PROJECTION_STATE_KEY];if(isObject(n))return n.activeTurnId!==void 0&&refuse(`a turn is still open`),readCount(n.nextSequence);let r=t[`eve.harness.emission`]??e.emissionState;return isObject(r)||refuse(`the session's turn position is missing`),r.turnId!==``&&refuse(`a turn is still open`),readCount(r.sequence)}function readCount(e){return(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)&&refuse(`the session's turn position is malformed`),e}function holdsRunningTask(e){return e!==void 0&&((!isObject(e)||!Array.isArray(e.tasks))&&refuse(`task table is malformed`),e.tasks.some(e=>!isObject(e)||e.run!==void 0||Array.isArray(e.held)&&e.held.length>0||Array.isArray(e.calls)&&e.calls.length>0))}var SessionBusy=class extends Error{};function importHistory(e){try{return normalizeHistory(e)}catch(e){refuse(`session history is malformed: ${e instanceof Error?e.message:`unknown`}`)}}function pick(e,t){return Object.fromEntries(t.flatMap(t=>e[t]===void 0?[]:[[t,e[t]]]))}function readRecord(e,t){let n=e[t];return isObject(n)||refuse(`${t} is not an object`),n}export{importPreV27Checkpoint,isPreV27CheckpointVersion,preV27Projection,withProjection};
|
|
@@ -41,6 +41,8 @@ export interface SessionBoot {
|
|
|
41
41
|
readonly anchor: SessionAnchor;
|
|
42
42
|
readonly caller: TurnCaller | undefined;
|
|
43
43
|
readonly capabilities?: SessionCapabilities;
|
|
44
|
+
/** Compacts the history before the first action, for a session an earlier build recorded. */
|
|
45
|
+
readonly compactFirst?: boolean;
|
|
44
46
|
readonly deploymentId: string;
|
|
45
47
|
readonly history: HarnessModelMessage[];
|
|
46
48
|
readonly initialTurnControl?: TurnControl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{storedProjection}from"#harness/session-machine/view.js";import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{turnCoordinates}from"#protocol/session-projection.js";import"#execution/session-inbox/inbox.js";import{signalSessionAnchorStep}from"#execution/session/handoff-steps.js";import{controlDeliveryOf}from"#execution/session/control-delivery.js";import{settleControlDeliveryStep}from"#execution/session/settle-control-delivery-step.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{createTurnControl}from"#execution/session/turn-control.js";import{SessionHandoff,sessionAnchorToken}from"#execution/session/handoff.js";import{notifyCancelledTaskCallerStep,notifyTurnCallerStep,resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{withStubPlayback}from"#execution/tool-stubs/playback.js";import{nextTurnDelivery}from"#execution/session/next-input.js";import{SessionExecution}from"#execution/session/turn.js";import{SessionStateCursor}from"#execution/session/state-cursor.js";import{cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{finalizeSession}from"#execution/session/finalization.js";import{prewarmSessionStep}from"#execution/session/prewarm-step.js";function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runPreparedSession(e,t){let n=e.serializedContext[STUB_CONTEXT_KEY];n!==void 0&&n.rootSessionId===void 0&&(e.serializedContext[STUB_CONTEXT_KEY]={...n,rootSessionId:e.sessionId});let r=new SessionStateCursor({history:e.history,inbox:t,sessionWritable:e.sessionWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}),i={caller:e.caller},a=new SessionHandoff({checkpoint:{capabilities:e.capabilities,retention:e.retention,sessionTimeoutMs:e.sessionTimeoutMs},deploymentId:e.deploymentId,inbox:t,isInitialOwner:e.anchor.kind===`self`,sessionId:e.sessionId,sessionWritable:e.sessionWritable}),o={output:``,isError:!0},s,c=!1;try{return o=await withStubPlayback(n,e.sessionId,async()=>{try{s=await runSessionLoop(e,{cursor:r,handoff:a,inbox:t,progress:i})}finally{await t.dispose()}return s.kind===`transferred`?e.anchor.kind===`self`?(o=await a.awaitAnchoredResult(),o):{output:``}:(c=!0,o=await finalizeSession(s.outcome,{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),o)}),o}catch(t){throw c||await finalizeSession({error:t,kind:`failed`,turnId:i.turnId},{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}finally{await t.dispose(),await reportResultToAnchor(e,o,a,s)}}async function failSession(e){let t;try{t=await resolveInitialTurnCallerStep({serializedContext:e.serializedContext})}catch{}throw await finalizeSession({error:e.error,kind:`failed`},{caller:t,cursor:{serializedContext:e.serializedContext,sessionState:e.sessionState},sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}async function reportResultToAnchor(e,t,n,r){switch(e.anchor.kind){case`self`:await n.disposeAnchor(),await e.anchor.notify?.(t);return;case`successor`:if(r?.kind===`transferred`)return;await signalSessionAnchorStep({result:t,token:sessionAnchorToken(e.sessionId)});return}}async function runSessionLoop(e,t){let{cursor:n,handoff:r,inbox:i,progress:a}=t,o=new SessionInputQueue(e.admittedDeliveryKeys),s=new SessionExecution({capabilities:e.capabilities,cursor:n,inbox:i,queue:o,sessionId:e.sessionId}),c=e.sessionTimeoutControl,l=Promise.resolve(),u=!0,d=!1,f=[],started=()=>storedProjection(n.sessionState.snapshot.session.state).view.session.status!==`new`,ignore=async e=>{if(!started()){f.push(e);return}await n.advance(t=>settleControlDeliveryStep({...t,settlement:e}))},settleUnstarted=async()=>{if(started())for(let e of f.splice(0))await n.advance(t=>settleControlDeliveryStep({...t,settlement:e}))},expired=e=>({kind:`expired`,...e&&{control:e},...f.length>0&&{settles:f.splice(0)}}),nextParkedActivity=async()=>{for(;;){let e=await nextTurnDelivery({cursor:n,hasWorkingTasks:()=>workingTasks(sessionTaskTable(n)).length>0,ignore,inbox:i,queue:o});if(e.kind===`prewarm`){if(u&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0&&o.pendingCount===0&&!i.hasPending()){let t=c?.getDeadline(),n=await r.tryPrewarmTransfer(transferState(),e.targetDeploymentId,t);if(n.kind===`transferred`)return n}continue}if(e.kind===`workflow`){await s.handleWorkflowMessage(e.message);continue}if(e.kind===`cancel-working-tasks`){if(await cancelWorkingTasks(n,`turn-cancelled`),e.origin!==void 0){let t=controlDeliveryOf(e.origin);await n.advance(e=>settleControlDeliveryStep({...e,settlement:{control:t,outcome:`applied`,source:`cancel`}}))}continue}if(!(e.kind===`expired`&&c!==void 0&&((o.pendingCount>0||i.hasPending())&&c.recordActivity(),await c.handleTimerElapsed()===`extended`)))return e}},p=e.initialTurnControl??(e.anchor.kind===`self`?createTurnControl():void 0),m=!1,runTurn=async e=>{let t=a.caller,r=p;p=void 0,a.turnId=e?.control===void 0?turnCoordinates(storedProjection(n.sessionState.snapshot.session.state)).turnId:void 0;let i=await s.runTurn(e,{caller:t,control:r});return a.turnId=void 0,c?.recordActivity(),i.caller!==void 0&&(a.caller=i.caller),i.compacted===!0&&(m=!0),i},transferState=()=>({admittedDeliveryKeys:o.admittedDeliveryKeys,history:n.history,serializedContext:n.serializedContext,sessionState:n.sessionState}),compactionHandoffReady=()=>m&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0,tryCompactionHandoff=async()=>{if(!compactionHandoffReady()||o.pendingCount>0||i.hasPending())return;let e=await r.tryCompactionTransfer(transferState());return e.kind===`transferred`?e:void 0},runDeliveredTurn=async e=>{let t=await r.tryTransfer(e,transferState());return t.kind===`transferred`?t:(e.delivery.caller!==void 0&&(a.caller=e.delivery.caller),{action:await runTurn({delivery:e.delivery}),kind:`action`})},settleCancelledTurn=async(e,t)=>{let r=await n.advanceWithHistory(n=>settleCancelledTurnStep({...n,control:t,reportUsage:e}));return a.caller=void 0,r},awaitPrewarmedAction=async()=>{for(;;){let e=await nextParkedActivity();switch(d=!1,e.kind){case`reset`:return{kind:`terminal`,outcome:expired(e.origin&&controlDeliveryOf(e.origin))};case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:expired()};case`transferred`:return e;case`expired`:return{kind:`terminal`,outcome:expired()};case`clear`:case`compact`:e.origin!==void 0&&await ignore({control:controlDeliveryOf(e.origin),outcome:`ignored`,source:e.kind});continue;case`turn`:return await runDeliveredTurn(e);case`cancel-turn`:continue}}},runInitialAction=async()=>{switch(e.start.kind){case`first-message`:return d=!0,u=!1,l=n.advanceBeside(({serializedContext:e,sessionState:t})=>prewarmSessionStep({serializedContext:e,sessionState:t}),()=>d).then(()=>void 0,()=>void 0).finally(()=>{u=!0}),await awaitPrewarmedAction();case`parked`:return{action:{kind:`park`},kind:`action`};case`turn`:{let{input:t}=e.start;return{action:await runTurn(t===void 0?void 0:{delivery:t}),kind:`action`}}}};try{let[t,n]=await Promise.allSettled([runInitialAction(),c?.start()]);if(n.status===`rejected`)throw n.reason;if(t.status===`rejected`)throw t.reason;let o=t.value;if(o.kind!==`action`)return o;let l=o.action;for(;;){if(l.kind===`done`)return{kind:`terminal`,outcome:{action:l,kind:`done`}};if(await settleUnstarted(),l.cancelled===!0){let{caller:t}=a,n=await settleCancelledTurn(t!==void 0,l.cancelledBy);if(t!==void 0){let r={caller:t,sessionId:e.sessionId};await notifyCancelledTaskCallerStep(n.usage===void 0?r:{...r,usage:n.usage})}}else l.settled!==void 0&&(a.caller!==void 0&&await notifyTurnCallerStep({caller:a.caller,lifecycle:`parked`,sessionId:e.sessionId,settled:l.settled}),a.caller=void 0);let t=await tryCompactionHandoff();if(t!==void 0)return t;p??=createTurnControl();let n=await nextParkedActivity();switch(n.kind){case`reset`:return{kind:`terminal`,outcome:resetOutcome(n.origin)};case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return n;case`expired`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:l=await runTurn(n.origin===void 0?{control:n.kind}:{control:n.kind,controlDelivery:controlDeliveryOf(n.origin)});continue;case`cancel-turn`:await s.cancelTurnWork(),await settleCancelledTurn(!1,n.origin===void 0?void 0:controlDeliveryOf(n.origin)),c?.recordActivity(),l={...l,settled:void 0};continue;case`turn`:{let e=await runDeliveredTurn(n);if(e.kind!==`action`)return e;l=e.action;continue}}}}finally{d=!1,await l,await c?.dispose()}}function resetOutcome(e){return e===void 0?{kind:`expired`}:{control:controlDeliveryOf(e),kind:`expired`}}export{failSession,runPreparedSession};
|
|
1
|
+
import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{storedProjection}from"#harness/session-machine/view.js";import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{turnCoordinates}from"#protocol/session-projection.js";import"#execution/session-inbox/inbox.js";import{signalSessionAnchorStep}from"#execution/session/handoff-steps.js";import{controlDeliveryOf}from"#execution/session/control-delivery.js";import{settleControlDeliveryStep}from"#execution/session/settle-control-delivery-step.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{createTurnControl}from"#execution/session/turn-control.js";import{SessionHandoff,sessionAnchorToken}from"#execution/session/handoff.js";import{notifyCancelledTaskCallerStep,notifyTurnCallerStep,resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{withStubPlayback}from"#execution/tool-stubs/playback.js";import{nextTurnDelivery}from"#execution/session/next-input.js";import{SessionExecution}from"#execution/session/turn.js";import{SessionStateCursor}from"#execution/session/state-cursor.js";import{cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{finalizeSession}from"#execution/session/finalization.js";import{prewarmSessionStep}from"#execution/session/prewarm-step.js";function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runPreparedSession(e,t){let n=e.serializedContext[STUB_CONTEXT_KEY];n!==void 0&&n.rootSessionId===void 0&&(e.serializedContext[STUB_CONTEXT_KEY]={...n,rootSessionId:e.sessionId});let r=new SessionStateCursor({history:e.history,inbox:t,sessionWritable:e.sessionWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}),i={caller:e.caller},a=new SessionHandoff({checkpoint:{capabilities:e.capabilities,retention:e.retention,sessionTimeoutMs:e.sessionTimeoutMs},deploymentId:e.deploymentId,inbox:t,isInitialOwner:e.anchor.kind===`self`,sessionId:e.sessionId,sessionWritable:e.sessionWritable}),o={output:``,isError:!0},s,c=!1;try{return o=await withStubPlayback(n,e.sessionId,async()=>{try{s=await runSessionLoop(e,{cursor:r,handoff:a,inbox:t,progress:i})}finally{await t.dispose()}return s.kind===`transferred`?e.anchor.kind===`self`?(o=await a.awaitAnchoredResult(),o):{output:``}:(c=!0,o=await finalizeSession(s.outcome,{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),o)}),o}catch(t){throw c||await finalizeSession({error:t,kind:`failed`,turnId:i.turnId},{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}finally{await t.dispose(),await reportResultToAnchor(e,o,a,s)}}async function failSession(e){let t;try{t=await resolveInitialTurnCallerStep({serializedContext:e.serializedContext})}catch{}throw await finalizeSession({error:e.error,kind:`failed`},{caller:t,cursor:{serializedContext:e.serializedContext,sessionState:e.sessionState},sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}async function reportResultToAnchor(e,t,n,r){switch(e.anchor.kind){case`self`:await n.disposeAnchor(),await e.anchor.notify?.(t);return;case`successor`:if(r?.kind===`transferred`)return;await signalSessionAnchorStep({result:t,token:sessionAnchorToken(e.sessionId)});return}}async function runSessionLoop(e,t){let{cursor:n,handoff:r,inbox:i,progress:a}=t,o=new SessionInputQueue(e.admittedDeliveryKeys),s=new SessionExecution({capabilities:e.capabilities,cursor:n,inbox:i,queue:o,sessionId:e.sessionId}),c=e.sessionTimeoutControl,l=Promise.resolve(),u=!0,d=!1,f=[],started=()=>storedProjection(n.sessionState.snapshot.session.state).view.session.status!==`new`,ignore=async e=>{if(!started()){f.push(e);return}await n.advance(t=>settleControlDeliveryStep({...t,settlement:e}))},settleUnstarted=async()=>{if(started())for(let e of f.splice(0))await n.advance(t=>settleControlDeliveryStep({...t,settlement:e}))},expired=e=>({kind:`expired`,...e&&{control:e},...f.length>0&&{settles:f.splice(0)}}),nextParkedActivity=async()=>{for(;;){let e=await nextTurnDelivery({cursor:n,hasWorkingTasks:()=>workingTasks(sessionTaskTable(n)).length>0,ignore,inbox:i,queue:o});if(e.kind===`prewarm`){if(u&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0&&o.pendingCount===0&&!i.hasPending()){let t=c?.getDeadline(),n=await r.tryPrewarmTransfer(transferState(),e.targetDeploymentId,t);if(n.kind===`transferred`)return n}continue}if(e.kind===`workflow`){await s.handleWorkflowMessage(e.message);continue}if(e.kind===`cancel-working-tasks`){if(await cancelWorkingTasks(n,`turn-cancelled`),e.origin!==void 0){let t=controlDeliveryOf(e.origin);await n.advance(e=>settleControlDeliveryStep({...e,settlement:{control:t,outcome:`applied`,source:`cancel`}}))}continue}if(!(e.kind===`expired`&&c!==void 0&&((o.pendingCount>0||i.hasPending())&&c.recordActivity(),await c.handleTimerElapsed()===`extended`)))return e}},p=e.initialTurnControl??(e.anchor.kind===`self`?createTurnControl():void 0),m=!1,runTurn=async e=>{let t=a.caller,r=p;p=void 0,a.turnId=e?.control===void 0?turnCoordinates(storedProjection(n.sessionState.snapshot.session.state)).turnId:void 0;let i=await s.runTurn(e,{caller:t,control:r});return a.turnId=void 0,c?.recordActivity(),i.caller!==void 0&&(a.caller=i.caller),i.compacted===!0&&(m=!0),i},transferState=()=>({admittedDeliveryKeys:o.admittedDeliveryKeys,history:n.history,serializedContext:n.serializedContext,sessionState:n.sessionState}),compactionHandoffReady=()=>m&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0,tryCompactionHandoff=async()=>{if(!compactionHandoffReady()||o.pendingCount>0||i.hasPending())return;let e=await r.tryCompactionTransfer(transferState());return e.kind===`transferred`?e:void 0},runDeliveredTurn=async e=>{let t=await r.tryTransfer(e,transferState());return t.kind===`transferred`?t:(e.delivery.caller!==void 0&&(a.caller=e.delivery.caller),{action:await runTurn({delivery:e.delivery}),kind:`action`})},settleCancelledTurn=async(e,t)=>{let r=await n.advanceWithHistory(n=>settleCancelledTurnStep({...n,control:t,reportUsage:e}));return a.caller=void 0,r},awaitPrewarmedAction=async()=>{for(;;){let e=await nextParkedActivity();switch(d=!1,e.kind){case`reset`:return{kind:`terminal`,outcome:expired(e.origin&&controlDeliveryOf(e.origin))};case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:expired()};case`transferred`:return e;case`expired`:return{kind:`terminal`,outcome:expired()};case`clear`:case`compact`:e.origin!==void 0&&await ignore({control:controlDeliveryOf(e.origin),outcome:`ignored`,source:e.kind});continue;case`turn`:return await runDeliveredTurn(e);case`cancel-turn`:continue}}},runInitialAction=async()=>{switch(e.compactFirst===!0&&(await runTurn({control:`compact`}),m=!1),e.start.kind){case`first-message`:return d=!0,u=!1,l=n.advanceBeside(({serializedContext:e,sessionState:t})=>prewarmSessionStep({serializedContext:e,sessionState:t}),()=>d).then(()=>void 0,()=>void 0).finally(()=>{u=!0}),await awaitPrewarmedAction();case`parked`:return{action:{kind:`park`},kind:`action`};case`turn`:{let{input:t}=e.start;return{action:await runTurn(t===void 0?void 0:{delivery:t}),kind:`action`}}}};try{let[t,n]=await Promise.allSettled([runInitialAction(),c?.start()]);if(n.status===`rejected`)throw n.reason;if(t.status===`rejected`)throw t.reason;let o=t.value;if(o.kind!==`action`)return o;let l=o.action;for(;;){if(l.kind===`done`)return{kind:`terminal`,outcome:{action:l,kind:`done`}};if(await settleUnstarted(),l.cancelled===!0){let{caller:t}=a,n=await settleCancelledTurn(t!==void 0,l.cancelledBy);if(t!==void 0){let r={caller:t,sessionId:e.sessionId};await notifyCancelledTaskCallerStep(n.usage===void 0?r:{...r,usage:n.usage})}}else l.settled!==void 0&&(a.caller!==void 0&&await notifyTurnCallerStep({caller:a.caller,lifecycle:`parked`,sessionId:e.sessionId,settled:l.settled}),a.caller=void 0);let t=await tryCompactionHandoff();if(t!==void 0)return t;p??=createTurnControl();let n=await nextParkedActivity();switch(n.kind){case`reset`:return{kind:`terminal`,outcome:resetOutcome(n.origin)};case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return n;case`expired`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:l=await runTurn(n.origin===void 0?{control:n.kind}:{control:n.kind,controlDelivery:controlDeliveryOf(n.origin)});continue;case`cancel-turn`:await s.cancelTurnWork(),await settleCancelledTurn(!1,n.origin===void 0?void 0:controlDeliveryOf(n.origin)),c?.recordActivity(),l={...l,settled:void 0};continue;case`turn`:{let e=await runDeliveredTurn(n);if(e.kind!==`action`)return e;l=e.action;continue}}}}finally{d=!1,await l,await c?.dispose()}}function resetOutcome(e){return e===void 0?{kind:`expired`}:{control:controlDeliveryOf(e),kind:`expired`}}export{failSession,runPreparedSession};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult,getAdapterKind}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,ChannelInstrumentationKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,SandboxKey,ScheduleIdKey,ScheduleInstanceKey,SessionKey,SessionPredecessorKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{bindMemoryInstrumentation}from"#reactions/kinds/memory.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{sandboxProvider}from"#context/providers/sandbox.js";import{isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{currentProjection,enterSessionProjection,enterSessionProjectionAt,nextLinePosition,recordAppliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{ConnectionRegistryKey,connectionProvider}from"#context/providers/connection.js";import{sessionProvider}from"#context/providers/session.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{runStep,withContextScope}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime,resolveSessionUsageLimit}from"#execution/effective-agent-config.js";import{checksSessionEvents,foldOrphanedLines,openSessionEventPublisher,readOrphanedLines}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/step-state-delta.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{matchSignIns,receive}from"#harness/session-machine/transitions.js";import{readPendingHistory,withoutPendingHistory}from"#execution/session/pending-history.js";import{fact}from"#harness/facts.js";import{admitDeliveries}from"#execution/session/delivery-facts.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{applyReactionEffects,restoreReactions}from"#reactions/runner.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{eventsOf}from"#harness/publication.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";import{pausedOrParked,resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{startSessionPrewarmers}from"#context/prewarm.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{readInterruptedAttempt,recoverInterruptedStep}from"#execution/session/interrupted-step.js";import{stepDisagreement}from"#execution/session/step-decision-check.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{runModelCallBatch}from"#execution/model-call-batching.js";const log=createLogger(`execution.turn-step`);async function turnStep(e){"use step";return e.handover!==void 0&&traceSessionHandover(`inbox_unblocked`,e.sessionState.sessionId,e.handover.attemptKey,{"eve.handoff.buffered_payload_count":e.handover.payloadCount,"eve.handoff.applied_at_ms":e.handover.appliedAtMs,"eve.handoff.applied_at_clock":`workflow`}),await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState),o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=await readOrphanedLines({sessionId:a.sessionId,position:nextLinePosition(o),sessionWritable:e.sessionWritable,always:e.recover!==void 0}),c=s.length>0||e.recover!==void 0?readInterruptedAttempt(nextLinePosition(o),s):void 0;s.length>0&&enterSessionProjectionAt(o,foldOrphanedLines(currentProjection(o),s));let l=o.require(ChannelKey),u=o.require(BundleKey),d=resolveEffectiveAgentRuntime(u,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:f}=readHitlState(a.state),p;if(f.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(f,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),p=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let m=o.get(AuthKey),h=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let g=r===void 0?p?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;g!==void 0&&o.set(AuthKey,g);let _={...hydrateDurableSession({compactionOverrides:{thresholdPercent:d.thresholdPercent},durable:a,turnAgent:d.turnAgent}),history:validateHarnessModelMessages(e.history)},v=bindSessionInstrumentation({agentName:d.turnAgent.id,ctx:o,rootSessionId:_.rootSessionId??_.sessionId,sessionId:_.sessionId});bindMemoryInstrumentation(o,v?.memory);let y=turnPosition(currentProjection(o)),b=isBetweenTurns(currentProjection(o));if(!y.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>v?.preparePreamble({sequence:y.sequence,sessionStarted:y.sessionStarted})),v?.prepareDelivery(n));let x=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:S}=x.dispatcher,C=new AbortController,w=e.abortSignal===void 0?C.signal:AbortSignal.any([e.abortSignal,C.signal]);try{let s={...u.graph.root,turnAgent:d.turnAgent},f=resolveSessionUsageLimit(u),g=!1,T=createTurnEventHandler({abortSignal:w,canCancelTurn:e.input?.control===void 0,conversation:_.history,hookCancellation:C,publisher:x}),handleEvent=async(e,t)=>{eventsOf(e).some(e=>e.type===`context.settled`&&e.data.kind===`compaction`&&e.data.outcome===`completed`)&&(g=!0),await T(e,t)},E=r!==void 0&&!b?structuredClone(S.state):void 0,D,O;if(r!==void 0){let e=[],t=r.payloads.some(e=>e.message!==void 0)?readPendingHistory(a.state):[],i=0;try{for(let n of r.payloads){let r=l.deliver?await l.deliver(n,S):defaultDeliverResult(n);if(r==null){e.push({input:void 0,payload:n});continue}let a=[...i===0?t:[],...n.history??[]];i+=1,e.push({input:a.length===0?r:{...r,history:a},payload:n})}}catch(e){throw await v?.flush(),e}O=admitDeliveries({channelKind:o.get(ChannelInstrumentationKey)?.kind??getAdapterKind(l),delivery:n??r,status:e=>currentProjection(o).view.deliveries[e]?.status,payloads:e}),i>0&&t.length>0&&(_={..._,state:withoutPendingHistory(_.state)}),D=O.inputs.length===0?void 0:O.inputs.reduce(coalesceTurnInputs)}let k=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:D});if(k!==void 0&&(D=k,m===void 0?o.delete(AuthKey):o.set(AuthKey,m),h||o.delete(InitiatorAuthKey)),r!==void 0&&D===void 0&&!b)m===void 0?o.delete(AuthKey):o.set(AuthKey,m),S.state=E;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,y.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!y.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),D={...D,delegatedUsage:i.delegatedUsage,runtimeActionResults:i.results}),n!==void 0){let e={...l,state:{...S.state}};setChannelContext(o,e)}let A=!1,admissionFacts=e=>{if(O===void 0||O.facts.length===0)return[];let t=[];if(!turnPosition(currentProjection(o)).sessionStarted){let n=o.get(ParentSessionKey),r=o.get(SessionPredecessorKey);t.push(fact(`session.started`,{parent:n===void 0?void 0:{callId:n.callId,sessionId:n.sessionId},predecessor:r,runtime:e}))}return[...t,...O.facts]},publishAdmission=async e=>{let t=admissionFacts(e);if(t.length===0)return;let n=sessionProvider.create(o,_);o.setVirtualContext(SessionKey,n.value);let r=await connectionProvider.create(o,_);r!==void 0&&o.setVirtualContext(ConnectionRegistryKey,r.value);let i=await sandboxProvider.create(o,_);i!==void 0&&o.setVirtualContext(SandboxKey,i.value);let a=v?.createHandleEvent({handleEvent})??handleEvent;try{await contextStorage.run(o,()=>a(t))}finally{if(i!==void 0){let e=await i.value.captureState();JSON.stringify(e)!==JSON.stringify(_.sandboxState??null)&&(A=!0,_={..._,sandboxState:e})}}},consumeCancelledInput=async()=>{let e=currentProjection(o),t=(D?.deliveries??[]).filter(({deliveryId:t})=>e.view.deliveries[t]?.status===`admitted`);if(t.length===0)return;let{events:n}=receive(sessionView(e,_.state),{deliveries:t}),r=createTurnEventHandler({abortSignal:w,canCancelTurn:!1,conversation:_.history,hookCancellation:new AbortController,publisher:x}),i=v?.createHandleEvent({handleEvent:r})??r;await contextStorage.run(o,()=>i(n))};if(r!==void 0&&D===void 0&&b){await publishAdmission(buildRuntimeIdentity(s)).catch(ignoreTurnCancellation),await v?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,_),o),n=serializeContext(o),r=t===_&&!A?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return pausedOrParked(t,{serializedContext:n,...r})}let j=buildRuntimeIdentity(s),M,prepareReactions=e=>(o.setVirtualContext(StaticModelReferenceKey,d.turnAgent.model??null),M??=(async()=>{try{let t=process.env.VERCEL_DEPLOYMENT_ID?.trim(),n=t?`deployment:${t}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);await contextStorage.run(o,()=>restoreReactions(o,{abortSignal:w,conversation:e.history,revision:n}))}catch(e){throw await v?.flush(),e}})());if(c!==void 0){let t=await recoverInterruptedStep({admission:admissionFacts(j),attempt:c,control:e.input?.control===void 0?void 0:{delivery:e.input.controlDelivery,kind:e.input.control},ctx:o,failed:e.recover,publish:async(e,t)=>(await withContextScope(o,t,async t=>{await prepareReactions(t);let n=createTurnEventHandler({abortSignal:w,canCancelTurn:!1,conversation:t.history,hookCancellation:new AbortController,publisher:x});return await(v?.createHandleEvent({handleEvent:n})??n)(e),{result:void 0,session:t}})).session,session:_,stepInput:D}).catch(async e=>{throw await v?.flush(),e});if(`result`in t)return await v?.flush(),t.result.action===`done`&&await x.writer.close().catch(()=>{}),t.result;_=t.session,D=t.stepInput}await prepareReactions(_);try{await publishAdmission(j)}catch(e){if(!isTurnCancellation(e))throw await v?.flush(),e}let N=u.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,P=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:d.thresholdPercent},session:n,turnAgent:d.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:w,capabilities:P,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,controlDelivery:e.input?.controlDelivery,createRuntime:createWorkflowRuntime,handleEvent,signInCompletions:i,typedAnswers:!hasDelegatedSessionContext(e.serializedContext),instrumentation:v,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:s,sessionUsageLimit:f,titleAttributeWrite:t.title})(a,r)},F,I;try{throwIfTurnAborted(w),I=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:D,initialSession:_,modelCallsPerStep:N,runStep:async({firstCall:t,session:n,stepInput:r})=>{let i=await runStep(o,n,async n=>{t&&e.input?.control===void 0&&startSessionPrewarmers(o,`turn`),o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,d.turnAgent.model??null);let i=t&&D?.outputSchema!==void 0?{...n,outputSchema:D.outputSchema}:n;await applyReactionEffects(o);let a=t&&p!==void 0?p.map(({challenge:e})=>e):void 0,s=await runHarnessStep(i,r,a);return await x.finish({announce:stoppedForPerson(s)}),s});i.settledTurn===void 0&&throwIfTurnAborted(w);let a={...i,session:saveSessionProjection(i.session,o)};return recordAppliedSession(o,a.session),F={result:a,serializedContext:serializeContext(o)},a}})}catch(t){if(!isTurnCancellation(t)&&!w.aborted)throw await v?.flush(),t;return F===void 0&&await consumeCancelledInput(),createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:F,ctx:o,initialSession:_,stepInput:D})}let L=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,I.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,L.sessionId,L.state);let R=serializeContext(o);I={...I,session:L};let z=resolveSessionStepResult(I,R);if(checksSessionEvents()){let e=stepDisagreement(z,currentProjection(o).view);e!==void 0&&e!==`dispatch-deferred`&&log.warn(`a turn step's decision disagrees with the session's tables`,{disagreement:e})}return z.action===`done`&&await x.writer.close(),g?{...z,compacted:!0}:z}finally{x.writer.release()}}function stoppedForPerson(e){return e.held===void 0?e.next===null&&e.settledTurn===void 0:e.held.kind===`request`}function ignoreTurnCancellation(e){if(!isTurnCancellation(e))throw e}export{turnStep};
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult,getAdapterKind}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,ChannelInstrumentationKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,SandboxKey,ScheduleIdKey,ScheduleInstanceKey,SessionKey,SessionPredecessorKey,SessionTitleKey,StaticModelReferenceKey,ToolChannelKey,TurnDeliveryIdsKey}from"#context/keys.js";import{bindMemoryInstrumentation}from"#reactions/kinds/memory.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{sandboxProvider}from"#context/providers/sandbox.js";import{isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{currentProjection,enterSessionProjection,enterSessionProjectionAt,nextLinePosition,recordAppliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{ConnectionRegistryKey,connectionProvider}from"#context/providers/connection.js";import{sessionProvider}from"#context/providers/session.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{runStep,withContextScope}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime,resolveSessionUsageLimit}from"#execution/effective-agent-config.js";import{checksSessionEvents,foldOrphanedLines,openSessionEventPublisher,readOrphanedLines}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/step-state-delta.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{matchSignIns,receive}from"#harness/session-machine/transitions.js";import{readPendingHistory,withoutPendingHistory}from"#execution/session/pending-history.js";import{fact}from"#harness/facts.js";import{admitDeliveries}from"#execution/session/delivery-facts.js";import{setChannelContext}from"#execution/channel-context.js";import{applyReactionEffects,restoreReactions}from"#reactions/runner.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{eventsOf}from"#harness/publication.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";import{pausedOrParked,resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{startSessionPrewarmers}from"#context/prewarm.js";import{createToolChannelTo}from"#execution/tools/channel-to.js";import{channelOf}from"#reactions/frame.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{readInterruptedAttempt,recoverInterruptedStep}from"#execution/session/interrupted-step.js";import{stepDisagreement}from"#execution/session/step-decision-check.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{runModelCallBatch}from"#execution/model-call-batching.js";const log=createLogger(`execution.turn-step`);async function turnStep(e){"use step";return e.handover!==void 0&&traceSessionHandover(`inbox_unblocked`,e.sessionState.sessionId,e.handover.attemptKey,{"eve.handoff.buffered_payload_count":e.handover.payloadCount,"eve.handoff.applied_at_ms":e.handover.appliedAtMs,"eve.handoff.applied_at_clock":`workflow`}),await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState),o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=await readOrphanedLines({sessionId:a.sessionId,position:nextLinePosition(o),sessionWritable:e.sessionWritable,always:e.recover!==void 0}),c=s.length>0||e.recover!==void 0?readInterruptedAttempt(nextLinePosition(o),s):void 0;s.length>0&&enterSessionProjectionAt(o,foldOrphanedLines(currentProjection(o),s));let l=o.require(ChannelKey),u=o.require(BundleKey),d=resolveEffectiveAgentRuntime(u,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:f}=readHitlState(a.state),p;if(f.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(f,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),p=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let m=o.get(AuthKey),h=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let g=r===void 0?p?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;g!==void 0&&o.set(AuthKey,g);let _={...hydrateDurableSession({compactionOverrides:{thresholdPercent:d.thresholdPercent},durable:a,turnAgent:d.turnAgent}),history:validateHarnessModelMessages(e.history)},v=bindSessionInstrumentation({agentName:d.turnAgent.id,ctx:o,rootSessionId:_.rootSessionId??_.sessionId,sessionId:_.sessionId});bindMemoryInstrumentation(o,v?.memory);let y=turnPosition(currentProjection(o)),b=isBetweenTurns(currentProjection(o));if(!y.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>v?.preparePreamble({sequence:y.sequence,sessionStarted:y.sessionStarted})),v?.prepareDelivery(n));let x=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:S}=x.dispatcher,C=new AbortController,w=e.abortSignal===void 0?C.signal:AbortSignal.any([e.abortSignal,C.signal]);try{let s={...u.graph.root,turnAgent:d.turnAgent},f=resolveSessionUsageLimit(u),g=!1,T=createTurnEventHandler({abortSignal:w,canCancelTurn:e.input?.control===void 0,conversation:_.history,hookCancellation:C,publisher:x}),handleEvent=async(e,t)=>{eventsOf(e).some(e=>e.type===`context.settled`&&e.data.kind===`compaction`&&e.data.outcome===`completed`)&&(g=!0),await T(e,t)},E=r!==void 0&&!b?structuredClone(S.state):void 0,D,O;if(r!==void 0){let e=[],t=r.payloads.some(e=>e.message!==void 0)?readPendingHistory(a.state):[],i=0;try{for(let n of r.payloads){let r=l.deliver?await l.deliver(n,S):defaultDeliverResult(n);if(r==null){e.push({input:void 0,payload:n});continue}let a=[...i===0?t:[],...n.history??[]];i+=1,e.push({input:a.length===0?r:{...r,history:a},payload:n})}}catch(e){throw await v?.flush(),e}O=admitDeliveries({channelKind:o.get(ChannelInstrumentationKey)?.kind??getAdapterKind(l),delivery:n??r,status:e=>currentProjection(o).view.deliveries[e]?.status,payloads:e}),i>0&&t.length>0&&(_={..._,state:withoutPendingHistory(_.state)}),D=O.inputs.length===0?void 0:O.inputs.reduce(coalesceTurnInputs)}let k=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:D});if(k!==void 0&&(D=k,m===void 0?o.delete(AuthKey):o.set(AuthKey,m),h||o.delete(InitiatorAuthKey)),r!==void 0&&D===void 0&&!b)m===void 0?o.delete(AuthKey):o.set(AuthKey,m),S.state=E;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,y.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!y.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),D={...D,delegatedUsage:i.delegatedUsage,runtimeActionResults:i.results}),n!==void 0){let e={...l,state:{...S.state}};setChannelContext(o,e)}let A=!1,admissionFacts=e=>{if(O===void 0||O.facts.length===0)return[];let t=[];if(!turnPosition(currentProjection(o)).sessionStarted){let n=o.get(ParentSessionKey),r=o.get(SessionPredecessorKey);t.push(fact(`session.started`,{parent:n===void 0?void 0:{callId:n.callId,sessionId:n.sessionId},predecessor:r,runtime:e}))}return[...t,...O.facts]},publishAdmission=async e=>{let t=admissionFacts(e);if(t.length===0)return;let n=sessionProvider.create(o,_);o.setVirtualContext(SessionKey,n.value);let r=await connectionProvider.create(o,_);r!==void 0&&o.setVirtualContext(ConnectionRegistryKey,r.value);let i=await sandboxProvider.create(o,_);i!==void 0&&o.setVirtualContext(SandboxKey,i.value);let a=v?.createHandleEvent({handleEvent})??handleEvent;try{await contextStorage.run(o,()=>a(t))}finally{if(i!==void 0){let e=await i.value.captureState();JSON.stringify(e)!==JSON.stringify(_.sandboxState??null)&&(A=!0,_={..._,sandboxState:e})}}},consumeCancelledInput=async()=>{let e=currentProjection(o),t=(D?.deliveries??[]).filter(({deliveryId:t})=>e.view.deliveries[t]?.status===`admitted`);if(t.length===0)return;let{events:n}=receive(sessionView(e,_.state),{deliveries:t}),r=createTurnEventHandler({abortSignal:w,canCancelTurn:!1,conversation:_.history,hookCancellation:new AbortController,publisher:x}),i=v?.createHandleEvent({handleEvent:r})??r;await contextStorage.run(o,()=>i(n))};if(r!==void 0&&D===void 0&&b){await publishAdmission(buildRuntimeIdentity(s)).catch(ignoreTurnCancellation),await v?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,_),o),n=serializeContext(o),r=t===_&&!A?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return pausedOrParked(t,{serializedContext:n,...r})}let j=buildRuntimeIdentity(s),M,prepareReactions=e=>(o.setVirtualContext(StaticModelReferenceKey,d.turnAgent.model??null),M??=(async()=>{try{let t=process.env.VERCEL_DEPLOYMENT_ID?.trim(),n=t?`deployment:${t}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);await contextStorage.run(o,()=>restoreReactions(o,{abortSignal:w,conversation:e.history,revision:n}))}catch(e){throw await v?.flush(),e}})());if(c!==void 0){let t=await recoverInterruptedStep({admission:admissionFacts(j),attempt:c,control:e.input?.control===void 0?void 0:{delivery:e.input.controlDelivery,kind:e.input.control},ctx:o,failed:e.recover,publish:async(e,t)=>(await withContextScope(o,t,async t=>{await prepareReactions(t);let n=createTurnEventHandler({abortSignal:w,canCancelTurn:!1,conversation:t.history,hookCancellation:new AbortController,publisher:x});return await(v?.createHandleEvent({handleEvent:n})??n)(e),{result:void 0,session:t}})).session,session:_,stepInput:D}).catch(async e=>{throw await v?.flush(),e});if(`result`in t)return await v?.flush(),t.result.action===`done`&&await x.writer.close().catch(()=>{}),t.result;_=t.session,D=t.stepInput}await prepareReactions(_);try{await publishAdmission(j)}catch(e){if(!isTurnCancellation(e))throw await v?.flush(),e}let N=u.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,P=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:d.thresholdPercent},session:n,turnAgent:d.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:w,capabilities:P,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,controlDelivery:e.input?.controlDelivery,createRuntime:createWorkflowRuntime,handleEvent,signInCompletions:i,typedAnswers:!hasDelegatedSessionContext(e.serializedContext),instrumentation:v,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:s,sessionUsageLimit:f,titleAttributeWrite:t.title})(a,r)},F,I;try{throwIfTurnAborted(w),I=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:D,initialSession:_,modelCallsPerStep:N,runStep:async({firstCall:t,session:n,stepInput:r})=>{let i=await runStep(o,n,async n=>{t&&e.input?.control===void 0&&startSessionPrewarmers(o,`turn`),o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,d.turnAgent.model??null),o.setVirtualContext(ToolChannelKey,{channel:channelOf(o),to:createToolChannelTo({delegated:hasDelegatedSessionContext(e.serializedContext),loadBundle:()=>o.require(BundleKey)})});let i=t&&D?.outputSchema!==void 0?{...n,outputSchema:D.outputSchema}:n;await applyReactionEffects(o);let a=t&&p!==void 0?p.map(({challenge:e})=>e):void 0,s=await runHarnessStep(i,r,a);return await x.finish({announce:stoppedForPerson(s)}),s});i.settledTurn===void 0&&throwIfTurnAborted(w);let a={...i,session:saveSessionProjection(i.session,o)};return recordAppliedSession(o,a.session),F={result:a,serializedContext:serializeContext(o)},a}})}catch(t){if(!isTurnCancellation(t)&&!w.aborted)throw await v?.flush(),t;return F===void 0&&await consumeCancelledInput(),createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:F,ctx:o,initialSession:_,stepInput:D})}let L=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,I.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,L.sessionId,L.state);let R=serializeContext(o);I={...I,session:L};let z=resolveSessionStepResult(I,R);if(checksSessionEvents()){let e=stepDisagreement(z,currentProjection(o).view);e!==void 0&&e!==`dispatch-deferred`&&log.warn(`a turn step's decision disagrees with the session's tables`,{disagreement:e})}return z.action===`done`&&await x.writer.close(),g?{...z,compacted:!0}:z}finally{x.writer.release()}}function stoppedForPerson(e){return e.held===void 0?e.next===null&&e.settledTurn===void 0:e.held.kind===`request`}function ignoreTurnCancellation(e){if(!isTurnCancellation(e))throw e}export{turnStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLocalDevelopmentServer}from"#internal/application/dev-environment.js";import{FatalError}from"#compiled/@workflow/core/index.js";import{UnsafeDestinationError,assertPublicHostname,createPublicDispatcher,fetchWithDispatcher,findUnsafeDestinationError,readBoundedResponse}from"#execution/public-destination.js";const log=createLogger(`execution.session-callback`),VERCEL_CALLBACK_HOST_ENVS=[`VERCEL_URL`,`VERCEL_BRANCH_URL`,`VERCEL_PROJECT_PRODUCTION_URL`],VERCEL_REQUEST_CONTEXT=Symbol.for(`@vercel/request-context`);async function postSessionCallbackRequest(e){let t=e.timeoutMs??3e4,n=AbortSignal.timeout(t),r;try{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLocalDevelopmentServer}from"#internal/application/dev-environment.js";import{FatalError}from"#compiled/@workflow/core/index.js";import{UnsafeDestinationError,assertPublicHostname,createPublicDispatcher,fetchWithDispatcher,findUnsafeDestinationError,readBoundedResponse}from"#execution/public-destination.js";const log=createLogger(`execution.session-callback`),VERCEL_CALLBACK_HOST_ENVS=[`VERCEL_URL`,`VERCEL_BRANCH_URL`,`VERCEL_PROJECT_PRODUCTION_URL`],VERCEL_REQUEST_CONTEXT=Symbol.for(`@vercel/request-context`);async function postSessionCallbackRequest(e){let t=e.timeoutMs??3e4,n=AbortSignal.timeout(t),r=await resolveSessionCallbackHeaders(e.url),i;try{i=await requestCallback(e.url,{body:JSON.stringify(e.body),headers:r,signal:n})}catch(r){let i=findUnsafeDestinationError(r);throw i===void 0?(e.logFailures!==!1&&log.error(`callback delivery failed`,{...callbackLogFields(e),failure:n.aborted?`timeout`:`transport`,timeoutMs:t,error:Error(`Callback request failed before receiving a response.`)}),r):(e.logFailures!==!1&&log.error(`callback delivery failed`,{...callbackLogFields(e),failure:`blocked-destination`,error:Error(i.message)}),new FatalError(`Callback delivery refused: ${i.message}`))}return!i.ok&&e.logFailures!==!1&&log.error(`callback delivery failed`,{...callbackLogFields(e),failure:`http`,statusCode:i.status,error:Error(`Callback request failed with HTTP ${i.status}.`)}),i}async function requestCallback(e,t){let n=new URL(e);if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new UnsafeDestinationError(`Callback URL must use http or https.`);let r={allowLoopback:isLocalDevelopmentServer()};assertPublicHostname(n.hostname,r);let i=await createPublicDispatcher(r);try{let n=await fetchWithDispatcher(e,{...t,dispatcher:i,method:`POST`,redirect:`error`});return await readBoundedResponse(n,65536)}finally{await i.close()}}function callbackLogFields(e){let t=URL.parse(e.url),n=t?.pathname.match(/^(.*?\/(?:callback|activity))\//)?.[1],r={callbackOrigin:t?.origin,callbackPath:n===void 0?`[redacted]`:`${n}/[redacted]`};if(isObject(e.body)){for(let t of[`kind`,`callId`,`sessionId`,`childSessionId`,`subagentName`,`updateEpoch`])typeof e.body[t]==`string`&&(r[t]=e.body[t]);typeof e.body.updateIndex==`number`&&(r.updateIndex=e.body.updateIndex)}return r}async function resolveSessionCallbackHeaders(e){let t={"content-type":`application/json`};if(process.env.VERCEL!==`1`)return t;let n;try{n=new URL(e)}catch{return t}let r=VERCEL_CALLBACK_HOST_ENVS.some(e=>{let t=process.env[e]?.trim();return t!==void 0&&t!==``&&URL.parse(`https://${t}`)?.origin===n.origin});if(n.protocol!==`https:`||!r&&!configuredCallbackOrigins().includes(n.origin))return t;let i=readAmbientVercelOidcToken();return i!==void 0&&(t[`x-vercel-trusted-oidc-idp-token`]=i),t}function configuredCallbackOrigins(){let e=process.env.EVE_CALLBACK_TRUSTED_ORIGINS?.trim();return e?e.split(`,`).map(e=>{let t=URL.parse(e.trim());if(t===null||t.protocol!==`https:`||t.username!==``||t.password!==``||t.pathname!==`/`||t.search!==``||t.hash!==``)throw new FatalError(`EVE_CALLBACK_TRUSTED_ORIGINS must be a comma-separated list of HTTPS origins without credentials, paths, queries, or fragments.`);return t.origin}):[]}function readAmbientVercelOidcToken(){let e=(globalThis[VERCEL_REQUEST_CONTEXT]?.get?.().headers?.[`x-vercel-oidc-token`]??process.env.VERCEL_OIDC_TOKEN)?.trim();return e===``?void 0:e}export{postSessionCallbackRequest};
|
|
@@ -5,6 +5,7 @@ export declare const SESSION_INBOX_SESSION_ID_METADATA_KEY = "sessionId";
|
|
|
5
5
|
/** Stable inbox coordinates. The owner and deployment are intentionally absent. */
|
|
6
6
|
export interface SessionInboxAddress {
|
|
7
7
|
readonly sessionId: string;
|
|
8
|
+
readonly inbox?: string;
|
|
8
9
|
}
|
|
9
10
|
export declare function isSessionInboxAddress(value: unknown): value is SessionInboxAddress;
|
|
10
11
|
/** Returns whether a token belongs to eve's framework-reserved session namespace. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Hook } from "#internal/workflow/runtime.js";
|
|
2
|
+
type InboxHook = Omit<Hook, "metadata">;
|
|
3
|
+
/** Opaque transport state; never includes user metadata or transient capabilities. */
|
|
4
|
+
export declare function issueInboxHandle(hook: unknown): string | undefined;
|
|
5
|
+
/** Verify the complete descriptor before using its routing or encryption fields. */
|
|
6
|
+
export declare function readInboxHandle(handle: string): InboxHook | undefined;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHmac,timingSafeEqual}from"node:crypto";import*as workflowRuntime from"#internal/workflow/runtime.js";const MAX_HANDLE_LENGTH=8192;function parseInboxHook(e){let t=Reflect.get(workflowRuntime,`parseHookResumeHandle`);if(typeof t==`function`)return t(e)}function signingKey(){let e=process.env.EVE_INBOX_HANDLE_SECRET;return e!==void 0&&e.length>=32?e:void 0}function signature(e,t){return createHmac(`sha256`,t).update(`eve:inbox:v1:`).update(e).digest()}function issueInboxHandle(e){let t=signingKey();if(t===void 0)return;let n=parseInboxHook(e);if(n?.resumeContext?.encryptionPublicKey===void 0)return;let r={...n,resumeContext:{...n.resumeContext,traceCarrier:void 0}},i=Buffer.from(JSON.stringify(r)).toString(`base64url`),a=`v1.${i}.${signature(i,t).toString(`base64url`)}`;return a.length<=MAX_HANDLE_LENGTH?a:void 0}function readInboxHandle(e){let t=signingKey();if(t===void 0||e.length>MAX_HANDLE_LENGTH)return;let[n,r,i,a]=e.split(`.`);if(n!==`v1`||r===void 0||i===void 0||a!==void 0)return;let o=signature(r,t),s=Buffer.from(i,`base64url`);if(o.length===s.length&&timingSafeEqual(o,s))try{return parseInboxHook(JSON.parse(Buffer.from(r,`base64url`).toString(`utf8`)))}catch{return}}export{issueInboxHandle,readInboxHandle};
|
|
@@ -16,11 +16,11 @@ export declare class StrandedSessionOwnerError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* The single ingress path into a hook: refuses a session inbox whose owner
|
|
19
|
-
* cannot execute before anything is committed
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* cannot execute before anything is committed. Vercel can reuse a validated
|
|
20
|
+
* inbox handle: Workflow requires its guarded, deduplicated write endpoint.
|
|
21
|
+
* Only a definite refusal falls back to resolving the current token owner.
|
|
22
22
|
*/
|
|
23
|
-
export declare function resumeRunnableHook(token: string, payload: unknown): Promise<Awaited<ReturnType<typeof resumeHook>>>;
|
|
23
|
+
export declare function resumeRunnableHook(token: string, payload: unknown, inbox?: string): Promise<Awaited<ReturnType<typeof resumeHook>>>;
|
|
24
24
|
/**
|
|
25
25
|
* Throws {@link StrandedSessionOwnerError} when the run holding a physical
|
|
26
26
|
* session inbox token cannot execute. An unheld token passes: resuming it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isSessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{findRetiredOwnerRun,routesToOwnerDeployment}from"#execution/session-inbox/runnable-owner.js";import{DevelopmentRunUnavailableError}from"#internal/workflow/development-run-unavailable-error.js";var StrandedSessionOwnerError=class extends Error{hook;ownerRun;constructor(e,t){super(`Session owner run "${e.runId}" is stranded.`),this.name=`StrandedSessionOwnerError`,this.hook=t,this.ownerRun=e}get ownerRunId(){return this.ownerRun.runId}get eveVersion(){return this.ownerRun.attributes[EVE_VERSION_ATTRIBUTE]}};async function resumeRunnableHook(e,t){return isSessionInboxHookToken(e)&&await assertRunnableSessionInbox(e),await resumeHook(e,t)}async function assertRunnableSessionInbox(e){let t=await getWorld();if(routesToOwnerDeployment(t))return;let n=await findSessionHookHolder(e);n!==void 0&&await assertRunnableOwner(t,n.runId,n.hook)}async function assertRunnableSessionOwner(e){let t=await getWorld();routesToOwnerDeployment(t)||await assertRunnableOwner(t,e.runId,e.hook)}async function findSessionHookHolder(e){try{let t=await getHookByToken(e);return{hook:t,runId:t.runId}}catch(e){if(HookNotFoundError.is(e))return;if(DevelopmentRunUnavailableError.is(e))return{runId:e.runId};throw e}}async function lookupSessionOwnerHook(e){try{return await getHookByToken(e)}catch(e){throw DevelopmentRunUnavailableError.is(e)&&await assertRunnableOwner(await getWorld(),e.runId),e}}async function assertRunnableOwner(e,t,n){let r=await findRetiredOwnerRun(e,t);if(r!==void 0)throw new StrandedSessionOwnerError(r,n)}export{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder,lookupSessionOwnerHook,resumeRunnableHook};
|
|
1
|
+
import{isSessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{readInboxHandle}from"#execution/session-inbox/handle.js";import{findRetiredOwnerRun,routesToOwnerDeployment}from"#execution/session-inbox/runnable-owner.js";import{DevelopmentRunUnavailableError}from"#internal/workflow/development-run-unavailable-error.js";var StrandedSessionOwnerError=class extends Error{hook;ownerRun;constructor(e,t){super(`Session owner run "${e.runId}" is stranded.`),this.name=`StrandedSessionOwnerError`,this.hook=t,this.ownerRun=e}get ownerRunId(){return this.ownerRun.runId}get eveVersion(){return this.ownerRun.attributes[EVE_VERSION_ATTRIBUTE]}};async function resumeRunnableHook(e,t,n){let r=n===void 0?void 0:await getWorld();if(n!==void 0&&n.length<=8192&&r!==void 0&&routesToOwnerDeployment(r)&&r.capabilities!==void 0&&`resolvedHookResume`in r.capabilities&&r.capabilities.resolvedHookResume===!0){let r=readInboxHandle(n),i=r?.token===e?r:void 0;if(i!==void 0)try{return await resumeHook(i,t)}catch(e){if(!HookNotFoundError.is(e))throw e}}return isSessionInboxHookToken(e)&&await assertRunnableSessionInbox(e),await resumeHook(e,t)}async function assertRunnableSessionInbox(e){let t=await getWorld();if(routesToOwnerDeployment(t))return;let n=await findSessionHookHolder(e);n!==void 0&&await assertRunnableOwner(t,n.runId,n.hook)}async function assertRunnableSessionOwner(e){let t=await getWorld();routesToOwnerDeployment(t)||await assertRunnableOwner(t,e.runId,e.hook)}async function findSessionHookHolder(e){try{let t=await getHookByToken(e);return{hook:t,runId:t.runId}}catch(e){if(HookNotFoundError.is(e))return;if(DevelopmentRunUnavailableError.is(e))return{runId:e.runId};throw e}}async function lookupSessionOwnerHook(e){try{return await getHookByToken(e)}catch(e){throw DevelopmentRunUnavailableError.is(e)&&await assertRunnableOwner(await getWorld(),e.runId),e}}async function assertRunnableOwner(e,t,n){let r=await findRetiredOwnerRun(e,t);if(r!==void 0)throw new StrandedSessionOwnerError(r,n)}export{StrandedSessionOwnerError,assertRunnableSessionInbox,assertRunnableSessionOwner,findSessionHookHolder,lookupSessionOwnerHook,resumeRunnableHook};
|
|
@@ -4,6 +4,7 @@ import type { DeliverHookPayload, SessionCommand, SessionTimeoutHookPayload } fr
|
|
|
4
4
|
import { type SessionInboxAddress } from "#execution/session-inbox/address.js";
|
|
5
5
|
export interface ResumedSessionInboxHook {
|
|
6
6
|
readonly ownerRunId: string;
|
|
7
|
+
readonly inbox?: string;
|
|
7
8
|
/** Lazy identity resolution; delivery never needs to decrypt hook metadata. */
|
|
8
9
|
readonly sessionId: Promise<string>;
|
|
9
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{SESSION_INBOX_SESSION_ID_METADATA_KEY,isSessionInboxAddress,sessionCommandHookToken,sessionHandoffMarkerToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{assertRunnableSessionOwner,lookupSessionOwnerHook,resumeRunnableHook}from"#execution/session-inbox/owner.js";import{withPreV27Answers}from"#execution/session-inbox/pre-v27.js";import{UnsupportedLegacySessionError,resolveLegacyInbox,resumeLegacyInbox}from"#execution/legacy-session/inbox.js";async function resumeSessionInbox(e,t){t=withPreV27Answers(t);let n=logicalSessionToken(e),r=typeof e==`string`?void 0:e.sessionId,i=Date.now()+5e3;for(;;){let
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{SESSION_INBOX_SESSION_ID_METADATA_KEY,isSessionInboxAddress,sessionCommandHookToken,sessionHandoffMarkerToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{getHookByToken}from"#internal/workflow/runtime.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{assertRunnableSessionOwner,lookupSessionOwnerHook,resumeRunnableHook}from"#execution/session-inbox/owner.js";import{issueInboxHandle}from"#execution/session-inbox/handle.js";import{withPreV27Answers}from"#execution/session-inbox/pre-v27.js";import{UnsupportedLegacySessionError,resolveLegacyInbox,resumeLegacyInbox}from"#execution/legacy-session/inbox.js";async function resumeSessionInbox(e,t){t=withPreV27Answers(t);let n=logicalSessionToken(e),r=typeof e==`string`?void 0:e.sessionId,i=Date.now()+5e3;for(;;){let a;try{a=await resumeRunnableHook(sessionInboxHookToken(n),t,typeof e==`string`?void 0:e.inbox)}catch(e){if(!HookNotFoundError.is(e))throw e;if(await waitWhileHandoffInProgress(n,i))continue;if(t.kind===`session-failure`||t.kind===`session-prewarm`)throw e;return await resumeLegacyInbox(n,t).catch(rethrowUnsupportedAsNotFound)}let o;return{ownerRunId:a.runId,inbox:issueInboxHandle(a),get sessionId(){return o??=(async()=>{try{return r??requireSessionId(await a.metadata)}catch(e){throw new AcceptedSessionIdentityError(e)}})()}}}}var SessionHandoffPendingError=class extends Error{constructor(e){super(`Session address "${e}" is still changing owners. Nothing was delivered; retry the request.`),this.name=`SessionHandoffPendingError`}},AcceptedSessionIdentityError=class extends Error{constructor(e){super(`Session command accepted, but its session identity could not be resolved.`,{cause:e}),this.name=`AcceptedSessionIdentityError`}};function requireSessionId(e){let t=isObject(e)?e[SESSION_INBOX_SESSION_ID_METADATA_KEY]:void 0;if(typeof t!=`string`||t.length===0)throw Error(`Session hook metadata is missing its session ID.`);return t}async function resolveSessionInbox(e){try{return{sessionId:requireSessionId(await(await getHookByToken(sessionInboxHookToken(e))).metadata)}}catch(t){if(!HookNotFoundError.is(t))throw t;return{sessionId:(await resolveLegacyInbox(e)).sessionId}}}function rethrowUnsupportedAsNotFound(e){throw e instanceof UnsupportedLegacySessionError?new HookNotFoundError(e.message):e}function logicalSessionToken(e){if(typeof e==`string`)return e;if(!isSessionInboxAddress(e))throw Error(`Session inbox target has an invalid address.`);return sessionCommandHookToken(e.sessionId)}async function waitWhileHandoffInProgress(e,t){let n;try{n=await lookupSessionOwnerHook(sessionHandoffMarkerToken(e))}catch(e){if(HookNotFoundError.is(e))return!1;throw e}if(Date.now()>=t)throw await assertRunnableSessionOwner({hook:n,runId:n.runId}),new SessionHandoffPendingError(e);return await new Promise(e=>setTimeout(e,20)),!0}export{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,requireSessionId,resolveSessionInbox,resumeSessionInbox};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{handleAuthorizationError}from"#runtime/connections/scoped-authorization.js";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{createAuthorizationContext}from"#runtime/authorization-context.js";function createToolExecuteWithAuth(e){return(t,n)=>{let r=createAuthorizationContext({scope:e.scope}),i={...buildBaseToolContext({options:n,toolName:e.scope}),messages:n.messages,getToken:r.getToken,requireAuth:r.requireAuth,...n.approval!==void 0&&{approval:approvalOf(n.approval.responder,r)}};return r.run(()=>e.execute(t,i))}}function approvalOf(e,t){return{responder:{...e,getToken:(n,r)=>t.getResponderToken(e,n,r)}}}function buildApprovalResponseAuth(e){let t=createAuthorizationContext({scope:e.scope,boundResponder:e.responder});return{getToken:(n,r)=>t.getToken(n,namespaceApprovalAuthOptions(e.scope,r)),requireAuth:(n,r)=>t.requireAuth(n,namespaceApprovalAuthOptions(e.scope,r))}}function namespaceApprovalAuthOptions(e,t){return t?.authKey===void 0?t:{...t,authKey:`${e}:${t.authKey}`}}async function handleApprovalResponsePolicyError(e){return await handleAuthorizationError(e)}export{buildApprovalResponseAuth,createToolExecuteWithAuth,handleApprovalResponsePolicyError};
|
|
1
|
+
import{contextStorage}from"#context/container.js";import{ToolChannelKey}from"#context/keys.js";import{handleAuthorizationError}from"#runtime/connections/scoped-authorization.js";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{createAuthorizationContext}from"#runtime/authorization-context.js";function createToolExecuteWithAuth(e){return(t,n)=>{let r=createAuthorizationContext({scope:e.scope}),i={...buildBaseToolContext({options:n,toolName:e.scope}),messages:n.messages,...contextStorage.getStore()?.get(ToolChannelKey)??{channel:{kind:`unknown`,metadata:{}},to:unavailableChannelTo},getToken:r.getToken,requireAuth:r.requireAuth,...n.approval!==void 0&&{approval:approvalOf(n.approval.responder,r)}};return r.run(()=>e.execute(t,i))}}const unavailableChannelTo=()=>{throw Error(`ctx.to() is only available while a session's turn runs the tool.`)};function approvalOf(e,t){return{responder:{...e,getToken:(n,r)=>t.getResponderToken(e,n,r)}}}function buildApprovalResponseAuth(e){let t=createAuthorizationContext({scope:e.scope,boundResponder:e.responder});return{getToken:(n,r)=>t.getToken(n,namespaceApprovalAuthOptions(e.scope,r)),requireAuth:(n,r)=>t.requireAuth(n,namespaceApprovalAuthOptions(e.scope,r))}}function namespaceApprovalAuthOptions(e,t){return t?.authKey===void 0?t:{...t,authKey:`${e}:${t.authKey}`}}async function handleApprovalResponsePolicyError(e){return await handleAuthorizationError(e)}export{buildApprovalResponseAuth,createToolExecuteWithAuth,handleApprovalResponsePolicyError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{reply:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({signal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.
|
|
1
|
+
import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{reply:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({signal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.85.0//runAgentRouterTask`;export{runAgentRouterTask};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CrossChannelToFn } from "#channel/cross-channel-receive.js";
|
|
2
|
+
import type { CompiledRuntimeAgentBundle } from "#runtime/sessions/compiled-agent-cache.js";
|
|
3
|
+
/**
|
|
4
|
+
* `ctx.to()` for a tool or a workflow tool's step: the root agent's channels,
|
|
5
|
+
* reached through their `receive()` hooks as a route's `ctx.to()` reaches them.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createToolChannelTo(input: {
|
|
8
|
+
/** Whether a parent, local or remote, delegated the session running the tool. */
|
|
9
|
+
readonly delegated: boolean;
|
|
10
|
+
/** The compiled agent that owns the tool. */
|
|
11
|
+
readonly loadBundle: () => CompiledRuntimeAgentBundle | Promise<CompiledRuntimeAgentBundle>;
|
|
12
|
+
}): CrossChannelToFn;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createCrossChannelToFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{ContextContainer,contextStorage}from"#context/container.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";function createToolChannelTo(e){return(t,n)=>{if(e.delegated)throw Error(`ctx.to() isn't available in a delegated session (a subagent, a root copy, or a remote agent call): a session it started would outlive the delegation and act for the caller. Return the result to the caller, and send from a tool on the root agent.`);return{async send(r,i){let a=await e.loadBundle(),o=createCrossChannelToFn(createWorkflowRuntime({compiledArtifactsSource:a.compiledArtifactsSource}),toCrossChannelTargets(a.graph.root.channels));return await contextStorage.run(new ContextContainer,()=>o(t,n).send(r,i))}}}}export{createToolChannelTo};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SessionContext } from "#context/session-context.js";
|
|
2
2
|
import type { AgentSessionContext } from "#execution/agent-sessions/context.js";
|
|
3
3
|
import { type RunUsageTally } from "#execution/agent-sessions/usage.js";
|
|
4
|
+
import type { InstrumentationChannel } from "#shared/instrumentation-channel.js";
|
|
4
5
|
import type { WorkflowSharedContext } from "#tools/workflow-definition.js";
|
|
5
6
|
import { WorkflowToolRunAsks } from "#execution/tools/workflow/ask.js";
|
|
6
7
|
import type { WorkflowBodyCommand, WorkflowToolRunOutcome, WorkflowToolRunRef } from "#execution/tools/workflow/messages.js";
|
|
@@ -75,6 +76,8 @@ export declare function resolveWorkflowEntryPoint<TEntryPoint>(input: WorkflowBo
|
|
|
75
76
|
* knows its calls.
|
|
76
77
|
*/
|
|
77
78
|
export declare function createSharedContext(input: WorkflowBodyInput, agent: WorkflowSharedContext["agent"], askPerson: WorkflowSharedContext["ask"]): Omit<ToolContext & WorkflowSharedContext, "abortSignal" | "agents" | "callId" | "messages" | "session">;
|
|
79
|
+
/** `ctx.channel` for a call: the channel that serves the calling session. */
|
|
80
|
+
export declare function workflowToolChannel(context: AgentSessionContext): InstrumentationChannel;
|
|
78
81
|
/** `ctx.agents` for a call: the agents its context lists, frozen. */
|
|
79
82
|
export declare function createAgentsView(context: AgentSessionContext): WorkflowSharedContext["agents"];
|
|
80
83
|
export declare class WorkflowToolRunCancelledError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseJsonValue}from"#shared/json.js";import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{readRegisteredWorkflow}from"#execution/workflow-registry.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";const INTERRUPTED_OUTPUT={interrupted:!0};var WorkflowCallSignals=class{body=new AbortController;run=new AbortController;asks;constructor(e){this.asks=e}get abortSignal(){return this.body.signal}get runSignal(){return this.run.signal}get interrupted(){return this.body.signal.aborted&&!this.run.signal.aborted}get unwinding(){return this.run.signal.aborted}apply(e){switch(e.kind){case`cancel`:case`end`:this.asks.cancelAll(),this.run.abort(new WorkflowToolRunCancelledError(e.reason)),this.body.abort(this.run.signal.reason);return;case`interrupt`:this.body.abort(new WorkflowToolRunInterruptedError);return;case`call`:return}}};function startCallBody(e){let t=createWorkflowBodyRef(e),n=new WorkflowToolRunAsks(t.runId),r=new WorkflowCallSignals(n),i={agentContext:e.agentContext,asks:n,auth:e.session.auth,control:e.hookToken,from:t,owner:e.owner},a=createRunUsageTally(),o=createAgentSessions(i,a),s=createCallContext(e,r,o.open);return attachWorkflowToolRunContext(s,i),{asks:n,close:o.close,control:r,outcome:executeCallBody(e,s,r,t),usage:a}}async function executeCallBody(e,t,n,r){try{let n=findStubTarget(e.agentContext.toolStubs,e.toolName);if(n!==void 0){let t=await callToolStubStep(n.scope,{callId:stubCallId(e.session.id,e.session.turn.id,e.callId),tool:n.tool,input:e.input});if(t.kind===`error`)throw Error(t.error);if(t.kind===`stub`)return{output:toolStubOutput(t.outcome),status:`completed`}}let i=resolveWorkflowEntryPoint(e)(e.executeInput??e.input,t),a;if(!isAsyncIterable(i))a=await i;else{let t=i[Symbol.asyncIterator](),n,o=await t.next();for(;o.done!==!0;)n=o.value,await e.owner.send({from:r,kind:`report`,update:o.value}),o=await t.next();a=o.value??n}return{output:toWorkflowOutput(e,a),status:`completed`}}catch(e){return n.interrupted?{output:INTERRUPTED_OUTPUT,status:`completed`}:toFailedOutcome(e,n.runSignal)}}function toWorkflowOutput(e,t){return withToolOutputSerializationError({boundary:`execute`,toolCallId:e.callId,toolName:e.toolName},()=>parseJsonValue(t??null))}function toFailedOutcome(e,t){if(t.aborted){let{reason:e}=t;return{reason:e instanceof Error?e.message:String(e??``),status:`cancelled`}}return{error:normalizeSerializableError(e),status:`failed`}}function createWorkflowBodyRef(e){let t={callId:e.callId,input:e.input,runId:e.runId??getWorkflowMetadata().workflowRunId,sequence:e.session.turn.sequence,stepIndex:e.stepIndex,toolName:e.toolName,turnId:e.session.turn.id};return e.entry.entryPoint===`execute`?t:{...t,taskId:e.entry.taskId}}function resolveWorkflowEntryPoint(e){let t=readRegisteredWorkflow(e.workflowId);if(typeof t!=`function`)throw Error(`Tool "${e.toolName}" is not registered as a workflow in this deployment (${e.workflowId}). The tool was renamed or removed after this run started.`);return t}function createSharedContext(e,t,n){let unavailable=(t,n)=>{throw Error(`ctx.${t} is not available inside a workflow tool; ${n}. Tool "${e.toolName}" runs as a durable workflow body, which only replays deterministic code.`)};return{agent:t,ask:n,getSandbox:()=>unavailable(`getSandbox()`,`pass ctx directly to a "use step" helper to open the session's sandbox`),getToken:()=>unavailable(`getToken()`,`pass ctx directly to a "use step" helper to resolve credentials`),requireAuth:()=>unavailable(`requireAuth()`,`pass ctx directly to a "use step" helper to request authorization`),toolName:e.toolName}}function createAgentsView(e){return Object.freeze(Object.fromEntries(Object.entries(e.agents).map(([e,t])=>[e,Object.freeze({...t})])))}function createCallContext(e,t,n){let r={...createSharedContext(e,n,(e,t)=>ask(r,e,t)),abortSignal:t.abortSignal,agents:createAgentsView(e.agentContext),callId:e.callId,session:e.session};return r}function isAsyncIterable(e){return typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`}var WorkflowToolRunCancelledError=class extends Error{constructor(e){super(e),this.name=`WorkflowToolRunCancelledError`}},WorkflowToolRunInterruptedError=class extends Error{constructor(){super(`A new message arrived while the turn waited on this call.`),this.name=`WorkflowToolRunInterruptedError`}};export{WorkflowToolRunCancelledError,WorkflowToolRunInterruptedError,createAgentsView,createSharedContext,createWorkflowBodyRef,resolveWorkflowEntryPoint,startCallBody,toFailedOutcome,toWorkflowOutput};
|
|
1
|
+
import{normalizeInstrumentationChannelKind}from"#shared/instrumentation-channel-kind.js";import{parseJsonValue}from"#shared/json.js";import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{readRegisteredWorkflow}from"#execution/workflow-registry.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";const INTERRUPTED_OUTPUT={interrupted:!0};var WorkflowCallSignals=class{body=new AbortController;run=new AbortController;asks;constructor(e){this.asks=e}get abortSignal(){return this.body.signal}get runSignal(){return this.run.signal}get interrupted(){return this.body.signal.aborted&&!this.run.signal.aborted}get unwinding(){return this.run.signal.aborted}apply(e){switch(e.kind){case`cancel`:case`end`:this.asks.cancelAll(),this.run.abort(new WorkflowToolRunCancelledError(e.reason)),this.body.abort(this.run.signal.reason);return;case`interrupt`:this.body.abort(new WorkflowToolRunInterruptedError);return;case`call`:return}}};function startCallBody(e){let t=createWorkflowBodyRef(e),n=new WorkflowToolRunAsks(t.runId),r=new WorkflowCallSignals(n),i={agentContext:e.agentContext,asks:n,auth:e.session.auth,control:e.hookToken,from:t,owner:e.owner},a=createRunUsageTally(),o=createAgentSessions(i,a),s=createCallContext(e,r,o.open);return attachWorkflowToolRunContext(s,i),{asks:n,close:o.close,control:r,outcome:executeCallBody(e,s,r,t),usage:a}}async function executeCallBody(e,t,n,r){try{let n=findStubTarget(e.agentContext.toolStubs,e.toolName);if(n!==void 0){let t=await callToolStubStep(n.scope,{callId:stubCallId(e.session.id,e.session.turn.id,e.callId),tool:n.tool,input:e.input});if(t.kind===`error`)throw Error(t.error);if(t.kind===`stub`)return{output:toolStubOutput(t.outcome),status:`completed`}}let i=resolveWorkflowEntryPoint(e)(e.executeInput??e.input,t),a;if(!isAsyncIterable(i))a=await i;else{let t=i[Symbol.asyncIterator](),n,o=await t.next();for(;o.done!==!0;)n=o.value,await e.owner.send({from:r,kind:`report`,update:o.value}),o=await t.next();a=o.value??n}return{output:toWorkflowOutput(e,a),status:`completed`}}catch(e){return n.interrupted?{output:INTERRUPTED_OUTPUT,status:`completed`}:toFailedOutcome(e,n.runSignal)}}function toWorkflowOutput(e,t){return withToolOutputSerializationError({boundary:`execute`,toolCallId:e.callId,toolName:e.toolName},()=>parseJsonValue(t??null))}function toFailedOutcome(e,t){if(t.aborted){let{reason:e}=t;return{reason:e instanceof Error?e.message:String(e??``),status:`cancelled`}}return{error:normalizeSerializableError(e),status:`failed`}}function createWorkflowBodyRef(e){let t={callId:e.callId,input:e.input,runId:e.runId??getWorkflowMetadata().workflowRunId,sequence:e.session.turn.sequence,stepIndex:e.stepIndex,toolName:e.toolName,turnId:e.session.turn.id};return e.entry.entryPoint===`execute`?t:{...t,taskId:e.entry.taskId}}function resolveWorkflowEntryPoint(e){let t=readRegisteredWorkflow(e.workflowId);if(typeof t!=`function`)throw Error(`Tool "${e.toolName}" is not registered as a workflow in this deployment (${e.workflowId}). The tool was renamed or removed after this run started.`);return t}function createSharedContext(e,t,n){let unavailable=(t,n)=>{throw Error(`ctx.${t} is not available inside a workflow tool; ${n}. Tool "${e.toolName}" runs as a durable workflow body, which only replays deterministic code.`)};return{agent:t,ask:n,getSandbox:()=>unavailable(`getSandbox()`,`pass ctx directly to a "use step" helper to open the session's sandbox`),getToken:()=>unavailable(`getToken()`,`pass ctx directly to a "use step" helper to resolve credentials`),requireAuth:()=>unavailable(`requireAuth()`,`pass ctx directly to a "use step" helper to request authorization`),to:()=>unavailable(`to()`,`pass ctx directly to a "use step" helper to send to a channel`),channel:workflowToolChannel(e.agentContext),toolName:e.toolName}}function workflowToolChannel(e){let t=e.channelMetadata;return{continuationToken:e.continuationToken,kind:normalizeInstrumentationChannelKind(t?.kind),metadata:t?.metadata??{}}}function createAgentsView(e){return Object.freeze(Object.fromEntries(Object.entries(e.agents).map(([e,t])=>[e,Object.freeze({...t})])))}function createCallContext(e,t,n){let r={...createSharedContext(e,n,(e,t)=>ask(r,e,t)),abortSignal:t.abortSignal,agents:createAgentsView(e.agentContext),callId:e.callId,session:e.session};return r}function isAsyncIterable(e){return typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`}var WorkflowToolRunCancelledError=class extends Error{constructor(e){super(e),this.name=`WorkflowToolRunCancelledError`}},WorkflowToolRunInterruptedError=class extends Error{constructor(){super(`A new message arrived while the turn waited on this call.`),this.name=`WorkflowToolRunInterruptedError`}};export{WorkflowToolRunCancelledError,WorkflowToolRunInterruptedError,createAgentsView,createSharedContext,createWorkflowBodyRef,resolveWorkflowEntryPoint,startCallBody,toFailedOutcome,toWorkflowOutput,workflowToolChannel};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionContext } from "#context/session-context.js";
|
|
2
|
+
import type { InstrumentationChannel } from "#shared/instrumentation-channel.js";
|
|
2
3
|
import type { AgentSessionBundle } from "#execution/agent-sessions/context.js";
|
|
3
4
|
import type { AuthorizationResult, AuthorizationSignal } from "#harness/authorization.js";
|
|
4
5
|
import type { SandboxState } from "#sandbox/state.js";
|
|
@@ -15,6 +16,10 @@ export interface WorkflowStepContext {
|
|
|
15
16
|
readonly token: string;
|
|
16
17
|
readonly authorizationResults: readonly WorkflowStepAuthorizationResult[];
|
|
17
18
|
readonly sandbox: WorkflowStepSandbox;
|
|
19
|
+
/** Whether a parent, local or remote, delegated the calling session, which `ctx.to()` refuses. */
|
|
20
|
+
readonly delegated: boolean;
|
|
21
|
+
/** The calling session's channel, which `ctx.channel` holds. */
|
|
22
|
+
readonly channel: InstrumentationChannel;
|
|
18
23
|
}
|
|
19
24
|
/** Where `ctx.getSandbox()` finds the calling session's sandbox: its agent and sandbox key. */
|
|
20
25
|
export interface WorkflowStepSandbox {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{ContextContainer,contextStorage}from"#context/container.js";import{AuthKey,InitiatorAuthKey,SandboxKey,SessionIdKey,SessionKey}from"#context/keys.js";import{ensureSandboxAccess}from"#execution/sandbox/ensure.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{getStepMetadata}from"#compiled/@workflow/core/index.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{isConnectionAuthorizationFailedError}from"#connections/errors.js";import{AuthorizationHookKey,CallbackBaseUrlKey,PendingAuthorizationResultKey,isAuthorizationSignal}from"#harness/authorization.js";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{createAuthorizationContext}from"#runtime/authorization-context.js";import{completeWorkflowStepAuthorization}from"#execution/tools/workflow/authorization-completion.js";import"#execution/tools/workflow/step-context.js";const log=createLogger(`workflow-step`);function withWorkflowStepAuthorization(e){let wrapped=async function(t){let{args:n,context:r}=t;getStepMetadata();let i=new ContextContainer;i.set(AuthKey,r.session.auth.current),i.set(InitiatorAuthKey,r.session.auth.initiator),i.set(SessionIdKey,r.session.id),i.setVirtualContext(SessionKey,{...r.session,sessionId:r.session.id}),i.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(r.baseUrl)),i.setVirtualContext(AuthorizationHookKey,r.token),i.setVirtualContext(PendingAuthorizationResultKey,r.authorizationResults);let a=openStepSandbox(r);return contextStorage.run(i,async()=>{let
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{ContextContainer,contextStorage}from"#context/container.js";import{AuthKey,InitiatorAuthKey,SandboxKey,SessionIdKey,SessionKey}from"#context/keys.js";import{ensureSandboxAccess}from"#execution/sandbox/ensure.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{getStepMetadata}from"#compiled/@workflow/core/index.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{isConnectionAuthorizationFailedError}from"#connections/errors.js";import{AuthorizationHookKey,CallbackBaseUrlKey,PendingAuthorizationResultKey,isAuthorizationSignal}from"#harness/authorization.js";import{createToolChannelTo}from"#execution/tools/channel-to.js";import{buildBaseToolContext}from"#context/build-base-tool-context.js";import{createAuthorizationContext}from"#runtime/authorization-context.js";import{completeWorkflowStepAuthorization}from"#execution/tools/workflow/authorization-completion.js";import"#execution/tools/workflow/step-context.js";const log=createLogger(`workflow-step`);function withWorkflowStepAuthorization(e){let wrapped=async function(t){let{args:n,context:r}=t;getStepMetadata();let i=new ContextContainer;i.set(AuthKey,r.session.auth.current),i.set(InitiatorAuthKey,r.session.auth.initiator),i.set(SessionIdKey,r.session.id),i.setVirtualContext(SessionKey,{...r.session,sessionId:r.session.id}),i.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(r.baseUrl)),i.setVirtualContext(AuthorizationHookKey,r.token),i.setVirtualContext(PendingAuthorizationResultKey,r.authorizationResults);let a=stepAgentLoader(r),o=openStepSandbox(r,a);return contextStorage.run(i,async()=>{let s=createAuthorizationContext({scope:r.toolName,completeAuthorization:completeWorkflowStepAuthorization}),c=buildBaseToolContext({toolName:r.toolName,options:{abortSignal:r.abortSignal,toolCallId:r.callId}}),l={...c,agent:()=>unavailableInStep(`ctx.agent()`,`Call ctx.agent() in the workflow body.`),ask:()=>unavailableInStep(`ctx.ask()`,`Call ctx.ask() in the workflow body.`),getSandbox:(async e=>{let t=await o.open();if(e!==void 0&&t.environment?.provider!==e.provider)throw fatal(`ctx.getSandbox() in a "use step" function received a sandbox environment the session's sandbox does not use. Pass the environment the agent's sandbox definition opens, or call ctx.getSandbox() without one.`);return i.setVirtualContext(SandboxKey,t),await c.getSandbox()}),getToken:s.getToken,requireAuth:s.requireAuth,channel:r.channel,to:createToolChannelTo({delegated:r.delegated,loadBundle:a})};Object.defineProperty(l,"agents",{get:()=>unavailableInStep(`ctx.agents`,`Read ctx.agents in the workflow body and pass the required serializable metadata into the step.`)});let u;try{u=await s.run(()=>Reflect.apply(e,this,n.map((e,n)=>t.contextIndexes.includes(n)?l:e)))}catch(e){throw isConnectionAuthorizationFailedError(e)&&!e.retryable&&Object.assign(e,{fatal:!0}),e}finally{await o.release()}let d=i.get(PendingAuthorizationResultKey)??[],f=r.authorizationResults.filter(e=>!d.includes(e)).map(e=>e.attemptId);return isAuthorizationSignal(u)?{kind:`authorization-required`,signal:u,authorized:f}:{kind:`result`,output:u,authorized:f}})};return Object.defineProperty(wrapped,"maxRetries",{get:()=>Reflect.get(e,`maxRetries`)}),wrapped}function stepAgentLoader(e){let{bundle:t}=e.sandbox,n=contextStorage.getStore(),resolveSource=()=>resolveDurableCompiledArtifactsSource(t.source);return async()=>await getCompiledRuntimeAgentBundle({compiledArtifactsSource:n===void 0?resolveSource():contextStorage.run(n,resolveSource),nodeId:t.nodeId})}function openStepSandbox(e,t){let{sessionId:n,state:r}=e.sandbox,i,a=!1,open=async()=>{let e=await t(),i=e.graph.root;return await ensureSandboxAccess({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:i.nodeId,ownsSandbox:!1,registry:i.sandboxRegistry,sessionId:n,state:r??null,shutdownTracking:`none`})},openOnce=()=>(i??=open().catch(e=>{throw i=void 0,e}),i);return{async open(){if(a)throw fatal(`ctx.getSandbox() was called after the "use step" function of tool "${e.toolName}" returned. Call it inside the step, which lets go of the sandbox when it ends.`);return{...await openOnce(),delete:()=>unavailableInStep(`sandbox.delete()`,`The step borrows the session's sandbox, and only the session can delete it.`),stop:()=>unavailableInStep(`sandbox.stop()`,`The session's turns may be using the sandbox; eve closes the step's connection when the step ends.`)}},async release(){a=!0;let t=await i?.catch(()=>void 0);try{await t?.release()}catch(t){logError(log,`failed to release a workflow step's sandbox`,t,{sessionId:n,toolName:e.toolName})}}}}function unavailableInStep(e,t){throw fatal(`${e} is unavailable inside a "use step" function. ${t}`)}function fatal(e){return Object.assign(Error(e),{fatal:!0})}export{withWorkflowStepAuthorization};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{findWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{signInInteractionId,signInOpened}from"#harness/interaction-facts.js";function workflowToolStep(e,t){return new Proxy(e,{apply(e,n,r){let i=findWorkflowContextArgument(r);return i===void 0?Reflect.apply(e,n,r):executeAuthorizedStep(t,n,r,i)}})}function findWorkflowContextArgument(e){for(let t of e){let e=findWorkflowToolRunContext(t);if(e!==void 0)return{ctx:t,run:e}}}async function executeAuthorizedStep(e,t,n,r){let{ctx:i,run:a}=r,o=[],s=new Map;for(;;){let r=createHook();try{let c;try{c=await invokeAuthorizedStep({args:n,authorizationResults:o,callbackToken:r.token,ctx:i,execute:e,receiver:t,run:a})}catch(e){throw i.abortSignal.aborted||await reportPendingAsFailed(a,i.abortSignal,s),e}if(await reconcileCompletedAuthorizations(a,i.abortSignal,s,o,c.authorized),c.kind===`result`)return await reportPendingAsFailed(a,i.abortSignal,s),c.output;await collectAuthorizationCallbacks({authorizationResults:o,callback:r,challenges:c.signal.challenges,ctx:i,pending:s,run:a})}finally{await disposeHook(r)}}}async function invokeAuthorizedStep(e){let{args:t,authorizationResults:n,callbackToken:r,ctx:i,execute:a,receiver:o,run:s}=e,c={callId:i.callId,toolName:i.toolName,session:i.session,abortSignal:i.abortSignal,baseUrl:getWorkflowMetadata().url,token:r,authorizationResults:n,sandbox:{bundle:s.agentContext.bundle,sessionId:s.agentContext.sandbox.sessionId,state:s.agentContext.sandbox.state}},l={args:t.map(e=>e===i?null:e),context:c,contextIndexes:t.flatMap((e,t)=>e===i?[t]:[])};return await a.call(o,l)}async function reconcileCompletedAuthorizations(e,t,n,r,i){let a=new Set(i);for(let r of a){let i=n.get(r);i!==void 0&&await reportAuthorization(e,t,i,`accepted`),n.delete(r)}for(let e=r.length-1;e>=0;e--){let t=r[e];t!==void 0&&a.has(t.attemptId)&&r.splice(e,1)}}async function collectAuthorizationCallbacks(e){let{authorizationResults:t,callback:n,challenges:r,ctx:i,pending:a,run:o}=e;for(let e of r){let r=requireAttemptId(e);a.set(r.attemptId,r),await reportAuthorization(o,i.abortSignal,r);try{let e=await waitForCallback(n,r,i.abortSignal);t.push({name:r.name,instanceId:r.instanceId,attemptId:r.attemptId,hookUrl:r.hookUrl,principal:r.principal,resume:r.resume,callback:e})}catch(e){throw i.abortSignal.aborted||await reportAuthorization(o,i.abortSignal,r,`failed`),e}}}function requireAttemptId(e){if(e.attemptId===void 0)throw Error(`Workflow authorization challenge "${e.name}" has no attempt id.`);return e}async function reportPendingAsFailed(e,t,n){for(let r of n.values())await reportAuthorization(e,t,r,`failed`)}async function reportAuthorization(e,t,n,r){let i=runSignIn(e.from,n,r),a=createHook();try{await a.getConflict(),await withAbort(e.owner.send({kind:`request`,from:e.from,replyTo:a.token,request:{kind:`relay`,event:{kind:`subagent-interaction`,callId:e.from.callId,childSessionId:e.from.runId,subagentName:e.from.toolName,events:[i]}}}),t),await withAbort(a,t)}finally{await disposeHook(a)}}async function waitForCallback(e,t,n){let r=e[Symbol.asyncIterator]();for(;;){let e=await withAbort(r.next(),n);if(e.done)throw Error(`Authorization callback closed before sign-in completed.`);let i=readCallback(e.value,t);if(i!==void 0)return i}}async function withAbort(e,t){let abort,n=new Promise((e,n)=>{abort=()=>n(t.reason??Error(`Workflow authorization cancelled.`)),t.addEventListener(`abort`,abort,{once:!0}),t.aborted&&abort()});try{return await Promise.race([e,n])}finally{t.removeEventListener(`abort`,abort)}}function readCallback(e,t){if(typeof e==`object`&&e&&`payloads`in e&&Array.isArray(e.payloads))for(let n of e.payloads){let e=n?.authorizationCallback;if(e?.attemptId!==t.attemptId||e?.connectionName!==t.name)continue;let r=e.callback;if(!(typeof r?.method!=`string`||typeof r.params!=`object`||r.params===null||Array.isArray(r.params))&&Object.values(r.params).every(e=>typeof e==`string`)&&(r.body===void 0||typeof r.body==`string`))return r}}function runSignIn(e,t,n){return n===void 0?{data:signInOpened(t,{prompt:`Sign in to ${t.name} to continue.`,subject:e.taskId===void 0?{turnId:e.turnId}:{taskId:e.taskId}}).data,type:`interaction.opened`}:{data:{interactionId:signInInteractionId(t),outcome:n},type:`interaction.settled`}}export{workflowToolStep};
|
|
1
|
+
import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{findWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{workflowToolChannel}from"#execution/tools/workflow/body.js";import{signInInteractionId,signInOpened}from"#harness/interaction-facts.js";function workflowToolStep(e,t){return new Proxy(e,{apply(e,n,r){let i=findWorkflowContextArgument(r);return i===void 0?Reflect.apply(e,n,r):executeAuthorizedStep(t,n,r,i)}})}function findWorkflowContextArgument(e){for(let t of e){let e=findWorkflowToolRunContext(t);if(e!==void 0)return{ctx:t,run:e}}}async function executeAuthorizedStep(e,t,n,r){let{ctx:i,run:a}=r,o=[],s=new Map;for(;;){let r=createHook();try{let c;try{c=await invokeAuthorizedStep({args:n,authorizationResults:o,callbackToken:r.token,ctx:i,execute:e,receiver:t,run:a})}catch(e){throw i.abortSignal.aborted||await reportPendingAsFailed(a,i.abortSignal,s),e}if(await reconcileCompletedAuthorizations(a,i.abortSignal,s,o,c.authorized),c.kind===`result`)return await reportPendingAsFailed(a,i.abortSignal,s),c.output;await collectAuthorizationCallbacks({authorizationResults:o,callback:r,challenges:c.signal.challenges,ctx:i,pending:s,run:a})}finally{await disposeHook(r)}}}async function invokeAuthorizedStep(e){let{args:t,authorizationResults:n,callbackToken:r,ctx:i,execute:a,receiver:o,run:s}=e,c={callId:i.callId,toolName:i.toolName,session:i.session,abortSignal:i.abortSignal,baseUrl:getWorkflowMetadata().url,token:r,authorizationResults:n,delegated:s.agentContext.delegated===!0,channel:workflowToolChannel(s.agentContext),sandbox:{bundle:s.agentContext.bundle,sessionId:s.agentContext.sandbox.sessionId,state:s.agentContext.sandbox.state}},l={args:t.map(e=>e===i?null:e),context:c,contextIndexes:t.flatMap((e,t)=>e===i?[t]:[])};return await a.call(o,l)}async function reconcileCompletedAuthorizations(e,t,n,r,i){let a=new Set(i);for(let r of a){let i=n.get(r);i!==void 0&&await reportAuthorization(e,t,i,`accepted`),n.delete(r)}for(let e=r.length-1;e>=0;e--){let t=r[e];t!==void 0&&a.has(t.attemptId)&&r.splice(e,1)}}async function collectAuthorizationCallbacks(e){let{authorizationResults:t,callback:n,challenges:r,ctx:i,pending:a,run:o}=e;for(let e of r){let r=requireAttemptId(e);a.set(r.attemptId,r),await reportAuthorization(o,i.abortSignal,r);try{let e=await waitForCallback(n,r,i.abortSignal);t.push({name:r.name,instanceId:r.instanceId,attemptId:r.attemptId,hookUrl:r.hookUrl,principal:r.principal,resume:r.resume,callback:e})}catch(e){throw i.abortSignal.aborted||await reportAuthorization(o,i.abortSignal,r,`failed`),e}}}function requireAttemptId(e){if(e.attemptId===void 0)throw Error(`Workflow authorization challenge "${e.name}" has no attempt id.`);return e}async function reportPendingAsFailed(e,t,n){for(let r of n.values())await reportAuthorization(e,t,r,`failed`)}async function reportAuthorization(e,t,n,r){let i=runSignIn(e.from,n,r),a=createHook();try{await a.getConflict(),await withAbort(e.owner.send({kind:`request`,from:e.from,replyTo:a.token,request:{kind:`relay`,event:{kind:`subagent-interaction`,callId:e.from.callId,childSessionId:e.from.runId,subagentName:e.from.toolName,events:[i]}}}),t),await withAbort(a,t)}finally{await disposeHook(a)}}async function waitForCallback(e,t,n){let r=e[Symbol.asyncIterator]();for(;;){let e=await withAbort(r.next(),n);if(e.done)throw Error(`Authorization callback closed before sign-in completed.`);let i=readCallback(e.value,t);if(i!==void 0)return i}}async function withAbort(e,t){let abort,n=new Promise((e,n)=>{abort=()=>n(t.reason??Error(`Workflow authorization cancelled.`)),t.addEventListener(`abort`,abort,{once:!0}),t.aborted&&abort()});try{return await Promise.race([e,n])}finally{t.removeEventListener(`abort`,abort)}}function readCallback(e,t){if(typeof e==`object`&&e&&`payloads`in e&&Array.isArray(e.payloads))for(let n of e.payloads){let e=n?.authorizationCallback;if(e?.attemptId!==t.attemptId||e?.connectionName!==t.name)continue;let r=e.callback;if(!(typeof r?.method!=`string`||typeof r.params!=`object`||r.params===null||Array.isArray(r.params))&&Object.values(r.params).every(e=>typeof e==`string`)&&(r.body===void 0||typeof r.body==`string`))return r}}function runSignIn(e,t,n){return n===void 0?{data:signInOpened(t,{prompt:`Sign in to ${t.name} to continue.`,subject:e.taskId===void 0?{turnId:e.turnId}:{taskId:e.taskId}}).data,type:`interaction.opened`}:{data:{interactionId:signInInteractionId(t),outcome:n},type:`interaction.settled`}}export{workflowToolStep};
|