@bastani/atomic 0.9.15 → 0.9.16-alpha.1
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 +7 -0
- package/dist/builtin/intercom/CHANGELOG.md +10 -0
- package/dist/builtin/intercom/README.md +8 -8
- package/dist/builtin/intercom/contact-supervisor-tool.ts +68 -32
- package/dist/builtin/intercom/index-heavy.ts +1 -0
- package/dist/builtin/intercom/index.ts +21 -15
- package/dist/builtin/intercom/intercom-tool.ts +66 -10
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/parent-ask-handoff.ts +72 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +13 -0
- package/dist/builtin/subagents/README.md +23 -12
- package/dist/builtin/subagents/agents/worker.md +2 -2
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +10 -17
- package/dist/builtin/subagents/src/extension/index.ts +5 -30
- package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
- package/dist/builtin/subagents/src/extension/schemas.ts +2 -14
- package/dist/builtin/subagents/src/extension/tool-description.ts +1 -2
- package/dist/builtin/subagents/src/extension/tool-rendering.ts +53 -0
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +1 -1
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
- package/dist/builtin/subagents/src/runs/foreground/execution-parent-ask-handoff.ts +78 -0
- package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +7 -5
- package/dist/builtin/subagents/src/runs/foreground/notify.ts +5 -6
- package/dist/builtin/subagents/src/runs/foreground/parent-ask-output.ts +48 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-burst-display.ts +46 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-burst.ts +403 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +48 -9
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +3 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-live-update.ts +11 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +164 -93
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +36 -29
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parent-ask-projection.ts +11 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +42 -17
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +3 -121
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +7 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +30 -220
- package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +0 -34
- package/dist/builtin/subagents/src/runs/inprocess/index.ts +0 -12
- package/dist/builtin/subagents/src/runs/inprocess/prompt-behavior.ts +1 -1
- package/dist/builtin/subagents/src/runs/inprocess/runner.ts +2 -141
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +8 -0
- package/dist/builtin/subagents/src/shared/status-format.ts +3 -3
- package/dist/builtin/subagents/src/shared/types-config.ts +41 -0
- package/dist/builtin/subagents/src/shared/types-foreground-state.ts +7 -15
- package/dist/builtin/subagents/src/shared/types-results.ts +3 -1
- package/dist/builtin/subagents/src/shared/types-runtime.ts +1 -11
- package/dist/builtin/subagents/src/tui/render-progress.ts +2 -2
- package/dist/builtin/subagents/src/tui/render-result-compact.ts +2 -2
- package/dist/builtin/subagents/src/tui/render-result.ts +38 -14
- package/dist/builtin/subagents/src/tui/render-status-progress.ts +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +10 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/dbos-embedded-postgres-root.ts +548 -39
- package/dist/builtin/workflows/src/durable/dbos-embedded-postgres.ts +529 -65
- package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +30 -8
- package/dist/builtin/workflows/src/durable/dbos-local-postgres.ts +36 -3
- package/dist/builtin/workflows/src/durable/local-command.ts +68 -10
- package/dist/builtin/workflows/src/extension/dispatcher.ts +7 -1
- package/dist/builtin/workflows/src/extension/extension-factory.ts +2 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +1094 -298
- package/dist/builtin/workflows/src/extension/public-types.ts +2 -2
- package/dist/builtin/workflows/src/extension/render-result.ts +16 -2
- package/dist/builtin/workflows/src/extension/runtime.ts +8 -1
- package/dist/builtin/workflows/src/extension/workflow-request-abort.ts +15 -0
- package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +4 -3
- package/dist/builtin/workflows/src/extension/workflow-tool-registration.ts +107 -13
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +22 -12
- package/dist/builtin/workflows/src/tui/widget.ts +25 -6
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +19 -3
- package/dist/core/event-bus.js.map +1 -1
- package/docs/intercom.md +28 -26
- package/docs/subagents.md +15 -11
- package/docs/workflows.md +27 -10
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
- package/dist/builtin/subagents/src/runs/inprocess/attempt-handles.ts +0 -104
- /package/dist/builtin/subagents/src/runs/foreground/{subagent-executor-resume.ts → subagent-executor-cwd.ts} +0 -0
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
provisionResolvedLocalDbos,
|
|
4
4
|
resolveDbosSystemDatabaseUrl,
|
|
5
5
|
shouldProvisionLocalDbos,
|
|
6
|
+
shutdownResolvedLocalDbos,
|
|
6
7
|
} from "./dbos-local-postgres.js";
|
|
7
8
|
import { getDbosProcessOwner, resetDbosProcessOwner } from "./dbos-process-owner.js";
|
|
8
9
|
import { classifyDbosDurabilityFailure, readDbosFailureDetail } from "./dbos-registration-diagnostics.js";
|
|
@@ -41,6 +42,7 @@ export class DbosShutdownError extends DbosDurabilityError {
|
|
|
41
42
|
}
|
|
42
43
|
type DbosConfigurator = () => Promise<ConfiguredDbosDurability>;
|
|
43
44
|
type LocalDbosProvisioner = () => Promise<void>;
|
|
45
|
+
type LocalDbosShutdowner = () => Promise<void>;
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
48
|
* Default path: resolve the local database first (explicit env URL, embedded
|
|
@@ -53,6 +55,7 @@ const defaultConfigurator: DbosConfigurator = async () => {
|
|
|
53
55
|
|
|
54
56
|
let configureDurability: DbosConfigurator = defaultConfigurator;
|
|
55
57
|
let provisionLocalDbos: LocalDbosProvisioner = provisionResolvedLocalDbos;
|
|
58
|
+
let shutdownLocalDbos: LocalDbosShutdowner = shutdownResolvedLocalDbos;
|
|
56
59
|
|
|
57
60
|
function owner(): ReturnType<typeof getDbosProcessOwner> {
|
|
58
61
|
return getDbosProcessOwner();
|
|
@@ -69,6 +72,11 @@ async function durabilityFailure(action: string, error: unknown): Promise<DbosDu
|
|
|
69
72
|
return new DbosDurabilityError(`DBOS workflow durability ${action} failed: ${detail}. ${guidance}`, cause);
|
|
70
73
|
}
|
|
71
74
|
|
|
75
|
+
function combinedShutdownFailure(errors: readonly unknown[]): unknown {
|
|
76
|
+
if (errors.length === 1) return errors[0];
|
|
77
|
+
return new AggregateError(errors, errors.map((error) => readDbosFailureDetail(error)).join("; "));
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
export async function configureDbosOnce(): Promise<ConfiguredDbosDurability> {
|
|
73
81
|
const slot = owner();
|
|
74
82
|
if (slot.failure !== undefined) throw slot.failure;
|
|
@@ -140,17 +148,29 @@ export async function shutdownDbos(): Promise<void> {
|
|
|
140
148
|
const configuredPromise = slot.configured;
|
|
141
149
|
if (configuredPromise === undefined) return;
|
|
142
150
|
slot.shutdownPromise = (async () => {
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
// session dispose — crashing otherwise-successful runs at process exit.
|
|
151
|
+
// Configuration and launch failures are intentionally not rethrown during
|
|
152
|
+
// session disposal, but local provisioning may already have started an
|
|
153
|
+
// owned cluster. Always attempt that cleanup exactly once.
|
|
147
154
|
const durability = await configuredPromise.catch(() => undefined);
|
|
148
|
-
if (durability === undefined)
|
|
155
|
+
if (durability === undefined) {
|
|
156
|
+
await shutdownLocalDbos();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
149
159
|
if (slot.launchPromise !== undefined) await slot.launchPromise.catch(() => undefined);
|
|
150
|
-
if (slot.state !== "ready")
|
|
160
|
+
if (slot.state !== "ready") {
|
|
161
|
+
await shutdownLocalDbos();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
151
164
|
slot.state = "shutting_down";
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
const errors: unknown[] = [];
|
|
166
|
+
for (const shutdown of [() => durability.backend.flush(), () => durability.shutdown(), shutdownLocalDbos]) {
|
|
167
|
+
try {
|
|
168
|
+
await shutdown();
|
|
169
|
+
} catch (error) {
|
|
170
|
+
errors.push(error);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (errors.length > 0) throw combinedShutdownFailure(errors);
|
|
154
174
|
slot.state = "shut_down";
|
|
155
175
|
})().catch(async (error: unknown) => {
|
|
156
176
|
slot.failure = await durabilityFailure("shutdown", error);
|
|
@@ -179,8 +199,10 @@ export function dbosLifecycleState(): DbosLifecycleState {
|
|
|
179
199
|
export function resetDbosLifecycleForTests(
|
|
180
200
|
configurator: DbosConfigurator = defaultConfigurator,
|
|
181
201
|
provisioner: LocalDbosProvisioner = provisionResolvedLocalDbos,
|
|
202
|
+
shutdowner: LocalDbosShutdowner = shutdownResolvedLocalDbos,
|
|
182
203
|
): void {
|
|
183
204
|
resetDbosProcessOwner();
|
|
184
205
|
configureDurability = configurator;
|
|
185
206
|
provisionLocalDbos = provisioner;
|
|
207
|
+
shutdownLocalDbos = shutdowner;
|
|
186
208
|
}
|
|
@@ -7,11 +7,16 @@
|
|
|
7
7
|
*
|
|
8
8
|
* 1. `DBOS_SYSTEM_DATABASE_URL` — the user's explicit database.
|
|
9
9
|
* 2. Atomic's embedded Postgres (npm-distributed binaries, no Docker).
|
|
10
|
-
* 3. DBOS's reusable `dbos-db` Docker container, only
|
|
11
|
-
*
|
|
10
|
+
* 3. DBOS's reusable `dbos-db` Docker container, only after embedded
|
|
11
|
+
* provisioning fails without leaving retained-process cleanup pending.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
EMBEDDED_DBOS_SYSTEM_DATABASE_URL,
|
|
16
|
+
EmbeddedPostgresCleanupPendingError,
|
|
17
|
+
ensureEmbeddedDbosPostgres,
|
|
18
|
+
shutdownEmbeddedDbosPostgres,
|
|
19
|
+
} from "./dbos-embedded-postgres.js";
|
|
15
20
|
import { commandFailureDetail, delay, runLocalCommand, tcpReachable } from "./local-command.js";
|
|
16
21
|
|
|
17
22
|
const DOCKER_CONTAINER = "dbos-db";
|
|
@@ -20,11 +25,14 @@ const DOCKER_READY_ATTEMPTS = 60;
|
|
|
20
25
|
const DOCKER_READY_DELAY_MS = 500;
|
|
21
26
|
|
|
22
27
|
type LocalDbosProvider = () => Promise<void>;
|
|
28
|
+
type LocalDbosShutdowner = () => Promise<void>;
|
|
23
29
|
|
|
24
30
|
let resolution: Promise<string | undefined> | undefined;
|
|
25
31
|
let resolvedProvider: LocalDbosProvider | undefined;
|
|
26
32
|
let embeddedProvider: LocalDbosProvider = ensureEmbeddedDbosPostgres;
|
|
27
33
|
let dockerProvider: LocalDbosProvider = ensureDockerDbosPostgres;
|
|
34
|
+
let shutdownEmbeddedProvider: LocalDbosShutdowner = shutdownEmbeddedDbosPostgres;
|
|
35
|
+
let embeddedShutdown: Promise<void> | undefined;
|
|
28
36
|
|
|
29
37
|
/**
|
|
30
38
|
* Resolve the system database URL for this process and make its database
|
|
@@ -44,6 +52,22 @@ export async function provisionResolvedLocalDbos(): Promise<void> {
|
|
|
44
52
|
await (resolvedProvider ?? embeddedProvider)();
|
|
45
53
|
}
|
|
46
54
|
|
|
55
|
+
/** Stop the local database only when the resolved provider was embedded. */
|
|
56
|
+
export function shutdownResolvedLocalDbos(): Promise<void> {
|
|
57
|
+
if (resolvedProvider !== embeddedProvider) return Promise.resolve();
|
|
58
|
+
embeddedShutdown ??= shutdownEmbeddedProvider().then(
|
|
59
|
+
() => {
|
|
60
|
+
resolvedProvider = undefined;
|
|
61
|
+
embeddedShutdown = undefined;
|
|
62
|
+
},
|
|
63
|
+
(error: unknown) => {
|
|
64
|
+
embeddedShutdown = undefined;
|
|
65
|
+
throw error;
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
return embeddedShutdown;
|
|
69
|
+
}
|
|
70
|
+
|
|
47
71
|
export function shouldProvisionLocalDbos(error: unknown): boolean {
|
|
48
72
|
if (process.env.DBOS_SYSTEM_DATABASE_URL?.trim()) return false;
|
|
49
73
|
const message = error instanceof Error ? `${error.message}\n${error.cause ?? ""}` : String(error);
|
|
@@ -61,6 +85,12 @@ async function resolve(): Promise<string | undefined> {
|
|
|
61
85
|
resolvedProvider = embeddedProvider;
|
|
62
86
|
return EMBEDDED_DBOS_SYSTEM_DATABASE_URL;
|
|
63
87
|
} catch (embeddedError) {
|
|
88
|
+
if (embeddedError instanceof EmbeddedPostgresCleanupPendingError) {
|
|
89
|
+
// A second database must not hide the exact child lease whose startup
|
|
90
|
+
// rollback timed out. Keep teardown routed to that embedded owner.
|
|
91
|
+
resolvedProvider = embeddedProvider;
|
|
92
|
+
throw embeddedError;
|
|
93
|
+
}
|
|
64
94
|
try {
|
|
65
95
|
await dockerProvider();
|
|
66
96
|
resolvedProvider = dockerProvider;
|
|
@@ -125,9 +155,12 @@ async function requireDockerSuccess(action: string, args: string[]): Promise<voi
|
|
|
125
155
|
export function resetLocalDbosProvisioningForTests(
|
|
126
156
|
embedded: LocalDbosProvider = ensureEmbeddedDbosPostgres,
|
|
127
157
|
docker: LocalDbosProvider = ensureDockerDbosPostgres,
|
|
158
|
+
shutdownEmbedded: LocalDbosShutdowner = shutdownEmbeddedDbosPostgres,
|
|
128
159
|
): void {
|
|
129
160
|
resolution = undefined;
|
|
130
161
|
resolvedProvider = undefined;
|
|
162
|
+
embeddedShutdown = undefined;
|
|
131
163
|
embeddedProvider = embedded;
|
|
132
164
|
dockerProvider = docker;
|
|
165
|
+
shutdownEmbeddedProvider = shutdownEmbedded;
|
|
133
166
|
}
|
|
@@ -8,12 +8,22 @@ export interface LocalCommandResult {
|
|
|
8
8
|
readonly exitCode: number;
|
|
9
9
|
readonly stdout: string;
|
|
10
10
|
readonly stderr: string;
|
|
11
|
+
/** True when bounded capture discarded the beginning of stdout. */
|
|
12
|
+
readonly stdoutTruncated?: true;
|
|
13
|
+
/** True when bounded capture discarded the beginning of stderr. */
|
|
14
|
+
readonly stderrTruncated?: true;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
const OUTPUT_LIMIT_BYTES = 16_384;
|
|
14
18
|
|
|
15
19
|
export interface LocalCommandOptions {
|
|
16
20
|
readonly env?: Readonly<Record<string, string>>;
|
|
21
|
+
/**
|
|
22
|
+
* For daemon launchers whose successful descendants inherit stdio, settle
|
|
23
|
+
* from a successful direct-child exit. Nonzero exits still drain through
|
|
24
|
+
* `close`, preserving bounded failure diagnostics.
|
|
25
|
+
*/
|
|
26
|
+
readonly completion?: "successful-exit";
|
|
17
27
|
/** POSIX drop-privilege identity for the spawned process (root only). */
|
|
18
28
|
readonly uid?: number;
|
|
19
29
|
readonly gid?: number;
|
|
@@ -34,16 +44,62 @@ export function runLocalCommand(
|
|
|
34
44
|
});
|
|
35
45
|
let stdout = "";
|
|
36
46
|
let stderr = "";
|
|
47
|
+
let stdoutTruncated = false;
|
|
48
|
+
let stderrTruncated = false;
|
|
49
|
+
let settled = false;
|
|
50
|
+
let exitFallback: NodeJS.Immediate | undefined;
|
|
37
51
|
child.stdout.setEncoding("utf8");
|
|
38
52
|
child.stderr.setEncoding("utf8");
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
const onStdout = (chunk: string): void => {
|
|
54
|
+
const appended = boundedAppend(stdout, chunk);
|
|
55
|
+
stdout = appended.value;
|
|
56
|
+
stdoutTruncated ||= appended.truncated;
|
|
57
|
+
};
|
|
58
|
+
const onStderr = (chunk: string): void => {
|
|
59
|
+
const appended = boundedAppend(stderr, chunk);
|
|
60
|
+
stderr = appended.value;
|
|
61
|
+
stderrTruncated ||= appended.truncated;
|
|
62
|
+
};
|
|
63
|
+
const cleanup = (): void => {
|
|
64
|
+
if (exitFallback !== undefined) clearImmediate(exitFallback);
|
|
65
|
+
child.off("error", onError);
|
|
66
|
+
child.off("exit", onExit);
|
|
67
|
+
child.off("close", onClose);
|
|
68
|
+
child.stdout.off("data", onStdout);
|
|
69
|
+
child.stderr.off("data", onStderr);
|
|
70
|
+
child.stdout.destroy();
|
|
71
|
+
child.stderr.destroy();
|
|
72
|
+
};
|
|
73
|
+
const finish = (code: number | null): void => {
|
|
74
|
+
if (settled) return;
|
|
75
|
+
settled = true;
|
|
76
|
+
cleanup();
|
|
77
|
+
resolve({
|
|
78
|
+
exitCode: code ?? 1,
|
|
79
|
+
stdout,
|
|
80
|
+
stderr,
|
|
81
|
+
...(stdoutTruncated ? { stdoutTruncated: true as const } : {}),
|
|
82
|
+
...(stderrTruncated ? { stderrTruncated: true as const } : {}),
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const onError = (error: Error): void => {
|
|
86
|
+
if (settled) return;
|
|
87
|
+
settled = true;
|
|
88
|
+
cleanup();
|
|
89
|
+
reject(error);
|
|
90
|
+
};
|
|
91
|
+
const onExit = (code: number | null): void => {
|
|
92
|
+
if (code !== 0) return;
|
|
93
|
+
// pg_ctl redirects server output with `-l`; only its successful child
|
|
94
|
+
// exit needs early settlement because Postgres can retain inherited EOF.
|
|
95
|
+
exitFallback = setImmediate(() => finish(code));
|
|
96
|
+
};
|
|
97
|
+
const onClose = (code: number | null): void => finish(code);
|
|
98
|
+
child.stdout.on("data", onStdout);
|
|
99
|
+
child.stderr.on("data", onStderr);
|
|
100
|
+
child.once("error", onError);
|
|
101
|
+
if (options?.completion === "successful-exit") child.once("exit", onExit);
|
|
102
|
+
child.once("close", onClose);
|
|
47
103
|
});
|
|
48
104
|
}
|
|
49
105
|
|
|
@@ -71,7 +127,9 @@ export function tcpReachable(host: string, port: number, timeoutMs = 1_000): Pro
|
|
|
71
127
|
});
|
|
72
128
|
}
|
|
73
129
|
|
|
74
|
-
function boundedAppend(current: string, chunk: string): string {
|
|
130
|
+
function boundedAppend(current: string, chunk: string): { readonly value: string; readonly truncated: boolean } {
|
|
75
131
|
const next = current + chunk;
|
|
76
|
-
return next.length <= OUTPUT_LIMIT_BYTES
|
|
132
|
+
return next.length <= OUTPUT_LIMIT_BYTES
|
|
133
|
+
? { value: next, truncated: false }
|
|
134
|
+
: { value: next.slice(-OUTPUT_LIMIT_BYTES), truncated: true };
|
|
77
135
|
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
import type { WorkflowRegistry } from "../workflows/registry.js";
|
|
30
30
|
import type { WorkflowToolArgs } from "./index.js";
|
|
31
31
|
import type { WorkflowInputEntry, WorkflowToolResult } from "./render-result.js";
|
|
32
|
+
import { raceWorkflowRequestAbort } from "./workflow-request-abort.js";
|
|
32
33
|
|
|
33
34
|
type WorkflowRunResult = Extract<WorkflowToolResult, { action: "run" }>;
|
|
34
35
|
|
|
@@ -90,6 +91,10 @@ export interface DispatcherOpts {
|
|
|
90
91
|
cwd?: string;
|
|
91
92
|
/** Host-resolved non-default session directory inherited by stages without explicit sessionDir. */
|
|
92
93
|
defaultSessionDir?: string;
|
|
94
|
+
/** Cancels only startup admission waiting; the detached run keeps its own lifecycle. */
|
|
95
|
+
signal?: AbortSignal;
|
|
96
|
+
/** Reports the exact detached identity before startup admission is awaited. */
|
|
97
|
+
onRunAccepted?: (runId: string) => void;
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
// ---------------------------------------------------------------------------
|
|
@@ -198,7 +203,8 @@ export async function dispatch(args: WorkflowToolArgs, opts: DispatcherOpts): Pr
|
|
|
198
203
|
return failedRunResult(def.name, runId, error instanceof Error ? error.message : String(error));
|
|
199
204
|
}
|
|
200
205
|
const { accepted } = launch;
|
|
201
|
-
|
|
206
|
+
opts.onRunAccepted?.(accepted.runId);
|
|
207
|
+
const admission = await raceWorkflowRequestAbort(launch.wait, opts.signal);
|
|
202
208
|
if (!admission.started) {
|
|
203
209
|
const activeStore = opts.store ?? defaultStore;
|
|
204
210
|
const snapshot = activeStore.runs().find((run) => run.id === accepted.runId);
|
|
@@ -89,8 +89,8 @@ function factory(pi: ExtensionAPI): void {
|
|
|
89
89
|
runtimeState.ensureWorkflowResourcesLoaded,
|
|
90
90
|
{ resolvePostMortemDeps: (runId) => postMortemDepsForRun(runId, postMortemResolverDeps) },
|
|
91
91
|
);
|
|
92
|
-
const executeWorkflowToolWithAutoAttach: typeof executeWorkflowTool = async (args, ctx) => {
|
|
93
|
-
const result = await executeWorkflowTool(args, ctx);
|
|
92
|
+
const executeWorkflowToolWithAutoAttach: typeof executeWorkflowTool = async (args, ctx, signal, onRunAccepted) => {
|
|
93
|
+
const result = await executeWorkflowTool(args, ctx, signal, onRunAccepted);
|
|
94
94
|
if (
|
|
95
95
|
workflowPolicyFromContext(ctx).mode === "interactive" &&
|
|
96
96
|
typeof args.workflow === "string" &&
|