eve 0.27.13 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/src/channel/adapter.d.ts +5 -5
- package/dist/src/channel/session.d.ts +2 -2
- package/dist/src/channel/types.d.ts +10 -6
- package/dist/src/chunks/{use-eve-agent-CsSQOKnp.js → use-eve-agent-CZkX_ZTT.js} +90 -1
- package/dist/src/chunks/{use-eve-agent-CWYe-vqE.js → use-eve-agent-hdPX68_i.js} +90 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +8 -2
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +15 -0
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +7 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +3 -3
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-action-parts.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +5 -3
- package/dist/src/client/message-response.d.ts +4 -4
- package/dist/src/client/ndjson.d.ts +3 -3
- package/dist/src/client/open-stream.d.ts +2 -2
- package/dist/src/client/output-schema.d.ts +2 -2
- package/dist/src/client/reducer.d.ts +2 -2
- package/dist/src/client/session-utils.d.ts +5 -5
- package/dist/src/client/session.d.ts +2 -2
- package/dist/src/client/types.d.ts +2 -2
- package/dist/src/compiler/compile-from-memory.d.ts +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +8 -8
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +2 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-model-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -2
- package/dist/src/context/hook-lifecycle.d.ts +2 -2
- package/dist/src/evals/assertions/run.d.ts +3 -3
- package/dist/src/evals/match.d.ts +4 -4
- package/dist/src/evals/runner/derive-run-facts.d.ts +2 -2
- package/dist/src/evals/session.d.ts +3 -3
- package/dist/src/evals/types.d.ts +12 -12
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/route-child-delivery.d.ts +4 -3
- package/dist/src/execution/route-child-delivery.js +1 -1
- package/dist/src/execution/session-delivery-hook.d.ts +1 -0
- package/dist/src/execution/session-delivery-hook.js +1 -1
- package/dist/src/execution/session-timeout-control.d.ts +9 -0
- package/dist/src/execution/session-timeout-control.js +1 -0
- package/dist/src/execution/session-timeout-steps.d.ts +13 -0
- package/dist/src/execution/session-timeout-steps.js +1 -0
- package/dist/src/execution/session-timeout-workflow.d.ts +6 -0
- package/dist/src/execution/session-timeout-workflow.js +1 -0
- package/dist/src/execution/session-timeout.d.ts +2 -0
- package/dist/src/execution/session-timeout.js +1 -0
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.d.ts +5 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/terminal-session-completion-step.d.ts +5 -0
- package/dist/src/execution/terminal-session-completion-step.js +1 -0
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.d.ts +1 -0
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +4 -0
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +5 -2
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/agent-otel-provider.js +1 -1
- package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
- package/dist/src/harness/input-extraction.js +1 -1
- package/dist/src/harness/input-request-class.d.ts +23 -0
- package/dist/src/harness/input-request-class.js +1 -0
- package/dist/src/harness/input-requests.d.ts +20 -9
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/instrumentation-lifecycle.d.ts +12 -1
- package/dist/src/harness/proxy-input-requests.d.ts +10 -4
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/session-limit-continuation.d.ts +0 -11
- package/dist/src/harness/session-limit-continuation.js +1 -1
- package/dist/src/harness/session-limit-enforcement.d.ts +3 -2
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/session-token-limits.d.ts +41 -0
- package/dist/src/harness/session-token-limits.js +1 -0
- package/dist/src/harness/stale-input-responses.js +1 -1
- package/dist/src/harness/subagent-token-budget.d.ts +6 -4
- package/dist/src/harness/subagent-token-budget.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +26 -17
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/harness/types.d.ts +4 -4
- package/dist/src/harness/workflow-lifecycle.d.ts +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/protocol/event-dedupe.d.ts +25 -0
- package/dist/src/protocol/event-dedupe.js +1 -0
- package/dist/src/protocol/event-id.d.ts +16 -0
- package/dist/src/protocol/event-id.js +1 -0
- package/dist/src/protocol/message.d.ts +39 -23
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
- package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
- package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
- package/dist/src/public/channels/slack/hitl.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +3 -3
- package/dist/src/public/channels/teams/hitl.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
- package/dist/src/public/definitions/channel.d.ts +4 -4
- package/dist/src/public/definitions/hook.d.ts +2 -2
- package/dist/src/react/use-eve-agent.d.ts +3 -2
- package/dist/src/runtime/framework-tools/ask-question.js +1 -1
- package/dist/src/runtime/hooks/registry.d.ts +2 -2
- package/dist/src/runtime/input/types.d.ts +19 -4
- package/dist/src/runtime/input/types.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +2 -2
- package/dist/src/shared/agent-definition.d.ts +12 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +2 -2
- package/dist/src/shared/ulid.d.ts +39 -0
- package/dist/src/shared/ulid.js +1 -0
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +4 -4
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +4 -4
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +28 -16
- package/docs/concepts/execution-model-and-durability.mdx +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +61 -0
- package/docs/guides/client/streaming.mdx +9 -3
- package/docs/guides/frontend/overview.mdx +4 -2
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-vue.mdx +10 -10
- package/docs/guides/hooks.md +40 -2
- package/docs/guides/instrumentation.md +4 -0
- package/docs/tools/human-in-the-loop.md +5 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
2
2
|
import type { EveEvalDerivedFacts } from "#evals/types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Options for {@link deriveRunFacts}.
|
|
@@ -15,7 +15,7 @@ export interface DeriveRunFactsOptions {
|
|
|
15
15
|
* `subagent.started` with `subagent.completed` the same way. These facts
|
|
16
16
|
* power checks, scorers, and reporters.
|
|
17
17
|
*/
|
|
18
|
-
export declare function deriveRunFacts(events: readonly
|
|
18
|
+
export declare function deriveRunFacts(events: readonly MessageStreamEvent[], options?: DeriveRunFactsOptions): EveEvalDerivedFacts;
|
|
19
19
|
/**
|
|
20
20
|
* Returns empty derived facts, used when a case produced no events
|
|
21
21
|
* (execution errors, transport failures).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Client } from "#client/client.js";
|
|
2
2
|
import type { ClientSession } from "#client/session.js";
|
|
3
3
|
import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { MessageStreamEvent, TurnFailureStreamEvent } from "#protocol/message.js";
|
|
5
5
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
6
6
|
import { AssertionCollector } from "#evals/assertions/collector.js";
|
|
7
7
|
import type { EveEvalAssertions, EveEvalLiveTurn, EveEvalOutputAssertions, EveEvalSession, EveEvalSessionResult, EveEvalTurn } from "#evals/types.js";
|
|
@@ -10,7 +10,7 @@ import type { EveEvalInputRequestMatchOptions } from "#evals/match.js";
|
|
|
10
10
|
* Error thrown by {@link EveEvalTurn.expectOk} when a turn failed.
|
|
11
11
|
*/
|
|
12
12
|
export declare class EveEvalTurnFailedError extends Error {
|
|
13
|
-
readonly event: TurnFailureStreamEvent | undefined;
|
|
13
|
+
readonly event: (TurnFailureStreamEvent & MessageStreamEvent) | undefined;
|
|
14
14
|
readonly turn: EveEvalTurn;
|
|
15
15
|
constructor(turn: EveEvalTurn);
|
|
16
16
|
}
|
|
@@ -23,7 +23,7 @@ export declare class EvalSessionDriver implements EveEvalSession {
|
|
|
23
23
|
readonly session: ClientSession;
|
|
24
24
|
readonly signal?: AbortSignal;
|
|
25
25
|
});
|
|
26
|
-
get events(): readonly
|
|
26
|
+
get events(): readonly MessageStreamEvent[];
|
|
27
27
|
get lastTurn(): EveEvalTurn | undefined;
|
|
28
28
|
get pendingInputRequests(): readonly InputRequest[];
|
|
29
29
|
get sessionId(): string | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LanguageModel } from "ai";
|
|
2
2
|
import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { RuntimeIdentity, MessageStreamEvent } from "#protocol/message.js";
|
|
4
4
|
import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
|
|
5
5
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
6
6
|
import type { JsonObject, JsonValue } from "#shared/json.js";
|
|
@@ -70,7 +70,7 @@ export interface EveEvalDerivedFacts {
|
|
|
70
70
|
*/
|
|
71
71
|
export interface EveEvalSessionResult {
|
|
72
72
|
readonly derived: EveEvalDerivedFacts;
|
|
73
|
-
readonly events: readonly
|
|
73
|
+
readonly events: readonly MessageStreamEvent[];
|
|
74
74
|
readonly primary: boolean;
|
|
75
75
|
readonly sessionId?: string;
|
|
76
76
|
readonly state: SessionState;
|
|
@@ -94,7 +94,7 @@ export interface EveEvalTaskResult {
|
|
|
94
94
|
*/
|
|
95
95
|
readonly status: "completed" | "failed" | "waiting";
|
|
96
96
|
/** The captured stream events from the run. */
|
|
97
|
-
readonly events: readonly
|
|
97
|
+
readonly events: readonly MessageStreamEvent[];
|
|
98
98
|
/** Lines written through `t.log` while the eval ran. */
|
|
99
99
|
readonly logs?: readonly string[];
|
|
100
100
|
/** Facts extracted from the stream (tool calls, message counts, etc.). */
|
|
@@ -173,14 +173,14 @@ export interface EveEvalAssertions {
|
|
|
173
173
|
maxToolCalls(max: number): AssertionHandle;
|
|
174
174
|
calledSubagent(name: string, options?: EveEvalSubagentCallMatchOptions): AssertionHandle;
|
|
175
175
|
noFailedActions(): AssertionHandle;
|
|
176
|
-
event<TType extends
|
|
176
|
+
event<TType extends MessageStreamEvent["type"]>(type: TType, options?: Omit<Extract<EveEvalEventMatch, {
|
|
177
177
|
type: TType;
|
|
178
178
|
}>, "type">): AssertionHandle;
|
|
179
|
-
notEvent<TType extends
|
|
179
|
+
notEvent<TType extends MessageStreamEvent["type"]>(type: TType, options?: Omit<Extract<EveEvalEventMatch, {
|
|
180
180
|
type: TType;
|
|
181
181
|
}>, "type" | "count">): AssertionHandle;
|
|
182
182
|
eventOrder(matchers: readonly EveEvalEventMatch[]): AssertionHandle;
|
|
183
|
-
eventsSatisfy(label: string, predicate: (events: readonly
|
|
183
|
+
eventsSatisfy(label: string, predicate: (events: readonly MessageStreamEvent[]) => boolean): AssertionHandle;
|
|
184
184
|
}
|
|
185
185
|
/** Assertions over the final output captured by one session or immutable turn. */
|
|
186
186
|
export interface EveEvalOutputAssertions {
|
|
@@ -188,11 +188,11 @@ export interface EveEvalOutputAssertions {
|
|
|
188
188
|
outputMatches(schema: StandardSchemaV1): AssertionHandle;
|
|
189
189
|
}
|
|
190
190
|
/** Typed stream event returned by {@link EveEvalLiveTurn.waitForEvent}. */
|
|
191
|
-
export type EveEvalStreamEvent<TType extends
|
|
191
|
+
export type EveEvalStreamEvent<TType extends MessageStreamEvent["type"] = MessageStreamEvent["type"]> = Extract<MessageStreamEvent, {
|
|
192
192
|
type: TType;
|
|
193
193
|
}>;
|
|
194
194
|
/** Matcher options for waiting until one live turn emits a specific event. */
|
|
195
|
-
export type EveEvalWaitForEventOptions<TType extends
|
|
195
|
+
export type EveEvalWaitForEventOptions<TType extends MessageStreamEvent["type"]> = Omit<Extract<EveEvalEventMatch, {
|
|
196
196
|
type: TType;
|
|
197
197
|
}>, "count" | "type">;
|
|
198
198
|
/**
|
|
@@ -203,7 +203,7 @@ export type EveEvalWaitForEventOptions<TType extends HandleMessageStreamEvent["t
|
|
|
203
203
|
*/
|
|
204
204
|
export interface EveEvalLiveTurn {
|
|
205
205
|
/** Events observed on this turn so far. */
|
|
206
|
-
readonly events: readonly
|
|
206
|
+
readonly events: readonly MessageStreamEvent[];
|
|
207
207
|
/** Session driver that started or owns this turn. */
|
|
208
208
|
readonly session: EveEvalSession;
|
|
209
209
|
/** Durable session id available as soon as the turn is accepted or attached. */
|
|
@@ -213,12 +213,12 @@ export interface EveEvalLiveTurn {
|
|
|
213
213
|
/** Wait for the turn boundary and return the recorded immutable result. */
|
|
214
214
|
result(): Promise<EveEvalTurn>;
|
|
215
215
|
/** Wait until the live stream emits one typed event matching `options`. */
|
|
216
|
-
waitForEvent<TType extends
|
|
216
|
+
waitForEvent<TType extends MessageStreamEvent["type"]>(type: TType, options?: EveEvalWaitForEventOptions<TType>): Promise<EveEvalStreamEvent<TType>>;
|
|
217
217
|
}
|
|
218
218
|
/** Operations and state shared by the primary eval context and independent sessions. */
|
|
219
219
|
export interface EveEvalSessionDriver {
|
|
220
220
|
/** All events observed on this session so far. */
|
|
221
|
-
readonly events: readonly
|
|
221
|
+
readonly events: readonly MessageStreamEvent[];
|
|
222
222
|
/** Input requests left pending by the last parked turn. */
|
|
223
223
|
readonly pendingInputRequests: readonly InputRequest[];
|
|
224
224
|
/** Serializable cursor for resuming this session. */
|
|
@@ -248,7 +248,7 @@ export interface EveEvalSession extends EveEvalSessionDriver, EveEvalAssertions,
|
|
|
248
248
|
*/
|
|
249
249
|
export interface EveEvalTurn extends EveEvalAssertions, EveEvalOutputAssertions {
|
|
250
250
|
readonly data: unknown;
|
|
251
|
-
readonly events: readonly
|
|
251
|
+
readonly events: readonly MessageStreamEvent[];
|
|
252
252
|
readonly inputRequests: readonly InputRequest[];
|
|
253
253
|
readonly message: string | undefined;
|
|
254
254
|
readonly sessionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{createSubagentCalledEvent,encodeMessageStreamEvent,
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{createSubagentCalledEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/remote-agent-dispatch.js";import{createWorkflowRuntime,workflowEntryReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch,recordPendingSubagentChild}from"#harness/runtime-actions.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{buildSubagentRunInput}from"#execution/subagent-tool.js";import{resolveSubagentDepth}from"#harness/subagent-depth.js";const log=createLogger(`execution.dispatch-runtime-actions`);async function dispatchRuntimeActionsStep(e){"use step";let f=await readDurableSession(e.sessionState),p=getPendingRuntimeActionBatch(f.state);if(p===void 0||p.actions.length===0)return{results:[],sessionState:e.sessionState};let m=await deserializeContext(e.serializedContext),h=m.require(BundleKey),g=hydrateDurableSession({compactionOverrides:{thresholdPercent:h.resolvedAgent.config.compaction?.thresholdPercent},durable:f,turnAgent:h.turnAgent}),_=m.require(ChannelKey),v=m.get(AuthKey)??null,y=m.get(CapabilitiesKey),b=m.get(ChannelInstrumentationKey),x=m.get(InitiatorAuthKey)??null,S=e.parentWritable.getWriter(),C=buildAdapterContext(_,m),w=resolveSubagentDepth(g),T=p.actions.filter(e=>e.kind===`subagent-call`).length,E=g,D=[];try{for(let r of p.actions){if(isRecursiveAgentAction(r,h.subagentRegistry.subagentsByNodeId)&&(g.rootSessionId!==void 0||w.currentDepth>0)){log.warn(`recursive agent call blocked outside the root session`,{callId:r.callId,currentDepth:w.currentDepth,nodeId:r.nodeId,subagentName:r.subagentName}),D.push(createRecursiveAgentRootOnlyResult(r));continue}let i,a,o,u;switch(r.kind){case`subagent-call`:{let n=h.subagentRegistry.subagentsByNodeId.get(r.nodeId),o=n?.definition.kind===`subagent`?{description:n.definition.description,type:`local`}:{type:`runtime`},s=createWorkflowRuntime({compiledArtifactsSource:h.compiledArtifactsSource,nodeId:r.nodeId}),{childContinuationToken:c,runInput:l}=buildSubagentRunInput({action:r,auth:v,batchEvent:p.event,capabilities:y,channelMetadata:b,fanoutSize:T,initiatorAuth:x,parentContinuationToken:e.parentContinuationToken,session:g,source:o});try{i=(await s.run(l)).sessionId}catch(e){logError(log,`local subagent start failed`,e,{callId:r.callId,nodeId:r.nodeId,subagentName:r.subagentName}),D.push({callId:r.callId,isError:!0,kind:`subagent-result`,output:{code:`SUBAGENT_START_FAILED`,message:toErrorMessage(e)},subagentName:r.subagentName});continue}E=recordPendingSubagentChild({callId:r.callId,child:{continuationToken:c,kind:`local`,sessionId:i},session:E}),a=r.name,u=r.subagentName;break}case`remote-agent-call`:{let n;try{n=resolveRemoteAgentForAction({nodeId:r.nodeId,remoteAgentName:r.remoteAgentName,registry:h.subagentRegistry.subagentsByNodeId}),i=await startRemoteAgentSession({action:r,auth:v,callbackBaseUrl:e.callbackBaseUrl,callbackToken:e.parentContinuationToken,initiatorAuth:x,remote:n,session:g})}catch(e){logError(log,`remote agent start failed`,e,{remoteAgentName:r.remoteAgentName,nodeId:r.nodeId,callId:r.callId}),D.push(createRemoteAgentStartFailureResult({action:r,error:e}));continue}a=r.name,o={url:n.url},u=r.remoteAgentName,E=recordPendingSubagentChild({callId:r.callId,child:{kind:`remote`,sessionId:i},session:E});break}default:throw Error(`Unsupported runtime action kind "${r.kind}" in workflow runtime.`)}let d=await callAdapterEventHandler(_,createSubagentCalledEvent({callId:r.callId,childSessionId:i,name:a,remote:o,sequence:p.event.sequence,sessionId:g.sessionId,toolName:u,turnId:p.event.turnId,workflowId:workflowEntryReference.workflowId}),C);await S.write(encodeMessageStreamEvent(stampMessageStreamEvent(d)))}}finally{S.releaseLock()}return{results:D,sessionState:E===g?e.sessionState:createDurableSessionState({session:E})}}function createRemoteAgentStartFailureResult(e){return{callId:e.action.callId,isError:!0,kind:`subagent-result`,output:{code:`REMOTE_AGENT_START_FAILED`,message:toErrorMessage(e.error)},subagentName:e.action.remoteAgentName}}function createRecursiveAgentRootOnlyResult(e){return{callId:e.callId,isError:!0,kind:`subagent-result`,output:{code:`RECURSIVE_AGENT_ROOT_ONLY`,message:`The built-in "agent" tool is only available to the root session.`},subagentName:e.subagentName}}function isRecursiveAgentAction(e,t){return e.kind===`subagent-call`&&e.subagentName===`agent`&&!t.has(e.nodeId)}export{dispatchRuntimeActionsStep};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { DeliverPayload, SessionAuthContext } from "#channel/types.js";
|
|
2
2
|
import type { DurableSessionState } from "#execution/durable-session-store.js";
|
|
3
|
+
import { type RoutedDeliverResult } from "#execution/workflow-steps.js";
|
|
3
4
|
/**
|
|
4
5
|
* Coalesces inbound deliver payloads and routes any descendant-bound input
|
|
5
|
-
* responses down to the owning child
|
|
6
|
-
*
|
|
6
|
+
* responses down to the owning child. A descendant session-limit Stop is
|
|
7
|
+
* returned as parent-owned turn control after the child consumes the answer.
|
|
7
8
|
*
|
|
8
9
|
* Short-circuits via `hasProxyInputRequests` so the common no-active-descendant
|
|
9
10
|
* path skips a durable step boundary. Lives in its own non-step module so both
|
|
@@ -15,4 +16,4 @@ export declare function routeDeliverToChildren(input: {
|
|
|
15
16
|
readonly parentWritable: WritableStream<Uint8Array>;
|
|
16
17
|
readonly payloads: readonly DeliverPayload[];
|
|
17
18
|
readonly sessionState: DurableSessionState;
|
|
18
|
-
}): Promise<
|
|
19
|
+
}): Promise<RoutedDeliverResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{routeProxiedDeliverStep}from"#execution/workflow-steps.js";async function routeDeliverToChildren(e){let t=coalesceDeliverPayloads(e.payloads);return e.sessionState.hasProxyInputRequests?
|
|
1
|
+
import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{routeProxiedDeliverStep}from"#execution/workflow-steps.js";async function routeDeliverToChildren(e){let t=coalesceDeliverPayloads(e.payloads);return e.sessionState.hasProxyInputRequests?await routeProxiedDeliverStep({auth:e.auth,parentWritable:e.parentWritable,payload:t,sessionState:e.sessionState}):{kind:`continue`,remainder:t}}export{routeDeliverToChildren};
|
|
@@ -2,6 +2,7 @@ import type { DeliverHookPayload, HookPayload } from "#channel/types.js";
|
|
|
2
2
|
/** Reads and rekeys the public delivery hook for one session driver. */
|
|
3
3
|
export interface SessionDeliveryHook {
|
|
4
4
|
consumeNext(): void;
|
|
5
|
+
consumeSessionTimeout(): boolean;
|
|
5
6
|
next(): Promise<IteratorResult<HookPayload>>;
|
|
6
7
|
rekey(token: string): Promise<void>;
|
|
7
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHook}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";function createSessionDeliveryHook(r){let i,a=[],o=[],s=0,c=null,l,u,enqueue=e=>{o.push(e),o.sort((e,t)=>e.order-t.order),
|
|
1
|
+
import{createHook}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";function createSessionDeliveryHook(r){let i,a=[],o=[],s=0,c=null,l,u=!1,d,enqueue=e=>{o.push(e),o.sort((e,t)=>e.order-t.order),d?.(),d=void 0},arm=e=>{e.closed||e.pending||(e.pending=!0,e.resolved=void 0,(e.retired?Promise.resolve(e.hook).then(e=>({done:!1,value:e})):e.iterator.next()).then(t=>{let n={order:s++,result:t,state:e};e.resolved=n,e.enabled&&enqueue(n)},()=>{}))},enable=e=>{e.enabled=!0,e.resolved!==void 0&&enqueue(e.resolved)},drainReady=async()=>{if(c===null)for(await Promise.resolve();o.length>0;){let e=o.shift();e.state.pending=!1,e.state.resolved=void 0,e.result.done?e.state.closed=!0:e.result.value.kind===`deliver`?r.push(e.result.value):e.result.value.kind===`session-timeout`&&(u=!0),arm(e.state),await Promise.resolve()}};return{consumeNext(){if(l===void 0)throw Error(`Cannot consume a public delivery before it resolves.`);!l.result.done&&l.result.value.kind===`session-timeout`&&(u=!0),l.state.pending=!1,l.state.resolved=void 0,l.result.done&&(l.state.closed=!0),l=void 0,c=null},consumeSessionTimeout(){let e=u;return u=!1,e},async dispose(){i!==void 0&&(await disposeHook(i.hook),i=void 0)},next(){if(i===void 0)throw Error(`Cannot wait for deliveries before a continuation token is available.`);if(c!==null)return c;arm(i);for(let e of a)arm(e);return i.closed&&a.every(e=>e.closed)?(l={order:s++,result:{done:!0,value:void 0},state:i},c=Promise.resolve(l.result),c):(c=(async()=>{for(;o.length===0;)await new Promise(e=>{d=e});let e=o.shift();return l=e,e.result})(),c)},async rekey(r){if(!r||i?.hook.token===r)return;let o=createHook({token:r}),s={closed:!1,enabled:!1,hook:o,iterator:o[Symbol.asyncIterator](),pending:!1,retired:!1};if(i===void 0){await claimHookOwnership(s.hook),enable(s),i=s;return}let c=i;arm(c),arm(s),await claimHookOwnership(s.hook),enable(s),await drainReady();try{await disposeHook(c.hook)}catch(e){i=void 0;try{await disposeHook(s.hook)}catch{}throw e}c.retired=!0,a.push(c),i=s,await drainReady()}}}export{createSessionDeliveryHook};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Workflow-body handle that targets a durable deadline at the active delivery hook. */
|
|
2
|
+
export interface SessionTimeoutControl {
|
|
3
|
+
dispose(): Promise<void>;
|
|
4
|
+
rekey(token: string): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/** Creates a timer controller that preserves one absolute session deadline across hook rekeys. */
|
|
7
|
+
export declare function createSessionTimeoutControl(input: {
|
|
8
|
+
readonly deadline: Date;
|
|
9
|
+
}): SessionTimeoutControl;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cancelSessionTimeoutStep,startSessionTimeoutStep}from"#execution/session-timeout-steps.js";function createSessionTimeoutControl(t){let n;return{async dispose(){if(n===void 0)return;let e=n;n=void 0,await cancelSessionTimeoutStep({runId:e.runId})},async rekey(r){if(!r||n?.token===r)return;n!==void 0&&await cancelSessionTimeoutStep({runId:n.runId});let{runId:i}=await startSessionTimeoutStep({deadline:t.deadline,token:r});n={runId:i,token:r}}}}export{createSessionTimeoutControl};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SessionTimeoutWorkflowInput } from "#execution/session-timeout-workflow.js";
|
|
2
|
+
/** Starts the durable timer that signals one session deadline. */
|
|
3
|
+
export declare function startSessionTimeoutStep(input: SessionTimeoutWorkflowInput): Promise<{
|
|
4
|
+
readonly runId: string;
|
|
5
|
+
}>;
|
|
6
|
+
/** Resumes the owning driver when its durable timer elapses. */
|
|
7
|
+
export declare function signalSessionTimeoutStep(input: {
|
|
8
|
+
readonly token: string;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
/** Cancels a timer whose session reached another terminal outcome first. */
|
|
11
|
+
export declare function cancelSessionTimeoutStep(input: {
|
|
12
|
+
readonly runId: string;
|
|
13
|
+
}): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{walkCauseChain}from"#shared/errors.js";import{sessionTimeoutWorkflowReference,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{cancelRun,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";async function startSessionTimeoutStep(e){"use step";return{runId:(await startWorkflowPreferLatest(sessionTimeoutWorkflowReference,[e])).runId}}async function signalSessionTimeoutStep(e){"use step";try{await resumeHook(e.token,{kind:`session-timeout`})}catch(e){if(!isInactiveTimeoutTarget(e))throw e}}async function cancelSessionTimeoutStep(e){"use step";try{await cancelRun(await getWorld(),e.runId,{cancelReason:`Session ended before its timeout`})}catch(e){if(!isInactiveTimeoutTarget(e))throw e}}function isInactiveTimeoutTarget(t){for(let n of walkCauseChain(t))if(HookNotFoundError.is(n)||WorkflowRunNotFoundError.is(n)||RunExpiredError.is(n)||EntityConflictError.is(n))return!0;return!1}export{cancelSessionTimeoutStep,signalSessionTimeoutStep,startSessionTimeoutStep};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface SessionTimeoutWorkflowInput {
|
|
2
|
+
readonly deadline: Date;
|
|
3
|
+
readonly token: string;
|
|
4
|
+
}
|
|
5
|
+
/** Sleeps until the session deadline, then signals its driver. */
|
|
6
|
+
export declare function sessionTimeoutWorkflow(input: SessionTimeoutWorkflowInput): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sleep}from"#compiled/@workflow/core/index.js";import{signalSessionTimeoutStep}from"#execution/session-timeout-steps.js";async function sessionTimeoutWorkflow(e){"use workflow";await sleep(e.deadline),await signalSessionTimeoutStep({token:e.token})}export{sessionTimeoutWorkflow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const DEFAULT_SESSION_TIMEOUT_MS=720*60*60*1e3;export{DEFAULT_SESSION_TIMEOUT_MS};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callAdapterEventHandler}from"#channel/adapter.js";import{encodeMessageStreamEvent,
|
|
1
|
+
import{callAdapterEventHandler}from"#channel/adapter.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState,isHarnessBetweenTurns,setHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{clearPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{clearPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{clearAllProxyInputRequests,getProxyInputRequests,hasProxyInputRequests}from"#harness/proxy-input-requests.js";import{getInstrumentationRuntime}from"#harness/instrumentation-runtime.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{activeTurnId}from"#harness/active-turn-id.js";import{emitCancelledTurn}from"#harness/cancelled-turn-emission.js";import{clearPendingSessionLimitPrompt}from"#harness/input-requests.js";import{createInstrumentationHandleEvent}from"#harness/instrumentation-native-events.js";async function settleCancelledTurnStep(a){"use step";let o=await readDurableSession(a.sessionState),s=await deserializeContext(a.serializedContext),c=s.require(ChannelKey),l=buildAdapterContext(c,s),u=s.require(BundleKey),d=getInstrumentationRuntime(),f=hydrateDurableSession({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},durable:o,turnAgent:u.turnAgent}),p=getHarnessEmissionState(o.state),m=[...getProxyInputRequests(o.state).values()].some(e=>e.kind===`session-limit`);if(!(isHarnessBetweenTurns(f)&&hasProxyInputRequests(o.state)&&!m)){let t=a.parentWritable.getWriter();try{let n=await withContextScope(s,f,async n=>{let baseEmit=async n=>{let r=await callAdapterEventHandler(c,n,l);setChannelContext(s,{...c,state:{...l.state}});let i=stampMessageStreamEvent(r);await t.write(encodeMessageStreamEvent(i)),await dispatchStreamEventHooks({ctx:s,event:i,registry:u.hookRegistry})};return{result:await emitCancelledTurn(createInstrumentationHandleEvent({agentName:u.resolvedAgent.config.name,handleEvent:baseEmit,hooks:d?.hooks,sessionId:f.sessionId,turnId:activeTurnId(p)})??baseEmit,p,n.continuationToken),session:n}});p=n.result,f=n.session}finally{await d?.forceFlush(),t.releaseLock()}}let h=reconcileSessionContinuationToken(s,setHarnessEmissionState(clearPendingSessionLimitPrompt(clearAllProxyInputRequests(clearPendingWorkflowInterrupt(clearPendingRuntimeActionBatch(f)))),p));return{serializedContext:serializeContext(s),sessionState:createDurableSessionState({session:h})}}export{settleCancelledTurnStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callAdapterEventHandler}from"#channel/adapter.js";import{ModeKey}from"#context/keys.js";import{encodeMessageStreamEvent,
|
|
1
|
+
import{callAdapterEventHandler}from"#channel/adapter.js";import{ModeKey}from"#context/keys.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{emitProxiedInputRequest}from"#execution/subagent-hitl-proxy.js";async function runProxySubagentEventStep(e){"use step";let t=await readDurableSession(e.sessionState);return emitProxiedSubagentEvent({ctx:await deserializeContext(e.serializedContext),durableSession:t,hookPayload:e.hookPayload,parentWritable:e.parentWritable})}async function emitProxiedSubagentEvent(i){let{ctx:a}=i,o=a.require(ChannelKey),s=a.require(BundleKey),c=hydrateDurableSession({compactionOverrides:{thresholdPercent:s.resolvedAgent.config.compaction?.thresholdPercent},durable:i.durableSession,turnAgent:s.turnAgent}),l=buildAdapterContext(o,a),u=i.parentWritable.getWriter(),d,f;try{let emit=async t=>{let r=await callAdapterEventHandler(o,t,l);await u.write(encodeMessageStreamEvent(stampMessageStreamEvent(r)))},r=await withContextScope(a,c,async e=>{if(i.hookPayload.kind===`subagent-authorization-event`)return await emit(i.hookPayload.event),{result:void 0,session:e};let n=await emitProxiedInputRequest({emit,hookPayload:i.hookPayload,mode:a.require(ModeKey),session:e});return{result:n.entries,session:n.session}});d=r.result,f=r.session}finally{u.releaseLock()}setChannelContext(a,{...o,state:{...l.state}}),d!==void 0&&i.hookPayload.kind===`subagent-input-request`&&(f=upsertProxyInputRequests({entries:d,forChildContinuationToken:i.hookPayload.childContinuationToken,session:f}));let p=reconcileSessionContinuationToken(a,f);return{serializedContext:serializeContext(a),sessionState:createDurableSessionState({session:p})}}export{emitProxiedSubagentEvent,runProxySubagentEventStep};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DeliverPayload, SubagentInputRequestHookPayload } from "#channel/types.js";
|
|
2
|
+
import type { ProxyInputRequest } from "#harness/proxy-input-requests.js";
|
|
2
3
|
import type { HarnessEmitFn, HarnessSession, SessionStateMap } from "#harness/types.js";
|
|
3
4
|
import type { RunMode } from "#shared/run-mode.js";
|
|
4
5
|
import type { InputResponse } from "#runtime/input/types.js";
|
|
@@ -13,7 +14,7 @@ export declare function emitProxiedInputRequest(input: {
|
|
|
13
14
|
readonly mode: RunMode;
|
|
14
15
|
readonly session: HarnessSession;
|
|
15
16
|
}): Promise<{
|
|
16
|
-
readonly entries: readonly (readonly [requestId: string,
|
|
17
|
+
readonly entries: readonly (readonly [requestId: string, route: ProxyInputRequest])[];
|
|
17
18
|
readonly session: HarnessSession;
|
|
18
19
|
}>;
|
|
19
20
|
/**
|
|
@@ -29,6 +30,9 @@ export interface RoutedDeliverPayload {
|
|
|
29
30
|
};
|
|
30
31
|
}[];
|
|
31
32
|
readonly forSelf: DeliverPayload | undefined;
|
|
33
|
+
readonly parentAction: {
|
|
34
|
+
readonly kind: "cancel-turn";
|
|
35
|
+
} | undefined;
|
|
32
36
|
}
|
|
33
37
|
/** Splits a deliver payload into parent-local and proxied-child buckets. */
|
|
34
38
|
export declare function routeDeliverPayload(input: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createInputRequestedEvent}from"#protocol/message.js";import{emitTurnEpilogue,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{getProxyInputRequests,toProxyInputRequestEntries}from"#harness/proxy-input-requests.js";async function emitProxiedInputRequest(i){await i.emit(createInputRequestedEvent({requests:i.hookPayload.event.requests,sequence:i.hookPayload.event.sequence,stepIndex:i.hookPayload.event.stepIndex,turnId:i.hookPayload.event.turnId}));let o=i.session;if(i.mode===`conversation`){let e=getHarnessEmissionState(i.session.state),a=await emitTurnEpilogue(i.emit,e,i.mode,i.session.continuationToken);o=setHarnessEmissionState(i.session,a)}return{entries:toProxyInputRequestEntries(i.hookPayload),session:o}}function routeDeliverPayload(e){let t=getProxyInputRequests(e.state),n=e.payload.inputResponses??[],r=new Map,a=[];for(let e of n){let n=t.get(e.requestId);if(n===void 0){a.push(e);continue}let i=r.get(n);i===void 0?r.set(n,[e]):i.push(e)}let
|
|
1
|
+
import{createInputRequestedEvent}from"#protocol/message.js";import{emitTurnEpilogue,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{getProxyInputRequests,toProxyInputRequestEntries}from"#harness/proxy-input-requests.js";import{SESSION_LIMIT_STOP_OPTION_ID}from"#harness/session-limit-continuation.js";async function emitProxiedInputRequest(i){await i.emit(createInputRequestedEvent({requests:i.hookPayload.event.requests,sequence:i.hookPayload.event.sequence,stepIndex:i.hookPayload.event.stepIndex,turnId:i.hookPayload.event.turnId}));let o=i.session;if(i.mode===`conversation`){let e=getHarnessEmissionState(i.session.state),a=await emitTurnEpilogue(i.emit,e,i.mode,i.session.continuationToken);o=setHarnessEmissionState(i.session,a)}return{entries:toProxyInputRequestEntries(i.hookPayload),session:o}}function routeDeliverPayload(e){let t=getProxyInputRequests(e.state),n=e.payload.inputResponses??[],r=new Map,a=[],s;for(let e of n){let n=t.get(e.requestId);if(n===void 0){a.push(e);continue}n.kind===`session-limit`&&e.optionId===SESSION_LIMIT_STOP_OPTION_ID&&(s={kind:`cancel-turn`});let i=r.get(n.childContinuationToken);i===void 0?r.set(n.childContinuationToken,[e]):i.push(e)}let c=[...r.entries()].map(([e,t])=>({childContinuationToken:e,payload:{inputResponses:t}})),l={};for(let[t,n]of Object.entries(e.payload))t===`inputResponses`||n===void 0||(l[t]=n);return a.length>0&&(l.inputResponses=a),{forChildren:c,forSelf:Object.keys(l).length>0?l:void 0,parentAction:s}}export{emitProxiedInputRequest,routeDeliverPayload};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{createSessionCompletedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionCompletionStep(e){"use step";let i=createSessionCompletedEvent(),a=e.serializedContext[`eve.sessionId`]??``;try{let n=await deserializeContext(e.serializedContext),r=n.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,i,buildAdapterContext(r,n))}catch(e){log.error(`adapter failed to handle terminal session.completed event`,{error:e,sessionId:a})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(stampMessageStreamEvent(i)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.completed event to durable stream`,{error:e,sessionId:a})}}export{emitTerminalSessionCompletionStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{createSessionFailedEvent,encodeMessageStreamEvent,
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{createSessionFailedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=summarizeKnownError(e.error),a=r;if(i!==null){let e={...r,message:i.message,name:i.name,semanticErrorId:i.id};a=i.hint===void 0?e:{...e,hint:i.hint}}let o=typeof a.name==`string`?a.name:`WORKFLOW_EXECUTION_FAILED`,s=typeof a.message==`string`?a.message:String(e.error),c=e.serializedContext[`eve.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:c,errorId:typeof a.errorId==`string`?a.errorId:void 0,code:o});let l=createSessionFailedEvent({code:o,details:a,message:s,sessionId:c});try{let t=await deserializeContext(e.serializedContext),n=t.get(ChannelKey);n!==void 0&&await callAdapterEventHandler(n,l,buildAdapterContext(n,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof a.errorId==`string`?a.errorId:void 0,sessionId:c,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(stampMessageStreamEvent(l)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof a.errorId==`string`?a.errorId:void 0,sessionId:c,error:e})}}export{emitTerminalSessionFailureStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{activeTurnId}from"#harness/active-turn-id.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await
|
|
1
|
+
import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{activeTurnId}from"#harness/active-turn-id.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await finishCancelledTurn({bufferedDeliveries:f,cancellation:h,cursor:u});return}if(i.action===`done`){await h?.dispose(),await u.finish(i,{kind:`done`,output:i.output??``,isError:i.isError,usage:i.usage},f);return}let o=i.action===`dispatch-workflow-runtime-actions`||i.action===`park`?i.pendingRuntimeActionKeys:void 0;if(o!==void 0){await u.adopt(i);let e=await(i.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:c.token,parentWritable:u.parentWritable,serializedContext:u.serializedContext,sessionState:u.sessionState});await u.adopt(e);let r=await waitForRuntimeActionResults({bufferedDeliveries:f,cancellation:h,cursor:u,inboxToken:c.token,initialResults:e.results,iterator:l,nextDeliveryRequestId,pendingActionKeys:o});if(r===`cancelled`){p=void 0;continue}if(r===`cancel-turn`){await finishCancelledTurn({bufferedDeliveries:f,cancellation:h,cursor:u});return}p={kind:`runtime-action-result`,results:r};continue}if(i.action===`park`){if(!(i.hasPendingAuthorization||i.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await h?.dispose(),await u.finish(i,{authorizationNames:i.authorizationNames,kind:`park`},f);return}await u.adopt(i),p=void 0}}catch(e){throw await u.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{h!==void 0&&await h.dispose(),m&&await disposeHook(c)}}async function finishCancelledTurn(e){await cancelDescendantTurnsStep({serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState}),await e.cancellation?.dispose(),await e.cursor.finish({sessionState:e.cursor.sessionState},{cancelled:!0,kind:`park`},e.bufferedDeliveries)}async function waitForRuntimeActionResults(t){let n,r=[...t.initialResults];for(;;){let i=resolveRuntimeActionResultsForKeys({pendingKeys:t.pendingActionKeys,results:r});if(i!==void 0)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),i;t.cursor.sessionState.hasProxyInputRequests&&n===void 0&&(n=t.nextDeliveryRequestId(),await t.cursor.send({continuationToken:t.cursor.sessionState.continuationToken,inboxToken:t.inboxToken,kind:`turn-delivery-request`,requestId:n}));let a=t.iterator.next();a.catch(()=>{});let o=await(t.cancellation===void 0?a:Promise.race([a,t.cancellation.requested]));if(o===`cancel`)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),`cancelled`;if(o.done)throw Error(`Turn inbox closed before runtime actions completed.`);let s=o.value;if(s.kind===`runtime-action-result`){r.push(...s.results);continue}if(s.kind===`subagent-input-request`||s.kind===`subagent-authorization-event`){let e=await runProxySubagentEventStep({hookPayload:s,parentWritable:t.cursor.parentWritable,serializedContext:t.cursor.serializedContext,sessionState:t.cursor.sessionState});await t.cursor.adopt(e);continue}if(s.kind===`driver-delivery`&&s.requestId===n){await t.cursor.send({kind:`turn-delivery-accepted`,requestId:s.requestId}),n=void 0;let e=await routeDeliverToChildren({auth:s.delivery.auth,parentWritable:t.cursor.parentWritable,payloads:s.delivery.payloads,sessionState:t.cursor.sessionState});if(e.kind===`cancel-turn`)return e.kind;e.remainder!==void 0&&t.bufferedDeliveries.push({...s.delivery,payloads:[e.remainder]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:n.pendingRuntimeActionKeys,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingRuntimeActionKeys;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationNames:n.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
|
|
@@ -7,6 +7,7 @@ import type { RunInput } from "#channel/types.js";
|
|
|
7
7
|
export interface WorkflowEntryInput {
|
|
8
8
|
readonly input: RunInput["input"];
|
|
9
9
|
readonly limits?: RunInput["limits"];
|
|
10
|
+
readonly sessionTimeoutMs?: number | false;
|
|
10
11
|
readonly serializedContext: Record<string, unknown>;
|
|
11
12
|
}
|
|
12
13
|
export interface WorkflowEntryResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{coalesceDeliveries}from"#harness/messages.js";import{readSerializedSubagentDepth}from"#harness/subagent-depth.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{dispatchAndAwaitTurn}from"#execution/turn-dispatch.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";import{createSessionDeliveryHook}from"#execution/session-delivery-hook.js";async function workflowEntry(e){"use workflow";let{workflowRunId:n}=getWorkflowMetadata(),
|
|
1
|
+
import{coalesceDeliveries}from"#harness/messages.js";import{readSerializedSubagentDepth}from"#harness/subagent-depth.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{dispatchAndAwaitTurn}from"#execution/turn-dispatch.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";import{createSessionDeliveryHook}from"#execution/session-delivery-hook.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session-timeout.js";import{emitTerminalSessionCompletionStep}from"#execution/terminal-session-completion-step.js";import{createSessionTimeoutControl}from"#execution/session-timeout-control.js";async function workflowEntry(e){"use workflow";let{workflowRunId:n,workflowStartedAt:a}=getWorkflowMetadata(),s=e.serializedContext[`eve.continuationToken`]||``,c=e.serializedContext[`eve.mode`],f=e.serializedContext[`eve.capabilities`],p=e.serializedContext[`eve.bundle`];e.serializedContext[`eve.sessionId`]=n;let m=getWritable();try{let r=readRootSessionId(e.serializedContext),i=readSerializedSubagentDepth(e.serializedContext),{state:o}=await createSessionStep({compiledArtifactsSource:p.source,continuationToken:s,inheritedLimits:e.limits,nodeId:p.nodeId,outputSchema:e.input.outputSchema,rootSessionId:r,sessionId:n,subagentDepth:i}),d=await runDriverLoop({capabilities:f,driverWritable:m,initialInput:{kind:`deliver`,payloads:[{message:e.input.message,context:e.input.context,outputSchema:e.input.outputSchema}],requestId:readChannelRequestId(e.serializedContext)},mode:c,serializedContext:e.serializedContext,sessionState:o,sessionTimeoutDeadline:e.sessionTimeoutMs===!1?void 0:new Date(a.getTime()+(e.sessionTimeoutMs??DEFAULT_SESSION_TIMEOUT_MS))});return d.kind===`result`?d.result:await finalizeExpiredSession({driverWritable:m,serializedContext:d.serializedContext})}catch(t){throw await emitTerminalSessionFailureStep({error:normalizeSerializableError(t),parentWritable:m,serializedContext:e.serializedContext}),await fireSessionCallbackStep({error:normalizeSerializableError(t),serializedContext:e.serializedContext,status:`failed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentErrorResult(e.serializedContext,t),serializedContext:e.serializedContext}),createSafeOuterWorkflowError()}}function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runDriverLoop(e){let t=createHook({token:`${e.sessionState.sessionId}:auth`}),r=t[Symbol.asyncIterator](),i=0,nextTurnControlToken=()=>`${e.sessionState.sessionId}:turn-control:${String(i++)}`,o=[],l=createSessionDeliveryHook(o),u=e.sessionTimeoutDeadline===void 0?void 0:createSessionTimeoutControl({deadline:e.sessionTimeoutDeadline}),d,runTurn=async t=>{let n=await dispatchAndAwaitTurn({bufferedDeliveries:o,capabilities:e.capabilities,controlToken:nextTurnControlToken(),delivery:t.delivery,deliveryHook:l,mode:e.mode,parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});return await d?.(),d=n.dispose,n.action};try{e.sessionState.continuationToken&&(await l.rekey(e.sessionState.continuationToken),await u?.rekey(e.sessionState.continuationToken));let t=await runTurn({delivery:e.initialInput,serializedContext:e.serializedContext,sessionState:e.sessionState});for(;;){if(t.kind===`done`)return{kind:`result`,result:await finalizeDone({action:t,driverWritable:e.driverWritable})};if(t.kind!==`park`)throw Error(`Driver received unexpected turn action "${t.kind}".`);if(t.cancelled===!0){let n=await settleCancelledTurnStep({parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});t={...t,serializedContext:n.serializedContext,sessionState:n.sessionState}}if(!t.sessionState.continuationToken)throw Error("Cannot park: no continuation token available. The channel must post the first message during the initial turn (anchoring the session) or `send()` must be called with an explicit continuationToken.");if(await l.rekey(t.sessionState.continuationToken),await u?.rekey(t.sessionState.continuationToken),t.authorizationNames&&t.authorizationNames.length>0){let e=t.authorizationNames.length,n=[];for(;n.length<e;){let e=await r.next();if(e.done)break;e.value.kind===`deliver`&&n.push(...e.value.payloads)}t=await runTurn({delivery:{kind:`deliver`,payloads:n},serializedContext:t.serializedContext,sessionState:t.sessionState});continue}let n=await waitForNextSessionAction({bufferedDeliveries:o,deliveryHook:l});if(n.kind===`expired`)return{kind:`expired`,serializedContext:t.serializedContext};let i=n.delivery;if(i===null)return{kind:`result`,result:{output:``}};let a=await routeDeliverToChildren({auth:i.auth,parentWritable:e.driverWritable,payloads:i.payloads,sessionState:t.sessionState});if(a.kind===`cancel-turn`){await cancelDescendantTurnsStep({serializedContext:t.serializedContext,sessionState:t.sessionState});let n=await settleCancelledTurnStep({parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});t={...t,serializedContext:n.serializedContext,sessionState:n.sessionState};continue}a.remainder!==void 0&&(t=await runTurn({delivery:{auth:i.auth,kind:`deliver`,payloads:[a.remainder],requestId:i.requestId},serializedContext:t.serializedContext,sessionState:t.sessionState}))}}finally{await d?.(),await u?.dispose(),await l.dispose(),await disposeHook(t)}}async function waitForNextSessionAction(t){if(t.deliveryHook.consumeSessionTimeout())return{kind:`expired`};if(t.bufferedDeliveries.length>0)return{delivery:coalesceDeliveries(t.bufferedDeliveries.splice(0)),kind:`delivery`};for(;;){let n=await t.deliveryHook.next();if(t.deliveryHook.consumeNext(),n.done)return{delivery:null,kind:`delivery`};if(n.value.kind===`session-timeout`)return{kind:`expired`};if(n.value.kind!==`deliver`)continue;let r=n.value;for(;;){let n=await takeReadyPayload(t.deliveryHook.next());if(n===NO_READY_MESSAGE)break;if(n.done){t.deliveryHook.consumeNext();break}if(n.value.kind===`session-timeout`)break;t.deliveryHook.consumeNext(),n.value.kind===`deliver`&&(r=coalesceDeliveries([r,n.value]))}return{delivery:r,kind:`delivery`}}}async function finalizeExpiredSession(e){return await emitTerminalSessionCompletionStep({parentWritable:e.driverWritable,serializedContext:e.serializedContext}),await fireSessionCallbackStep({output:``,serializedContext:e.serializedContext,status:`completed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentSuccessResult(e.serializedContext,``),serializedContext:e.serializedContext}),{output:``}}async function finalizeDone(e){let{output:t,serializedContext:n}=e.action,r=e.action.isError===!0;return await fireSessionCallbackStep({error:r?t:void 0,output:r?void 0:t,serializedContext:n,status:r?`failed`:`completed`,usage:r?void 0:e.action.usage}),await notifyDelegatedParentStep({result:r?createDelegatedSubagentErrorResult(n,t):createDelegatedSubagentSuccessResult(n,t),serializedContext:n,usage:r?void 0:e.action.usage}),{output:t}}const NO_READY_MESSAGE=Symbol(`no-ready-message`);async function takeReadyPayload(e){return await Promise.resolve(),await Promise.race([e,Promise.resolve(NO_READY_MESSAGE)])}export{workflowEntry};
|
|
@@ -32,6 +32,10 @@ export declare const workflowEntryReference: {
|
|
|
32
32
|
export declare const turnWorkflowReference: {
|
|
33
33
|
workflowId: string;
|
|
34
34
|
};
|
|
35
|
+
/** Stable workflow reference for session deadline timers. */
|
|
36
|
+
export declare const sessionTimeoutWorkflowReference: {
|
|
37
|
+
workflowId: string;
|
|
38
|
+
};
|
|
35
39
|
/**
|
|
36
40
|
* Creates a workflow-backed runtime whose long-lived driver owns the
|
|
37
41
|
* event stream and dispatches each turn as a child workflow run.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";const WORKFLOW_ENTRY_NAME=`workflowEntry`,TURN_WORKFLOW_NAME=`turnWorkflow`,SESSION_TIMEOUT_WORKFLOW_NAME=`sessionTimeoutWorkflow`,EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE=`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`,STABLE_WORKFLOW_NAMES=new Set([WORKFLOW_ENTRY_NAME,TURN_WORKFLOW_NAME,SESSION_TIMEOUT_WORKFLOW_NAME]),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},turnWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${TURN_WORKFLOW_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async run(n){let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),i=serializeContext(buildRunContext({bundle:r,run:n})),a=readParentLineage(i),o=r.resolvedAgent.config.limits?.sessionTimeoutMs,s={input:n.input,limits:n.limits,serializedContext:i};o!==void 0&&(s.sessionTimeoutMs=o);let c=a.sessionId===void 0?buildSessionAttributes({inputMessage:n.title??n.input.message,serializedContext:i}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:a.callId,parentSessionId:a.sessionId,parentTurnId:a.turnId,rootSessionId:a.rootSessionId??a.sessionId,serializedContext:i}),l;try{l=await startWorkflowPreferLatest(workflowEntryReference,[s],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(c)})}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:n.continuationToken}),e}let u,getEvents=()=>(u??=parseNdjsonStream(()=>getRun(l.runId).getReadable()),u);return{continuationToken:n.continuationToken??l.runId,get events(){return getEvents()},sessionId:l.runId}},async cancelTurn(e){return await requestWorkflowTurnCancellation(e)},async terminateSession(e){try{return await cancelRun(await getWorld(),e.sessionId,{cancelReason:e.reason??`Session reset by channel`}),{status:`terminated`}}catch(e){if(isAlreadyTerminalSessionError(e))return{status:`already_terminal`};throw e}},async deliver(e){let r={auth:e.auth,kind:`deliver`,payloads:[e.payload],requestId:e.requestId};try{return{sessionId:normalizeWorkflowHook(await resumeHook(e.continuationToken,r)).runId}}catch(r){throw HookNotFoundError.is(r)?new RuntimeNoActiveSessionError(e.continuationToken):(logError(log,`failed to deliver to active session`,r,{continuationToken:e.continuationToken}),r)}},async getEventStream(e,t){return parseNdjsonStream(()=>getRun(e).getReadable({startIndex:t?.startIndex}))},async getStreamTailIndex(e){let t=getRun(e).getReadable();try{return await t.getTailIndex()}finally{await t.cancel().catch(()=>{})}},async resolveSession(e){try{return{sessionId:(await getHookByToken(e)).runId}}catch(n){if(HookNotFoundError.is(n))return;throw logError(log,`failed to resolve session by continuation token`,n,{continuationToken:e}),n}}}}async function requestWorkflowTurnCancellation(e){let t=e.turnId===void 0?{}:{turnId:e.turnId};try{return await resumeHook(sessionCancelHookToken(e.sessionId),t),{status:`accepted`}}catch(e){if(isInactiveCancelTarget(e))return{status:`no_active_turn`};throw e}}function isInactiveCancelTarget(e){return HookNotFoundError.is(e)||WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e)||EntityConflictError.is(e)}function isAlreadyTerminalSessionError(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function startWorkflowPreferLatest(e,t,n){if(!shouldRouteToLatestDeployment())return n===void 0?await start(e,t):await start(e,t,n);try{return await start(e,t,{...n,deploymentId:`latest`})}catch(r){if(!isLatestDeploymentUnsupportedError(r))throw r;return n===void 0?await start(e,t):await start(e,t,n)}}function shouldRouteToLatestDeployment(){return process.env.VERCEL_ENV===`production`||isEveDevEnvironment()}function isLatestDeploymentUnsupportedError(e){return e instanceof Error&&e.message.includes(`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`)}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{LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE,STABLE_WORKFLOW_NAMES,createWorkflowRuntime,requestWorkflowTurnCancellation,sessionTimeoutWorkflowReference,startWorkflowPreferLatest,turnWorkflowReference,workflowEntryReference};
|
|
@@ -66,10 +66,13 @@ export declare function resolveEffectiveOutputSchema(input: {
|
|
|
66
66
|
readonly mode: RunMode;
|
|
67
67
|
readonly session: HarnessSession;
|
|
68
68
|
}): HarnessSession;
|
|
69
|
-
export
|
|
69
|
+
export type RoutedDeliverResult = {
|
|
70
|
+
readonly kind: "cancel-turn";
|
|
71
|
+
} | {
|
|
72
|
+
readonly kind: "continue";
|
|
70
73
|
/** `undefined` when the entire payload was routed to descendants. */
|
|
71
74
|
readonly remainder: DeliverPayload | undefined;
|
|
72
|
-
}
|
|
75
|
+
};
|
|
73
76
|
/**
|
|
74
77
|
* Splits an inbound deliver payload into parent-local and
|
|
75
78
|
* proxied-child buckets and forwards the child buckets via
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,
|
|
1
|
+
import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{createWorkflowRuntime,startWorkflowPreferLatest,turnWorkflowReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resumeHook}from"#internal/workflow/runtime.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{preserveSerializedAgentTraceState}from"#harness/agent-trace-context-store.js";import{getTurnUsageState,toUsage}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{recordSubagentUsageSpans}from"#execution/subagent-usage-span.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";async function turnStep(a){"use step";let o=a,s=await readDurableSession(o.sessionState),c=await deserializeContext(o.serializedContext),l=c.require(ChannelKey),u=c.require(BundleKey);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&c.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let d=getPendingAuthorization(s.state),f;if(d&&o.input?.kind===`deliver`){let e=[],t=[],n=[];for(let r of o.input.payloads){let i=r.authorizationCallback;if(i){let n=d.challenges.find(e=>e.name===i.connectionName);n&&(e.push({name:n.name,resume:n.resume,callback:i.callback,hookUrl:n.hookUrl}),t.push({name:n.name,authorization:n.challenge}))}else n.push(r)}e.length>0&&(c.set(PendingAuthorizationResultKey,e),s={...s,state:clearPendingAuthorization(s.state,e.map(e=>e.name))},f=t,o=n.length>0?{...o,input:{...o.input,payloads:n}}:{...o,input:void 0})}o.input?.kind===`deliver`&&o.input.auth!==void 0&&c.set(AuthKey,o.input.auth??null);let p=hydrateDurableSession({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},durable:s,turnAgent:u.turnAgent}),m=buildAdapterContext(l,c),h;if(o.input?.kind===`deliver`){let e=[];for(let n of o.input.payloads){let r=l.deliver?await l.deliver(n,m):defaultDeliverResult(n);r!=null&&e.push(r)}h=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else o.input?.kind===`runtime-action-result`&&(recordSubagentUsageSpans(o.input.results),h={runtimeActionResults:o.input.results});if(o.input?.kind===`deliver`&&setChannelContext(c,{...l,state:{...m.state}}),o.input?.kind===`deliver`&&h===void 0){let e=reconcileSessionContinuationToken(c,p),t=serializeContext(c),n=e===p?o.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:t,sessionState:n}}let g=u.hookRegistry,_=u.resolvedAgent.dynamicInstructionsResolvers??[],v=u.resolvedAgent.dynamicSkillResolvers??[],y=u.resolvedAgent.dynamicToolResolvers??[],b=buildRuntimeIdentity(u.graph.root),x=process.env.VERCEL_DEPLOYMENT_ID?.trim(),S=x?`deployment:${x}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);getHarnessEmissionState(p.state).sessionStarted?await refreshDynamicSessionToolsForRuntimeRevision({ctx:c,resolvers:y,event:createSessionStartedEvent({runtime:b}),messages:p.history,runtimeRevision:S}):c.set(SessionDynamicToolRuntimeRevisionKey,S);let C=o.parentWritable.getWriter(),emit=async t=>{let n=await callAdapterEventHandler(l,t,m);setChannelContext(c,{...l,state:{...m.state}});let r=stampMessageStreamEvent(n);return await C.write(encodeMessageStreamEvent(r)),r},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:c,registry:g,event:n}),n.type!==`step.started`&&await dispatchDynamicModelEvent({ctx:c,dynamicModel:u.turnAgent.dynamicModel,event:n,fallback:u.turnAgent.model,messages:t??[],scope:{moduleMap:u.moduleMap,nodeId:u.nodeId}}),await dispatchDynamicToolEvent({ctx:c,resolvers:y,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:c,resolvers:v,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:c,resolvers:_,event:n,messages:t??[]})},w=c.require(ModeKey),T;try{throwIfTurnAborted(o.abortSignal),T=await runStep(c,p,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:u.turnAgent.outputSchema,input:h,mode:w,session:e});if(f){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of f)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=c.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:u.turnAgent});return createExecutionNodeStep({abortSignal:o.abortSignal,capabilities:n,createRuntime:createWorkflowRuntime,handleEvent,mode:w,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:u.graph.root,workflowMaxSubagents:r.workflowMaxSubagents})(r,t)})(t,h)})}catch(e){if(!isTurnCancellation(e))throw e;return C.releaseLock(),{action:`cancelled`,serializedContext:preserveSerializedAgentTraceState(o.serializedContext,serializeContext(c)),sessionState:o.sessionState}}let E=reconcileSessionContinuationToken(c,T.session),D=serializeContext(c);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next){await C.close();let e=getTurnUsageState(T.session.state)?.session;return{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O,usage:e===void 0?void 0:toUsage(e)}}if(T.next===null){C.releaseLock();let e=getPendingWorkflowInterrupt(T.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return C.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return n.parentAction??{kind:`continue`,remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflowReference,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,resolveEffectiveOutputSchema,routeProxiedDeliverStep,turnStep};
|