@bastani/atomic 0.9.3-alpha.1 → 0.9.3-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/builtin/cursor/CHANGELOG.md +15 -0
- package/dist/builtin/cursor/README.md +2 -1
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/cursor/src/cursor-models-raw.json +2 -9
- package/dist/builtin/cursor/src/model-mapper.ts +14 -3
- package/dist/builtin/cursor/src/proto/protobuf-codec-base64.ts +22 -0
- package/dist/builtin/cursor/src/proto/protobuf-codec-request.ts +53 -13
- package/dist/builtin/cursor/src/proto/protobuf-codec-wire.ts +24 -7
- package/dist/builtin/cursor/src/proto/protobuf-codec.ts +3 -2
- package/dist/builtin/cursor/src/stream.ts +5 -11
- package/dist/builtin/cursor/src/transport-types.ts +3 -0
- package/dist/builtin/cursor/src/transport.ts +1 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +9 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -0
- package/dist/builtin/subagents/src/extension/index.ts +6 -3
- package/dist/builtin/subagents/src/extension/schemas.ts +0 -5
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -4
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +15 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +35 -1
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +4 -2
- package/dist/builtin/subagents/src/shared/types-async.ts +1 -0
- package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +27 -5
- package/dist/builtin/subagents/src/tui/render-layout.ts +27 -4
- package/dist/builtin/subagents/src/tui/render-result-animation.ts +22 -31
- package/dist/builtin/subagents/src/tui/render-result-compact.ts +6 -6
- package/dist/builtin/subagents/src/tui/render-result.ts +20 -19
- package/dist/builtin/subagents/src/tui/render-status-progress.ts +3 -3
- package/dist/builtin/subagents/src/tui/render-widget.ts +46 -7
- package/dist/builtin/subagents/src/tui/render.ts +2 -2
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +43 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/authoring.d.ts +1 -1
- package/dist/builtin/workflows/src/durable/backend.ts +343 -0
- package/dist/builtin/workflows/src/durable/child-primitive.ts +79 -0
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +421 -0
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +171 -0
- package/dist/builtin/workflows/src/durable/factory.ts +96 -0
- package/dist/builtin/workflows/src/durable/file-backend.ts +433 -0
- package/dist/builtin/workflows/src/durable/index.ts +73 -0
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +217 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +299 -0
- package/dist/builtin/workflows/src/durable/scoped-backend.ts +171 -0
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +284 -0
- package/dist/builtin/workflows/src/durable/tool-primitive.ts +180 -0
- package/dist/builtin/workflows/src/durable/types.ts +168 -0
- package/dist/builtin/workflows/src/durable/ui-primitive.ts +96 -0
- package/dist/builtin/workflows/src/engine/options.ts +3 -0
- package/dist/builtin/workflows/src/engine/primitives/parallel.ts +2 -2
- package/dist/builtin/workflows/src/engine/primitives/task.ts +4 -4
- package/dist/builtin/workflows/src/engine/primitives/ui.ts +22 -8
- package/dist/builtin/workflows/src/engine/primitives/workflow.ts +8 -0
- package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +69 -0
- package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +31 -0
- package/dist/builtin/workflows/src/engine/run.ts +148 -6
- package/dist/builtin/workflows/src/engine/runtime.ts +8 -2
- package/dist/builtin/workflows/src/extension/extension-factory.ts +6 -12
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +5 -1
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +3 -0
- package/dist/builtin/workflows/src/extension/runtime.ts +48 -9
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +143 -4
- package/dist/builtin/workflows/src/runs/background/quit.ts +61 -0
- package/dist/builtin/workflows/src/runs/background/status.ts +1 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +74 -33
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +20 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +8 -7
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +1 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +19 -2
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +4 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +10 -10
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +5 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +25 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +16 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +20 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +23 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +30 -1
- package/dist/builtin/workflows/src/shared/store-public-types.ts +6 -2
- package/dist/builtin/workflows/src/shared/store-run-methods.ts +12 -6
- package/dist/builtin/workflows/src/shared/types.ts +55 -0
- package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -1
- package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +41 -0
- package/dist/builtin/workflows/src/tui/graph-view-input.ts +82 -24
- package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -0
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +22 -2
- package/dist/builtin/workflows/src/tui/graph-view-types.ts +4 -5
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -11
- package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +9 -3
- package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +11 -2
- package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +35 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +51 -17
- package/dist/builtin/workflows/src/tui/stage-chat-view-status.ts +36 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +5 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -1
- package/dist/builtin/workflows/src/tui/status-list.ts +14 -2
- package/dist/builtin/workflows/src/tui/widget.ts +23 -8
- package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +5 -4
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -8
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +151 -0
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +47 -30
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/messages.d.ts +1 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +46 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +12 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +15 -7
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +20 -9
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +2 -2
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +9 -3
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +2 -1
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/session-manager-list.d.ts +3 -3
- package/dist/core/session-manager-list.d.ts.map +1 -1
- package/dist/core/session-manager-list.js +27 -8
- package/dist/core/session-manager-list.js.map +1 -1
- package/dist/core/session-manager-storage.d.ts +3 -1
- package/dist/core/session-manager-storage.d.ts.map +1 -1
- package/dist/core/session-manager-storage.js +55 -12
- package/dist/core/session-manager-storage.js.map +1 -1
- package/dist/core/session-manager-tool-dependencies.d.ts +10 -0
- package/dist/core/session-manager-tool-dependencies.d.ts.map +1 -0
- package/dist/core/session-manager-tool-dependencies.js +133 -0
- package/dist/core/session-manager-tool-dependencies.js.map +1 -0
- package/dist/core/session-manager-types.d.ts +22 -0
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +1 -0
- package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-runtime.js +12 -0
- package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts +4 -0
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js +131 -0
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js.map +1 -0
- package/dist/modes/interactive/components/chat-session-host.d.ts +2 -0
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +7 -1
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.js +15 -4
- package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +3 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +26 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/docs/compaction.md +2 -0
- package/docs/models.md +1 -1
- package/docs/providers.md +2 -1
- package/docs/session-format.md +6 -0
- package/docs/sessions.md +6 -0
- package/docs/workflows.md +105 -3
- package/package.json +4 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { StageContextWithMeta, StageNoticeInput, LiveStageRuntime } from "./executor-stage-types.js";
|
|
2
2
|
import type { InternalStageContext } from "./stage-runner.js";
|
|
3
|
+
import type { TrackedStageCaller } from "./executor-stage-call.js";
|
|
3
4
|
|
|
4
5
|
function noticeValue(value: unknown): string {
|
|
5
6
|
if (typeof value === "string") return value;
|
|
@@ -31,7 +32,7 @@ function compactionMeta(result: unknown): string | undefined {
|
|
|
31
32
|
|
|
32
33
|
export function createStageContext(input: {
|
|
33
34
|
readonly runtime: LiveStageRuntime;
|
|
34
|
-
readonly runTrackedStageCall:
|
|
35
|
+
readonly runTrackedStageCall: TrackedStageCaller;
|
|
35
36
|
}): StageContextWithMeta {
|
|
36
37
|
const { runtime } = input;
|
|
37
38
|
const recordStageNotice = (notice: StageNoticeInput): void => {
|
|
@@ -43,6 +44,19 @@ export function createStageContext(input: {
|
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
const innerCtx: InternalStageContext = runtime.innerCtx;
|
|
47
|
+
const sendStreamingUserMessage: InternalStageContext["sendUserMessage"] = async (text, options) => {
|
|
48
|
+
runtime.mcpScope.apply();
|
|
49
|
+
try {
|
|
50
|
+
await innerCtx.sendUserMessage(text, options);
|
|
51
|
+
} finally {
|
|
52
|
+
try {
|
|
53
|
+
runtime.mcpScope.clear();
|
|
54
|
+
} finally {
|
|
55
|
+
runtime.captureStageSessionMeta();
|
|
56
|
+
runtime.applyModelFallbackMeta(innerCtx.__modelFallbackMeta());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
46
60
|
return {
|
|
47
61
|
name: innerCtx.name,
|
|
48
62
|
prompt: (text, promptOptions) => {
|
|
@@ -53,6 +67,11 @@ export function createStageContext(input: {
|
|
|
53
67
|
runtime.throwIfStageMutationBlocked();
|
|
54
68
|
return input.runTrackedStageCall(() => innerCtx.complete(text, completeOptions));
|
|
55
69
|
},
|
|
70
|
+
sendUserMessage: (text, options) => {
|
|
71
|
+
runtime.throwIfStageMutationBlocked();
|
|
72
|
+
if (innerCtx.isStreaming) return sendStreamingUserMessage(text, options);
|
|
73
|
+
return input.runTrackedStageCall(() => innerCtx.sendUserMessage(text, options), { allowFinalized: true });
|
|
74
|
+
},
|
|
56
75
|
steer: (text) => {
|
|
57
76
|
runtime.throwIfStageMutationBlocked();
|
|
58
77
|
return innerCtx.steer(text);
|
|
@@ -193,6 +193,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
193
193
|
if (meta.sessionId !== undefined) stageSnapshot.sessionId = meta.sessionId;
|
|
194
194
|
if (meta.sessionFile !== undefined) stageSnapshot.sessionFile = meta.sessionFile;
|
|
195
195
|
if (meta.sessionId !== undefined || meta.sessionFile !== undefined) input.activeStore.recordStageSession(input.runId, stageId, meta);
|
|
196
|
+
void input.opts.onStageSession?.(input.runId, stageSnapshot);
|
|
196
197
|
};
|
|
197
198
|
const releaseLiveHandle = async (): Promise<void> => {
|
|
198
199
|
if (state.liveHandleReleased) return;
|
|
@@ -226,7 +227,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
226
227
|
});
|
|
227
228
|
};
|
|
228
229
|
|
|
229
|
-
const finalizeStageSnapshot = (): boolean => {
|
|
230
|
+
const finalizeStageSnapshot = async (): Promise<boolean> => {
|
|
230
231
|
if (state.stageFinalized) return false;
|
|
231
232
|
if (stageSnapshot.endedAt !== undefined && isTerminalStage(stageSnapshot)) {
|
|
232
233
|
state.stageFinalized = true;
|
|
@@ -242,7 +243,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
242
243
|
applyModelFallbackMeta(innerCtx.__modelFallbackMeta());
|
|
243
244
|
input.activeStore.recordStageEnd(input.runId, stageSnapshot);
|
|
244
245
|
stageUiBroker.cancelStagePrompt(input.runId, stageId, new Error(`atomic-workflows: stage ${stageId} completed with pending custom UI`));
|
|
245
|
-
input.opts.onStageEnd?.(input.runId, stageSnapshot);
|
|
246
|
+
await input.opts.onStageEnd?.(input.runId, stageSnapshot);
|
|
246
247
|
if (input.opts.persistence) {
|
|
247
248
|
appendStageStartOnce();
|
|
248
249
|
appendStageEnd(input.opts.persistence, {
|
|
@@ -325,12 +326,12 @@ export function createWorkflowStageFactory(input: {
|
|
|
325
326
|
// workflow-exit cleanup and removes the stage from the fail-fast active set.
|
|
326
327
|
// Later paths must not overwrite the terminal skippedReason; they only abort
|
|
327
328
|
// and release idempotent live handles.
|
|
328
|
-
const skipForParallelFailFast = (): void => {
|
|
329
|
+
const skipForParallelFailFast = async (): Promise<void> => {
|
|
329
330
|
if (isTerminalStage(stageSnapshot)) return;
|
|
330
331
|
markSkippedForParallelFailFast();
|
|
331
|
-
finalizeStageSnapshot();
|
|
332
|
-
|
|
333
|
-
|
|
332
|
+
await finalizeStageSnapshot();
|
|
333
|
+
await innerCtx.abort().catch(() => {});
|
|
334
|
+
await dropStageControlForCompletion().catch(() => {});
|
|
334
335
|
};
|
|
335
336
|
stageFailFastScope?.activeStages.set(stageId, { skip: skipForParallelFailFast });
|
|
336
337
|
runtime.unregisterWorkflowExitCleanup = input.exit.registerWorkflowExitCleanup(stageId, {
|
|
@@ -339,7 +340,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
339
340
|
if (!isTerminalStage(stageSnapshot)) {
|
|
340
341
|
stageSnapshot.status = "skipped";
|
|
341
342
|
stageSnapshot.skippedReason = input.exit.workflowExitSkippedReason(reason);
|
|
342
|
-
finalizeStageSnapshot();
|
|
343
|
+
await finalizeStageSnapshot();
|
|
343
344
|
}
|
|
344
345
|
await innerCtx.abort().catch(() => {});
|
|
345
346
|
await releaseLiveHandle().catch(() => {});
|
|
@@ -95,6 +95,7 @@ export function createReplayStageContext(input: {
|
|
|
95
95
|
name,
|
|
96
96
|
prompt: replayText,
|
|
97
97
|
complete: replayText,
|
|
98
|
+
sendUserMessage: async () => rejectReplayMutation("send a user message"),
|
|
98
99
|
steer: async () => rejectReplayMutation("steer"),
|
|
99
100
|
followUp: async () => rejectReplayMutation("follow up"),
|
|
100
101
|
subscribe: () => () => {},
|
|
@@ -48,7 +48,7 @@ export interface LiveStageRuntime {
|
|
|
48
48
|
readonly captureStageSessionMeta: () => void;
|
|
49
49
|
readonly applyModelFallbackMeta: (meta: ReturnType<InternalStageContext["__modelFallbackMeta"]>) => void;
|
|
50
50
|
readonly appendStageStartOnce: () => void;
|
|
51
|
-
readonly finalizeStageSnapshot: () => boolean
|
|
51
|
+
readonly finalizeStageSnapshot: () => Promise<boolean>;
|
|
52
52
|
readonly releaseLiveHandle: () => Promise<void>;
|
|
53
53
|
readonly dropStageControlForCompletion: () => Promise<void>;
|
|
54
54
|
readonly markSkippedForParallelFailFast: () => void;
|
|
@@ -70,6 +70,22 @@ export interface RunOpts extends Omit<AuthoringContract.RunOpts, "adapters" | "s
|
|
|
70
70
|
runId?: string;
|
|
71
71
|
/** Replay completed stages from a failed source run, then resume at this stage. */
|
|
72
72
|
continuation?: RunContinuationOpts;
|
|
73
|
+
/**
|
|
74
|
+
* Durable workflow backend override (for testing). Defaults to the global
|
|
75
|
+
* backend resolved by `getDurableBackend()`.
|
|
76
|
+
*
|
|
77
|
+
* cross-ref: issue #1498 — DBOS-backed cross-session resumability.
|
|
78
|
+
*/
|
|
79
|
+
durableBackend?: import("../../durable/backend.js").DurableWorkflowBackend;
|
|
80
|
+
/**
|
|
81
|
+
* Durable scope for a child workflow run. When set, the child's internal
|
|
82
|
+
* `ctx.tool`/`ctx.ui`/`ctx.stage` checkpoints are routed under the root
|
|
83
|
+
* workflow id with a stable boundary prefix so an interrupted child does
|
|
84
|
+
* not re-execute completed side effects on parent resume.
|
|
85
|
+
*
|
|
86
|
+
* cross-ref: issue #1498.
|
|
87
|
+
*/
|
|
88
|
+
durableScope?: import("../../durable/scoped-backend.js").DurableScope;
|
|
73
89
|
/** Internal parent linkage for nested ctx.workflow(...) runs. */
|
|
74
90
|
parentRun?: {
|
|
75
91
|
readonly runId: string;
|
|
@@ -78,7 +94,8 @@ export interface RunOpts extends Omit<AuthoringContract.RunOpts, "adapters" | "s
|
|
|
78
94
|
};
|
|
79
95
|
onRunStart?: (snapshot: RunSnapshot) => void;
|
|
80
96
|
onStageStart?: (runId: string, snapshot: StageSnapshot) => void;
|
|
81
|
-
onStageEnd?: (runId: string, snapshot: StageSnapshot) =>
|
|
97
|
+
onStageEnd?: (runId: string, snapshot: StageSnapshot) => unknown;
|
|
98
|
+
onStageSession?: (runId: string, snapshot: StageSnapshot) => unknown;
|
|
82
99
|
onRunEnd?: (runId: string, status: RunStatus, result?: WorkflowOutputValues, error?: string, exitReason?: string) => void;
|
|
83
100
|
}
|
|
84
101
|
|
|
@@ -94,7 +111,7 @@ export interface RunResult<TOutputs extends WorkflowOutputValues = WorkflowOutpu
|
|
|
94
111
|
}
|
|
95
112
|
|
|
96
113
|
export interface ParallelFailFastStage {
|
|
97
|
-
readonly skip: () => void
|
|
114
|
+
readonly skip: () => Promise<void>;
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
export interface ParallelFailFastScope {
|
|
@@ -92,6 +92,10 @@ export function createStageContext(opts: StageRunnerOpts): InternalStageContext
|
|
|
92
92
|
return lastAssistantText;
|
|
93
93
|
},
|
|
94
94
|
|
|
95
|
+
async sendUserMessage(text, options) {
|
|
96
|
+
await controller.sendUserMessage(text, options);
|
|
97
|
+
},
|
|
98
|
+
|
|
95
99
|
async steer(text) {
|
|
96
100
|
await (await controller.ensureSession()).steer(text);
|
|
97
101
|
},
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getModelDefaultContextWindow, getSupportedContextWindows, SessionManager, shouldApplyCodexFastModeForScope, type AgentSession, type CreateAgentSessionOptions, type PromptOptions, type StructuredOutputCapture } from "@bastani/atomic";
|
|
2
|
-
import type { StageContext, StageExecutionMeta, StageOptions, WorkflowModelAttempt, WorkflowModelCatalogPort } from "../../shared/types.js";
|
|
2
|
+
import type { StageContext, StageExecutionMeta, StageOptions, StageSendUserMessageOptions, StageUserMessageContent, WorkflowModelAttempt, WorkflowModelCatalogPort } from "../../shared/types.js";
|
|
3
3
|
import { buildModelCandidatesFromCatalog, errorMessage, isRetryableModelFailure, workflowModelId, type WorkflowResolvedModelCandidate } from "../shared/model-fallback.js";
|
|
4
4
|
import { WorkflowPromptModelFailure, lastAssistantTextFromSession, latestTerminalAssistantFailureSince } from "./stage-runner-messages.js";
|
|
5
5
|
import { missingAdapter, stripWorkflowOnlyOptions, unavailableSync } from "./stage-runner-options.js";
|
|
6
6
|
import { asAgentSession, disposeStageSession, normalizeSessionCreateResult } from "./stage-runner-session.js";
|
|
7
7
|
import { structuredOutputToolErrorFromEvent } from "./stage-runner-structured-output.js";
|
|
8
|
+
import { sendStageUserMessage } from "./stage-runner-send-user-message.js";
|
|
8
9
|
import type { AgentSessionConsumer, StageModelFallbackMeta, StageRunnerOpts, StageSessionCreateOptions, StageSessionCreateResult, StageSessionEvent, StageSessionRuntime, WorkflowFastModeSettingsManager } from "./stage-runner-types.js";
|
|
9
10
|
|
|
10
11
|
type PauseRequest = {
|
|
@@ -60,7 +61,6 @@ export class StageSessionController {
|
|
|
60
61
|
get latestStructuredOutputToolError(): string | undefined { return this.latestStructuredOutputToolErrorValue; }
|
|
61
62
|
|
|
62
63
|
resetStructuredOutputToolError(): void { this.latestStructuredOutputToolErrorValue = undefined; }
|
|
63
|
-
|
|
64
64
|
requireSession(property: string): StageSessionRuntime {
|
|
65
65
|
if (!this.session) unavailableSync(property);
|
|
66
66
|
return this.session;
|
|
@@ -98,6 +98,10 @@ export class StageSessionController {
|
|
|
98
98
|
return this.ensureSession(consumer);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
async sendUserMessage(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void> {
|
|
102
|
+
await sendStageUserMessage(await this.ensureSession("prompt"), content, options);
|
|
103
|
+
}
|
|
104
|
+
|
|
101
105
|
async promptWithFallback(
|
|
102
106
|
text: string,
|
|
103
107
|
sdkOptions: PromptOptions | undefined,
|
|
@@ -242,14 +246,10 @@ export class StageSessionController {
|
|
|
242
246
|
fallbackThinkingLevels: undefined,
|
|
243
247
|
};
|
|
244
248
|
if (resumeOptions?.restoreSavedModel) delete optionsForCandidate.model;
|
|
245
|
-
// Pin a tiered model's
|
|
246
|
-
// the
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
// selected long tier) from leaking into workflow stages, so a tiered model
|
|
250
|
-
// uses its short tier unless the author explicitly opts into the long tier
|
|
251
|
-
// via the `(1m)` token or the numeric contextWindow option. Single-window
|
|
252
|
-
// models carry no selectable long tier, so they are left untouched.
|
|
249
|
+
// Pin a tiered model's short default context window for fresh, non-resumed
|
|
250
|
+
// stage sessions unless the author selected a long tier via `(1m)` or
|
|
251
|
+
// contextWindow. This prevents persisted interactive long-tier preferences
|
|
252
|
+
// from leaking into workflow stages; single-window models are left alone.
|
|
253
253
|
if (
|
|
254
254
|
resumeOptions?.restoreSavedModel !== true &&
|
|
255
255
|
this.reattachSessionFile === undefined &&
|
|
@@ -18,6 +18,8 @@ export function stripWorkflowOnlyOptions(
|
|
|
18
18
|
fallbackThinkingLevels: _fallbackThinkingLevels,
|
|
19
19
|
context,
|
|
20
20
|
forkFromSessionFile,
|
|
21
|
+
resumeFromSessionFile,
|
|
22
|
+
durableReplayKey: _durableReplayKey,
|
|
21
23
|
sessionDir,
|
|
22
24
|
gitWorktreeDir: _gitWorktreeDir,
|
|
23
25
|
baseBranch: _baseBranch,
|
|
@@ -26,7 +28,9 @@ export function stripWorkflowOnlyOptions(
|
|
|
26
28
|
if (sessionOptions.sessionManager === undefined) {
|
|
27
29
|
const cwd = sessionOptions.cwd ?? process.cwd();
|
|
28
30
|
const effectiveSessionDir = sessionDir ?? defaultSessionDir;
|
|
29
|
-
if (
|
|
31
|
+
if (resumeFromSessionFile !== undefined) {
|
|
32
|
+
sessionOptions.sessionManager = SessionManager.open(resumeFromSessionFile, effectiveSessionDir, cwd);
|
|
33
|
+
} else if (context === "fork" && forkFromSessionFile !== undefined) {
|
|
30
34
|
sessionOptions.sessionManager = SessionManager.forkFrom(forkFromSessionFile, cwd, effectiveSessionDir);
|
|
31
35
|
} else if (effectiveSessionDir !== undefined) {
|
|
32
36
|
sessionOptions.sessionManager = SessionManager.create(cwd, effectiveSessionDir);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StageSendUserMessageOptions, StageUserMessageContent } from "../../shared/types.js";
|
|
2
|
+
import type { StageSessionRuntime } from "./stage-runner-types.js";
|
|
3
|
+
|
|
4
|
+
function unsupportedContentError(): Error {
|
|
5
|
+
return new Error("atomic-workflows: this stage session adapter does not support non-string sendUserMessage content; provide a runtime sendUserMessage implementation for text/image blocks.");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function sendStageUserMessage(
|
|
9
|
+
activeSession: StageSessionRuntime,
|
|
10
|
+
content: StageUserMessageContent,
|
|
11
|
+
options?: StageSendUserMessageOptions,
|
|
12
|
+
): Promise<void> {
|
|
13
|
+
const deliverAs = activeSession.isStreaming ? options?.deliverAs ?? "followUp" : options?.deliverAs;
|
|
14
|
+
if (activeSession.sendUserMessage !== undefined) {
|
|
15
|
+
await activeSession.sendUserMessage(content, deliverAs === undefined ? undefined : { deliverAs });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (typeof content !== "string") throw unsupportedContentError();
|
|
19
|
+
if (activeSession.isStreaming) {
|
|
20
|
+
if (deliverAs === "steer") await activeSession.steer(content);
|
|
21
|
+
else await activeSession.followUp(content);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
await activeSession.prompt(content);
|
|
25
|
+
}
|
|
@@ -6,6 +6,8 @@ import type {
|
|
|
6
6
|
import type {
|
|
7
7
|
CompleteStageOpts,
|
|
8
8
|
StageContext,
|
|
9
|
+
StageSendUserMessageOptions,
|
|
10
|
+
StageUserMessageContent,
|
|
9
11
|
StageExecutionMeta,
|
|
10
12
|
StageOptions,
|
|
11
13
|
WorkflowExecutionMode,
|
|
@@ -26,6 +28,7 @@ export type WorkflowFastModeSettingsManager = {
|
|
|
26
28
|
|
|
27
29
|
export interface StageSessionRuntime {
|
|
28
30
|
prompt(text: string, options?: PromptOptions): Promise<string | void>;
|
|
31
|
+
sendUserMessage?(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
29
32
|
steer(text: string): Promise<void>;
|
|
30
33
|
followUp(text: string): Promise<void>;
|
|
31
34
|
subscribe(listener: (event: StageSessionEvent) => void): () => void;
|
|
@@ -40,6 +40,16 @@ export interface WorkflowModelFallbackFields {
|
|
|
40
40
|
readonly fallbackThinkingLevels?: readonly string[];
|
|
41
41
|
}
|
|
42
42
|
export type WorkflowModelValue = string | object;
|
|
43
|
+
export interface StageTextContent {
|
|
44
|
+
readonly type: "text";
|
|
45
|
+
readonly text: string;
|
|
46
|
+
}
|
|
47
|
+
export interface StageImageContent {
|
|
48
|
+
readonly type: "image";
|
|
49
|
+
readonly data: string;
|
|
50
|
+
readonly mimeType: string;
|
|
51
|
+
}
|
|
52
|
+
export type StageUserMessageContent = string | readonly (StageTextContent | StageImageContent)[];
|
|
43
53
|
export type WorkflowStageResult<TSchemaDef extends TSchema | undefined = undefined> = [TSchemaDef] extends [TSchema] ? Static<TSchemaDef> : string;
|
|
44
54
|
export interface WorkflowModelUsage extends WorkflowSerializableObject {
|
|
45
55
|
readonly input?: number;
|
|
@@ -178,6 +188,7 @@ export interface WorkflowPersistencePort {
|
|
|
178
188
|
}
|
|
179
189
|
export interface StageSessionRuntime {
|
|
180
190
|
prompt(text: string, options?: PromptOptions): Promise<string | void>;
|
|
191
|
+
sendUserMessage?(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
181
192
|
steer(text: string): Promise<void>;
|
|
182
193
|
followUp(text: string): Promise<void>;
|
|
183
194
|
subscribe(listener: (event: never) => void): () => void;
|
|
@@ -236,10 +247,15 @@ export interface StageAdapters {
|
|
|
236
247
|
readonly prompt?: PromptAdapter;
|
|
237
248
|
readonly complete?: CompleteAdapter;
|
|
238
249
|
}
|
|
250
|
+
export type StageUserMessageDelivery = "steer" | "followUp";
|
|
251
|
+
export interface StageSendUserMessageOptions {
|
|
252
|
+
readonly deliverAs?: StageUserMessageDelivery;
|
|
253
|
+
}
|
|
239
254
|
export interface StageContext<TSchemaDef extends TSchema | undefined = undefined> {
|
|
240
255
|
readonly name: string;
|
|
241
256
|
prompt(text: string, options?: StagePromptOptions): Promise<WorkflowStageResult<TSchemaDef>>;
|
|
242
257
|
complete(text: string, options?: CompleteStageOpts): Promise<string>;
|
|
258
|
+
sendUserMessage(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
243
259
|
steer(text: string): Promise<void>;
|
|
244
260
|
followUp(text: string): Promise<void>;
|
|
245
261
|
subscribe(listener: (event: never) => void): () => void;
|
|
@@ -55,6 +55,18 @@ export interface WorkflowModelFallbackFields {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export type WorkflowModelValue = string | object;
|
|
58
|
+
// Standalone authoring contract mirror of shared/types.ts StageUserMessageContent,
|
|
59
|
+
// whose runtime source of truth is derived from AgentSession["sendUserMessage"].
|
|
60
|
+
export interface StageTextContent {
|
|
61
|
+
readonly type: "text";
|
|
62
|
+
readonly text: string;
|
|
63
|
+
}
|
|
64
|
+
export interface StageImageContent {
|
|
65
|
+
readonly type: "image";
|
|
66
|
+
readonly data: string;
|
|
67
|
+
readonly mimeType: string;
|
|
68
|
+
}
|
|
69
|
+
export type StageUserMessageContent = string | readonly (StageTextContent | StageImageContent)[];
|
|
58
70
|
export type WorkflowStageResult<TSchemaDef extends TSchema | undefined = undefined> = [TSchemaDef] extends [TSchema]
|
|
59
71
|
? Static<TSchemaDef>
|
|
60
72
|
: string;
|
|
@@ -223,6 +235,7 @@ export interface WorkflowPersistencePort {
|
|
|
223
235
|
|
|
224
236
|
export interface StageSessionRuntime {
|
|
225
237
|
prompt(text: string, options?: PromptOptions): Promise<string | void>;
|
|
238
|
+
sendUserMessage?(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
226
239
|
steer(text: string): Promise<void>;
|
|
227
240
|
followUp(text: string): Promise<void>;
|
|
228
241
|
subscribe(listener: (event: never) => void): () => void;
|
|
@@ -284,10 +297,17 @@ export interface StageAdapters {
|
|
|
284
297
|
readonly complete?: CompleteAdapter;
|
|
285
298
|
}
|
|
286
299
|
|
|
300
|
+
export type StageUserMessageDelivery = "steer" | "followUp";
|
|
301
|
+
|
|
302
|
+
export interface StageSendUserMessageOptions {
|
|
303
|
+
readonly deliverAs?: StageUserMessageDelivery;
|
|
304
|
+
}
|
|
305
|
+
|
|
287
306
|
export interface StageContext<TSchemaDef extends TSchema | undefined = undefined> {
|
|
288
307
|
readonly name: string;
|
|
289
308
|
prompt(text: string, options?: StagePromptOptions): Promise<WorkflowStageResult<TSchemaDef>>;
|
|
290
309
|
complete(text: string, options?: CompleteStageOpts): Promise<string>;
|
|
310
|
+
sendUserMessage(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
291
311
|
steer(text: string): Promise<void>;
|
|
292
312
|
followUp(text: string): Promise<void>;
|
|
293
313
|
subscribe(listener: (event: never) => void): () => void;
|
|
@@ -57,6 +57,28 @@ export interface WorkflowRunContext<TInputs extends WorkflowInputValues = Workfl
|
|
|
57
57
|
parallel(steps: readonly WorkflowTaskStep[], options?: WorkflowParallelOptions): Promise<WorkflowTaskResult[]>;
|
|
58
58
|
workflow<TChildInputs extends WorkflowInputValues, TChildOutputs extends WorkflowOutputValues, TChildRunInputs extends WorkflowInputValues = TChildInputs>(definition: WorkflowDefinition<TChildInputs, TChildOutputs, TChildRunInputs> & TDefinitionBrand, ...args: WorkflowRunChildArgs<TChildRunInputs>): Promise<WorkflowChildResult<TChildOutputs>>;
|
|
59
59
|
readonly ui: WorkflowUIContext;
|
|
60
|
+
/**
|
|
61
|
+
* Durable cached tool execution. Runs arbitrary TypeScript code and caches
|
|
62
|
+
* the result durably so completed side effects are not repeated on resume.
|
|
63
|
+
* Only `ctx.*` blocks (tool, ui, stage, task, chain, parallel, workflow)
|
|
64
|
+
* produce durable checkpoints.
|
|
65
|
+
*
|
|
66
|
+
* cross-ref: issue #1498 — DBOS-backed cross-session resumability.
|
|
67
|
+
*/
|
|
68
|
+
tool: WorkflowToolPrimitive;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `ctx.tool` primitive signature. Runs an async function and caches the result.
|
|
72
|
+
*/
|
|
73
|
+
export interface WorkflowToolPrimitive {
|
|
74
|
+
<TValue extends WorkflowSerializableValue>(name: string, args: Readonly<Record<string, WorkflowSerializableValue>>, fn: () => Promise<TValue>, options?: WorkflowToolOptions): Promise<TValue>;
|
|
75
|
+
}
|
|
76
|
+
/** Options for `ctx.tool`. */
|
|
77
|
+
export interface WorkflowToolOptions {
|
|
78
|
+
readonly retriesAllowed?: boolean;
|
|
79
|
+
readonly maxAttempts?: number;
|
|
80
|
+
readonly intervalMs?: number;
|
|
81
|
+
readonly backoffRate?: number;
|
|
60
82
|
}
|
|
61
83
|
export type WorkflowRunFn<TInputs extends WorkflowInputValues = WorkflowInputValues, TOutputs extends WorkflowOutputValues = WorkflowOutputValues, TDefinitionBrand extends object = {}> = (ctx: WorkflowRunContext<TInputs, TDefinitionBrand, TOutputs>) => Promise<TOutputs> | TOutputs;
|
|
62
84
|
export interface WorkflowRuntimeConfig {
|
|
@@ -140,7 +162,7 @@ export interface RunOpts {
|
|
|
140
162
|
readonly parentRun?: WorkflowParentRunLink;
|
|
141
163
|
readonly onRunStart?: (snapshot: RunSnapshot) => void;
|
|
142
164
|
readonly onStageStart?: (runId: string, snapshot: StageSnapshot) => void;
|
|
143
|
-
readonly onStageEnd?: (runId: string, snapshot: StageSnapshot) =>
|
|
165
|
+
readonly onStageEnd?: (runId: string, snapshot: StageSnapshot) => unknown;
|
|
144
166
|
readonly onRunEnd?: (runId: string, status: RunStatus, result?: WorkflowOutputValues, error?: string, exitReason?: string) => void;
|
|
145
167
|
}
|
|
146
168
|
export interface WorkflowProgressSummary extends WorkflowSerializableObject {
|
|
@@ -104,6 +104,35 @@ export interface WorkflowRunContext<
|
|
|
104
104
|
...args: WorkflowRunChildArgs<TChildRunInputs>
|
|
105
105
|
): Promise<WorkflowChildResult<TChildOutputs>>;
|
|
106
106
|
readonly ui: WorkflowUIContext;
|
|
107
|
+
/**
|
|
108
|
+
* Durable cached tool execution. Runs arbitrary TypeScript code and caches
|
|
109
|
+
* the result durably so completed side effects are not repeated on resume.
|
|
110
|
+
* Only `ctx.*` blocks (tool, ui, stage, task, chain, parallel, workflow)
|
|
111
|
+
* produce durable checkpoints.
|
|
112
|
+
*
|
|
113
|
+
* cross-ref: issue #1498 — DBOS-backed cross-session resumability.
|
|
114
|
+
*/
|
|
115
|
+
tool: WorkflowToolPrimitive;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* `ctx.tool` primitive signature. Runs an async function and caches the result.
|
|
120
|
+
*/
|
|
121
|
+
export interface WorkflowToolPrimitive {
|
|
122
|
+
<TValue extends WorkflowSerializableValue>(
|
|
123
|
+
name: string,
|
|
124
|
+
args: Readonly<Record<string, WorkflowSerializableValue>>,
|
|
125
|
+
fn: () => Promise<TValue>,
|
|
126
|
+
options?: WorkflowToolOptions,
|
|
127
|
+
): Promise<TValue>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Options for `ctx.tool`. */
|
|
131
|
+
export interface WorkflowToolOptions {
|
|
132
|
+
readonly retriesAllowed?: boolean;
|
|
133
|
+
readonly maxAttempts?: number;
|
|
134
|
+
readonly intervalMs?: number;
|
|
135
|
+
readonly backoffRate?: number;
|
|
107
136
|
}
|
|
108
137
|
|
|
109
138
|
export type WorkflowRunFn<
|
|
@@ -206,7 +235,7 @@ export interface RunOpts {
|
|
|
206
235
|
readonly parentRun?: WorkflowParentRunLink;
|
|
207
236
|
readonly onRunStart?: (snapshot: RunSnapshot) => void;
|
|
208
237
|
readonly onStageStart?: (runId: string, snapshot: StageSnapshot) => void;
|
|
209
|
-
readonly onStageEnd?: (runId: string, snapshot: StageSnapshot) =>
|
|
238
|
+
readonly onStageEnd?: (runId: string, snapshot: StageSnapshot) => unknown;
|
|
210
239
|
readonly onRunEnd?: (runId: string, status: RunStatus, result?: WorkflowOutputValues, error?: string, exitReason?: string) => void;
|
|
211
240
|
}
|
|
212
241
|
|
|
@@ -30,6 +30,10 @@ export interface RunEndMetadata {
|
|
|
30
30
|
readonly exitReason?: string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export interface RunPauseMetadata {
|
|
34
|
+
readonly resumable?: boolean;
|
|
35
|
+
readonly exitReason?: string;
|
|
36
|
+
}
|
|
33
37
|
export interface RunBlockedMetadata extends RunEndMetadata {
|
|
34
38
|
readonly failureRecoverability: "recoverable";
|
|
35
39
|
readonly failedStageId: string;
|
|
@@ -204,8 +208,8 @@ export interface Store {
|
|
|
204
208
|
recordStageBlocked(runId: string, stageId: string, blockedBy: string): boolean;
|
|
205
209
|
recordStageUnblocked(runId: string, stageId: string): boolean;
|
|
206
210
|
recordStageNotice(runId: string, stageId: string, notice: StageNotice): boolean;
|
|
207
|
-
/** Mark a run as `paused`. */
|
|
208
|
-
recordRunPaused(runId: string, pausedAt?: number): boolean;
|
|
211
|
+
/** Mark a run as `paused`. Optional metadata can annotate resumable quit/detach state. */
|
|
212
|
+
recordRunPaused(runId: string, pausedAt?: number, metadata?: RunPauseMetadata): boolean;
|
|
209
213
|
/** Restore a run from `paused` back to `running`. */
|
|
210
214
|
recordRunResumed(runId: string, resumedAt?: number): boolean;
|
|
211
215
|
/** Drop every run and notice. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorkflowOutputValues } from "./types.js";
|
|
2
|
-
import type { Store, RunBlockedMetadata, RunEndMetadata } from "./store-public-types.js";
|
|
2
|
+
import type { Store, RunBlockedMetadata, RunEndMetadata, RunPauseMetadata } from "./store-public-types.js";
|
|
3
3
|
import type { RunSnapshot, RunStatus, StoreSnapshot, WorkflowNotice } from "./store-types.js";
|
|
4
4
|
import { accumulatePausedDurationMs, elapsedRunMs } from "./timing.js";
|
|
5
5
|
import { isTopLevelWorkflowRun } from "./run-visibility.js";
|
|
@@ -164,14 +164,19 @@ export function createRunStoreMethods(context: StoreContext): RunStoreMethods {
|
|
|
164
164
|
return true;
|
|
165
165
|
},
|
|
166
166
|
|
|
167
|
-
recordRunPaused(runId: string, pausedAt?: number): boolean {
|
|
167
|
+
recordRunPaused(runId: string, pausedAt?: number, metadata?: RunPauseMetadata): boolean {
|
|
168
168
|
const run = context.findRun(runId);
|
|
169
169
|
if (!run) return false;
|
|
170
170
|
if (TERMINAL_STATUSES.has(run.status)) return false;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
const wasPaused = run.status === "paused";
|
|
172
|
+
if (!wasPaused) {
|
|
173
|
+
run.status = "paused";
|
|
174
|
+
run.pausedAt = pausedAt ?? Date.now();
|
|
175
|
+
run.resumedAt = undefined;
|
|
176
|
+
}
|
|
177
|
+
if (metadata?.resumable !== undefined) run.resumable = metadata.resumable;
|
|
178
|
+
if (metadata?.exitReason !== undefined) run.exitReason = metadata.exitReason;
|
|
179
|
+
if (wasPaused && metadata === undefined) return false;
|
|
175
180
|
context.bumpAndNotify();
|
|
176
181
|
return true;
|
|
177
182
|
},
|
|
@@ -186,6 +191,7 @@ export function createRunStoreMethods(context: StoreContext): RunStoreMethods {
|
|
|
186
191
|
run.pausedDurationMs = accumulatePausedDurationMs(run.pausedDurationMs, run.pausedAt, resumedTs);
|
|
187
192
|
run.resumedAt = resumedTs;
|
|
188
193
|
run.pausedAt = undefined;
|
|
194
|
+
delete run.exitReason;
|
|
189
195
|
context.bumpAndNotify();
|
|
190
196
|
return true;
|
|
191
197
|
},
|
|
@@ -21,6 +21,15 @@ export type { TSchema };
|
|
|
21
21
|
|
|
22
22
|
export type { AgentSessionEvent, ContextCompactionResult, ModelCycleResult, PromptOptions };
|
|
23
23
|
|
|
24
|
+
export type StageUserMessageContent = Parameters<AgentSession["sendUserMessage"]>[0];
|
|
25
|
+
|
|
26
|
+
export type StageUserMessageDelivery = "steer" | "followUp";
|
|
27
|
+
|
|
28
|
+
export interface StageSendUserMessageOptions {
|
|
29
|
+
/** Delivery mode to use when the stage session is already streaming. Defaults to followUp. */
|
|
30
|
+
readonly deliverAs?: StageUserMessageDelivery;
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
export type WorkflowModelValue = NonNullable<CreateAgentSessionOptions["model"]> | string;
|
|
25
34
|
export type WorkflowModelUsage = AuthoringContract.WorkflowModelUsage;
|
|
26
35
|
export type WorkflowModelAttempt = AuthoringContract.WorkflowModelAttempt;
|
|
@@ -178,6 +187,10 @@ export interface StageOptions<TSchemaDef extends TSchema | undefined = TSchema |
|
|
|
178
187
|
scopedModels?: CreateAgentSessionOptions["scopedModels"];
|
|
179
188
|
sessionManager?: SessionManager;
|
|
180
189
|
settingsManager?: SettingsManager;
|
|
190
|
+
/** Internal durable resume hook: reopen this exact Atomic/Pi session file instead of forking. */
|
|
191
|
+
resumeFromSessionFile?: string;
|
|
192
|
+
/** Internal durable replay key used to map a live LM session to durable resume state. */
|
|
193
|
+
durableReplayKey?: string;
|
|
181
194
|
}
|
|
182
195
|
|
|
183
196
|
// ---------------------------------------------------------------------------
|
|
@@ -299,6 +312,15 @@ export interface StageContext<TSchemaDef extends TSchema | undefined = undefined
|
|
|
299
312
|
prompt(text: string, options?: StagePromptOptions): Promise<WorkflowStageResult<TSchemaDef>>;
|
|
300
313
|
complete(text: string, options?: CompleteStageOpts): Promise<string>;
|
|
301
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Send a user-authored follow-on message to this stage session.
|
|
317
|
+
*
|
|
318
|
+
* When the session is idle this starts a new user turn immediately. When the
|
|
319
|
+
* session is streaming, the message is queued as a follow-up by default, or
|
|
320
|
+
* as steering when `deliverAs: "steer"` is provided.
|
|
321
|
+
*/
|
|
322
|
+
sendUserMessage(content: StageUserMessageContent, options?: StageSendUserMessageOptions): Promise<void>;
|
|
323
|
+
|
|
302
324
|
/** Queue messages during streaming. */
|
|
303
325
|
steer(text: string): Promise<void>;
|
|
304
326
|
followUp(text: string): Promise<void>;
|
|
@@ -381,6 +403,39 @@ export interface WorkflowRunContext<
|
|
|
381
403
|
): Promise<WorkflowChildResult<TChildOutputs>>;
|
|
382
404
|
/** HIL primitives for user interaction during a run. */
|
|
383
405
|
readonly ui: WorkflowUIContext;
|
|
406
|
+
/**
|
|
407
|
+
* Durable cached tool execution. Runs arbitrary TypeScript code and caches
|
|
408
|
+
* the result so completed side effects are not repeated on resume.
|
|
409
|
+
* Only `ctx.*` blocks produce durable checkpoints.
|
|
410
|
+
*
|
|
411
|
+
* cross-ref: issue #1498 — DBOS-backed cross-session resumability.
|
|
412
|
+
*/
|
|
413
|
+
tool: WorkflowToolPrimitive;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* `ctx.tool` primitive signature. Runs an async function and caches the result
|
|
418
|
+
* durably via the durable workflow backend.
|
|
419
|
+
*/
|
|
420
|
+
export interface WorkflowToolPrimitive {
|
|
421
|
+
<TValue extends WorkflowSerializableValue>(
|
|
422
|
+
name: string,
|
|
423
|
+
args: Readonly<Record<string, WorkflowSerializableValue>>,
|
|
424
|
+
fn: () => Promise<TValue>,
|
|
425
|
+
options?: WorkflowToolOptions,
|
|
426
|
+
): Promise<TValue>;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** Options for `ctx.tool`. */
|
|
430
|
+
export interface WorkflowToolOptions {
|
|
431
|
+
/** When true, the tool function is retried on failure. Default false. */
|
|
432
|
+
readonly retriesAllowed?: boolean;
|
|
433
|
+
/** Max retry attempts when retriesAllowed is true. Default 3. */
|
|
434
|
+
readonly maxAttempts?: number;
|
|
435
|
+
/** Initial retry interval in ms. Default 1000. */
|
|
436
|
+
readonly intervalMs?: number;
|
|
437
|
+
/** Backoff multiplier. Default 2. */
|
|
438
|
+
readonly backoffRate?: number;
|
|
384
439
|
}
|
|
385
440
|
|
|
386
441
|
// ---------------------------------------------------------------------------
|