experimental-ash 0.22.2 → 0.24.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 +36 -0
- package/dist/docs/internals/hooks.md +13 -16
- package/dist/docs/internals/message-runtime.md +1 -1
- package/dist/docs/public/auth-and-route-protection.md +3 -3
- package/dist/docs/public/faqs.md +67 -0
- package/dist/docs/public/meta.json +1 -0
- package/dist/docs/public/schedules.md +11 -0
- package/dist/docs/public/session-context.md +46 -89
- package/dist/docs/public/skills.md +13 -0
- package/dist/docs/public/subagents.md +12 -6
- package/dist/docs/public/tools.md +9 -13
- package/dist/docs/public/typescript-api.md +4 -4
- package/dist/src/channel/types.d.ts +10 -12
- package/dist/src/chunks/{client-CKsU8Li3.js → client-nshDsWNF.js} +1 -1
- package/dist/src/chunks/{dev-authored-source-watcher-BLzYWh05.js → dev-authored-source-watcher-B4PaZGUr.js} +1 -1
- package/dist/src/chunks/host-DsW72Q-w.js +65 -0
- package/dist/src/chunks/paths-OknjaYR8.js +89 -0
- package/dist/src/chunks/prewarm-B4YblQ5m.js +6 -0
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/dev/repl.js +2 -2
- package/dist/src/cli/run.js +1 -1
- package/dist/src/client/session.js +8 -0
- package/dist/src/client/types.d.ts +12 -1
- package/dist/src/compiled/.vendor-stamp.json +3 -3
- package/dist/src/compiled/@workflow/core/_ms.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/_workflow-serde.d.ts +5 -0
- package/dist/src/compiled/@workflow/core/_workflow-utils.d.ts +8 -0
- package/dist/src/compiled/@workflow/core/_workflow-world.d.ts +59 -0
- package/dist/src/compiled/@workflow/core/capabilities.d.ts +45 -0
- package/dist/src/compiled/@workflow/core/capture-stack.d.ts +16 -0
- package/dist/src/compiled/@workflow/core/class-serialization.d.ts +31 -0
- package/dist/src/compiled/@workflow/core/classify-error.d.ts +20 -0
- package/dist/src/compiled/@workflow/core/context-errors.d.ts +27 -0
- package/dist/src/compiled/@workflow/core/context-violation-error.d.ts +97 -0
- package/dist/src/compiled/@workflow/core/create-hook.d.ts +179 -0
- package/dist/src/compiled/@workflow/core/define-hook.d.ts +68 -0
- package/dist/src/compiled/@workflow/core/describe-error.d.ts +70 -0
- package/dist/src/compiled/@workflow/core/encryption.d.ts +51 -0
- package/dist/src/compiled/@workflow/core/events-consumer.d.ts +64 -0
- package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +82 -0
- package/dist/src/compiled/@workflow/core/global.d.ts +48 -0
- package/dist/src/compiled/@workflow/core/index.d.ts +19 -38
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/log-format.d.ts +25 -0
- package/dist/src/compiled/@workflow/core/logger.d.ts +29 -0
- package/dist/src/compiled/@workflow/core/package.json +1 -1
- package/dist/src/compiled/@workflow/core/private.d.ts +59 -10
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +51 -0
- package/dist/src/compiled/@workflow/core/runtime/get-port-lazy.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/runtime/get-world-lazy.d.ts +32 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +97 -0
- package/dist/src/compiled/@workflow/core/runtime/replay-budget.d.ts +98 -0
- package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +77 -0
- package/dist/src/compiled/@workflow/core/runtime/run.d.ts +134 -0
- package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +50 -0
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +59 -0
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +40 -0
- package/dist/src/compiled/@workflow/core/runtime/step-handler.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +42 -0
- package/dist/src/compiled/@workflow/core/runtime/world-init.d.ts +75 -0
- package/dist/src/compiled/@workflow/core/runtime/world.d.ts +32 -0
- package/dist/src/compiled/@workflow/core/runtime.d.ts +22 -67
- package/dist/src/compiled/@workflow/core/runtime.js +27 -27
- package/dist/src/compiled/@workflow/core/schemas.d.ts +15 -0
- package/dist/src/compiled/@workflow/core/serialization/client.d.ts +17 -0
- package/dist/src/compiled/@workflow/core/serialization/codec-devalue.d.ts +14 -0
- package/dist/src/compiled/@workflow/core/serialization/codec.d.ts +90 -0
- package/dist/src/compiled/@workflow/core/serialization/encryption.d.ts +32 -0
- package/dist/src/compiled/@workflow/core/serialization/errors.d.ts +21 -0
- package/dist/src/compiled/@workflow/core/serialization/format.d.ts +60 -0
- package/dist/src/compiled/@workflow/core/serialization/index.d.ts +18 -0
- package/dist/src/compiled/@workflow/core/serialization/reducers/class.d.ts +11 -0
- package/dist/src/compiled/@workflow/core/serialization/reducers/common.d.ts +16 -0
- package/dist/src/compiled/@workflow/core/serialization/reducers/step-function.d.ts +35 -0
- package/dist/src/compiled/@workflow/core/serialization/step.d.ts +17 -0
- package/dist/src/compiled/@workflow/core/serialization/types.d.ts +215 -0
- package/dist/src/compiled/@workflow/core/serialization/workflow.d.ts +29 -0
- package/dist/src/compiled/@workflow/core/serialization-format.d.ts +171 -0
- package/dist/src/compiled/@workflow/core/serialization.d.ts +337 -0
- package/dist/src/compiled/@workflow/core/sleep.d.ts +33 -0
- package/dist/src/compiled/@workflow/core/source-map.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +13 -0
- package/dist/src/compiled/@workflow/core/step/get-closure-vars.d.ts +9 -0
- package/dist/src/compiled/@workflow/core/step/get-step-metadata.d.ts +42 -0
- package/dist/src/compiled/@workflow/core/step/get-workflow-metadata.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/step/writable-stream.d.ts +22 -0
- package/dist/src/compiled/@workflow/core/step.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/symbols.d.ts +36 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +283 -0
- package/dist/src/compiled/@workflow/core/telemetry.d.ts +53 -0
- package/dist/src/compiled/@workflow/core/types.d.ts +14 -0
- package/dist/src/compiled/@workflow/core/util.d.ts +40 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/vm/index.d.ts +17 -0
- package/dist/src/compiled/@workflow/core/vm/uint8array-base64.d.ts +21 -0
- package/dist/src/compiled/@workflow/core/vm/uuid.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/workflow/abort-controller.d.ts +65 -0
- package/dist/src/compiled/@workflow/core/workflow/create-hook.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/workflow/define-hook.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/workflow/get-workflow-metadata.d.ts +32 -0
- package/dist/src/compiled/@workflow/core/workflow/hook.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/workflow/index.d.ts +11 -0
- package/dist/src/compiled/@workflow/core/workflow/sleep.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/workflow/world-init-stub.d.ts +15 -0
- package/dist/src/compiled/@workflow/core/workflow/writable-stream.d.ts +3 -0
- package/dist/src/compiled/@workflow/core/workflow.d.ts +1 -38
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/error-codes.d.ts +5 -1
- package/dist/src/compiled/@workflow/errors/index.d.ts +15 -1
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/@workflow/errors/package.json +1 -1
- package/dist/src/compiled/_chunks/workflow/{context-errors-zbKocOyk.js → context-errors-Bbvvp-li.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/{dist-0iNBqPYp.js → dist-C7wPwOI9.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/{dist-D774SUM4.js → dist-C_oiE-l7.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +12 -0
- package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{symbols-D-4tVV8x.js → symbols-QezhMuLg.js} +1 -1
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/execution/await-authorization-orchestrator.d.ts +2 -1
- package/dist/src/execution/await-authorization-orchestrator.js +4 -0
- package/dist/src/execution/connection-auth-steps.d.ts +4 -0
- package/dist/src/execution/connection-auth-steps.js +9 -11
- package/dist/src/execution/node-step.d.ts +4 -5
- package/dist/src/execution/subagent-adapter.d.ts +0 -27
- package/dist/src/execution/subagent-adapter.js +2 -66
- package/dist/src/execution/subagent-hitl-proxy.d.ts +2 -2
- package/dist/src/execution/subagent-hitl-proxy.js +2 -2
- package/dist/src/execution/task-mode.d.ts +3 -3
- package/dist/src/execution/task-mode.js +3 -3
- package/dist/src/execution/turn-workflow.d.ts +41 -0
- package/dist/src/execution/turn-workflow.js +96 -0
- package/dist/src/execution/workflow-entry.js +77 -87
- package/dist/src/execution/workflow-errors.d.ts +14 -0
- package/dist/src/execution/workflow-errors.js +54 -0
- package/dist/src/execution/workflow-runtime.d.ts +34 -3
- package/dist/src/execution/workflow-runtime.js +52 -10
- package/dist/src/execution/workflow-steps.d.ts +27 -2
- package/dist/src/execution/workflow-steps.js +31 -26
- package/dist/src/harness/instrumentation-config.js +14 -7
- package/dist/src/harness/messages.d.ts +7 -7
- package/dist/src/harness/messages.js +4 -4
- package/dist/src/harness/runtime-actions.d.ts +4 -4
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.js +20 -8
- package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +13 -0
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +10 -4
- package/dist/src/protocol/message.d.ts +6 -1
- package/dist/src/public/channels/ash.js +50 -3
- package/dist/src/public/context/index.d.ts +4 -7
- package/dist/src/public/context/index.js +4 -5
- package/dist/src/public/definitions/state.d.ts +33 -0
- package/dist/src/public/definitions/state.js +34 -0
- package/dist/src/public/next/index.d.ts +7 -0
- package/dist/src/public/next/index.js +2 -0
- package/dist/src/public/next/vercel-json.d.ts +1 -0
- package/dist/src/public/next/vercel-json.js +1 -0
- package/dist/src/react/index.d.ts +1 -1
- package/dist/src/react/use-ash-agent.d.ts +8 -0
- package/dist/src/react/use-ash-agent.js +26 -4
- package/dist/src/services/dev-client.d.ts +4 -1
- package/dist/src/services/dev-client.js +1 -0
- package/package.json +4 -4
- package/dist/src/chunks/host-DREC8e8Z.js +0 -65
- package/dist/src/chunks/paths-C6sp4T2U.js +0 -88
- package/dist/src/chunks/prewarm-hz8p2jlZ.js +0 -6
- package/dist/src/compiled/_chunks/workflow/resume-hook-CL8Ed91K.js +0 -12
- package/dist/src/compiled/_chunks/workflow/sleep-Dn3i9nxI.js +0 -1
- package/dist/src/execution/continuous-entry.d.ts +0 -59
- package/dist/src/execution/continuous-entry.js +0 -487
- package/dist/src/execution/continuous-runtime.d.ts +0 -17
- package/dist/src/execution/continuous-runtime.js +0 -123
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
import { buildAdapterContext } from "#channel/adapter-context.js";
|
|
2
|
-
import { defaultDeliverResult } from "#channel/adapter.js";
|
|
3
|
-
import { toContextAccessor } from "#context/container.js";
|
|
4
|
-
import { runHookLifecycleStep } from "#context/hook-lifecycle.js";
|
|
5
|
-
import { AuthKey, BundleKey, CapabilitiesKey, ChannelKey, ContinuationTokenKey, InitiatorAuthKey, ModeKey, SessionIdKey, } from "#context/keys.js";
|
|
6
|
-
import { runStep } from "#context/run-step.js";
|
|
7
|
-
import { getHarnessEmissionState, isHarnessBetweenTurns } from "#harness/emission.js";
|
|
8
|
-
import { hasPendingInputBatch } from "#harness/input-requests.js";
|
|
9
|
-
import { coalesceDeliveries, coalesceTurnInputs } from "#harness/messages.js";
|
|
10
|
-
import { hasProxyInputRequests, upsertProxyInputRequests } from "#harness/proxy-input-requests.js";
|
|
11
|
-
import { accumulateRuntimeActionResults, getPendingRuntimeActionBatch, hasPendingRuntimeActionBatch, recordPendingSubagentChildToken, } from "#harness/runtime-actions.js";
|
|
12
|
-
import { createErrorId, createLogger } from "#internal/logging.js";
|
|
13
|
-
import { createSubagentCalledEvent } from "#protocol/message.js";
|
|
14
|
-
import { drainPendingConnectionAuthorizations } from "#runtime/framework-tools/connection-search.js";
|
|
15
|
-
import { toErrorMessage } from "#shared/errors.js";
|
|
16
|
-
import { isRuntimeNoActiveSessionError } from "#execution/runtime-errors.js";
|
|
17
|
-
import { registerContinuousSubagentInputRequestDispatcher, unregisterContinuousSubagentInputRequestDispatcher, } from "#execution/subagent-adapter.js";
|
|
18
|
-
import { createExecutionNodeStep } from "#execution/node-step.js";
|
|
19
|
-
import { emitProxiedInputRequest, routeDeliverPayload } from "#execution/subagent-hitl-proxy.js";
|
|
20
|
-
import { createSession } from "#execution/session.js";
|
|
21
|
-
import { buildSubagentRunInput } from "#execution/subagent-tool.js";
|
|
22
|
-
import { createTaskModeWaitError } from "#execution/task-mode.js";
|
|
23
|
-
const log = createLogger("execution.continuous-entry");
|
|
24
|
-
/**
|
|
25
|
-
* Main body of a continuous (in-memory) run.
|
|
26
|
-
*/
|
|
27
|
-
export async function continuousEntry(input) {
|
|
28
|
-
const { createRuntime, ctx, emit, input: entryInput, park, queue, wake } = input;
|
|
29
|
-
const bundle = ctx.require(BundleKey);
|
|
30
|
-
const capabilities = ctx.get(CapabilitiesKey);
|
|
31
|
-
const mode = ctx.require(ModeKey);
|
|
32
|
-
const session = createSession({
|
|
33
|
-
compactionOverrides: {
|
|
34
|
-
thresholdPercent: bundle.resolvedAgent.config.compaction?.thresholdPercent,
|
|
35
|
-
},
|
|
36
|
-
continuationToken: ctx.require(ContinuationTokenKey),
|
|
37
|
-
sessionId: ctx.require(SessionIdKey),
|
|
38
|
-
turnAgent: bundle.turnAgent,
|
|
39
|
-
});
|
|
40
|
-
const rawStep = createExecutionNodeStep({
|
|
41
|
-
capabilities,
|
|
42
|
-
compiledArtifactsSource: bundle.compiledArtifactsSource,
|
|
43
|
-
createRuntime,
|
|
44
|
-
emit,
|
|
45
|
-
mode,
|
|
46
|
-
node: bundle.graph.root,
|
|
47
|
-
});
|
|
48
|
-
// Every step in the continuous runtime runs inside `runStep(ctx, ...)`.
|
|
49
|
-
// After each step returns we drain any `connection.authorization_required`
|
|
50
|
-
// events that tools flagged during the step so the channel sees them
|
|
51
|
-
// while the scope is still active. Keeping this here (and not in the
|
|
52
|
-
// harness) preserves the channel-harness-runtime split.
|
|
53
|
-
const runScopedStep = async (stepSession, body) => {
|
|
54
|
-
return runStep(ctx, stepSession, async (enrichedSession) => {
|
|
55
|
-
const result = await body(enrichedSession);
|
|
56
|
-
await drainPendingConnectionAuthorizations({
|
|
57
|
-
ctx,
|
|
58
|
-
emit,
|
|
59
|
-
state: getHarnessEmissionState(result.session),
|
|
60
|
-
});
|
|
61
|
-
return result;
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
const deliverStep = (item) => {
|
|
65
|
-
return async (stepSession, _stepInput) => {
|
|
66
|
-
ctx.clearVirtualContext();
|
|
67
|
-
if (item.auth !== undefined) {
|
|
68
|
-
ctx.set(AuthKey, item.auth ?? null);
|
|
69
|
-
}
|
|
70
|
-
// Split the payload into parent-local and proxied-child buckets
|
|
71
|
-
// before handing any of it to the parent's own adapter. Each
|
|
72
|
-
// proxied bucket is pushed onto the target child's queue and
|
|
73
|
-
// wakes the child runtime; the parent processes only the
|
|
74
|
-
// residual payload (if any).
|
|
75
|
-
const routed = await routeDeliverQueueItem(stepSession, item);
|
|
76
|
-
if (routed === undefined) {
|
|
77
|
-
return { next: null, session: stepSession };
|
|
78
|
-
}
|
|
79
|
-
const remainders = routed.payloads;
|
|
80
|
-
// Re-read adapter from context each delivery so state mutations
|
|
81
|
-
// from previous deliveries are visible.
|
|
82
|
-
const adapter = ctx.require(ChannelKey);
|
|
83
|
-
const adapterCtx = buildAdapterContext(adapter, toContextAccessor(ctx));
|
|
84
|
-
const results = [];
|
|
85
|
-
for (const payload of remainders) {
|
|
86
|
-
const result = adapter.deliver
|
|
87
|
-
? await adapter.deliver(payload, adapterCtx)
|
|
88
|
-
: defaultDeliverResult(payload);
|
|
89
|
-
if (result !== undefined && result !== null) {
|
|
90
|
-
results.push(result);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Update adapter state after deliver mutations.
|
|
94
|
-
const updatedAdapter = { ...adapter, state: { ...adapterCtx.state } };
|
|
95
|
-
ctx.set(ChannelKey, updatedAdapter);
|
|
96
|
-
// Adapter handled all deliveries inline — re-park without a model turn.
|
|
97
|
-
if (results.length === 0) {
|
|
98
|
-
return { next: null, session: stepSession };
|
|
99
|
-
}
|
|
100
|
-
const resolved = results.reduce(coalesceTurnInputs);
|
|
101
|
-
return await runScopedStep(stepSession, (enrichedSession) => {
|
|
102
|
-
// Gate lifecycle dispatch on the harness being between turns —
|
|
103
|
-
// same contract as the workflow runtime. A fresh delivery is
|
|
104
|
-
// the start of a new turn; a deliver carrying HITL
|
|
105
|
-
// `inputResponses` while the harness still owns a turn is a
|
|
106
|
-
// continuation of that turn, and lifecycle hooks must not
|
|
107
|
-
// re-fire.
|
|
108
|
-
if (isHarnessBetweenTurns(enrichedSession)) {
|
|
109
|
-
return runHookLifecycleStep({
|
|
110
|
-
ctx,
|
|
111
|
-
emit,
|
|
112
|
-
input: resolved,
|
|
113
|
-
mode,
|
|
114
|
-
registry: bundle.hookRegistry,
|
|
115
|
-
session: enrichedSession,
|
|
116
|
-
}, rawStep);
|
|
117
|
-
}
|
|
118
|
-
return rawStep(enrichedSession, resolved);
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
const subagentInputRequestStep = async (sessionIn, item) => {
|
|
123
|
-
ctx.clearVirtualContext();
|
|
124
|
-
// `emitProxiedInputRequest` fires the `input.requested` event
|
|
125
|
-
// through the parent's adapter (the outer-scope `emit` applies the
|
|
126
|
-
// transform) and, when the parent is in conversation mode, follows
|
|
127
|
-
// it with a `turn.completed` + `session.waiting` pair so HTTP /
|
|
128
|
-
// REPL clients can stop draining the stream and prompt the user
|
|
129
|
-
// for HITL input. The parent session's emission state advances
|
|
130
|
-
// through the pseudo-turn and is returned on `result.session`.
|
|
131
|
-
const result = await emitProxiedInputRequest({
|
|
132
|
-
emit,
|
|
133
|
-
hookPayload: {
|
|
134
|
-
callId: item.callId,
|
|
135
|
-
childContinuationToken: item.childContinuationToken,
|
|
136
|
-
childSessionId: item.childSessionId,
|
|
137
|
-
event: item.event,
|
|
138
|
-
kind: "subagent-input-request",
|
|
139
|
-
subagentName: item.subagentName,
|
|
140
|
-
},
|
|
141
|
-
mode,
|
|
142
|
-
session: sessionIn,
|
|
143
|
-
});
|
|
144
|
-
return upsertProxyInputRequests({
|
|
145
|
-
entries: result.entries,
|
|
146
|
-
forChildContinuationToken: item.childContinuationToken,
|
|
147
|
-
session: result.session,
|
|
148
|
-
});
|
|
149
|
-
};
|
|
150
|
-
const runtimeActionResultStep = (item) => {
|
|
151
|
-
return async (stepSession, _stepInput) => await runScopedStep(stepSession, (enrichedSession) => rawStep(enrichedSession, {
|
|
152
|
-
runtimeActionResults: item.results,
|
|
153
|
-
}));
|
|
154
|
-
};
|
|
155
|
-
/**
|
|
156
|
-
* Routes one inbound deliver queue item to any descendant subagents
|
|
157
|
-
* whose proxied HITL requests match the payload's `inputResponses`.
|
|
158
|
-
* Returns the parent-local remainder (`undefined` means the whole
|
|
159
|
-
* item was routed away). Short-circuits when the session has no
|
|
160
|
-
* proxy entries so the common path skips the routing loop entirely.
|
|
161
|
-
*/
|
|
162
|
-
const routeDeliverQueueItem = async (sessionIn, item) => {
|
|
163
|
-
if (!hasProxyInputRequests(sessionIn)) {
|
|
164
|
-
return item;
|
|
165
|
-
}
|
|
166
|
-
const remainders = await routeProxiedDeliverPayloads({
|
|
167
|
-
auth: item.auth,
|
|
168
|
-
createRuntime,
|
|
169
|
-
ctx,
|
|
170
|
-
payloads: item.payloads,
|
|
171
|
-
session: sessionIn,
|
|
172
|
-
});
|
|
173
|
-
if (remainders.length === 0) {
|
|
174
|
-
return undefined;
|
|
175
|
-
}
|
|
176
|
-
return { ...item, payloads: remainders };
|
|
177
|
-
};
|
|
178
|
-
const wrapContinuation = (innerStep) => {
|
|
179
|
-
return async (stepSession, stepInput) => await runScopedStep(stepSession, (enrichedSession) => innerStep(enrichedSession, stepInput));
|
|
180
|
-
};
|
|
181
|
-
let currentStep = deliverStep({
|
|
182
|
-
kind: "deliver",
|
|
183
|
-
payloads: [{ message: entryInput.message }],
|
|
184
|
-
});
|
|
185
|
-
let currentSession = session;
|
|
186
|
-
const bufferedDeliveries = [];
|
|
187
|
-
while (true) {
|
|
188
|
-
const stepResult = await currentStep(currentSession, undefined);
|
|
189
|
-
currentSession = stepResult.session;
|
|
190
|
-
if (stepResult.next !== null &&
|
|
191
|
-
typeof stepResult.next === "object" &&
|
|
192
|
-
"done" in stepResult.next) {
|
|
193
|
-
return { output: stepResult.next.output, status: "completed" };
|
|
194
|
-
}
|
|
195
|
-
if (stepResult.next === null) {
|
|
196
|
-
if (hasPendingRuntimeActionBatch(currentSession)) {
|
|
197
|
-
currentSession = dispatchPendingRuntimeActions({
|
|
198
|
-
createRuntime,
|
|
199
|
-
ctx,
|
|
200
|
-
emit,
|
|
201
|
-
queue,
|
|
202
|
-
session: currentSession,
|
|
203
|
-
wake,
|
|
204
|
-
});
|
|
205
|
-
const waited = await waitForRuntimeActionResults({
|
|
206
|
-
bufferedDeliveries,
|
|
207
|
-
park,
|
|
208
|
-
proxyInputRequestStep: subagentInputRequestStep,
|
|
209
|
-
queue,
|
|
210
|
-
routeDeliver: routeDeliverQueueItem,
|
|
211
|
-
session: currentSession,
|
|
212
|
-
});
|
|
213
|
-
currentSession = waited.session;
|
|
214
|
-
currentStep = runtimeActionResultStep(waited.result);
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
// Task-mode HITL park is allowed when the session has HITL
|
|
218
|
-
// capabilities — the proxy bridge will forward the request up
|
|
219
|
-
// to a capable ancestor. Conversation mode always allows a park
|
|
220
|
-
// for the next user message.
|
|
221
|
-
if (capabilities?.requestInput === true && hasPendingInputBatch(currentSession)) {
|
|
222
|
-
const waited = await waitForDeliverQueueItem({
|
|
223
|
-
bufferedDeliveries,
|
|
224
|
-
park,
|
|
225
|
-
proxyInputRequestStep: subagentInputRequestStep,
|
|
226
|
-
queue,
|
|
227
|
-
session: currentSession,
|
|
228
|
-
});
|
|
229
|
-
currentSession = waited.session;
|
|
230
|
-
currentStep = deliverStep(waited.item);
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
if (mode === "task") {
|
|
234
|
-
throw createTaskModeWaitError();
|
|
235
|
-
}
|
|
236
|
-
const waited = await waitForDeliverQueueItem({
|
|
237
|
-
bufferedDeliveries,
|
|
238
|
-
park,
|
|
239
|
-
proxyInputRequestStep: subagentInputRequestStep,
|
|
240
|
-
queue,
|
|
241
|
-
session: currentSession,
|
|
242
|
-
});
|
|
243
|
-
currentSession = waited.session;
|
|
244
|
-
currentStep = deliverStep(waited.item);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
currentStep = wrapContinuation(stepResult.next);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
async function routeProxiedDeliverPayloads(input) {
|
|
251
|
-
const remainders = [];
|
|
252
|
-
const compiledArtifactsSource = input.ctx.require(BundleKey).compiledArtifactsSource;
|
|
253
|
-
for (const payload of input.payloads) {
|
|
254
|
-
const routed = routeDeliverPayload({ payload, session: input.session });
|
|
255
|
-
for (const forChild of routed.forChildren) {
|
|
256
|
-
// The child runtime owns its own queue. Reach it through the
|
|
257
|
-
// shared `createRuntime` closure — the continuous runtime's
|
|
258
|
-
// `deliver` implementation looks up the queue by continuation
|
|
259
|
-
// token and wakes the parked child.
|
|
260
|
-
const childRuntime = input.createRuntime({ compiledArtifactsSource });
|
|
261
|
-
try {
|
|
262
|
-
await childRuntime.deliver({
|
|
263
|
-
auth: input.auth ?? null,
|
|
264
|
-
continuationToken: forChild.childContinuationToken,
|
|
265
|
-
payload: forChild.payload,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
catch (error) {
|
|
269
|
-
// The child session may have already completed or failed
|
|
270
|
-
// between the HITL emission and the user's response. Treat
|
|
271
|
-
// the deliver as a no-op — the response effectively falls
|
|
272
|
-
// through to the parent as stale input.
|
|
273
|
-
if (!isRuntimeNoActiveSessionError(error)) {
|
|
274
|
-
throw error;
|
|
275
|
-
}
|
|
276
|
-
// Breadcrumb the drop so an operator chasing a "user
|
|
277
|
-
// clicked approve and nothing happened" report can correlate
|
|
278
|
-
// the request ids to the child session that had already
|
|
279
|
-
// completed. Warn-level because the condition is expected
|
|
280
|
-
// (races between child completion and parent delivery) but
|
|
281
|
-
// worth surfacing.
|
|
282
|
-
log.warn("dropped stale HITL response for completed subagent", {
|
|
283
|
-
childContinuationToken: forChild.childContinuationToken,
|
|
284
|
-
errorId: createErrorId(),
|
|
285
|
-
requestIds: forChild.payload.inputResponses.map((response) => response.requestId),
|
|
286
|
-
sessionId: input.session.sessionId,
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
if (routed.forSelf !== undefined) {
|
|
291
|
-
remainders.push(routed.forSelf);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
return remainders;
|
|
295
|
-
}
|
|
296
|
-
function dispatchPendingRuntimeActions(input) {
|
|
297
|
-
const batch = getPendingRuntimeActionBatch(input.session);
|
|
298
|
-
if (batch === undefined) {
|
|
299
|
-
return input.session;
|
|
300
|
-
}
|
|
301
|
-
const bundle = input.ctx.require(BundleKey);
|
|
302
|
-
const auth = input.ctx.get(AuthKey) ?? null;
|
|
303
|
-
const capabilities = input.ctx.get(CapabilitiesKey);
|
|
304
|
-
const initiatorAuth = input.ctx.get(InitiatorAuthKey) ?? null;
|
|
305
|
-
let nextSession = input.session;
|
|
306
|
-
for (const action of batch.actions) {
|
|
307
|
-
if (action.kind !== "subagent-call") {
|
|
308
|
-
throw new Error(`Unsupported runtime action kind "${action.kind}" in continuous runtime.`);
|
|
309
|
-
}
|
|
310
|
-
const childRuntime = input.createRuntime({
|
|
311
|
-
compiledArtifactsSource: bundle.compiledArtifactsSource,
|
|
312
|
-
nodeId: action.nodeId,
|
|
313
|
-
});
|
|
314
|
-
const { childContinuationToken, runInput } = buildSubagentRunInput({
|
|
315
|
-
action,
|
|
316
|
-
auth,
|
|
317
|
-
batchEvent: batch.event,
|
|
318
|
-
capabilities,
|
|
319
|
-
initiatorAuth,
|
|
320
|
-
session: input.session,
|
|
321
|
-
});
|
|
322
|
-
nextSession = recordPendingSubagentChildToken({
|
|
323
|
-
callId: action.callId,
|
|
324
|
-
childContinuationToken,
|
|
325
|
-
session: nextSession,
|
|
326
|
-
});
|
|
327
|
-
// Register the continuous-runtime dispatcher for this child so
|
|
328
|
-
// its subagent-adapter `input.requested` handler can forward
|
|
329
|
-
// HITL requests to this parent's queue without going through
|
|
330
|
-
// the workflow `resumeHook` path.
|
|
331
|
-
registerContinuousSubagentInputRequestDispatcher({
|
|
332
|
-
childContinuationToken,
|
|
333
|
-
dispatcher: (payload) => {
|
|
334
|
-
input.queue.push(payload);
|
|
335
|
-
input.wake();
|
|
336
|
-
},
|
|
337
|
-
});
|
|
338
|
-
void childRuntime
|
|
339
|
-
.run(runInput)
|
|
340
|
-
.then(async (handle) => {
|
|
341
|
-
await input.emit(createSubagentCalledEvent({
|
|
342
|
-
callId: action.callId,
|
|
343
|
-
childSessionId: handle.sessionId,
|
|
344
|
-
name: action.name,
|
|
345
|
-
sequence: batch.event.sequence,
|
|
346
|
-
sessionId: input.session.sessionId,
|
|
347
|
-
toolName: action.subagentName,
|
|
348
|
-
turnId: batch.event.turnId,
|
|
349
|
-
workflowId: "continuous://subagent",
|
|
350
|
-
}));
|
|
351
|
-
const result = await handle.result;
|
|
352
|
-
if (result.status !== "completed") {
|
|
353
|
-
throw new Error(`Subagent "${action.subagentName}" did not complete (status: ${result.status}).`);
|
|
354
|
-
}
|
|
355
|
-
return result.output;
|
|
356
|
-
})
|
|
357
|
-
.then((output) => {
|
|
358
|
-
input.queue.push({
|
|
359
|
-
kind: "runtime-action-result",
|
|
360
|
-
results: [
|
|
361
|
-
{
|
|
362
|
-
callId: action.callId,
|
|
363
|
-
kind: "subagent-result",
|
|
364
|
-
output,
|
|
365
|
-
subagentName: action.subagentName,
|
|
366
|
-
},
|
|
367
|
-
],
|
|
368
|
-
});
|
|
369
|
-
input.wake();
|
|
370
|
-
}, (error) => {
|
|
371
|
-
// Surface the failure through the shared structured-log path
|
|
372
|
-
// (`log.error` records on the active OTel span and walks
|
|
373
|
-
// the `error` cause chain via `formatError`) before
|
|
374
|
-
// enqueueing the result. Without this log the
|
|
375
|
-
// fire-and-forget rejection branch silently stuffed a
|
|
376
|
-
// generic "SUBAGENT_EXECUTION_FAILED" message into the queue
|
|
377
|
-
// with no operator-visible breadcrumb.
|
|
378
|
-
const errorId = createErrorId();
|
|
379
|
-
log.error("subagent child run failed", {
|
|
380
|
-
callId: action.callId,
|
|
381
|
-
childContinuationToken,
|
|
382
|
-
errorId,
|
|
383
|
-
sessionId: input.session.sessionId,
|
|
384
|
-
subagentName: action.subagentName,
|
|
385
|
-
error,
|
|
386
|
-
});
|
|
387
|
-
input.queue.push({
|
|
388
|
-
kind: "runtime-action-result",
|
|
389
|
-
results: [
|
|
390
|
-
{
|
|
391
|
-
callId: action.callId,
|
|
392
|
-
isError: true,
|
|
393
|
-
kind: "subagent-result",
|
|
394
|
-
output: {
|
|
395
|
-
code: "SUBAGENT_EXECUTION_FAILED",
|
|
396
|
-
message: toErrorMessage(error),
|
|
397
|
-
},
|
|
398
|
-
subagentName: action.subagentName,
|
|
399
|
-
},
|
|
400
|
-
],
|
|
401
|
-
});
|
|
402
|
-
input.wake();
|
|
403
|
-
})
|
|
404
|
-
.finally(() => {
|
|
405
|
-
unregisterContinuousSubagentInputRequestDispatcher(childContinuationToken);
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
return nextSession;
|
|
409
|
-
}
|
|
410
|
-
async function waitForRuntimeActionResults(input) {
|
|
411
|
-
let currentSession = input.session;
|
|
412
|
-
const results = await accumulateRuntimeActionResults({
|
|
413
|
-
bufferedDeliveries: input.bufferedDeliveries,
|
|
414
|
-
async getNext() {
|
|
415
|
-
while (true) {
|
|
416
|
-
const item = await takeNextQueueItem(input.queue, input.park);
|
|
417
|
-
if (item.kind === "deliver") {
|
|
418
|
-
// Inbound deliveries mid-wait may carry `inputResponses`
|
|
419
|
-
// bound to a descendant's pending HITL batch. Route them
|
|
420
|
-
// down **before** buffering — otherwise the response would
|
|
421
|
-
// sit in `bufferedDeliveries` until the child completes,
|
|
422
|
-
// which it can never do without the response. That
|
|
423
|
-
// asymmetry is the parent↔child deadlock this branch
|
|
424
|
-
// exists to prevent.
|
|
425
|
-
const remainder = await input.routeDeliver(currentSession, item);
|
|
426
|
-
if (remainder === undefined) {
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
return { kind: "deliver", value: remainder };
|
|
430
|
-
}
|
|
431
|
-
if (item.kind === "runtime-action-result") {
|
|
432
|
-
return { kind: "runtime-action-result", results: item.results };
|
|
433
|
-
}
|
|
434
|
-
// subagent-input-request: proxy the child's HITL up through
|
|
435
|
-
// the parent's adapter and keep waiting.
|
|
436
|
-
currentSession = await input.proxyInputRequestStep(currentSession, item);
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
session: currentSession,
|
|
440
|
-
});
|
|
441
|
-
return {
|
|
442
|
-
result: {
|
|
443
|
-
kind: "runtime-action-result",
|
|
444
|
-
results: (results ?? []),
|
|
445
|
-
},
|
|
446
|
-
session: currentSession,
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
async function waitForDeliverQueueItem(input) {
|
|
450
|
-
let currentSession = input.session;
|
|
451
|
-
if (input.bufferedDeliveries.length > 0) {
|
|
452
|
-
return {
|
|
453
|
-
item: coalesceDeliveries(input.bufferedDeliveries.splice(0)),
|
|
454
|
-
session: currentSession,
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
while (true) {
|
|
458
|
-
const first = await takeNextQueueItem(input.queue, input.park);
|
|
459
|
-
if (first.kind === "subagent-input-request") {
|
|
460
|
-
currentSession = await input.proxyInputRequestStep(currentSession, first);
|
|
461
|
-
continue;
|
|
462
|
-
}
|
|
463
|
-
if (first.kind !== "deliver") {
|
|
464
|
-
continue;
|
|
465
|
-
}
|
|
466
|
-
const deliveries = [first];
|
|
467
|
-
await Promise.resolve();
|
|
468
|
-
while (input.queue[0]?.kind === "deliver") {
|
|
469
|
-
deliveries.push(input.queue.shift());
|
|
470
|
-
}
|
|
471
|
-
return {
|
|
472
|
-
item: coalesceDeliveries(deliveries),
|
|
473
|
-
session: currentSession,
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
async function takeNextQueueItem(queue, park) {
|
|
478
|
-
while (queue.length === 0) {
|
|
479
|
-
await park();
|
|
480
|
-
await Promise.resolve();
|
|
481
|
-
}
|
|
482
|
-
const next = queue.shift();
|
|
483
|
-
if (next === undefined) {
|
|
484
|
-
throw new Error("Expected one queued runtime item.");
|
|
485
|
-
}
|
|
486
|
-
return next;
|
|
487
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Runtime } from "#channel/types.js";
|
|
2
|
-
import type { RuntimeCompiledArtifactsSource } from "#runtime/compiled-artifacts-source.js";
|
|
3
|
-
import type { CreateRuntime } from "#execution/node-step.js";
|
|
4
|
-
export { RuntimeNoActiveSessionError, isRuntimeNoActiveSessionError, } from "#execution/runtime-errors.js";
|
|
5
|
-
/**
|
|
6
|
-
* Creates a {@link CreateRuntime} factory for the continuous
|
|
7
|
-
* (non-durable) runtime.
|
|
8
|
-
*/
|
|
9
|
-
export declare function createContinuousLoopRuntimeFactory(): CreateRuntime;
|
|
10
|
-
/**
|
|
11
|
-
* Creates an in-memory runtime that provides the delivery shell for a
|
|
12
|
-
* continuous (non-durable) run.
|
|
13
|
-
*/
|
|
14
|
-
export declare function createContinuousLoopRuntime(config: {
|
|
15
|
-
readonly compiledArtifactsSource: RuntimeCompiledArtifactsSource;
|
|
16
|
-
readonly nodeId?: string;
|
|
17
|
-
}): Runtime;
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { buildAdapterContext } from "#channel/adapter-context.js";
|
|
2
|
-
import { callAdapterEventHandler } from "#channel/adapter.js";
|
|
3
|
-
import { toContextAccessor } from "#context/container.js";
|
|
4
|
-
import { dispatchStreamEventHooks } from "#context/hook-lifecycle.js";
|
|
5
|
-
import { BundleKey, ChannelKey, SessionIdKey } from "#context/keys.js";
|
|
6
|
-
import { getCompiledRuntimeAgentBundle } from "#runtime/sessions/compiled-agent-cache.js";
|
|
7
|
-
import { continuousEntry } from "#execution/continuous-entry.js";
|
|
8
|
-
import { buildRunContext } from "#execution/runtime-context.js";
|
|
9
|
-
import { RuntimeNoActiveSessionError } from "#execution/runtime-errors.js";
|
|
10
|
-
export { RuntimeNoActiveSessionError, isRuntimeNoActiveSessionError, } from "#execution/runtime-errors.js";
|
|
11
|
-
/**
|
|
12
|
-
* Creates a {@link CreateRuntime} factory for the continuous
|
|
13
|
-
* (non-durable) runtime.
|
|
14
|
-
*/
|
|
15
|
-
export function createContinuousLoopRuntimeFactory() {
|
|
16
|
-
const state = {
|
|
17
|
-
queues: new Map(),
|
|
18
|
-
parked: new Map(),
|
|
19
|
-
};
|
|
20
|
-
return function createRuntime(config) {
|
|
21
|
-
return buildContinuousRuntime({ config, createRuntime, state });
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Creates an in-memory runtime that provides the delivery shell for a
|
|
26
|
-
* continuous (non-durable) run.
|
|
27
|
-
*/
|
|
28
|
-
export function createContinuousLoopRuntime(config) {
|
|
29
|
-
const factory = createContinuousLoopRuntimeFactory();
|
|
30
|
-
return factory(config);
|
|
31
|
-
}
|
|
32
|
-
function buildContinuousRuntime(input) {
|
|
33
|
-
const { config, createRuntime, state } = input;
|
|
34
|
-
const { queues, parked } = state;
|
|
35
|
-
return {
|
|
36
|
-
async run(input) {
|
|
37
|
-
const bundle = await getCompiledRuntimeAgentBundle({
|
|
38
|
-
compiledArtifactsSource: config.compiledArtifactsSource,
|
|
39
|
-
nodeId: config.nodeId,
|
|
40
|
-
});
|
|
41
|
-
const sessionId = crypto.randomUUID();
|
|
42
|
-
const ctx = buildRunContext({ bundle, run: input });
|
|
43
|
-
ctx.set(SessionIdKey, sessionId);
|
|
44
|
-
const eventStream = new TransformStream(undefined, undefined, new CountQueuingStrategy({ highWaterMark: 1024 }));
|
|
45
|
-
const queue = [];
|
|
46
|
-
const effectiveToken = input.continuationToken ?? `continuous:${crypto.randomUUID()}`;
|
|
47
|
-
queues.set(effectiveToken, queue);
|
|
48
|
-
const result = (async () => {
|
|
49
|
-
const writer = eventStream.writable.getWriter();
|
|
50
|
-
const wake = () => {
|
|
51
|
-
const signal = parked.get(effectiveToken);
|
|
52
|
-
if (signal !== undefined) {
|
|
53
|
-
parked.delete(effectiveToken);
|
|
54
|
-
signal();
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
const adapter = ctx.require(ChannelKey);
|
|
58
|
-
const adapterCtx = buildAdapterContext(adapter, toContextAccessor(ctx));
|
|
59
|
-
const bundle = ctx.require(BundleKey);
|
|
60
|
-
const hookRegistry = bundle.hookRegistry;
|
|
61
|
-
const emit = async (event) => {
|
|
62
|
-
const toEmit = await callAdapterEventHandler(adapter, event, adapterCtx);
|
|
63
|
-
await writer.write(toEmit);
|
|
64
|
-
await dispatchStreamEventHooks({ ctx, registry: hookRegistry, event: toEmit });
|
|
65
|
-
};
|
|
66
|
-
try {
|
|
67
|
-
const entryResult = await continuousEntry({
|
|
68
|
-
createRuntime,
|
|
69
|
-
ctx,
|
|
70
|
-
emit,
|
|
71
|
-
input: input.input,
|
|
72
|
-
park: () => new Promise((resolve) => {
|
|
73
|
-
parked.set(effectiveToken, resolve);
|
|
74
|
-
}),
|
|
75
|
-
queue,
|
|
76
|
-
wake,
|
|
77
|
-
});
|
|
78
|
-
await writer.close();
|
|
79
|
-
return entryResult;
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
await writer.abort(error);
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
finally {
|
|
86
|
-
queues.delete(effectiveToken);
|
|
87
|
-
parked.delete(effectiveToken);
|
|
88
|
-
}
|
|
89
|
-
})();
|
|
90
|
-
return {
|
|
91
|
-
continuationToken: effectiveToken,
|
|
92
|
-
events: eventStream.readable,
|
|
93
|
-
result,
|
|
94
|
-
sessionId,
|
|
95
|
-
};
|
|
96
|
-
},
|
|
97
|
-
async deliver(input) {
|
|
98
|
-
const queue = queues.get(input.continuationToken);
|
|
99
|
-
if (queue === undefined) {
|
|
100
|
-
throw new RuntimeNoActiveSessionError(input.continuationToken);
|
|
101
|
-
}
|
|
102
|
-
queue.push({
|
|
103
|
-
auth: input.auth,
|
|
104
|
-
kind: "deliver",
|
|
105
|
-
payloads: [input.payload],
|
|
106
|
-
});
|
|
107
|
-
const signal = parked.get(input.continuationToken);
|
|
108
|
-
if (signal !== undefined) {
|
|
109
|
-
parked.delete(input.continuationToken);
|
|
110
|
-
signal();
|
|
111
|
-
}
|
|
112
|
-
return { sessionId: input.continuationToken };
|
|
113
|
-
},
|
|
114
|
-
async getEventStream(_sessionId, _options) {
|
|
115
|
-
// The continuous runtime delivers events synchronously through the
|
|
116
|
-
// `RunHandle.events` stream returned by `run()`. There is no
|
|
117
|
-
// out-of-band durable event store to read from, so a separate
|
|
118
|
-
// event-stream lookup by session id is unsupported here. Routes
|
|
119
|
-
// that need this method should target the workflow runtime.
|
|
120
|
-
throw new Error("createContinuousLoopRuntime does not support getEventStream(); read events from RunHandle.events instead.");
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
}
|