eve 0.70.0 → 0.70.2
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 +37 -0
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-operations.js +1 -1
- package/dist/src/channel/resolve-text.d.ts +8 -0
- package/dist/src/channel/resolve-text.js +2 -1
- package/dist/src/cli/banner.d.ts +2 -2
- package/dist/src/cli/banner.js +1 -1
- package/dist/src/cli/commands/init-agent-workspace.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +7 -7
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +4 -3
- package/dist/src/cli/dev/tui/runner.js +2 -2
- package/dist/src/cli/dev/tui/task-activity.d.ts +0 -17
- package/dist/src/cli/dev/tui/task-activity.js +1 -1
- package/dist/src/cli/dev/tui/task-records.d.ts +17 -0
- package/dist/src/cli/dev/tui/task-records.js +1 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +7 -1
- package/dist/src/cli/dev/tui/test/mock-terminal.js +4 -3
- package/dist/src/cli/dev/tui/theme.d.ts +1 -1
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tool-presentation.d.ts +15 -2
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
- package/dist/src/cli/dev/tui/transcript-parts.d.ts +10 -2
- package/dist/src/cli/dev/tui/transcript-parts.js +2 -2
- package/dist/src/cli/dev/tui/transcript.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +8 -8
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +1 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +15 -0
- package/dist/src/compiled/@workflow/core/runtime/dynamic-workflow.d.ts +182 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/quickjs-assets.generated.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +2 -30
- package/dist/src/compiled/@workflow/core/runtime/quickjs-log-view.d.ts +27 -4
- package/dist/src/compiled/@workflow/core/runtime/quickjs-runtime.d.ts +55 -3
- package/dist/src/compiled/@workflow/core/runtime/quickjs-snapshot-codec.d.ts +74 -0
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +44 -0
- package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime.js +4 -4
- package/dist/src/compiled/@workflow/core/schemas.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +27 -2
- package/dist/src/compiled/@workflow/core/serialization/hardened.d.ts +8 -0
- package/dist/src/compiled/@workflow/core/serialization/types.d.ts +1 -0
- package/dist/src/compiled/@workflow/core/serialization.d.ts +48 -0
- package/dist/src/compiled/@workflow/core/serialization.js +1 -1
- package/dist/src/compiled/@workflow/core/set-error-stack.d.ts +12 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +47 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world/events.d.ts +10 -0
- package/dist/src/compiled/@workflow/world/index.d.ts +2 -0
- package/dist/src/compiled/@workflow/world/interfaces.d.ts +127 -0
- package/dist/src/compiled/@workflow/world/queue.d.ts +6 -0
- package/dist/src/compiled/@workflow/world/runs.d.ts +9 -2
- package/dist/src/compiled/@workflow/world/snapshots.d.ts +60 -0
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +19 -17
- package/dist/src/compiled/_chunks/node/undici-B61sz6UT.js +95 -0
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-D721NpZv.js → attribute-changes-VaTKT4K8.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/dist-B7NC1c9-.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{functions-DpZiBxgQ.js → functions-CKkqf9V6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/helpers-CP9TjeO8.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{logger-D4GJNTk4.js → logger-oqfblE3p.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/resume-hook-yq-NAdBu.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-DYKeqbob.js +32 -0
- package/dist/src/compiled/_chunks/workflow/serialization-APSKphN5.js +3 -0
- package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +95 -0
- package/dist/src/compiled/_chunks/workflow/sleep-Ba8SExMt.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-BhlnqoHM.js → token-BKeK6DmC.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/token-Cv2GYj9A.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-util-DaeRTzDa.js → token-util-CddTZ_ef.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{wait-until-3_1djUuL.js → wait-until-Dc9s3yyP.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{wrapper-CzrF_dmI.js → wrapper-Dq4OeGmJ.js} +4 -4
- package/dist/src/compiled/{gray-matter → js-yaml}/LICENSE +2 -2
- package/dist/src/compiled/js-yaml/index.d.ts +12 -0
- package/dist/src/compiled/js-yaml/index.js +34 -0
- package/dist/src/compiled/shadcn-registry/index.js +4 -4
- package/dist/src/context/serialize.d.ts +5 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/discover/discover-agent.js +1 -1
- package/dist/src/discover/extension-specifier.d.ts +1 -0
- package/dist/src/discover/extension-specifier.js +1 -1
- package/dist/src/discover/extensions.d.ts +1 -1
- package/dist/src/discover/extensions.js +1 -1
- package/dist/src/discover/project-source.d.ts +5 -0
- package/dist/src/discover/project-source.js +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/session.d.ts +1 -0
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +6 -0
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-remote-agent/protocol.d.ts +8 -0
- package/dist/src/execution/legacy-remote-agent/protocol.js +1 -1
- package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
- package/dist/src/execution/proxied-deliver-step.d.ts +11 -0
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/sandbox/read-file.d.ts +8 -1
- package/dist/src/execution/sandbox/read-file.js +3 -3
- package/dist/src/execution/session/active-turn.d.ts +4 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.d.ts +23 -0
- package/dist/src/execution/session/checkpoint-migrations.js +1 -0
- package/dist/src/execution/session/entry-input.d.ts +23 -5
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff-steps.d.ts +24 -5
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +40 -16
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/pending-turn-state.d.ts +2 -0
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/program.d.ts +16 -3
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step-result.js +1 -1
- package/dist/src/execution/session/turn-step-types.d.ts +13 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +14 -2
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +4 -4
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/attachment-staging.d.ts +27 -7
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/compaction-prompt.js +2 -2
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/token-estimate.d.ts +5 -3
- package/dist/src/harness/token-estimate.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/media-metadata.d.ts +25 -0
- package/dist/src/internal/attachments/media-metadata.js +1 -0
- package/dist/src/internal/attachments/sandbox-refs.d.ts +12 -7
- package/dist/src/internal/attachments/sandbox-refs.js +1 -1
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/bundler/extension-mount-plugin.d.ts +4 -0
- package/dist/src/internal/bundler/extension-mount-plugin.js +1 -1
- package/dist/src/internal/bundler/extension-scope-plugin.js +2 -2
- package/dist/src/internal/helpers/frontmatter.d.ts +24 -0
- package/dist/src/internal/helpers/frontmatter.js +1 -0
- package/dist/src/internal/helpers/markdown.js +1 -3
- package/dist/src/internal/input-text.d.ts +12 -0
- package/dist/src/internal/input-text.js +1 -0
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/nitro-bundler-config.js +1 -1
- package/dist/src/internal/node-esm-compat-banner.js +1 -1
- package/dist/src/internal/workflow/vercel-world-defaults.d.ts +1 -1
- package/dist/src/internal/workflow/vercel-world-defaults.js +1 -1
- package/dist/src/public/channels/chat-sdk/input-actions.d.ts +8 -2
- package/dist/src/public/channels/chat-sdk/input-actions.js +4 -1
- package/dist/src/public/channels/github/defaults.js +2 -3
- package/dist/src/public/channels/linear/hitl.js +2 -3
- package/dist/src/public/channels/slack/action-status.d.ts +10 -5
- package/dist/src/public/channels/slack/action-status.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +3 -3
- package/dist/src/public/channels/slack/limits.d.ts +1 -1
- package/dist/src/public/channels/slack/limits.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +11 -9
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/slack/task-card.js +1 -1
- package/dist/src/public/channels/slack/thread-status.d.ts +33 -0
- package/dist/src/public/channels/slack/thread-status.js +1 -0
- package/dist/src/public/channels/twilio/defaults.js +4 -2
- package/dist/src/public/definitions/state.d.ts +2 -0
- package/dist/src/public/definitions/state.js +1 -1
- package/dist/src/runtime/connections/openapi-spec.d.ts +1 -4
- package/dist/src/runtime/connections/openapi-spec.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +4 -4
- package/dist/src/setup/scaffold/create/web-template.js +33 -26
- package/dist/src/subagents/callback-route.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +2 -2
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/subagents/parent-notification.d.ts +7 -7
- package/dist/src/subagents/parent-notification.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/read-file.d.ts +7 -0
- package/dist/src/tools/provided/read-file.js +2 -2
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/docs/agent-config.md +2 -2
- package/docs/channels/chat-sdk.mdx +1 -1
- package/docs/channels/slack.mdx +21 -15
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/concepts/default-harness.md +4 -0
- package/docs/concepts/execution-model-and-durability.mdx +9 -1
- package/docs/concepts/sessions-runs-and-streaming.md +3 -3
- package/docs/evals/cases.mdx +1 -0
- package/docs/extensions.md +6 -3
- package/docs/guides/dev-tui.md +5 -3
- package/docs/guides/dynamic-capabilities.md +1 -1
- package/docs/sandbox/index.mdx +11 -0
- package/docs/tools/overview.mdx +4 -2
- package/package.json +8 -8
- package/dist/src/compiled/_chunks/node/undici-h5GH4RBM.js +0 -95
- package/dist/src/compiled/_chunks/workflow/debug-log-CVPstO1D.js +0 -1
- package/dist/src/compiled/_chunks/workflow/dist-BUFGAKRb.js +0 -1
- package/dist/src/compiled/_chunks/workflow/frames-Dr9fHWdo.js +0 -3
- package/dist/src/compiled/_chunks/workflow/helpers-DkKxg_yn.js +0 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-uTW-jBYz.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-5DmiMN9b.js +0 -1
- package/dist/src/compiled/_chunks/workflow/serialization-CNIYl1D3.js +0 -3
- package/dist/src/compiled/_chunks/workflow/signal-exit-DZKTacNU.js +0 -95
- package/dist/src/compiled/_chunks/workflow/sleep-DFKgN7UG.js +0 -1
- package/dist/src/compiled/_chunks/workflow/token-1wSBbi5N.js +0 -1
- package/dist/src/compiled/_chunks/workflow/token-util-Cm4Ec1Bg.js +0 -1
- package/dist/src/compiled/_chunks/workflow/ws-transport--rYOVIaf.js +0 -1
- package/dist/src/compiled/gray-matter/index.d.ts +0 -62
- package/dist/src/compiled/gray-matter/index.js +0 -48
- package/dist/src/internal/helpers/gray-matter.d.ts +0 -25
- package/dist/src/internal/helpers/gray-matter.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{deserializeContext}from"#context/serialize.js";import{resumeHook}from"#internal/workflow/runtime.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";function isSessionStateIdleForHandoff(e){let{state:t}=readDurableSession(e),n=getBlockingWorkflowToolRuns(t);if([`eve.runtime.pendingAuthorization`,`eve.runtime.pendingInputBatch`,`eve.runtime.pendingCoordinationBatch`,`eve.runtime.deferredStepInput`,`eve.harness.pendingWorkflowInterrupt`].some(e=>t?.[e]!==void 0))return!1;let r=t?.[`eve.runtime.pendingInputBatches`];if(r!==void 0&&(!Array.isArray(r)||r.length>0))return!1;let i=t?.[`eve.runtime.proxyInputRequests`];return i!==void 0&&(!isObject(i)||Object.keys(i).length>0)?!1:n.length===0}async function isSessionIdleForHandoffStep(e){"use step";return isSessionStateIdleForHandoff(e.sessionState)}async function validateSessionCheckpointStep(e){"use step";let{
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{walkCauseChain}from"#shared/errors.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{EntityConflictError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{cancelRun,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";const log=createLogger(`execution.handoff`);function isSessionStateIdleForHandoff(e){let{state:t}=readDurableSession(e),n=getBlockingWorkflowToolRuns(t);if([`eve.runtime.pendingAuthorization`,`eve.runtime.pendingInputBatch`,`eve.runtime.pendingCoordinationBatch`,`eve.runtime.deferredStepInput`,`eve.harness.pendingWorkflowInterrupt`].some(e=>t?.[e]!==void 0))return!1;let r=t?.[`eve.runtime.pendingInputBatches`];if(r!==void 0&&(!Array.isArray(r)||r.length>0))return!1;let i=t?.[`eve.runtime.proxyInputRequests`];return i!==void 0&&(!isObject(i)||Object.keys(i).length>0)?!1:n.length===0}async function isSessionIdleForHandoffStep(e){"use step";return isSessionStateIdleForHandoff(e.sessionState)}async function validateSessionCheckpointStep(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{checkpoint:n}=t,r=n.sessionTimeoutMs;if(r!==!1&&(typeof r!=`number`||!Number.isFinite(r)||r<0))throw Error(`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){let e=getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.inheritance?.definition??getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.definition;if(e.kind!==`independent`)throw Error(`Session checkpoint sandbox has no resolved provider.`);let t=getSandboxEnvironmentRuntime(e.environment);if(o.providerName!==t.providerName||o.stateProtocolVersion!==t.stateProtocolVersion)throw Error(`Session checkpoint sandbox provider state is incompatible.`)}if(!isSessionStateIdleForHandoff(n.sessionState))throw Error(`Session checkpoint contains pending work and cannot be handed off.`);return{kind:`valid`}}async function stopUntrackedChildSessionsStep(e){"use step";let t=await getWorld();for(let n of e.runIds)if(n!==e.sessionId)try{await cancelRun(t,n,{cancelReason:`Session upgraded`})}catch(t){[...walkCauseChain(t)].some(e=>EntityConflictError.is(e)||RunExpiredError.is(e)||WorkflowRunNotFoundError.is(e))||logError(log,`could not stop a subagent session after handoff`,t,{childRunId:n,sessionId:e.sessionId})}}async function reportSessionHandoffRetainedStep(e){"use step";log.warn(`session handoff failed; the current owner keeps the session`,{...e,checkpointVersion:SESSION_CHECKPOINT_VERSION})}async function signalSessionOwnerActivationStep(e){"use step";await resumeHook(e.token,e.activation)}async function signalSessionAnchorStep(e){"use step";await resumeHook(e.token,e.result)}export{isSessionIdleForHandoffStep,isSessionStateIdleForHandoff,reportSessionHandoffRetainedStep,signalSessionAnchorStep,signalSessionOwnerActivationStep,stopUntrackedChildSessionsStep,validateSessionCheckpointStep};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SessionCapabilities } from "#channel/types.js";
|
|
1
|
+
import type { DeliverHookPayload, SessionCapabilities } from "#channel/types.js";
|
|
2
2
|
import type { DurableSessionState } from "#execution/durable-session-store.js";
|
|
3
3
|
import type { HarnessModelMessage } from "#harness/messages.js";
|
|
4
4
|
import type { SessionInboxHandle, SessionInboxPayload } from "#execution/session-inbox/inbox.js";
|
|
@@ -8,9 +8,10 @@ import type { AgentWorkflowRetentionDefinition } from "#shared/agent-definition.
|
|
|
8
8
|
/**
|
|
9
9
|
* Cross-deployment checkpoint contract. The successor may run a different eve
|
|
10
10
|
* build than the owner that produced it; bump when any field changes shape so
|
|
11
|
-
* an
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* an older successor rejects the handoff instead of misreading state.
|
|
12
|
+
*
|
|
13
|
+
* A newer successor must always accept older checkpoints: every bump adds the
|
|
14
|
+
* upgrade from the previous version in `checkpoint-migrations.ts`.
|
|
14
15
|
*/
|
|
15
16
|
export declare const SESSION_CHECKPOINT_VERSION = 11;
|
|
16
17
|
/** Everything a successor needs to continue an idle session. Hooks are derived from the state. */
|
|
@@ -36,12 +37,6 @@ export type SessionOwnerActivation = {
|
|
|
36
37
|
/** Commands accepted by partial successor claims before startup failed. */
|
|
37
38
|
readonly payloads: readonly SessionInboxPayload[];
|
|
38
39
|
};
|
|
39
|
-
type SessionTransferOutcome = {
|
|
40
|
-
readonly kind: "transferred";
|
|
41
|
-
} | {
|
|
42
|
-
readonly kind: "retained";
|
|
43
|
-
readonly reason: "same-deployment" | "missing-deployment" | "not-idle" | "busy" | "accepted-during-release" | "activation-failed" | "checkpoint-incompatible" | "known-incompatible";
|
|
44
|
-
};
|
|
45
40
|
interface SessionHandoffInput {
|
|
46
41
|
readonly checkpoint: Omit<SessionCheckpoint, "history" | "serializedContext" | "sessionState" | "version">;
|
|
47
42
|
readonly deploymentId: string;
|
|
@@ -50,9 +45,23 @@ interface SessionHandoffInput {
|
|
|
50
45
|
readonly sessionId: string;
|
|
51
46
|
}
|
|
52
47
|
export declare function sessionAnchorToken(sessionId: string): string;
|
|
48
|
+
type SessionTransferOutcome = {
|
|
49
|
+
readonly kind: "transferred";
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: "retained";
|
|
52
|
+
readonly reason: SessionRetainedReason;
|
|
53
|
+
};
|
|
54
|
+
type SessionRetainedReason = "same-deployment" | "missing-deployment" | "not-idle" | "busy" | "accepted-during-release" | "activation-failed" | "checkpoint-incompatible" | "known-incompatible";
|
|
55
|
+
/** A compaction handoff the owner owes; the successor keeps this deadline. */
|
|
56
|
+
export interface CompactionHandoff {
|
|
57
|
+
readonly sessionTimeoutDeadline: Date | undefined;
|
|
58
|
+
}
|
|
59
|
+
type SessionTransferState = Pick<SessionCheckpoint, "history" | "serializedContext" | "sessionState">;
|
|
53
60
|
/**
|
|
54
|
-
* The sole boundary for moving an idle session to
|
|
55
|
-
*
|
|
61
|
+
* The sole boundary for moving an idle session to a successor run: on another
|
|
62
|
+
* exact deployment when newer code accepts a delivery, or on this deployment
|
|
63
|
+
* after compaction so no single run's event log grows with the session.
|
|
64
|
+
* Constructed once per owner; each `try*` method attempts one transfer.
|
|
56
65
|
* When the upstream atomic hook-handoff primitive lands, only this class changes.
|
|
57
66
|
*
|
|
58
67
|
* Skipping known-incompatible targets requires this owner run to execute the
|
|
@@ -68,11 +77,25 @@ export declare class SessionHandoff {
|
|
|
68
77
|
private readonly incompatibleTargetDeploymentIds;
|
|
69
78
|
constructor(input: SessionHandoffInput);
|
|
70
79
|
/**
|
|
71
|
-
* Attempts to move the session to the selected delivery's deployment.
|
|
72
|
-
*
|
|
73
|
-
* session
|
|
80
|
+
* Attempts to move the session to the selected delivery's deployment. When a
|
|
81
|
+
* compaction handoff is due and that deployment is this one or unknown, the
|
|
82
|
+
* session moves to a fresh run here instead. The outcome states whether the
|
|
83
|
+
* successor activated or this owner retained the session. Candidate failures
|
|
84
|
+
* recover locally rather than escaping.
|
|
85
|
+
*/
|
|
86
|
+
tryTransfer(selection: TurnSelection, state: SessionTransferState, options?: {
|
|
87
|
+
readonly compaction?: CompactionHandoff;
|
|
88
|
+
}): Promise<SessionTransferOutcome>;
|
|
89
|
+
/**
|
|
90
|
+
* Attempts to move a session that compacted to a fresh run on this
|
|
91
|
+
* deployment. Without a delivery the caller guarantees no input is waiting,
|
|
92
|
+
* and the successor parks until the next one arrives. The successor keeps
|
|
93
|
+
* the session's deadline.
|
|
74
94
|
*/
|
|
75
|
-
|
|
95
|
+
tryCompactionTransfer(state: SessionTransferState, compaction: CompactionHandoff & {
|
|
96
|
+
readonly delivery?: DeliverHookPayload;
|
|
97
|
+
}): Promise<SessionTransferOutcome>;
|
|
98
|
+
private transfer;
|
|
76
99
|
/** After a transfer, the original run parks until the final owner reports the session result. */
|
|
77
100
|
awaitAnchoredResult(): Promise<WorkflowEntryResult>;
|
|
78
101
|
disposeAnchor(): Promise<void>;
|
|
@@ -80,6 +103,7 @@ export declare class SessionHandoff {
|
|
|
80
103
|
private startAndActivate;
|
|
81
104
|
/** Reclaims the exact hook set and replays payloads accepted while it was released. */
|
|
82
105
|
private recover;
|
|
106
|
+
private reportRetained;
|
|
83
107
|
private ensureAnchor;
|
|
84
108
|
}
|
|
85
109
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sessionHandoffMarkerToken}from"#execution/session-inbox/address.js";import{startSessionOwnerStep}from"#execution/workflow-runtime.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{isSessionIdleForHandoffStep}from"#execution/session/handoff-steps.js";import{readAcceptedDeploymentId}from"#execution/session/accepted-deployment.js";const SESSION_CHECKPOINT_VERSION=11;function sessionAnchorToken(e){return`${e}:anchor`}var SessionHandoff=class{input;anchor;incompatibleTargetDeploymentIds=new Set;constructor(e){this.input=e}async tryTransfer(e,t){let{
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{sessionHandoffMarkerToken}from"#execution/session-inbox/address.js";import{startSessionOwnerStep}from"#execution/workflow-runtime.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{isSessionIdleForHandoffStep,reportSessionHandoffRetainedStep}from"#execution/session/handoff-steps.js";import{readAcceptedDeploymentId}from"#execution/session/accepted-deployment.js";const SESSION_CHECKPOINT_VERSION=11;function sessionAnchorToken(e){return`${e}:anchor`}var SessionHandoff=class{input;anchor;incompatibleTargetDeploymentIds=new Set;constructor(e){this.input=e}async tryTransfer(e,t,n={}){let{delivery:r}=e,i=readAcceptedDeploymentId(r);return(i===void 0||i===this.input.deploymentId)&&n.compaction!==void 0?e.handoffEligible?await this.tryCompactionTransfer(t,{...n.compaction,delivery:r}):{kind:`retained`,reason:`busy`}:i===void 0?{kind:`retained`,reason:`missing-deployment`}:i===this.input.deploymentId?{kind:`retained`,reason:`same-deployment`}:this.incompatibleTargetDeploymentIds.has(i)?{kind:`retained`,reason:`known-incompatible`}:e.handoffEligible?await this.transfer(t,i,{delivery:r}):{kind:`retained`,reason:`busy`}}async tryCompactionTransfer(e,t){let{deploymentId:n}=this.input;return this.incompatibleTargetDeploymentIds.has(n)?{kind:`retained`,reason:`known-incompatible`}:await this.transfer(e,n,{...t,reason:`compaction`})}async transfer(e,t,n){let{inbox:r}=this.input;if(!await isSessionIdleForHandoffStep({sessionState:e.sessionState}))return{kind:`retained`,reason:`not-idle`};let i={...this.input.checkpoint,...e,version:11},a=sessionHookTokens(e);await this.ensureAnchor();let o=a.map(e=>createHook({token:sessionHandoffMarkerToken(e)}));await Promise.all(o.map(e=>claimHookOwnership(e)));let s;try{let e=await r.release();if(e.length>0)return await this.recover(a,e),{kind:`retained`,reason:`accepted-during-release`};let o=[];try{let e=await this.startAndActivate(i,n,t);if(e.kind===`active`)return{kind:`transferred`};o=e.payloads,e.kind===`incompatible`?(this.incompatibleTargetDeploymentIds.add(t),s={reason:`checkpoint-incompatible`}):s={error:e.error,reason:`activation-failed`}}catch(e){s={error:e,reason:`activation-failed`}}await this.recover(a,o)}finally{await Promise.all(o.map(e=>disposeHook(e)))}return await this.reportRetained(s.reason,t,s.error),{kind:`retained`,reason:s.reason}}async awaitAnchoredResult(){if(this.anchor===void 0)throw Error(`Session anchor was never claimed.`);try{return await this.anchor}finally{await this.disposeAnchor()}}async disposeAnchor(){if(this.anchor===void 0)return;let e=this.anchor;this.anchor=void 0,await disposeHook(e)}async startAndActivate(e,t,n){let r=createHook({token:`${getWorkflowMetadata().workflowRunId}:handoff`});await claimHookOwnership(r);try{return await startSessionOwnerStep({...t,activationToken:r.token,anchorRunId:this.input.sessionId,checkpoint:e,targetDeploymentId:n}),await r}finally{await disposeHook(r)}}async recover(e,t){await this.input.inbox.claimSessionHooks(e),this.input.inbox.restore(t)}async reportRetained(e,t,n){let r=isObject(n)&&typeof n.message==`string`?n.message:void 0;await reportSessionHandoffRetainedStep({error:r,reason:e,sessionId:this.input.sessionId,sourceDeploymentId:this.input.deploymentId,targetDeploymentId:t})}async ensureAnchor(){this.input.isInitialOwner&&this.anchor===void 0&&(this.anchor=createHook({token:sessionAnchorToken(this.input.sessionId)}),await claimHookOwnership(this.anchor))}};export{SESSION_CHECKPOINT_VERSION,SessionHandoff,sessionAnchorToken};
|
|
@@ -5,6 +5,8 @@ export declare function derivePendingState(session: HarnessSession): {
|
|
|
5
5
|
readonly authorizationAttemptIds?: readonly string[];
|
|
6
6
|
readonly hasPendingAuthorization: boolean;
|
|
7
7
|
readonly hasPendingInputBatch: boolean;
|
|
8
|
+
/** The pending batch has workflow tool runs to start; task tool calls are answered by the session. */
|
|
9
|
+
readonly hasRunsToDispatch?: boolean;
|
|
8
10
|
readonly pendingCoordinationCallIds?: readonly string[];
|
|
9
11
|
readonly pendingTaskToolCalls?: readonly TaskToolCall[];
|
|
10
12
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPendingCoordinationBatch,pendingCoordinationCallIds}from"#harness/coordination.js";import{getPendingAuthorization}from"#harness/authorization.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{pendingTaskToolCalls}from"#execution/tasks/calls.js";function derivePendingState(e){let t=getPendingCoordinationBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationAttemptIds:n?.challenges.flatMap(e=>e.attemptId===void 0?[]:[e.attemptId]),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingCoordinationCallIds:pendingCoordinationCallIds(t),pendingTaskToolCalls:pendingTaskToolCalls(t.responseMessages)}}export{derivePendingState};
|
|
1
|
+
import{getPendingCoordinationBatch,pendingCoordinationCallIds}from"#harness/coordination.js";import{getPendingAuthorization}from"#harness/authorization.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{pendingTaskToolCalls}from"#execution/tasks/calls.js";function derivePendingState(e){let t=getPendingCoordinationBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationAttemptIds:n?.challenges.flatMap(e=>e.attemptId===void 0?[]:[e.attemptId]),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,hasRunsToDispatch:t.tasks.length>0,pendingCoordinationCallIds:pendingCoordinationCallIds(t),pendingTaskToolCalls:pendingTaskToolCalls(t.responseMessages)}}export{derivePendingState};
|
|
@@ -16,15 +16,28 @@ export type SessionAnchor = {
|
|
|
16
16
|
} | {
|
|
17
17
|
readonly kind: "successor";
|
|
18
18
|
};
|
|
19
|
+
/** What an owner does before it first waits on its inbox. */
|
|
20
|
+
export type SessionStart =
|
|
21
|
+
/** Runs a turn first; `input` is absent for a session started without a message. */
|
|
22
|
+
{
|
|
23
|
+
readonly kind: "turn";
|
|
24
|
+
readonly input: DeliverHookPayload | undefined;
|
|
25
|
+
}
|
|
26
|
+
/** A prewarmed session parks on the inbox before any session-scoped lifecycle work. */
|
|
27
|
+
| {
|
|
28
|
+
readonly kind: "first-message";
|
|
29
|
+
}
|
|
30
|
+
/** A successor that received a settled session waits for its next input. */
|
|
31
|
+
| {
|
|
32
|
+
readonly kind: "parked";
|
|
33
|
+
};
|
|
19
34
|
export interface SessionBoot {
|
|
20
35
|
readonly anchor: SessionAnchor;
|
|
21
36
|
readonly caller: TurnCaller | undefined;
|
|
22
37
|
readonly capabilities?: SessionCapabilities;
|
|
23
38
|
readonly deploymentId: string;
|
|
24
39
|
readonly history: HarnessModelMessage[];
|
|
25
|
-
readonly
|
|
26
|
-
/** Parks on the inbox before any session-scoped lifecycle work. */
|
|
27
|
-
readonly awaitFirstMessage: boolean;
|
|
40
|
+
readonly start: SessionStart;
|
|
28
41
|
readonly retention?: AgentWorkflowRetentionDefinition;
|
|
29
42
|
readonly serializedContext: Record<string, unknown>;
|
|
30
43
|
readonly sessionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import"#execution/session-inbox/inbox.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{
|
|
1
|
+
import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import"#execution/session-inbox/inbox.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{SessionHandoff,sessionAnchorToken}from"#execution/session/handoff.js";import{notifyCancelledTaskCallerStep,notifyTurnCallerStep,resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{signalSessionAnchorStep}from"#execution/session/handoff-steps.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{createSessionTimeoutControl}from"#execution/session/timeout-control.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=new SessionStateCursor({history:e.history,inbox:t,sessionWritable:e.sessionWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}),r={caller:e.caller,terminalEmitted:!1},i=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}),a={output:``,isError:!0},o;try{try{o=await runSessionLoop(e,{cursor:n,handoff:i,inbox:t,progress:r})}finally{await t.dispose()}return o.kind===`transferred`?e.anchor.kind===`self`?(a=await i.awaitAnchoredResult(),a):{output:``}:(a=await finalizeSession(o.outcome,{caller:r.caller,cursor:n,sessionWritable:e.sessionWritable}),r.terminalEmitted=!0,a)}catch(t){throw r.terminalEmitted||await finalizeSession({error:t,kind:`failed`,turnId:r.turnId},{caller:r.caller,cursor:n,sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}finally{await reportResultToAnchor(e,a,i,o)}}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,s=new SessionExecution({capabilities:e.capabilities,cursor:n,inbox:i,queue:o,sessionId:e.sessionId}),c=e.sessionTimeoutDeadline===void 0?void 0:createSessionTimeoutControl({deadline:e.sessionTimeoutDeadline,sessionId:e.sessionId}),nextParkedActivity=async()=>{for(;;){let e=await nextTurnDelivery({cursor:n,hasWorkingTasks:()=>workingTasks(sessionTaskTable(n)).length>0,inbox:i,queue:o});if(e.kind===`workflow`){await s.handleWorkflowMessage(e.message);continue}if(e.kind===`cancel-working-tasks`){await cancelWorkingTasks(n,`turn_cancelled`);continue}return e}},l=0,u=!1,runTurn=async e=>{let t=a.caller;a.turnId=`turn_${String(l++)}`;let n=await s.runTurn(e,{caller:t});return n.caller!==void 0&&(a.caller=n.caller),n.compacted===!0&&(u=!0),n},transferState=()=>({history:n.history,serializedContext:n.serializedContext,sessionState:n.sessionState}),dueCompactionHandoff=()=>u&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0?{sessionTimeoutDeadline:e.sessionTimeoutDeadline}:void 0,tryCompactionHandoff=async()=>{let e=dueCompactionHandoff();if(e===void 0||o.pendingCount>0||i.hasPending())return;let t=await r.tryCompactionTransfer(transferState(),e);return t.kind===`transferred`?t:void 0},runDeliveredTurn=async e=>{let t=await r.tryTransfer(e,transferState(),{compaction:dueCompactionHandoff()});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=>{let t=await n.advanceWithHistory(t=>settleCancelledTurnStep({...t,reportUsage:e}));return a.caller=void 0,t},awaitPrewarmedAction=async()=>{for(;;){let e=await nextParkedActivity();switch(e.kind){case`expired`:case`reset`:case`closed`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:continue;case`turn`:return await runDeliveredTurn(e);case`cancel-turn`:continue}}},runInitialAction=async()=>{switch(e.start.kind){case`first-message`:return 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 r=t.value;if(r.kind!==`action`)return r;let i=r.action;for(;;){if(i.kind===`done`)return{kind:`terminal`,outcome:{action:i,kind:`done`}};if(i.cancelled===!0){let{caller:t}=a,n=await settleCancelledTurn(t!==void 0);if(t!==void 0){let r={caller:t,sessionId:e.sessionId};await notifyCancelledTaskCallerStep(n.usage===void 0?r:{...r,usage:n.usage})}}else i.settled!==void 0&&(a.caller!==void 0&&await notifyTurnCallerStep({caller:a.caller,lifecycle:`parked`,sessionId:e.sessionId,settled:i.settled}),a.caller=void 0);let t=await tryCompactionHandoff();if(t!==void 0)return t;let n=await nextParkedActivity();switch(n.kind){case`expired`:case`reset`:case`closed`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:i=await runTurn({control:n.kind});continue;case`cancel-turn`:await s.cancelTurnWork(),await settleCancelledTurn(!1),i={...i,settled:void 0};continue;case`turn`:{let e=await runDeliveredTurn(n);if(e.kind!==`action`)return e;i=e.action;continue}}}}finally{await c?.dispose()}}export{failSession,runPreparedSession};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getTurnUsageState,takeSessionUsageDelta,toUsage}from"#harness/turn-tag-state.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{getPendingInputBatches}from"#harness/pending-input-batches.js";function resolveSessionStepResult(e,t){let n={serializedContext:t,...createDurableSessionValues(e.session)};if(e.steered)return{action:`steered`,...n};if(e.next!==null&&typeof e.next==`object`&&`done`in e.next){let t=getTurnUsageState(e.session.state)?.session;return{action:`done`,output:e.next.output,isError:e.next.isError,...n,usage:t===void 0?void 0:toUsage(t),usageDelta:takeSessionUsageDelta(e.session).delta}}if(e.held?.kind===`tasks`)return{action:`held`,hold:`tasks`,...n,taskIds:e.held.taskIds};if(e.held?.kind===`request`){let t=derivePendingState(e.session);return{action:`held`,authorizationAttemptIds:t.authorizationAttemptIds??[],hasPendingInputBatch:t.hasPendingInputBatch,hold:`request`,inputRequestIds:getPendingInputBatches(e.session.state).flatMap(e=>e.requests.map(e=>e.requestId)),...n}}if(e.next===null){let{
|
|
1
|
+
import{getTurnUsageState,takeSessionUsageDelta,toUsage}from"#harness/turn-tag-state.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{getPendingInputBatches}from"#harness/pending-input-batches.js";function resolveSessionStepResult(e,t){let n={serializedContext:t,...createDurableSessionValues(e.session)};if(e.steered)return{action:`steered`,...n};if(e.next!==null&&typeof e.next==`object`&&`done`in e.next){let t=getTurnUsageState(e.session.state)?.session;return{action:`done`,output:e.next.output,isError:e.next.isError,...n,usage:t===void 0?void 0:toUsage(t),usageDelta:takeSessionUsageDelta(e.session).delta}}if(e.held?.kind===`tasks`)return{action:`held`,hold:`tasks`,...n,taskIds:e.held.taskIds};if(e.held?.kind===`request`){let t=derivePendingState(e.session);return{action:`held`,authorizationAttemptIds:t.authorizationAttemptIds??[],hasPendingInputBatch:t.hasPendingInputBatch,hold:`request`,inputRequestIds:getPendingInputBatches(e.session.state).flatMap(e=>e.requests.map(e=>e.requestId)),...n}}if(e.next===null){let{hasRunsToDispatch:r,pendingCoordinationCallIds:i,pendingTaskToolCalls:a}=derivePendingState(e.session),o={hasRunsToDispatch:r,pendingCoordinationCallIds:i,pendingTaskToolCalls:a};if(e.settledTurn!==void 0){let{delta:n,session:r}=takeSessionUsageDelta(e.session);return{action:`park`,...o,serializedContext:t,...createDurableSessionValues(r),settled:{output:e.settledTurn.output,isError:e.settledTurn.isError,usage:n}}}return{action:`park`,...o,...n}}return{action:`continue`,...n}}export{resolveSessionStepResult};
|
|
@@ -26,6 +26,8 @@ export interface TurnStepPayload {
|
|
|
26
26
|
/** Input for one atomic, session-owner-executed turn step. */
|
|
27
27
|
export interface TurnStepInput {
|
|
28
28
|
readonly abortSignal?: AbortSignal;
|
|
29
|
+
/** The delegated caller to bind into the context before the step runs; sent on a turn's first step. */
|
|
30
|
+
readonly caller?: TurnCaller;
|
|
29
31
|
readonly steeringSignal?: AbortSignal;
|
|
30
32
|
readonly input: TurnStepPayload | undefined;
|
|
31
33
|
readonly sessionWritable: WritableStream<Uint8Array>;
|
|
@@ -64,10 +66,18 @@ export type DurableStepResult = ({
|
|
|
64
66
|
readonly inputRequestIds: readonly string[];
|
|
65
67
|
} | {
|
|
66
68
|
readonly action: "park";
|
|
69
|
+
/**
|
|
70
|
+
* `false` when every pending call is a task tool call the session answers
|
|
71
|
+
* itself, so the dispatch step can be skipped. Absent, the step runs.
|
|
72
|
+
*/
|
|
73
|
+
readonly hasRunsToDispatch?: boolean;
|
|
67
74
|
readonly pendingCoordinationCallIds?: readonly string[];
|
|
68
75
|
readonly pendingTaskToolCalls?: readonly TaskToolCall[];
|
|
69
76
|
readonly settled?: SettledTurn;
|
|
70
|
-
}) & DurableStepResultFields
|
|
77
|
+
}) & DurableStepResultFields & {
|
|
78
|
+
/** The step compacted the history. */
|
|
79
|
+
readonly compacted?: true;
|
|
80
|
+
};
|
|
71
81
|
/** What `turnStep` returns: its result, with the session state as a delta. */
|
|
72
82
|
export type TurnStepResult = WithSessionStateDelta<DurableStepResult>;
|
|
73
83
|
/** The only two ways a locally executed conversational turn can settle. */
|
|
@@ -77,6 +87,8 @@ export type TurnOutcome = {
|
|
|
77
87
|
* later message awaits its reply at its own address, so the turn reports there.
|
|
78
88
|
*/
|
|
79
89
|
readonly caller?: TurnCaller;
|
|
90
|
+
/** A step of the turn compacted the history. */
|
|
91
|
+
readonly compacted?: true;
|
|
80
92
|
} & ({
|
|
81
93
|
readonly kind: "done";
|
|
82
94
|
readonly output: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,ParentSessionKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,createTurnStartedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,createTurnInputMessages,validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryPreamble}from"#context/memory-lifecycle.js";import{emitTurnPreamble,getHarnessEmissionState,isHarnessBetweenTurns,setHarnessEmissionState}from"#harness/emission.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import*as agentTraceState from"#tracing/agent-trace-context-store.js";import{activeTurnId}from"#harness/active-turn-id.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{setChannelContext}from"#execution/channel-context.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{drainDynamicInstructionUserMessages,prepareDynamicInstructionPreamble}from"#context/dynamic-instruction-lifecycle.js";import{consumeDeferredStepInput}from"#harness/pending-input-batches.js";import{bindDynamicConnections}from"#execution/dynamic-connections.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{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{authorizationEventFields}from"#harness/authorization-event-fields.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{prepareWorkflowPreambleTrace}from"#execution/workflow-trace-context.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return await withSessionStateDelta(e,runSessionStep)}async function runSessionStep(e){let t=e.input?.delivery,n=t,r=e.input?.runtimeResults,i=readDurableSession(e.sessionState);for(let e of r?.delegatedUsage??[])i=countRunUsage(i,e);let a=await deserializeContext(e.serializedContext),o=a.require(ChannelKey),s=a.require(BundleKey),c=resolveEffectiveAgentRuntime(s,a);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&a.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let l=getPendingAuthorization(i.state),u;if(l&&n!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(l,n.payloads);if(n={...n,payloads:t},e.length>0){let r=e.map(e=>e.result.attemptId),o=e.map(e=>e.result);a.set(PendingAuthorizationResultKey,o),i={...i,state:clearPendingAuthorization(i.state,r)},u=e,t.length===0&&(n=void 0)}}let d=a.get(AuthKey);n?.auth!==void 0&&(a.set(AuthKey,n.auth??null),a.has(InitiatorAuthKey)||a.set(InitiatorAuthKey,n.auth??null));let f=n===void 0?u?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;f!==void 0&&a.set(AuthKey,f);let p={...hydrateDurableSession({compactionOverrides:{thresholdPercent:c.thresholdPercent},durable:i,turnAgent:c.turnAgent}),history:validateHarnessModelMessages(e.history)},m=createExecutionHistoryView(p),h=bindSessionInstrumentation({agentName:c.turnAgent.id,ctx:a,rootSessionId:p.rootSessionId??p.sessionId,sessionId:p.sessionId}),g=getHarnessEmissionState(p.state);if(!g.sessionStarted&&!a.has(SessionTitleKey)&&!a.has(ParentSessionKey)){let e=t?.payloads.find(e=>e.message!==void 0)?.message,n=deriveSessionTitle(t?.title??e);n!==void 0&&(a.set(SessionTitleKey,n),await setEveAttributes({"$eve.title":n}))}t!==void 0&&(await contextStorage.run(a,()=>h?.preparePreamble({sequence:g.sequence,sessionStarted:g.sessionStarted})),await contextStorage.run(a,()=>h?.instrumentChannelDelivery({agentName:s.turnAgent.id,ctx:a,delivery:t,rootSessionId:p.rootSessionId??p.sessionId,sequence:g.sequence,sessionId:p.sessionId,turnId:activeTurnId(g)})));let failChannelDeliveries=async e=>{await contextStorage.run(a,()=>h?.instrumentChannelDelivery({ctx:a,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await h?.flush()},_=openSessionEventPublisher({ctx:a,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:v}=_.dispatcher,y=new AbortController,b=e.abortSignal===void 0?y.signal:AbortSignal.any([e.abortSignal,y.signal]);try{let i=bindDynamicConnections(a,s.resolvedAgent),l={...s.graph.root,turnAgent:c.turnAgent},f=createTurnEventHandler({abortSignal:b,bundle:s,canCancelTurn:e.input?.control===void 0,hookCancellation:y,ctx:a,dynamicConnections:i,effectiveAgent:c,effectiveNode:l,instrumentation:h,publisher:_}),x=n!==void 0&&!isHarnessBetweenTurns(p)?structuredClone(v.state):void 0,S;if(n!==void 0){let e=[];try{for(let t of n.payloads){let n=o.deliver?await o.deliver(t,v):defaultDeliverResult(t);n!=null&&e.push(n)}}catch(e){throw await failChannelDeliveries(e),e}S=e.length===0?void 0:e.reduce(coalesceTurnInputs)}if(n!==void 0&&S===void 0&&!isHarnessBetweenTurns(p))d===void 0?a.delete(AuthKey):a.set(AuthKey,d),v.state=x;else if(t?.payloads.some(e=>e.message!==void 0)){let e=t.deliveryMetadata?.map(e=>e.deliveryId)??[];a.set(TurnDeliveryIdsKey,g.turnId?[...new Set([...a.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!g.sessionStarted&&a.get(ChannelDeliveryKey)!==void 0&&a.set(TurnDeliveryIdsKey,[a.require(ChannelDeliveryKey).deliveryId]);if(r!==void 0&&(r.acceptedAtMsByCallId!==void 0&&a.set(RuntimeActionSettlementTimesKey,r.acceptedAtMsByCallId),S={...S,runtimeActionResults:r.results}),t!==void 0){let e={...o,state:{...v.state}};setChannelContext(a,e)}if(n!==void 0&&S===void 0&&isHarnessBetweenTurns(p)){await contextStorage.run(a,()=>h?.instrumentChannelDelivery({ctx:a,includeTurn:!1,outcome:`completed`})),await h?.flush();let t=reconcileSessionContinuationToken(a,p),n=serializeContext(a),r=t===p?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t),serializedContext:n,...r}}let C=s.subagentRegistry.dynamicResolvers??[],w=s.resolvedAgent.dynamicToolResolvers??[],T=buildRuntimeIdentity(l);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(s.compiledArtifactsSource),n=g.sessionStarted;if(a.setVirtualContext(StaticModelReferenceKey,c.turnAgent.model??null),!n)a.set(SessionDynamicSubagentRuntimeRevisionKey,t),a.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=createSessionStartedEvent({runtime:T});await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:a,resolvers:C,event:e,messages:m.initial.messages,runtimeRevision:t}),contextStorage.run(a,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:a,resolvers:w,event:e,messages:m.initial.messages,runtimeRevision:t}))]),isHarnessBetweenTurns(p)||await rebindMissingCompiledDynamicToolCallbacks({ctx:a,event:createTurnStartedEvent({sequence:g.sequence,turnId:activeTurnId(g)}),messages:m.initial.messages,resolvers:w})}}catch(e){throw await failChannelDeliveries(e),e}let E=s.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,D=a.get(CapabilitiesKey),runHarnessStep=async(t,n)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:c.thresholdPercent},session:t,turnAgent:c.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:b,capabilities:D,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent:f,prepareApprovalTurn:e=>i.dispatch(createTurnStartedEvent(e)),historyProjector:m.projector,historyView:m.prepare(r),instrumentation:h,modelResolutionScope:{moduleMap:s.moduleMap,nodeId:s.nodeId},node:l})(r,n)},O,k;try{throwIfTurnAborted(b),k=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:S,initialSession:p,modelCallsPerStep:E,runStep:async({firstCall:e,session:t,stepInput:n})=>{let r=await runStep(a,t,async t=>{a.setVirtualContext(HandleEventKey,f),a.setVirtualContext(StaticModelReferenceKey,c.turnAgent.model??null);let r=e&&S?.outputSchema!==void 0?{...t,outputSchema:S.outputSchema}:t,o=getHarnessEmissionState(r.state);if(await i.rehydrate(o,T,isHarnessBetweenTurns(r)?void 0:{sequence:o.sequence,turnId:activeTurnId(o)}),e&&u){let e=getHarnessEmissionState(r.state);if(u.some(({challenge:e})=>e.candidateId===void 0)&&isHarnessBetweenTurns(r)){let t=createTurnInputMessages(consumeDeferredStepInput({session:r,input:n}).input);prepareDynamicInstructionPreamble(a,m.messages(r)),prepareMemoryPreamble(a,{history:r.history,input:t,projector:m.projector,state:r.state});let i=[],o=await prepareWorkflowPreambleTrace({emissionState:e,instrumentation:h});try{e=await emitTurnPreamble(f,{},e,m.projector({messages:[...r.history,...t],state:r.state}),T,o)}finally{i=drainDynamicInstructionUserMessages(a);let e=drainMemoryCommit(a);r={...r,history:validateHarnessModelMessages([...r.history,...e?.recalledMessages??[],...i]),state:e?.state??r.state}}r=setHarnessEmissionState(r,e)}for(let{challenge:t}of u)await f(createAuthorizationCompletedEvent({...authorizationEventFields(t),outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}return runHarnessStep(r,n)});return r.settledTurn===void 0&&throwIfTurnAborted(b),O={result:r,serializedContext:serializeContext(a)},r}})}catch(t){if(!isTurnCancellation(t)&&!b.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:O,ctx:a,initialSession:p,stepInput:S})}let A=reconcileSessionContinuationToken(a,k.session);agentTraceState.pruneAgentTraceState(a,A.sessionId,A.state);let j=serializeContext(a);k={...k,session:A};let M=resolveSessionStepResult(k,j);return M.action===`done`&&await _.writer.close(),M}finally{_.writer.release()}}export{turnStep};
|
|
1
|
+
import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,ParentSessionKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,createTurnStartedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,createTurnInputMessages,validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryPreamble}from"#context/memory-lifecycle.js";import{emitTurnPreamble,getHarnessEmissionState,isHarnessBetweenTurns,setHarnessEmissionState}from"#harness/emission.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import*as agentTraceState from"#tracing/agent-trace-context-store.js";import{activeTurnId}from"#harness/active-turn-id.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{setChannelContext}from"#execution/channel-context.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.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{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{drainDynamicInstructionUserMessages,prepareDynamicInstructionPreamble}from"#context/dynamic-instruction-lifecycle.js";import{consumeDeferredStepInput}from"#harness/pending-input-batches.js";import{bindDynamicConnections}from"#execution/dynamic-connections.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{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{authorizationEventFields}from"#harness/authorization-event-fields.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{prepareWorkflowPreambleTrace}from"#execution/workflow-trace-context.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t=e.input?.delivery,n=t,r=e.input?.runtimeResults,i=readDurableSession(e.sessionState);for(let e of r?.delegatedUsage??[])i=countRunUsage(i,e);let a=await deserializeContext(e.serializedContext),o=a.require(ChannelKey),s=a.require(BundleKey),c=resolveEffectiveAgentRuntime(s,a);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&a.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let l=getPendingAuthorization(i.state),u;if(l&&n!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(l,n.payloads);if(n={...n,payloads:t},e.length>0){let r=e.map(e=>e.result.attemptId),o=e.map(e=>e.result);a.set(PendingAuthorizationResultKey,o),i={...i,state:clearPendingAuthorization(i.state,r)},u=e,t.length===0&&(n=void 0)}}let d=a.get(AuthKey);n?.auth!==void 0&&(a.set(AuthKey,n.auth??null),a.has(InitiatorAuthKey)||a.set(InitiatorAuthKey,n.auth??null));let f=n===void 0?u?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;f!==void 0&&a.set(AuthKey,f);let p={...hydrateDurableSession({compactionOverrides:{thresholdPercent:c.thresholdPercent},durable:i,turnAgent:c.turnAgent}),history:validateHarnessModelMessages(e.history)},m=createExecutionHistoryView(p),h=bindSessionInstrumentation({agentName:c.turnAgent.id,ctx:a,rootSessionId:p.rootSessionId??p.sessionId,sessionId:p.sessionId}),g=getHarnessEmissionState(p.state);if(!g.sessionStarted&&!a.has(SessionTitleKey)&&!a.has(ParentSessionKey)){let e=t?.payloads.find(e=>e.message!==void 0)?.message,n=deriveSessionTitle(t?.title??e);n!==void 0&&(a.set(SessionTitleKey,n),await setEveAttributes({"$eve.title":n}))}t!==void 0&&(await contextStorage.run(a,()=>h?.preparePreamble({sequence:g.sequence,sessionStarted:g.sessionStarted})),await contextStorage.run(a,()=>h?.instrumentChannelDelivery({agentName:s.turnAgent.id,ctx:a,delivery:t,rootSessionId:p.rootSessionId??p.sessionId,sequence:g.sequence,sessionId:p.sessionId,turnId:activeTurnId(g)})));let failChannelDeliveries=async e=>{await contextStorage.run(a,()=>h?.instrumentChannelDelivery({ctx:a,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await h?.flush()},_=openSessionEventPublisher({ctx:a,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:v}=_.dispatcher,y=new AbortController,b=e.abortSignal===void 0?y.signal:AbortSignal.any([e.abortSignal,y.signal]);try{let i=bindDynamicConnections(a,s.resolvedAgent),l={...s.graph.root,turnAgent:c.turnAgent},f=!1,x=createTurnEventHandler({abortSignal:b,bundle:s,canCancelTurn:e.input?.control===void 0,hookCancellation:y,ctx:a,dynamicConnections:i,effectiveAgent:c,effectiveNode:l,instrumentation:h,publisher:_}),handleEvent=async(e,t)=>{e.type===`compaction.completed`&&(f=!0),await x(e,t)},S=n!==void 0&&!isHarnessBetweenTurns(p)?structuredClone(v.state):void 0,C;if(n!==void 0){let e=[];try{for(let t of n.payloads){let n=o.deliver?await o.deliver(t,v):defaultDeliverResult(t);n!=null&&e.push(n)}}catch(e){throw await failChannelDeliveries(e),e}C=e.length===0?void 0:e.reduce(coalesceTurnInputs)}if(n!==void 0&&C===void 0&&!isHarnessBetweenTurns(p))d===void 0?a.delete(AuthKey):a.set(AuthKey,d),v.state=S;else if(t?.payloads.some(e=>e.message!==void 0)){let e=t.deliveryMetadata?.map(e=>e.deliveryId)??[];a.set(TurnDeliveryIdsKey,g.turnId?[...new Set([...a.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!g.sessionStarted&&a.get(ChannelDeliveryKey)!==void 0&&a.set(TurnDeliveryIdsKey,[a.require(ChannelDeliveryKey).deliveryId]);if(r!==void 0&&(r.acceptedAtMsByCallId!==void 0&&a.set(RuntimeActionSettlementTimesKey,r.acceptedAtMsByCallId),C={...C,runtimeActionResults:r.results}),t!==void 0){let e={...o,state:{...v.state}};setChannelContext(a,e)}if(n!==void 0&&C===void 0&&isHarnessBetweenTurns(p)){await contextStorage.run(a,()=>h?.instrumentChannelDelivery({ctx:a,includeTurn:!1,outcome:`completed`})),await h?.flush();let t=reconcileSessionContinuationToken(a,p),n=serializeContext(a),r=t===p?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t),serializedContext:n,...r}}let w=s.subagentRegistry.dynamicResolvers??[],T=s.resolvedAgent.dynamicToolResolvers??[],E=buildRuntimeIdentity(l);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(s.compiledArtifactsSource),n=g.sessionStarted;if(a.setVirtualContext(StaticModelReferenceKey,c.turnAgent.model??null),!n)a.set(SessionDynamicSubagentRuntimeRevisionKey,t),a.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=createSessionStartedEvent({runtime:E});await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:a,resolvers:w,event:e,messages:m.initial.messages,runtimeRevision:t}),contextStorage.run(a,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:a,resolvers:T,event:e,messages:m.initial.messages,runtimeRevision:t}))]),isHarnessBetweenTurns(p)||await rebindMissingCompiledDynamicToolCallbacks({ctx:a,event:createTurnStartedEvent({sequence:g.sequence,turnId:activeTurnId(g)}),messages:m.initial.messages,resolvers:T})}}catch(e){throw await failChannelDeliveries(e),e}let D=s.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,O=a.get(CapabilitiesKey),runHarnessStep=async(t,n)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:c.thresholdPercent},session:t,turnAgent:c.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:b,capabilities:O,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent,prepareApprovalTurn:e=>i.dispatch(createTurnStartedEvent(e)),historyProjector:m.projector,historyView:m.prepare(r),instrumentation:h,modelResolutionScope:{moduleMap:s.moduleMap,nodeId:s.nodeId},node:l})(r,n)},k,A;try{throwIfTurnAborted(b),A=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:C,initialSession:p,modelCallsPerStep:D,runStep:async({firstCall:e,session:t,stepInput:n})=>{let r=await runStep(a,t,async t=>{a.setVirtualContext(HandleEventKey,handleEvent),a.setVirtualContext(StaticModelReferenceKey,c.turnAgent.model??null);let r=e&&C?.outputSchema!==void 0?{...t,outputSchema:C.outputSchema}:t,o=getHarnessEmissionState(r.state);if(await i.rehydrate(o,E,isHarnessBetweenTurns(r)?void 0:{sequence:o.sequence,turnId:activeTurnId(o)}),e&&u){let e=getHarnessEmissionState(r.state);if(u.some(({challenge:e})=>e.candidateId===void 0)&&isHarnessBetweenTurns(r)){let t=createTurnInputMessages(consumeDeferredStepInput({session:r,input:n}).input);prepareDynamicInstructionPreamble(a,m.messages(r)),prepareMemoryPreamble(a,{history:r.history,input:t,projector:m.projector,state:r.state});let i=[],o=await prepareWorkflowPreambleTrace({emissionState:e,instrumentation:h});try{e=await emitTurnPreamble(handleEvent,{},e,m.projector({messages:[...r.history,...t],state:r.state}),E,o)}finally{i=drainDynamicInstructionUserMessages(a);let e=drainMemoryCommit(a);r={...r,history:validateHarnessModelMessages([...r.history,...e?.recalledMessages??[],...i]),state:e?.state??r.state}}r=setHarnessEmissionState(r,e)}for(let{challenge:t}of u)await handleEvent(createAuthorizationCompletedEvent({...authorizationEventFields(t),outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}return runHarnessStep(r,n)});return r.settledTurn===void 0&&throwIfTurnAborted(b),k={result:r,serializedContext:serializeContext(a)},r}})}catch(t){if(!isTurnCancellation(t)&&!b.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:k,ctx:a,initialSession:p,stepInput:C})}let j=reconcileSessionContinuationToken(a,A.session);agentTraceState.pruneAgentTraceState(a,j.sessionId,j.state);let M=serializeContext(a);A={...A,session:j};let N=resolveSessionStepResult(A,M);return N.action===`done`&&await _.writer.close(),f?{...N,compacted:!0}:N}finally{_.writer.release()}}export{turnStep};
|
|
@@ -25,8 +25,8 @@ export declare class SessionExecution {
|
|
|
25
25
|
get cursor(): SessionStateCursor;
|
|
26
26
|
runTurn(delivery: TurnStepPayload | undefined, options?: {
|
|
27
27
|
/**
|
|
28
|
-
* The delegated caller the turn answers
|
|
29
|
-
*
|
|
28
|
+
* The delegated caller the turn answers, including for a first turn whose
|
|
29
|
+
* input carries no caller. The turn's first step binds it into the context.
|
|
30
30
|
*/
|
|
31
31
|
readonly caller?: TurnCaller;
|
|
32
32
|
}): Promise<TurnOutcome>;
|
|
@@ -38,7 +38,19 @@ export declare class SessionExecution {
|
|
|
38
38
|
*/
|
|
39
39
|
private handleBoundaryMessages;
|
|
40
40
|
private runTurnSteps;
|
|
41
|
+
/**
|
|
42
|
+
* Starts the workflow tool runs a parked step requested, and returns the
|
|
43
|
+
* results of any that settled at once. Task tool calls need no dispatch: the
|
|
44
|
+
* session answers them itself.
|
|
45
|
+
*/
|
|
46
|
+
private dispatchRuns;
|
|
41
47
|
handleWorkflowMessage(message: WorkflowToolRunMessage): Promise<RuntimeActionResult | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* Stops the work a cancelled turn leaves behind: the workflow tool runs it
|
|
50
|
+
* waits on and every working task. A turn that waits on no run, the common
|
|
51
|
+
* case, skips that durable step.
|
|
52
|
+
*/
|
|
53
|
+
cancelTurnWork(): Promise<void>;
|
|
42
54
|
/** `session.cancel()` stops the turn, the calls it waits on, and every working task. */
|
|
43
55
|
private finishCancelledTurn;
|
|
44
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{TASK_WAIT_TOOL_NAME}from"#protocol/task-tools.js";import{renderTaskWaitResult}from"#execution/tasks/render.js";import{taskWaitResult}from"#execution/tasks/table.js";import{sleep}from"#compiled/@workflow/core/index.js";import{findBlockingWorkflowToolRun,isInboxToolResultFromRecordedWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{resolveTurnPrincipal}from"#execution/session/principal.js";import{taskToolResult}from"#execution/tasks/calls.js";import{
|
|
1
|
+
import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{TASK_WAIT_TOOL_NAME}from"#protocol/task-tools.js";import{renderTaskWaitResult}from"#execution/tasks/render.js";import{taskWaitResult}from"#execution/tasks/table.js";import{sleep}from"#compiled/@workflow/core/index.js";import{findBlockingWorkflowToolRun,getBlockingWorkflowToolRuns,isInboxToolResultFromRecordedWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{resolveTurnPrincipal}from"#execution/session/principal.js";import{taskToolResult}from"#execution/tasks/calls.js";import{answerTaskCancel,cancelWorkingTasks,isTaskRunMessage,sessionTaskTable}from"#execution/tasks/session.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchCoordinationStep}from"#execution/coordination-dispatch-step.js";import{applyTaskRunMessageStep}from"#execution/tasks/steps.js";import{publishTurnWaitingStep}from"#execution/session/turn-waiting-step.js";import{batchAgentStarts,handleWorkflowToolRunMessage}from"#execution/session-workflow-tool-run.js";import{emitAgentStartedStep}from"#execution/tools/workflow/emit-workflow-tool-run-report-step.js";import{interruptWorkflowToolRun}from"#execution/tools/workflow/interrupt.js";import{turnStep}from"#execution/session/turn-step.js";import{ActiveTurn}from"#execution/session/active-turn.js";import{resolveRuntimeActionResultsForCallIds}from"#runtime/actions/results.js";function hasDelegatedCallerContext(e){if(e[`eve.sessionCallback`]!==void 0)return!0;let t=e[`eve.channel`];return typeof t==`object`&&!!t&&Reflect.get(t,`kind`)===`subagent`}var SessionExecution=class{input;constructor(e){this.input=e}get cursor(){return this.input.cursor}async runTurn(e,t={}){let n=new ActiveTurn(this.input,{caller:t.caller,principal:resolveTurnPrincipal(e,this.input.cursor.serializedContext)});try{let t=await this.runTurnSteps(n,e);return await this.handleBoundaryMessages(n.takeBoundaryMessages(),t.kind===`done`),t.kind===`park`&&t.settled!==void 0&&await cancelWorkingTasks(this.input.cursor,`turn_ended`),{...t,...n.caller!==void 0&&{caller:n.caller},...n.compacted&&{compacted:!0}}}finally{n.dispose()}}async handleBoundaryMessages(e,t=!1){for(let n of batchAgentStarts(e))n.kind===`message`?await this.handleWorkflowMessage(n.message):t||await this.input.cursor.advance(e=>emitAgentStartedStep({...e,messages:n.messages}))}async runTurnSteps(e,t){let n=t,r=e.caller;for(;;){let{cursor:t}=this.input,i=r;r=void 0;let a=await t.advanceWithHistory(t=>turnStep({...t,abortSignal:e.signal,caller:i,input:n,steeringSignal:e.steeringSignal}));a.compacted===!0&&(e.compacted=!0);let o=a.action===`park`?a.pendingCoordinationCallIds:void 0,s=a.action===`park`&&a.settled!==void 0;if(await e.admitBoundary(),await this.handleBoundaryMessages(e.takeBoundaryMessages(),a.action===`done`),a.action===`cancelled`||!s&&e.signal.aborted&&o===void 0)return await this.finishCancelledTurn(e);if(a.action===`done`)return{isError:a.isError,kind:`done`,output:a.output??``,usage:a.usage,usageDelta:a.usageDelta};if(a.action===`held`&&a.hold===`request`){if(a.hasPendingInputBatch&&this.input.capabilities?.requestInput!==!0&&!hasDelegatedCallerContext(this.input.cursor.serializedContext))throw Error("This session cannot request human input, so it cannot wait for a tool approval or question. Sessions started without `capabilities.requestInput`, such as schedules, must not use approval-gated tools.");let t=await this.waitForHeldRequest(e,a);if(t===`cancelled`)return await this.finishCancelledTurn(e);n={delivery:t};continue}if(a.action===`held`){if(await this.waitForHeldTurn(e)===`cancelled`)return await this.finishCancelledTurn(e);let t=await e.takeSteering();n=t===void 0?void 0:{delivery:t};continue}if(o!==void 0&&a.action===`park`){let t=a.hasRunsToDispatch===!1?[]:await this.dispatchRuns(),r=t.length===0?void 0:Date.now(),i=await this.waitForRuntimeActionResults({initialAcceptedAtMs:r,initialResults:t,taskToolCalls:a.pendingTaskToolCalls??[],pendingCallIds:o,turn:e});if(i===`cancelled`)return await this.finishCancelledTurn(e);n={delivery:await e.takeSteering(),runtimeResults:i};continue}if(a.action===`park`)return{kind:`park`,settled:a.settled};let c=await e.takeSteering();n=c===void 0?void 0:{delivery:c}}}async dispatchRuns(){return(await this.input.cursor.advance(e=>dispatchCoordinationStep({action:`park`,workflowToolRunOwner:{inbox:sessionInboxHookToken(sessionCommandHookToken(this.input.sessionId))},...e}))).results}async handleWorkflowMessage(e){if(isTaskRunMessage(e)){await this.input.cursor.advance(t=>applyTaskRunMessageStep({...t,message:e}));return}return await handleWorkflowToolRunMessage({cursor:this.input.cursor,message:e})}async cancelTurnWork(){let{cursor:e}=this.input;mayWaitOnWorkflowToolRuns(e.sessionState)&&await cancelDescendantTurnsStep({sessionState:e.sessionState}),await cancelWorkingTasks(e,`turn_cancelled`)}async finishCancelledTurn(e){return await this.handleBoundaryMessages(e.takeBoundaryMessages(`agent-started`)),await this.cancelTurnWork(),{cancelled:!0,kind:`park`}}async waitForHeldTurn(e){let t=!1;for(;;){let n={interrupted:t,timedOut:!1};if(taskWaitResult(sessionTaskTable(this.input.cursor),n)!==void 0)return`woke`;let r=await e.nextRuntimeEvent([]);if(r===`cancelled`)return r;switch(r.kind){case`steering`:t=!0;continue;case`workflow`:await this.handleWorkflowMessage(r.message);continue;case`input`:case`runtime-action-result`:case`timeout`:continue}}}async waitForHeldRequest(e,t){let n=new Set(t.authorizationAttemptIds),r=new Set(t.inputRequestIds);for(;;){let t=this.input.queue.takeAuthorizations(n);if(t!==void 0)return{kind:`deliver`,payloads:t};let i=await e.takeInputResponses(r);if(i!==void 0)return i;let a=await e.takeSteering({heldOnPerson:!0});if(a!==void 0)return a;let o=await e.nextRuntimeEvent([]);if(o===`cancelled`)return o;o.kind===`workflow`&&await this.handleWorkflowMessage(o.message)}}async waitForRuntimeActionResults(e){let t=[...e.initialResults],n=!1,r=new Map,i=new Map;if(e.initialAcceptedAtMs!==void 0)for(let n of t)r.set(n.callId,e.initialAcceptedAtMs);let accept=e=>{t.push(e),r.set(e.callId,Date.now())},a=await this.answerTaskToolCalls(e.taskToolCalls,accept);for(;;){a=this.resolveTaskWaits(a,n,accept);let o=resolveRuntimeActionResultsForCallIds({pendingCallIds:e.pendingCallIds,results:t});if(o!==void 0){let e=o.flatMap(e=>{let t=i.get(e.callId);return t===void 0?[]:[t]});return{acceptedAtMsByCallId:Object.fromEntries(o.map(e=>[e.callId,r.get(e.callId)])),...e.length>0&&{delegatedUsage:e},results:o}}let s=a.flatMap(e=>e.timer===void 0?[]:[e.timer]),c=await e.turn.nextRuntimeEvent(s);if(c===`cancelled`)return c;if(c.kind===`timeout`){for(let e of a)e.callId===c.callId&&(e.timedOut=!0);continue}if(c.kind===`input`)continue;if(c.kind===`steering`){n||await this.interruptWaitedWorkflowCalls(e.pendingCallIds,t),n=!0;continue}if(c.kind===`runtime-action-result`){let e=this.input.cursor.sessionState.snapshot.session.state,n=c.results.filter(t=>t.kind===`tool-result`&&isInboxToolResultFromRecordedWorkflowToolRun(e,t));if(n.length>0){let e=Date.now();t.push(...n);for(let t of n)r.set(t.callId,e)}continue}let l=await this.handleWorkflowMessage(c.message);l!==void 0&&(accept(l),c.message.kind===`outcome`&&c.message.usage!==void 0&&i.set(l.callId,c.message.usage))}}resolveTaskWaits(e,t,n){let r=sessionTaskTable(this.input.cursor),i=[];for(let a of e){let e=taskWaitResult(r,{interrupted:t,timedOut:a.timedOut});if(e===void 0){i.push(a);continue}let o=renderTaskWaitResult(e,Date.now()-a.startedAtMs);n(taskToolResult(a.callId,TASK_WAIT_TOOL_NAME,o))}return i}async answerTaskToolCalls(e,t){let n=[];for(let r of e)r.kind===`task_wait`?n.push(startTaskWait(r)):t(await answerTaskCancel(this.input.cursor,r));let r=this.resolveTaskWaits(n,!1,t);return r.length>0&&await this.input.cursor.advance(publishTurnWaitingStep),r}async interruptWaitedWorkflowCalls(e,t){let n=this.input.cursor.sessionState.snapshot.session.state,r=new Set(t.map(e=>e.callId)),i=e.filter(e=>!r.has(e)).flatMap(e=>{let t=findBlockingWorkflowToolRun(n,e);return t===void 0?[]:[t.address]});await Promise.all(i.map(e=>interruptWorkflowToolRun(e)))}};function startTaskWait(e){let{callId:t,timeoutMs:n}=e,r=n===void 0?void 0:sleep(n).then(()=>t);return{callId:t,startedAtMs:Date.now(),timedOut:!1,timer:r}}function mayWaitOnWorkflowToolRuns(e){try{return getBlockingWorkflowToolRuns(e.snapshot?.session?.state).length>0}catch{return!0}}export{SessionExecution,hasDelegatedCallerContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{evaluate}from"#ai/evaluate.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message: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 evaluate({abortSignal: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.70.
|
|
1
|
+
import{evaluate}from"#ai/evaluate.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message: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 evaluate({abortSignal: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.70.2//runAgentRouterTask`;export{runAgentRouterTask};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { CancelTurnInput, CancelTurnResult,
|
|
1
|
+
import type { CancelTurnInput, CancelTurnResult, DispatchSessionInput, Runtime, SessionCommand, SessionCommandResult } from "#channel/types.js";
|
|
2
2
|
import { type Run, type StartOptionsWithoutDeploymentId, type WorkflowFunction, type WorkflowMetadata } from "#internal/workflow/runtime.js";
|
|
3
3
|
import type { RuntimeCompiledArtifactsSource } from "#runtime/compiled-artifacts-source.js";
|
|
4
|
+
import { type SessionHandoffStart } from "#execution/session/entry-input.js";
|
|
4
5
|
import type { SessionCheckpoint } from "#execution/session/handoff.js";
|
|
5
6
|
import type { DynamicSubagentAgentConfig } from "#runtime/subagents/dynamic-agent-config.js";
|
|
6
7
|
interface WorkflowHookRecord {
|
|
@@ -32,14 +33,13 @@ export declare function createWorkflowRuntime(config: {
|
|
|
32
33
|
readonly dynamicSubagentAgentConfig?: DynamicSubagentAgentConfig;
|
|
33
34
|
readonly nodeId?: string;
|
|
34
35
|
}): Runtime;
|
|
35
|
-
export
|
|
36
|
+
export type SessionOwnerStartInput = SessionHandoffStart & {
|
|
36
37
|
readonly activationToken: string;
|
|
37
38
|
/** Original run whose stream stays the public session stream. */
|
|
38
39
|
readonly anchorRunId: string;
|
|
39
40
|
readonly checkpoint: SessionCheckpoint;
|
|
40
|
-
readonly delivery: DeliverHookPayload;
|
|
41
41
|
readonly targetDeploymentId: string;
|
|
42
|
-
}
|
|
42
|
+
};
|
|
43
43
|
/** Starts a successor owner and binds its output to the original session stream. */
|
|
44
44
|
export declare function startSessionOwnerStep(input: SessionOwnerStartInput): Promise<void>;
|
|
45
45
|
/** Sends one command to a session through its stable command inbox. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{readSessionEventStream,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/agent-trace-context.js";import{SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),COMMAND_HOOK_READY_TIMEOUT_MS=3e4,STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async createSession(t){let n=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),r=buildRunContext({bundle:n,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t}),i=resolveEffectiveAgentRuntime(n,r);initializeSessionInstrumentation({agentName:i.turnAgent.id,ctx:r});let a=i.limits?.sessionTimeoutMs,o=n.resolvedAgent.config?.experimental?.workflow?.retention,s=serializeContext(r),c=readParentLineage(s),l={kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:s};t.limits!==void 0&&(l.limits=t.limits),t.continuationConflictCommand!==void 0&&(l.continuationConflictCommand=t.continuationConflictCommand),a!==void 0&&(l.sessionTimeoutMs=a),o!==void 0&&(l.retention=o);let u={...c.sessionId===void 0?buildSessionAttributes({serializedContext:s}):buildSubagentRootAttributes({identity:{nodeId:n.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:c.callId,parentSessionId:c.sessionId,parentTurnId:c.turnId,rootSessionId:c.rootSessionId??c.sessionId,serializedContext:s}),...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},d;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(u)};o!==void 0&&(e.experimental_retention=o),d=await startWorkflowOnDeployment(workflowEntryReference,[l],l.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let f,getEvents=()=>(f??=readSessionEventStream(d.runId),f);return{get events(){return getEvents()},sessionId:d.runId}},async dispatchContinuation(e){return await dispatchWorkflowCommand(e.continuationToken,e.command)},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){return readSessionEventStream(e,t?.startIndex)},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},async resolveContinuation(e){try{return await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}}}}async function startSessionOwnerStep(e){"use step";let
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{readSessionEventStream,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/agent-trace-context.js";import{SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),COMMAND_HOOK_READY_TIMEOUT_MS=3e4,STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async createSession(t){let n=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),r=buildRunContext({bundle:n,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t}),i=resolveEffectiveAgentRuntime(n,r);initializeSessionInstrumentation({agentName:i.turnAgent.id,ctx:r});let a=i.limits?.sessionTimeoutMs,o=n.resolvedAgent.config?.experimental?.workflow?.retention,s=serializeContext(r),c=readParentLineage(s),l={kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:s};t.limits!==void 0&&(l.limits=t.limits),t.continuationConflictCommand!==void 0&&(l.continuationConflictCommand=t.continuationConflictCommand),a!==void 0&&(l.sessionTimeoutMs=a),o!==void 0&&(l.retention=o);let u={...c.sessionId===void 0?buildSessionAttributes({serializedContext:s}):buildSubagentRootAttributes({identity:{nodeId:n.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:c.callId,parentSessionId:c.sessionId,parentTurnId:c.turnId,rootSessionId:c.rootSessionId??c.sessionId,serializedContext:s}),...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},d;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(u)};o!==void 0&&(e.experimental_retention=o),d=await startWorkflowOnDeployment(workflowEntryReference,[l],l.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let f,getEvents=()=>(f??=readSessionEventStream(d.runId),f);return{get events(){return getEvents()},sessionId:d.runId}},async dispatchContinuation(e){return await dispatchWorkflowCommand(e.continuationToken,e.command)},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){return readSessionEventStream(e,t?.startIndex)},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},async resolveContinuation(e){try{return await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}}}}async function startSessionOwnerStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,targetDeploymentId:i,...a}=e,o={...a,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:i,sessionWritable:getRun(n).getWritable(),sessionId:n};await startWorkflowOnDeployment(workflowEntryReference,[o],i,r.retention===void 0?void 0:{experimental_retention:r.retention})}async function dispatchWorkflowCommand(e,t){let n;try{let r=await resumeSessionInbox(e,t);n={runId:r.ownerRunId,sessionId:await r.sessionId}}catch(n){if(isInactiveCommandTarget(n)){if(t.kind===`send`&&typeof e!=`string`)try{let t=await getRun(e.sessionId).status;if(t===`pending`||t===`running`)return{status:`session_not_active`,retryable:!0}}catch(e){if(!isInactiveCommandTarget(e))throw e}return inactiveCommandResult(t)}throw logError(log,`failed to dispatch session command`,n,{command:t.kind,token:e}),n}if(t.kind===`reset`){let t=typeof e==`string`?e:sessionCommandHookToken(e.sessionId),r=new Set([sessionCommandHookToken(n.sessionId),t]);await Promise.all([...r].map(e=>waitForHookRelease(sessionInboxHookToken(e),n.runId)))}return activeCommandResult(t,n.sessionId)}function activeCommandResult(e,t){return e.kind===`reset`?{previousSessionId:t,status:`reset`}:e.kind===`send`&&e.delivery!==void 0?{sessionId:t,status:`accepted`,deliveryId:e.delivery.deliveryId}:{sessionId:t,status:`accepted`}}function inactiveCommandResult(e){return e.kind===`send`?{status:`session_not_active`}:e.kind===`cancel`?{status:`no_active_turn`}:{status:`no_active_session`}}async function dispatchWorkflowSessionCommand(e){return await dispatchWorkflowCommand({sessionId:e.sessionId},e.command)}async function requestWorkflowTurnCancellation(e){let t={kind:`cancel`};return e.turnId!==void 0&&(t.turnId=e.turnId),await dispatchWorkflowCommand({sessionId:e.sessionId},t)}function isInactiveCommandTarget(e){if(e instanceof AcceptedSessionIdentityError)return!1;if(HookNotFoundError.is(e))return!0;for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function waitForCommandHookOwner(e){let t=Date.now()+COMMAND_HOOK_READY_TIMEOUT_MS;for(;;)try{return normalizeWorkflowHook(await getHookByToken(e))}catch(e){if(!HookNotFoundError.is(e)||Date.now()>=t)throw e;await new Promise(e=>setTimeout(e,20))}}async function waitForHookRelease(e,t){let n=Date.now()+COMMAND_HOOK_READY_TIMEOUT_MS;for(;;){try{if(normalizeWorkflowHook(await getHookByToken(e)).runId!==t)return}catch(e){if(HookNotFoundError.is(e))return;throw e}if(Date.now()>=n)throw Error(`Timed out waiting for session "${t}" to release inbox "${e}".`);await new Promise(e=>setTimeout(e,20))}}async function startWorkflowOnCurrentDeployment(e,t,n){return await startWorkflowOnDeployment(e,t,await resolveCurrentWorkflowDeploymentId(),n)}async function startWorkflowOnDeployment(e,t,n,r){return await withWorkflowStartContext(async()=>{if(n.length===0||n===`latest`)throw Error(`Workflow starts require an exact deployment id.`);return await start(e,t,{...r,deploymentId:n})})}async function resolveCurrentWorkflowDeploymentId(){let e=process.env.VERCEL_DEPLOYMENT_ID?.trim()||await(await getWorld()).getDeploymentId();if(e.length===0||e===`latest`)throw Error(`Workflow runtime could not resolve an exact deployment id.`);return e}async function withWorkflowStartContext(e){let t=context.active(),n=isAgentTraceContext(t)?trace.deleteSpan(t):t;return await context.with(n,e)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{createWorkflowRuntime,dispatchWorkflowSessionCommand,requestWorkflowTurnCancellation,sessionTimeoutWorkflowReference,startSessionOwnerStep,startWorkflowOnCurrentDeployment,waitForCommandHookOwner,workflowEntryReference,workflowToolRunWorkflowReference};
|
|
@@ -2,11 +2,12 @@ import type { ModelMessage, UserContent } from "ai";
|
|
|
2
2
|
import type { ChannelAdapterContext } from "#channel/adapter.js";
|
|
3
3
|
import type { SandboxSession } from "#public/definitions/sandbox.js";
|
|
4
4
|
/**
|
|
5
|
-
* Sandbox directory where
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Sandbox directory where eve stages message attachments and tool-result
|
|
6
|
+
* files. It sits under eve's own dot-directory so it never collides with an
|
|
7
|
+
* agent's `/workspace/attachments`. Authored canonical path —
|
|
8
|
+
* {@link SandboxSession.writeFile} translates to the backend-native location.
|
|
8
9
|
*/
|
|
9
|
-
export declare const ATTACHMENTS_ROOT = "/workspace/attachments";
|
|
10
|
+
export declare const ATTACHMENTS_ROOT = "/workspace/.eve/attachments";
|
|
10
11
|
/**
|
|
11
12
|
* Writes inbound `FilePart` bytes into the sandbox and rewrites each
|
|
12
13
|
* staged part to a compact `eve-sandbox:` ref.
|
|
@@ -20,11 +21,30 @@ export declare function stageAttachmentsForAdapter(content: string | UserContent
|
|
|
20
21
|
* the input unchanged when there is no active sandbox or no file parts.
|
|
21
22
|
*/
|
|
22
23
|
export declare function stageAttachmentsToSandbox(message: string | UserContent): Promise<string | UserContent>;
|
|
24
|
+
/**
|
|
25
|
+
* Moves inline file payloads in `content` tool outputs into the sandbox and
|
|
26
|
+
* leaves `eve-sandbox:` refs in their place, so durable history never
|
|
27
|
+
* carries tool-result bytes. {@link hydrateSandboxAttachments} restores the
|
|
28
|
+
* bytes on every model call. Without an active sandbox, messages pass
|
|
29
|
+
* through unchanged.
|
|
30
|
+
*/
|
|
31
|
+
export declare function stageToolResultMedia<T extends ModelMessage>(messages: readonly T[]): Promise<T[]>;
|
|
23
32
|
/**
|
|
24
33
|
* Hydrates `eve-sandbox:` file refs for a single model call.
|
|
25
34
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
35
|
+
* Tool-result refs always hydrate as bytes: the tool chose to show them to
|
|
36
|
+
* the model. Inbound attachments inline small images and PDFs; larger or
|
|
37
|
+
* unsupported files become text references to their sandbox path. Every
|
|
38
|
+
* decision is pure in the ref, so each message renders identically on every
|
|
39
|
+
* call and the provider's prompt cache stays valid. The returned messages
|
|
40
|
+
* must not be written back to session history, which stays ref-only.
|
|
29
41
|
*/
|
|
30
42
|
export declare function hydrateSandboxAttachments(messages: readonly ModelMessage[]): Promise<ModelMessage[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Chat Completions-style providers (`*.chat`) serialize `content` tool
|
|
45
|
+
* outputs as JSON text, so a file would reach the model as base64
|
|
46
|
+
* characters. Moves the files of each run of tool messages into one user
|
|
47
|
+
* message right after it, leaving a text stub in the tool result. The move
|
|
48
|
+
* is deterministic, so the prompt prefix stays cache-stable.
|
|
49
|
+
*/
|
|
50
|
+
export declare function moveToolResultFilesToUserMessages(messages: readonly ModelMessage[]): ModelMessage[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash}from"node:crypto";import{buildSessionHandle}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{loadContext}from"#context/container.js";import{SandboxKey}from"#context/keys.js";import{deserializeUrlFilePart,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{basename}from"node:path";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{fileDataToBytes}from"#internal/attachments/data.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{decodeSandboxRef,encodeSandboxRef,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";const ATTACHMENTS_ROOT=`/workspace/attachments`,log=createLogger(`harness.attachment-staging`),UNSAFE_FILENAME_CHARS=/[^\w.-]+/g;async function stageAttachmentsForAdapter(e,t,n){if(typeof e==`string`)return e;let r=reconstitueFilePartUrls(e);return Promise.all(r.map(async e=>e.type===`file`?stageFilePart(e,t,n):e))}async function stageAttachmentsToSandbox(e){if(typeof e==`string`||!Array.isArray(e)||!hasFileParts(e))return e;let t=loadContext(),n=t.get(SandboxKey);if(n===void 0)return e;let r=await n.get();if(r===null)return e;let i=t.get(ChannelKey);return stageAttachmentsForAdapter(e,r,i?buildAdapterContext(i,t):{ctx:t,state:{},session:buildSessionHandle(t)})}async function hydrateSandboxAttachments(e){if(!messagesContainSandboxRef(e))return e;let t=loadContext().get(SandboxKey);if(t===void 0)throw Error(`Cannot hydrate sandbox-ref FilePart: no SandboxKey is bound on the active eve context. Hydration must run inside a step scope with the framework sandbox provider installed.`);let n=await t.get();if(n===null)throw Error(`Cannot hydrate sandbox-ref FilePart: SandboxKey is bound but no active sandbox session is available.`);return Promise.all(e.map(async e=>{if(!messageContainsSandboxRef(e))return e;let t=await hydrateMessageContent(e.content,n);return{...e,content:t}}))}function hasFileParts(e){for(let t of e)if(t.type===`file`)return!0;return!1}function messagesContainSandboxRef(e){for(let t of e)if(messageContainsSandboxRef(t))return!0;return!1}function messageContainsSandboxRef(e){let t=e.content;if(!Array.isArray(t))return!1;for(let e of t)if(isSandboxRefFilePart(e))return!0;return!1}function isSandboxRefFilePart(e){return typeof e==`object`&&!!e&&e.type===`file`&&isSandboxRefUrl(e.data)}async function hydrateMessageContent(e,t){return Array.isArray(e)?Promise.all(e.map(async e=>{if(
|
|
1
|
+
import{createHash}from"node:crypto";import{buildSessionHandle}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{contextStorage,loadContext}from"#context/container.js";import{SandboxKey}from"#context/keys.js";import{deserializeUrlFilePart,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{basename,extname}from"node:path";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createFrameworkUserMessage}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{readMediaMetadata}from"#internal/attachments/media-metadata.js";import{fileDataToBytes}from"#internal/attachments/data.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{decodeSandboxRef,encodeSandboxRef,inlinesSandboxRefAsBytes,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";const ATTACHMENTS_ROOT=`/workspace/.eve/attachments`,log=createLogger(`harness.attachment-staging`),UNSAFE_FILENAME_CHARS=/[^\w.-]+/g,MEDIA_TYPE_EXTENSIONS={"application/pdf":`.pdf`,"image/gif":`.gif`,"image/jpeg":`.jpg`,"image/png":`.png`,"image/webp":`.webp`};async function stageAttachmentsForAdapter(e,t,n){if(typeof e==`string`)return e;let r=reconstitueFilePartUrls(e);return Promise.all(r.map(async e=>e.type===`file`?stageFilePart(e,t,n):e))}async function stageAttachmentsToSandbox(e){if(typeof e==`string`||!Array.isArray(e)||!hasFileParts(e))return e;let t=loadContext(),n=t.get(SandboxKey);if(n===void 0)return e;let r=await n.get();if(r===null)return e;let i=t.get(ChannelKey);return stageAttachmentsForAdapter(e,r,i?buildAdapterContext(i,t):{ctx:t,state:{},session:buildSessionHandle(t)})}async function stageToolResultMedia(e){if(!e.some(hasInlineToolResultFile))return[...e];let t=await contextStorage.getStore()?.get(SandboxKey)?.get();return t==null?[...e]:Promise.all(e.map(async e=>{if(e.role!==`tool`||!hasInlineToolResultFile(e))return e;let n=await Promise.all(e.content.map(async e=>e.type===`tool-result`?{...e,output:await stageToolOutputFiles(e.output,t)}:e));return{...e,content:n}}))}async function hydrateSandboxAttachments(e){if(!messagesContainSandboxRef(e))return e;let t=loadContext().get(SandboxKey);if(t===void 0)throw Error(`Cannot hydrate sandbox-ref FilePart: no SandboxKey is bound on the active eve context. Hydration must run inside a step scope with the framework sandbox provider installed.`);let n=await t.get();if(n===null)throw Error(`Cannot hydrate sandbox-ref FilePart: SandboxKey is bound but no active sandbox session is available.`);return Promise.all(e.map(async e=>{if(!messageContainsSandboxRef(e))return e;let t=await hydrateMessageContent(e.content,n);return{...e,content:t}}))}function hasFileParts(e){for(let t of e)if(t.type===`file`)return!0;return!1}function messagesContainSandboxRef(e){for(let t of e)if(messageContainsSandboxRef(t))return!0;return!1}function messageContainsSandboxRef(e){let t=e.content;if(!Array.isArray(t))return!1;for(let e of t)if(isSandboxRefFilePart(e)||e.type===`tool-result`&&contentOutputParts(e.output).some(isToolOutputRefFile))return!0;return!1}function contentOutputParts(e){return e.type===`content`?e.value:[]}function hasInlineToolResultFile(e){return e.role===`tool`&&e.content.some(e=>e.type===`tool-result`&&contentOutputParts(e.output).some(isInlineToolOutputFile))}function isInlineToolOutputFile(e){return e.type===`file`&&e.data.type===`data`}function isToolOutputRefFile(e){return e.type===`file`&&e.data.type===`url`&&isSandboxRefUrl(e.data.url)}async function stageToolOutputFiles(e,t){if(e.type!==`content`||!e.value.some(isInlineToolOutputFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isInlineToolOutputFile(e)||e.data.type!==`data`)return e;let n=await fileDataToBytes(e.data.data);if(n===null)return e;let r=await writeSandboxRef(n,e.mediaType,e.filename,t);return{...e,data:{type:`url`,url:encodeSandboxRef(r)}}}));return{...e,value:n}}function isSandboxRefFilePart(e){return typeof e==`object`&&!!e&&e.type===`file`&&isSandboxRefUrl(e.data)}async function hydrateMessageContent(e,t){return Array.isArray(e)?Promise.all(e.map(async e=>{if(isSandboxRefFilePart(e)){let n=decodeSandboxRef(e.data);if(!inlinesSandboxRefAsBytes(n))return renderSandboxRefAsTextPart(n);let r=await readSandboxRefBytes(n,t);return r===null?renderMissingSandboxRef(n):{...e,data:r,mediaType:n.mediaType}}if(e.type===`tool-result`){let n=e;return{...n,output:await hydrateToolOutput(n.output,t)}}return e})):e}async function hydrateToolOutput(e,t){if(e.type!==`content`||!e.value.some(isToolOutputRefFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isToolOutputRefFile(e)||e.data.type!==`url`)return e;let n=decodeSandboxRef(e.data.url),r=await readSandboxRefBytes(n,t);return r===null?renderMissingSandboxRef(n):{...e,data:{data:Buffer.from(r).toString(`base64`),type:`data`}}}));return{...e,value:n}}async function readSandboxRefBytes(e,t){let n=await t.readBinaryFile({path:e.path});return n===null&&log.warn(`sandbox-ref attachment bytes missing on hydration — degrading to text reference`,{mediaType:e.mediaType,path:e.path,size:e.size}),n}function renderMissingSandboxRef(e){return{text:`FileNotFound: Current snapshot may be newer and does not contain ${e.path}.`,type:`text`}}function moveToolResultFilesToUserMessages(e){let t=[],n=[];for(let r of e){if(r.role!==`tool`&&n.length>0&&(t.push(createReturnedFilesMessage(n)),n=[]),r.role!==`tool`){t.push(r);continue}let e=r.content.map(e=>{if(e.type!==`tool-result`||e.output.type!==`content`)return e;let t=e.output.value.map(e=>{if(e.type!==`file`)return e;let t={data:e.data,mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),n.push(t),{text:`Attached file ${e.filename??`file`} (${e.mediaType}) follows this tool result.`,type:`text`}});return{...e,output:{...e.output,value:t}}});t.push({...r,content:e})}return n.length>0&&t.push(createReturnedFilesMessage(n)),t}function createReturnedFilesMessage(e){return createFrameworkUserMessage(`context.state`,[{text:`Files returned by the preceding tool results:`,type:`text`},...e])}function renderSandboxRefAsTextPart(e){return{text:`Attached file ${e.path} (${e.mediaType})`,type:`text`}}async function stageFilePart(e,t,n){if(isSandboxRefUrl(e.data))return e;if(e.data instanceof URL&&e.data.protocol!==`data:`){let r;try{r=await tryFetchFile(e.data.href,n)}catch(t){if(!(t instanceof EveAttachmentError))throw t;let n=e.filename?.trim()||`file`;return log.warn(`attachment resolver failed — degrading to text part`,{adapterKind:t.adapterKind,error:t.cause,filename:n,kind:t.kind}),{text:`Attachment ${n} could not be retrieved: ${t.message}`,type:`text`}}return r===null?e:stageResolvedBytes(e,r,t)}let r=await fileDataToBytes(e.data);return r===null?e:stageResolvedBytes(e,{bytes:r},t)}async function stageResolvedBytes(e,t,n){let r=t.mediaType??e.mediaType??`application/octet-stream`,i=await writeSandboxRef(t.bytes,r,t.filename??e.filename,n);return{...e,data:encodeSandboxRef(i),filename:i.path,mediaType:r}}async function writeSandboxRef(e,t,n,r){let i=sha256Prefix(e),a=`${ATTACHMENTS_ROOT}/${i}/${safeFilename(n,i,t)}`;return await r.writeBinaryFile({content:e,path:a}),{...readMediaMetadata(e,t),path:r.resolvePath(a)}}async function tryFetchFile(e,t){let n=t.ctx.get(ChannelKey);if(n?.fetchFile===void 0)return null;let r=getAdapterKind(n);try{let r=await n.fetchFile(e,t);return r===null?null:Buffer.isBuffer(r)?{bytes:r}:r}catch(e){throw e instanceof EveAttachmentError?e:new EveAttachmentError({adapterKind:r,cause:e,kind:`resolver-threw`,message:`Attachment retrieval failed in the "${r}" channel.`})}}function reconstitueFilePartUrls(e){let t=!1,n=e.map(e=>e.type===`file`&&isSerializedUrlFilePart(e.data)?(t=!0,{...e,data:deserializeUrlFilePart(e.data)}):e);return t?n:e}function sha256Prefix(e){return createHash(`sha256`).update(e).digest(`hex`).slice(0,16)}function safeFilename(e,t,n){let r=e===void 0?``:basename(e).replace(UNSAFE_FILENAME_CHARS,`_`),i=r.length>0?r:`file-${t}`,a=MEDIA_TYPE_EXTENSIONS[n];return a===void 0||extname(i)!==``?i:`${i}${a}`}export{ATTACHMENTS_ROOT,hydrateSandboxAttachments,moveToolResultFilesToUserMessages,stageAttachmentsForAdapter,stageAttachmentsToSandbox,stageToolResultMedia};
|