acpx 0.15.0 → 0.16.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.
Files changed (39) hide show
  1. package/dist/agent-registry-DU6mhZBL.js +785 -0
  2. package/dist/agent-registry-DU6mhZBL.js.map +1 -0
  3. package/dist/agent-registry.d.ts +70 -0
  4. package/dist/agent-registry.d.ts.map +1 -0
  5. package/dist/agent-registry.js +2 -0
  6. package/dist/{cli-Cen2Rb6S.js → cli-BkYIxj_N.js} +6 -14
  7. package/dist/cli-BkYIxj_N.js.map +1 -0
  8. package/dist/cli.d.ts +1 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +137 -333
  11. package/dist/cli.js.map +1 -1
  12. package/dist/{client-Cvz6msGc.d.ts → client-5levcBIs.d.ts} +11 -9
  13. package/dist/client-5levcBIs.d.ts.map +1 -0
  14. package/dist/{flows-D-F3Y2o9.js → flows-Bxs4udrs.js} +205 -277
  15. package/dist/flows-Bxs4udrs.js.map +1 -0
  16. package/dist/flows.d.ts +6 -17
  17. package/dist/flows.d.ts.map +1 -1
  18. package/dist/flows.js +1 -1
  19. package/dist/{flags-CRh8BJre.js → invocation-options-BY4lxkn3.js} +82 -58
  20. package/dist/invocation-options-BY4lxkn3.js.map +1 -0
  21. package/dist/{live-checkpoint-CYRs-D9t.js → live-checkpoint-BEfxBKCh.js} +1033 -1437
  22. package/dist/live-checkpoint-BEfxBKCh.js.map +1 -0
  23. package/dist/{output-CIVecnHU.js → output-uo5a27KB.js} +487 -490
  24. package/dist/output-uo5a27KB.js.map +1 -0
  25. package/dist/runtime.d.ts +105 -22
  26. package/dist/runtime.d.ts.map +1 -1
  27. package/dist/runtime.js +582 -366
  28. package/dist/runtime.js.map +1 -1
  29. package/dist/{session-options-DyIGRNfu.d.ts → session-options-t3d-F4dn.d.ts} +8 -6
  30. package/dist/session-options-t3d-F4dn.d.ts.map +1 -0
  31. package/package.json +27 -25
  32. package/skills/acpx/SKILL.md +19 -17
  33. package/dist/cli-Cen2Rb6S.js.map +0 -1
  34. package/dist/client-Cvz6msGc.d.ts.map +0 -1
  35. package/dist/flags-CRh8BJre.js.map +0 -1
  36. package/dist/flows-D-F3Y2o9.js.map +0 -1
  37. package/dist/live-checkpoint-CYRs-D9t.js.map +0 -1
  38. package/dist/output-CIVecnHU.js.map +0 -1
  39. package/dist/session-options-DyIGRNfu.d.ts.map +0 -1
@@ -1,11 +1,13 @@
1
- import { d as createSessionWithClient, f as cancelSessionPrompt, o as runOnce, s as sendSessionDirect, t as createOutputFormatter } from "./output-CIVecnHU.js";
2
- import { Dt as TimeoutError, Et as InterruptedError, F as runTimedExecFile, Ot as withInterrupt, Tt as textPrompt, Y as resolveSessionRecord, Yt as PERMISSION_MODES, Zt as SESSION_RECORD_SCHEMA, _ as recordPromptSubmission, dt as defaultSessionEventLog, g as recordClientOperation, h as createSessionConversation, kt as withTimeout, p as cloneSessionAcpxState, v as recordSessionUpdate, wt as promptToDisplayText } from "./live-checkpoint-CYRs-D9t.js";
1
+ import { f as createSessionWithClient, o as runOnce, p as cancelSessionPrompt, s as sendSessionDirect, t as createOutputFormatter } from "./output-uo5a27KB.js";
2
+ import { C as recordSessionUpdate, Dt as withTimeout, Et as withInterrupt, I as promptToDisplayText, L as textPrompt, S as recordPromptSubmission, Tt as TimeoutError, Ut as SESSION_RECORD_SCHEMA, Vt as PERMISSION_MODES, Y as resolveSessionRecord, b as createSessionConversation, gt as writePrivateJsonFile, ht as writePrivateFile, ut as defaultSessionEventLog, v as cloneSessionAcpxState, wt as InterruptedError, x as recordClientOperation } from "./live-checkpoint-BEfxBKCh.js";
3
+ import { M as runTimedExecFile } from "./agent-registry-DU6mhZBL.js";
3
4
  import path from "node:path";
5
+ import { spawn } from "node:child_process";
4
6
  import fs from "node:fs/promises";
5
7
  import os from "node:os";
8
+ import { appendRegularFile } from "@openclaw/fs-safe/advanced";
6
9
  import { createHash, randomUUID } from "node:crypto";
7
10
  import { ZodError, z } from "zod";
8
- import { spawn } from "node:child_process";
9
11
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
10
12
  //#region src/flows/authoring.ts
11
13
  const FLOW_DEFINITION_BRAND = Symbol.for("acpx.flow.definition");
@@ -592,9 +594,12 @@ function validateFlowEdge(flow, edge, outgoingEdges) {
592
594
  }
593
595
  for (const target of Object.values(edge.switch.cases)) assertKnownFlowNode(flow, target, "Flow switch references unknown to-node");
594
596
  }
597
+ function canFollowEdge(edge, result) {
598
+ return !result || result.outcome === "ok" || "switch" in edge && edge.switch.on.startsWith("$result.");
599
+ }
595
600
  function resolveNext(edges, from, output, result) {
596
601
  const edge = edges.find((candidate) => candidate.from === from);
597
- if (!edge) return null;
602
+ if (!edge || !canFollowEdge(edge, result)) return null;
598
603
  if ("to" in edge) return edge.to;
599
604
  const value = getBySwitchPath(output, result, edge.switch.on);
600
605
  if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") throw new Error(`Flow switch value must be scalar for ${edge.switch.on}`);
@@ -602,16 +607,6 @@ function resolveNext(edges, from, output, result) {
602
607
  if (!next) throw new Error(`No flow switch case for ${edge.switch.on}=${JSON.stringify(value)}`);
603
608
  return next;
604
609
  }
605
- function resolveNextForOutcome(edges, from, result) {
606
- const edge = edges.find((candidate) => candidate.from === from);
607
- if (!edge || "to" in edge) return null;
608
- if (!edge.switch.on.startsWith("$result.")) return null;
609
- const value = getBySwitchPath(void 0, result, edge.switch.on);
610
- if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") throw new Error(`Flow switch value must be scalar for ${edge.switch.on}`);
611
- const next = edge.switch.cases[String(value)];
612
- if (!next) throw new Error(`No flow switch case for ${edge.switch.on}=${JSON.stringify(value)}`);
613
- return next;
614
- }
615
610
  function getBySwitchPath(output, result, jsonPath) {
616
611
  if (jsonPath.startsWith("$result.")) return getByPath(result, `$.${jsonPath.slice(8)}`);
617
612
  if (jsonPath.startsWith("$output.")) return getByPath(output, `$.${jsonPath.slice(8)}`);
@@ -919,41 +914,30 @@ var FlowRunStore = class {
919
914
  }
920
915
  async createRunDir(runId) {
921
916
  const runDir = path.join(this.outputRoot, runId);
922
- await fs.mkdir(path.join(runDir, PROJECTIONS_DIR), { recursive: true });
923
- await fs.mkdir(path.join(runDir, SESSIONS_DIR), { recursive: true });
924
- await fs.mkdir(path.join(runDir, ARTIFACTS_DIR), { recursive: true });
917
+ await fs.mkdir(path.join(runDir, PROJECTIONS_DIR), {
918
+ recursive: true,
919
+ mode: 448
920
+ });
921
+ await fs.mkdir(path.join(runDir, SESSIONS_DIR), {
922
+ recursive: true,
923
+ mode: 448
924
+ });
925
+ await fs.mkdir(path.join(runDir, ARTIFACTS_DIR), {
926
+ recursive: true,
927
+ mode: 448
928
+ });
925
929
  this.traceSeqByRun.set(runDir, 0);
926
930
  return runDir;
927
931
  }
928
932
  async initializeRunBundle(runDir, options) {
929
933
  const snapshot = createFlowDefinitionSnapshot(options.flow);
930
- const manifest = {
931
- schema: FLOW_BUNDLE_SCHEMA,
932
- runId: options.state.runId,
933
- flowName: options.state.flowName,
934
- runTitle: options.state.runTitle,
935
- flowPath: options.state.flowPath,
936
- startedAt: options.state.startedAt,
937
- finishedAt: options.state.finishedAt,
938
- status: options.state.status,
939
- traceSchema: FLOW_TRACE_SCHEMA,
940
- paths: {
941
- flow: FLOW_SNAPSHOT_PATH,
942
- trace: TRACE_PATH,
943
- runProjection: RUN_PROJECTION_PATH,
944
- liveProjection: LIVE_PROJECTION_PATH,
945
- stepsProjection: STEPS_PROJECTION_PATH,
946
- sessionsDir: SESSIONS_DIR,
947
- artifactsDir: ARTIFACTS_DIR
948
- },
949
- sessions: []
950
- };
934
+ const manifest = createRunManifest(options.state);
951
935
  this.manifestByRun.set(runDir, manifest);
952
- await writeJsonAtomic(this.resolveRunPath(runDir, FLOW_SNAPSHOT_PATH), snapshot);
953
- await writeJsonAtomic(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
954
- await writeJsonAtomic(this.resolveRunPath(runDir, RUN_PROJECTION_PATH), options.state);
955
- await writeJsonAtomic(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(options.state));
956
- await writeJsonAtomic(this.resolveRunPath(runDir, STEPS_PROJECTION_PATH), options.state.steps);
936
+ await writePrivateJsonFile(this.resolveRunPath(runDir, FLOW_SNAPSHOT_PATH), snapshot);
937
+ await writePrivateJsonFile(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
938
+ await writePrivateJsonFile(this.resolveRunPath(runDir, RUN_PROJECTION_PATH), options.state);
939
+ await writePrivateJsonFile(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(options.state));
940
+ await writePrivateJsonFile(this.resolveRunPath(runDir, STEPS_PROJECTION_PATH), options.state.steps);
957
941
  await ensureFile(this.resolveRunPath(runDir, TRACE_PATH));
958
942
  await this.appendTrace(runDir, options.state, {
959
943
  scope: "run",
@@ -968,15 +952,15 @@ var FlowRunStore = class {
968
952
  }
969
953
  async writeSnapshot(runDir, state, event) {
970
954
  state.updatedAt = isoNow();
971
- await writeJsonAtomic(this.resolveRunPath(runDir, RUN_PROJECTION_PATH), state);
972
- await writeJsonAtomic(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(state));
973
- await writeJsonAtomic(this.resolveRunPath(runDir, STEPS_PROJECTION_PATH), state.steps);
955
+ await writePrivateJsonFile(this.resolveRunPath(runDir, RUN_PROJECTION_PATH), state);
956
+ await writePrivateJsonFile(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(state));
957
+ await writePrivateJsonFile(this.resolveRunPath(runDir, STEPS_PROJECTION_PATH), state.steps);
974
958
  await this.writeManifest(runDir, state);
975
959
  await this.appendTrace(runDir, state, event);
976
960
  }
977
961
  async writeLive(runDir, state, event) {
978
962
  state.updatedAt = isoNow();
979
- await writeJsonAtomic(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(state));
963
+ await writePrivateJsonFile(this.resolveRunPath(runDir, LIVE_PROJECTION_PATH), createLiveState(state));
980
964
  await this.writeManifest(runDir, state);
981
965
  await this.appendTrace(runDir, state, event);
982
966
  }
@@ -995,11 +979,10 @@ var FlowRunStore = class {
995
979
  const sha256 = createHash("sha256").update(buffer).digest("hex");
996
980
  const relativePath = path.posix.join(ARTIFACTS_DIR, `sha256-${sha256}${normalizeArtifactExtension(options.extension)}`);
997
981
  const filePath = this.resolveRunPath(runDir, relativePath);
998
- await fs.mkdir(path.dirname(filePath), { recursive: true });
999
982
  try {
1000
983
  await fs.access(filePath);
1001
984
  } catch {
1002
- await fs.writeFile(filePath, buffer);
985
+ await writePrivateFile(filePath, buffer);
1003
986
  }
1004
987
  const artifact = {
1005
988
  path: relativePath,
@@ -1020,8 +1003,11 @@ var FlowRunStore = class {
1020
1003
  }
1021
1004
  async ensureSessionBundle(runDir, state, binding, record) {
1022
1005
  const sessionDir = this.resolveRunPath(runDir, sessionDirPath(binding.bundleId));
1023
- await fs.mkdir(sessionDir, { recursive: true });
1024
- await writeJsonAtomic(path.join(sessionDir, "binding.json"), binding);
1006
+ await fs.mkdir(sessionDir, {
1007
+ recursive: true,
1008
+ mode: 448
1009
+ });
1010
+ await writePrivateJsonFile(path.join(sessionDir, "binding.json"), binding);
1025
1011
  await ensureFile(path.join(sessionDir, "events.ndjson"));
1026
1012
  if (record) await this.writeSessionRecord(runDir, state, binding, record);
1027
1013
  const manifest = this.getManifest(runDir, state);
@@ -1035,7 +1021,7 @@ var FlowRunStore = class {
1035
1021
  eventsPath: path.posix.join(sessionDirPath(binding.bundleId), "events.ndjson")
1036
1022
  };
1037
1023
  manifest.sessions.push(entry);
1038
- await writeJsonAtomic(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
1024
+ await writePrivateJsonFile(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
1039
1025
  }
1040
1026
  if (isNew) await this.appendTrace(runDir, state, {
1041
1027
  scope: "session",
@@ -1054,7 +1040,7 @@ var FlowRunStore = class {
1054
1040
  }
1055
1041
  async writeSessionRecord(runDir, _state, binding, record) {
1056
1042
  const bundledRecord = createBundledSessionRecord(binding, record, this.sessionSeqByBundle.get(`${runDir}::${binding.bundleId}`) ?? 0);
1057
- await writeJsonAtomic(this.resolveRunPath(runDir, path.posix.join(sessionDirPath(binding.bundleId), "record.json")), bundledRecord);
1043
+ await writePrivateJsonFile(this.resolveRunPath(runDir, path.posix.join(sessionDirPath(binding.bundleId), "record.json")), bundledRecord);
1058
1044
  }
1059
1045
  async appendSessionEvent(runDir, binding, direction, message) {
1060
1046
  const sessionKey = `${runDir}::${binding.bundleId}`;
@@ -1079,33 +1065,13 @@ var FlowRunStore = class {
1079
1065
  existing.runTitle = state.runTitle;
1080
1066
  return existing;
1081
1067
  }
1082
- const created = {
1083
- schema: FLOW_BUNDLE_SCHEMA,
1084
- runId: state.runId,
1085
- flowName: state.flowName,
1086
- runTitle: state.runTitle,
1087
- flowPath: state.flowPath,
1088
- startedAt: state.startedAt,
1089
- finishedAt: state.finishedAt,
1090
- status: state.status,
1091
- traceSchema: FLOW_TRACE_SCHEMA,
1092
- paths: {
1093
- flow: FLOW_SNAPSHOT_PATH,
1094
- trace: TRACE_PATH,
1095
- runProjection: RUN_PROJECTION_PATH,
1096
- liveProjection: LIVE_PROJECTION_PATH,
1097
- stepsProjection: STEPS_PROJECTION_PATH,
1098
- sessionsDir: SESSIONS_DIR,
1099
- artifactsDir: ARTIFACTS_DIR
1100
- },
1101
- sessions: []
1102
- };
1068
+ const created = createRunManifest(state);
1103
1069
  this.manifestByRun.set(runDir, created);
1104
1070
  return created;
1105
1071
  }
1106
1072
  async writeManifest(runDir, state) {
1107
1073
  const manifest = this.getManifest(runDir, state);
1108
- await writeJsonAtomic(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
1074
+ await writePrivateJsonFile(this.resolveRunPath(runDir, MANIFEST_PATH), manifest);
1109
1075
  }
1110
1076
  nextTraceSeq(runDir) {
1111
1077
  const next = (this.traceSeqByRun.get(runDir) ?? 0) + 1;
@@ -1117,8 +1083,15 @@ var FlowRunStore = class {
1117
1083
  }
1118
1084
  async appendJsonLine(filePath, value) {
1119
1085
  const tracked = (this.appendChainByPath.get(filePath) ?? Promise.resolve()).then(async () => {
1120
- await fs.mkdir(path.dirname(filePath), { recursive: true });
1121
- await fs.appendFile(filePath, `${JSON.stringify(value)}\n`, "utf8");
1086
+ await fs.mkdir(path.dirname(filePath), {
1087
+ recursive: true,
1088
+ mode: 448
1089
+ });
1090
+ await appendRegularFile({
1091
+ filePath,
1092
+ content: `${JSON.stringify(value)}\n`,
1093
+ mode: 384
1094
+ });
1122
1095
  }).finally(() => {
1123
1096
  if (this.appendChainByPath.get(filePath) === tracked) this.appendChainByPath.delete(filePath);
1124
1097
  });
@@ -1126,6 +1099,29 @@ var FlowRunStore = class {
1126
1099
  await tracked;
1127
1100
  }
1128
1101
  };
1102
+ function createRunManifest(state) {
1103
+ return {
1104
+ schema: FLOW_BUNDLE_SCHEMA,
1105
+ runId: state.runId,
1106
+ flowName: state.flowName,
1107
+ runTitle: state.runTitle,
1108
+ flowPath: state.flowPath,
1109
+ startedAt: state.startedAt,
1110
+ finishedAt: state.finishedAt,
1111
+ status: state.status,
1112
+ traceSchema: FLOW_TRACE_SCHEMA,
1113
+ paths: {
1114
+ flow: FLOW_SNAPSHOT_PATH,
1115
+ trace: TRACE_PATH,
1116
+ runProjection: RUN_PROJECTION_PATH,
1117
+ liveProjection: LIVE_PROJECTION_PATH,
1118
+ stepsProjection: STEPS_PROJECTION_PATH,
1119
+ sessionsDir: SESSIONS_DIR,
1120
+ artifactsDir: ARTIFACTS_DIR
1121
+ },
1122
+ sessions: []
1123
+ };
1124
+ }
1129
1125
  function createLiveState(state) {
1130
1126
  return {
1131
1127
  runId: state.runId,
@@ -1225,16 +1221,12 @@ function createBundledSessionRecord(binding, record, bundleLastSeq) {
1225
1221
  }
1226
1222
  };
1227
1223
  }
1228
- async function writeJsonAtomic(filePath, value) {
1229
- const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
1230
- const payload = JSON.stringify(value, null, 2);
1231
- await fs.mkdir(path.dirname(filePath), { recursive: true });
1232
- await fs.writeFile(tempPath, `${payload}\n`, "utf8");
1233
- await fs.rename(tempPath, filePath);
1234
- }
1235
1224
  async function ensureFile(filePath) {
1236
- await fs.mkdir(path.dirname(filePath), { recursive: true });
1237
- await fs.appendFile(filePath, "", "utf8");
1225
+ await appendRegularFile({
1226
+ filePath,
1227
+ content: "",
1228
+ mode: 384
1229
+ });
1238
1230
  }
1239
1231
  async function fileSha256(filePath) {
1240
1232
  const payload = await fs.readFile(filePath);
@@ -1264,16 +1256,8 @@ const DEFAULT_FLOW_STEP_TIMEOUT_MS = 9e5;
1264
1256
  var FlowRunner = class {
1265
1257
  resolveAgent;
1266
1258
  defaultCwd;
1267
- permissionMode;
1268
- mcpServers;
1269
- nonInteractivePermissions;
1270
- permissionPolicy;
1271
- authCredentials;
1272
- authPolicy;
1273
- fs;
1274
- timeoutMs;
1259
+ connectionOptions;
1275
1260
  defaultNodeTimeoutMs;
1276
- verbose;
1277
1261
  suppressSdkConsoleErrors;
1278
1262
  sessionOptions;
1279
1263
  services;
@@ -1285,16 +1269,17 @@ var FlowRunner = class {
1285
1269
  constructor(options) {
1286
1270
  this.resolveAgent = options.resolveAgent;
1287
1271
  this.defaultCwd = options.resolveAgent(void 0).cwd;
1288
- this.permissionMode = options.permissionMode;
1289
- this.mcpServers = options.mcpServers;
1290
- this.nonInteractivePermissions = options.nonInteractivePermissions;
1291
- this.permissionPolicy = options.permissionPolicy;
1292
- this.authCredentials = options.authCredentials;
1293
- this.authPolicy = options.authPolicy;
1294
- this.fs = options.fs;
1295
- this.timeoutMs = options.timeoutMs;
1272
+ this.connectionOptions = {
1273
+ permissionMode: options.permissionMode,
1274
+ mcpServers: options.mcpServers,
1275
+ nonInteractivePermissions: options.nonInteractivePermissions,
1276
+ permissionPolicy: options.permissionPolicy,
1277
+ authCredentials: options.authCredentials,
1278
+ authPolicy: options.authPolicy,
1279
+ fs: options.fs,
1280
+ verbose: options.verbose
1281
+ };
1296
1282
  this.defaultNodeTimeoutMs = options.defaultNodeTimeoutMs ?? options.timeoutMs ?? DEFAULT_FLOW_STEP_TIMEOUT_MS;
1297
- this.verbose = options.verbose;
1298
1283
  this.suppressSdkConsoleErrors = options.suppressSdkConsoleErrors;
1299
1284
  this.sessionOptions = options.sessionOptions;
1300
1285
  this.services = options.services ?? {};
@@ -1432,16 +1417,47 @@ var FlowRunner = class {
1432
1417
  const startedAt = isoNow$1();
1433
1418
  markNodeStarted(state, nodeId, attemptId, node.nodeType, startedAt, node.statusDetail);
1434
1419
  await this.writeNodeStartedSnapshot(runDir, state, nodeId, attemptId, node);
1435
- return await this.executeStartedFlowStep({
1436
- flow,
1437
- input,
1438
- runDir,
1439
- state,
1440
- nodeId,
1441
- node,
1420
+ const context = makeFlowNodeContext(state, input, this.services);
1421
+ let executed;
1422
+ let outcome = "ok";
1423
+ let executionError;
1424
+ try {
1425
+ this.throwIfRunInterrupted(runDir);
1426
+ executed = await this.executeNode(runDir, state, flow, nodeId, node, context);
1427
+ this.throwIfRunInterrupted(runDir);
1428
+ executed.trace = await finalizeStepTrace(this.store, runDir, state, nodeId, attemptId, executed.output, executed.trace);
1429
+ } catch (error) {
1430
+ outcome = outcomeForError(error);
1431
+ executionError = error;
1432
+ executed = {
1433
+ output: void 0,
1434
+ promptText: null,
1435
+ rawText: null,
1436
+ sessionInfo: null,
1437
+ agentInfo: null,
1438
+ trace: await finalizeStepTrace(this.store, runDir, state, nodeId, attemptId, void 0, extractAttachedStepTrace(error) ?? null)
1439
+ };
1440
+ }
1441
+ const nodeResult = createNodeResult({
1442
1442
  attemptId,
1443
- startedAt
1443
+ nodeId,
1444
+ nodeType: node.nodeType,
1445
+ outcome,
1446
+ startedAt,
1447
+ finishedAt: isoNow$1(),
1448
+ ...outcome === "ok" ? { output: executed.output } : { error: executionError instanceof Error ? executionError.message : String(executionError) }
1444
1449
  });
1450
+ state.results[nodeId] = nodeResult;
1451
+ return {
1452
+ ...executed,
1453
+ nodeResult,
1454
+ executionError,
1455
+ attemptId,
1456
+ nodeId,
1457
+ node,
1458
+ startedAt,
1459
+ state
1460
+ };
1445
1461
  }
1446
1462
  async writeNodeStartedSnapshot(runDir, state, nodeId, attemptId, node) {
1447
1463
  await this.store.writeSnapshot(runDir, state, {
@@ -1451,84 +1467,18 @@ var FlowRunner = class {
1451
1467
  attemptId,
1452
1468
  payload: {
1453
1469
  nodeType: node.nodeType,
1454
- ...node.timeoutMs !== void 0 ? { timeoutMs: node.timeoutMs ?? this.defaultNodeTimeoutMs } : { timeoutMs: this.defaultNodeTimeoutMs },
1470
+ timeoutMs: node.timeoutMs ?? this.defaultNodeTimeoutMs,
1455
1471
  ...state.statusDetail ? { statusDetail: state.statusDetail } : {}
1456
1472
  }
1457
1473
  });
1458
1474
  }
1459
- async executeStartedFlowStep(params) {
1460
- const context = makeFlowNodeContext(params.state, params.input, this.services);
1461
- try {
1462
- this.throwIfRunInterrupted(params.runDir);
1463
- const executed = await this.executeNode(params.runDir, params.state, params.flow, params.nodeId, params.node, context);
1464
- this.throwIfRunInterrupted(params.runDir);
1465
- return await this.createSuccessfulFlowStep(params, executed);
1466
- } catch (error) {
1467
- return await this.createFailedFlowStep(params, error);
1468
- }
1469
- }
1470
- async createSuccessfulFlowStep(params, executed) {
1471
- const trace = await finalizeStepTrace(this.store, params.runDir, params.state, params.nodeId, params.attemptId, executed.output, executed.trace);
1472
- const nodeResult = createNodeResult({
1473
- attemptId: params.attemptId,
1474
- nodeId: params.nodeId,
1475
- nodeType: params.node.nodeType,
1476
- outcome: "ok",
1477
- startedAt: params.startedAt,
1478
- finishedAt: isoNow$1(),
1479
- output: executed.output
1480
- });
1481
- params.state.results[params.nodeId] = nodeResult;
1482
- return {
1483
- ...executed,
1484
- trace,
1485
- nodeResult,
1486
- attemptId: params.attemptId,
1487
- nodeId: params.nodeId,
1488
- node: params.node,
1489
- startedAt: params.startedAt,
1490
- state: params.state
1491
- };
1492
- }
1493
- async createFailedFlowStep(params, error) {
1494
- const trace = await finalizeStepTrace(this.store, params.runDir, params.state, params.nodeId, params.attemptId, void 0, extractAttachedStepTrace(error) ?? null);
1495
- const nodeResult = createNodeResult({
1496
- attemptId: params.attemptId,
1497
- nodeId: params.nodeId,
1498
- nodeType: params.node.nodeType,
1499
- outcome: outcomeForError(error),
1500
- startedAt: params.startedAt,
1501
- finishedAt: isoNow$1(),
1502
- error: error instanceof Error ? error.message : String(error)
1503
- });
1504
- params.state.results[params.nodeId] = nodeResult;
1505
- return {
1506
- output: void 0,
1507
- promptText: null,
1508
- rawText: null,
1509
- sessionInfo: null,
1510
- agentInfo: null,
1511
- trace,
1512
- nodeResult,
1513
- executionError: error,
1514
- attemptId: params.attemptId,
1515
- nodeId: params.nodeId,
1516
- node: params.node,
1517
- startedAt: params.startedAt,
1518
- state: params.state
1519
- };
1520
- }
1521
1475
  async maybeCompleteCheckpointStep(runDir, state, step) {
1522
1476
  if (step.nodeResult.outcome !== "ok" || step.node.nodeType !== "checkpoint") return;
1523
1477
  state.outputs[step.nodeId] = step.output;
1524
1478
  state.waitingOn = step.nodeId;
1525
1479
  state.updatedAt = isoNow$1();
1526
1480
  state.status = "waiting";
1527
- await this.recordFlowStepOutcome(runDir, state, step, {
1528
- sessionInfo: null,
1529
- agentInfo: null,
1530
- statusDetail: step.output?.summary ?? step.nodeId
1531
- });
1481
+ await this.recordFlowStepOutcome(runDir, state, step, { statusDetail: step.output?.summary ?? step.nodeId });
1532
1482
  return {
1533
1483
  runDir,
1534
1484
  state
@@ -1539,7 +1489,7 @@ var FlowRunner = class {
1539
1489
  step.state.outputs[step.nodeId] = step.output;
1540
1490
  return resolveNext(flow.edges, step.nodeId, step.output, step.nodeResult);
1541
1491
  }
1542
- const next = resolveNextForOutcome(flow.edges, step.nodeId, step.nodeResult);
1492
+ const next = resolveNext(flow.edges, step.nodeId, void 0, step.nodeResult);
1543
1493
  if (next) return next;
1544
1494
  throw step.executionError;
1545
1495
  }
@@ -1572,8 +1522,8 @@ var FlowRunner = class {
1572
1522
  rawText: step.rawText,
1573
1523
  output: step.output,
1574
1524
  error: step.nodeResult.error,
1575
- session: overrides.sessionInfo ?? step.sessionInfo,
1576
- agent: overrides.agentInfo ?? step.agentInfo,
1525
+ session: step.sessionInfo,
1526
+ agent: step.agentInfo,
1577
1527
  ...step.trace ? { trace: step.trace } : {}
1578
1528
  });
1579
1529
  await this.store.writeSnapshot(runDir, state, {
@@ -1586,34 +1536,28 @@ var FlowRunner = class {
1586
1536
  }
1587
1537
  async executeNode(runDir, state, flow, nodeId, node, context) {
1588
1538
  switch (node.nodeType) {
1589
- case "compute": return await this.executeComputeNode(runDir, state, node, context);
1590
- case "action": return await this.executeActionNode(runDir, state, node, context);
1591
- case "checkpoint": return await this.executeCheckpointNode(runDir, state, nodeId, node, context);
1539
+ case "compute": return await this.executeCallbackNode(runDir, state, nodeId, node, context);
1540
+ case "action": return "run" in node ? await this.executeCallbackNode(runDir, state, nodeId, node, context) : await this.executeShellNode(runDir, state, node, context);
1541
+ case "checkpoint": return await this.executeCallbackNode(runDir, state, nodeId, node, context);
1592
1542
  case "acp": return await this.executeAcpNode(runDir, state, flow, node, context);
1593
1543
  default: throw new Error(`Unsupported flow node: ${String(node)}`);
1594
1544
  }
1595
1545
  }
1596
- async executeComputeNode(runDir, state, node, context) {
1597
- const nodeTimeoutMs = node.timeoutMs ?? this.defaultNodeTimeoutMs;
1546
+ async executeCallbackNode(runDir, state, nodeId, node, context) {
1598
1547
  return {
1599
- output: await this.runWithHeartbeat(runDir, state, state.currentNode ?? "", node, nodeTimeoutMs, async () => await Promise.resolve(node.run(context))),
1548
+ output: node.nodeType === "checkpoint" && typeof node.run !== "function" ? {
1549
+ checkpoint: nodeId,
1550
+ summary: node.summary ?? nodeId
1551
+ } : await this.runWithHeartbeat(runDir, state, nodeId, node, node.timeoutMs ?? this.defaultNodeTimeoutMs, async () => await node.run?.(context)),
1600
1552
  promptText: null,
1601
1553
  rawText: null,
1602
1554
  sessionInfo: null,
1603
1555
  agentInfo: null,
1604
- trace: null
1556
+ trace: node.nodeType === "action" ? { action: { actionType: "function" } } : null
1605
1557
  };
1606
1558
  }
1607
- async executeActionNode(runDir, state, node, context) {
1559
+ async executeShellNode(runDir, state, node, context) {
1608
1560
  const nodeTimeoutMs = node.timeoutMs ?? this.defaultNodeTimeoutMs;
1609
- if ("run" in node) return {
1610
- output: await this.runWithHeartbeat(runDir, state, state.currentNode ?? "", node, nodeTimeoutMs, async () => await Promise.resolve(node.run(context))),
1611
- promptText: null,
1612
- rawText: null,
1613
- sessionInfo: null,
1614
- agentInfo: null,
1615
- trace: { action: { actionType: "function" } }
1616
- };
1617
1561
  const shellAbort = new AbortController();
1618
1562
  let runningOwner;
1619
1563
  const shellControl = {
@@ -1739,20 +1683,6 @@ var FlowRunner = class {
1739
1683
  trace
1740
1684
  };
1741
1685
  }
1742
- async executeCheckpointNode(runDir, state, nodeId, node, context) {
1743
- const nodeTimeoutMs = node.timeoutMs ?? this.defaultNodeTimeoutMs;
1744
- return {
1745
- output: typeof node.run === "function" ? await this.runWithHeartbeat(runDir, state, state.currentNode ?? "", node, nodeTimeoutMs, async () => await Promise.resolve(node.run?.(context))) : {
1746
- checkpoint: nodeId,
1747
- summary: node.summary ?? nodeId
1748
- },
1749
- promptText: null,
1750
- rawText: null,
1751
- sessionInfo: null,
1752
- agentInfo: null,
1753
- trace: null
1754
- };
1755
- }
1756
1686
  async executeAcpNode(runDir, state, flow, node, context) {
1757
1687
  const nodeTimeoutMs = node.timeoutMs ?? this.defaultNodeTimeoutMs;
1758
1688
  let boundSession = null;
@@ -1932,15 +1862,8 @@ var FlowRunner = class {
1932
1862
  agentArgv: agent.agentArgv,
1933
1863
  cwd: agent.cwd,
1934
1864
  name,
1935
- mcpServers: this.mcpServers,
1936
- permissionMode: this.permissionMode,
1937
- nonInteractivePermissions: this.nonInteractivePermissions,
1938
- permissionPolicy: this.permissionPolicy,
1939
- authCredentials: this.authCredentials,
1940
- authPolicy: this.authPolicy,
1941
- fs: this.fs,
1865
+ ...this.connectionOptions,
1942
1866
  timeoutMs,
1943
- verbose: this.verbose,
1944
1867
  sessionOptions: this.sessionOptions
1945
1868
  });
1946
1869
  const binding = {
@@ -1970,40 +1893,68 @@ var FlowRunner = class {
1970
1893
  agentSessionId: record.agentSessionId
1971
1894
  };
1972
1895
  }
1896
+ createPromptEventCapture(runDir, binding) {
1897
+ const pending = [];
1898
+ return {
1899
+ onAcpMessage: (direction, message) => {
1900
+ pending.push(this.store.appendSessionEvent(runDir, binding, direction, message).then((value) => ({
1901
+ status: "fulfilled",
1902
+ value
1903
+ }), (reason) => ({
1904
+ status: "rejected",
1905
+ reason
1906
+ })));
1907
+ },
1908
+ async run(operation) {
1909
+ let result;
1910
+ try {
1911
+ result = {
1912
+ status: "fulfilled",
1913
+ value: await operation()
1914
+ };
1915
+ } catch (reason) {
1916
+ result = {
1917
+ status: "rejected",
1918
+ reason
1919
+ };
1920
+ }
1921
+ const writes = await Promise.all(pending);
1922
+ if (result.status === "rejected") throw result.reason;
1923
+ let eventStartSeq;
1924
+ let eventEndSeq = 0;
1925
+ for (const write of writes) {
1926
+ if (write.status === "rejected") throw write.reason;
1927
+ eventStartSeq = Math.min(eventStartSeq ?? write.value, write.value);
1928
+ eventEndSeq = Math.max(eventEndSeq, write.value);
1929
+ }
1930
+ if (eventStartSeq === void 0) throw new Error(`Missing ACP event capture for session ${binding.bundleId}`);
1931
+ return {
1932
+ result: result.value,
1933
+ eventStartSeq,
1934
+ eventEndSeq
1935
+ };
1936
+ }
1937
+ };
1938
+ }
1973
1939
  async runPersistentPrompt(runDir, state, binding, prompt, timeoutMs) {
1974
1940
  const capture = createQuietCaptureOutput();
1975
1941
  const beforeRecord = await resolveSessionRecord(binding.acpxRecordId);
1976
- let eventStartSeq;
1977
- let eventEndSeq;
1978
- const pendingEventWrites = [];
1942
+ const events = this.createPromptEventCapture(runDir, binding);
1979
1943
  const initialClient = this.pendingPersistentSessionClients.get(binding.key);
1980
1944
  if (initialClient) this.pendingPersistentSessionClients.delete(binding.key);
1981
1945
  try {
1982
- await sendSessionDirect({
1946
+ const { eventStartSeq, eventEndSeq } = await events.run(() => sendSessionDirect({
1983
1947
  sessionId: binding.acpxRecordId,
1984
1948
  prompt,
1985
1949
  resumePolicy: "same-session-only",
1986
- mcpServers: this.mcpServers,
1987
- permissionMode: this.permissionMode,
1988
- nonInteractivePermissions: this.nonInteractivePermissions,
1989
- permissionPolicy: this.permissionPolicy,
1990
- authCredentials: this.authCredentials,
1991
- authPolicy: this.authPolicy,
1992
- fs: this.fs,
1950
+ ...this.connectionOptions,
1993
1951
  outputFormatter: capture.formatter,
1994
- onAcpMessage: (direction, message) => {
1995
- const pending = this.store.appendSessionEvent(runDir, binding, direction, message).then((seq) => {
1996
- eventStartSeq = eventStartSeq === void 0 ? seq : Math.min(eventStartSeq, seq);
1997
- eventEndSeq = eventEndSeq === void 0 ? seq : Math.max(eventEndSeq, seq);
1998
- });
1999
- pendingEventWrites.push(pending);
2000
- },
1952
+ errorEmissionPolicy: { queueErrorAlreadyEmitted: false },
1953
+ onAcpMessage: events.onAcpMessage,
2001
1954
  suppressSdkConsoleErrors: this.suppressSdkConsoleErrors,
2002
1955
  timeoutMs,
2003
- verbose: this.verbose,
2004
1956
  client: initialClient
2005
- });
2006
- await Promise.all(pendingEventWrites);
1957
+ }));
2007
1958
  const sessionInfo = await this.refreshSessionBinding(binding);
2008
1959
  state.sessionBindings[sessionInfo.key] = sessionInfo;
2009
1960
  await this.store.ensureSessionBundle(runDir, state, sessionInfo);
@@ -2017,12 +1968,8 @@ var FlowRunner = class {
2017
1968
  sessionId: sessionInfo.bundleId,
2018
1969
  messageStart: messageStartResolved,
2019
1970
  messageEnd: Math.max(messageStartResolved, afterRecord.messages.length - 1),
2020
- eventStartSeq: eventStartSeq ?? (() => {
2021
- throw new Error(`Missing ACP event capture for session ${sessionInfo.bundleId}`);
2022
- })(),
2023
- eventEndSeq: eventEndSeq ?? (() => {
2024
- throw new Error(`Missing ACP event capture for session ${sessionInfo.bundleId}`);
2025
- })()
1971
+ eventStartSeq,
1972
+ eventEndSeq
2026
1973
  }
2027
1974
  };
2028
1975
  } finally {
@@ -2041,29 +1988,16 @@ var FlowRunner = class {
2041
1988
  const conversation = createSessionConversation(state.currentNodeStartedAt ?? isoNow$1());
2042
1989
  let acpxState;
2043
1990
  recordPromptSubmission(conversation, prompt, state.currentNodeStartedAt ?? isoNow$1());
2044
- let eventStartSeq;
2045
- let eventEndSeq;
2046
- const pendingEventWrites = [];
2047
- const result = await runOnce({
1991
+ const events = this.createPromptEventCapture(runDir, binding);
1992
+ const { result, eventStartSeq, eventEndSeq } = await events.run(() => runOnce({
2048
1993
  agentCommand: agent.agentCommand,
2049
1994
  agentArgv: agent.agentArgv,
2050
1995
  cwd: agent.cwd,
2051
1996
  prompt,
2052
- mcpServers: this.mcpServers,
2053
- permissionMode: this.permissionMode,
2054
- nonInteractivePermissions: this.nonInteractivePermissions,
2055
- permissionPolicy: this.permissionPolicy,
2056
- authCredentials: this.authCredentials,
2057
- authPolicy: this.authPolicy,
2058
- fs: this.fs,
1997
+ ...this.connectionOptions,
2059
1998
  outputFormatter: capture.formatter,
2060
- onAcpMessage: (direction, message) => {
2061
- const pending = this.store.appendSessionEvent(runDir, binding, direction, message).then((seq) => {
2062
- eventStartSeq = eventStartSeq === void 0 ? seq : Math.min(eventStartSeq, seq);
2063
- eventEndSeq = eventEndSeq === void 0 ? seq : Math.max(eventEndSeq, seq);
2064
- });
2065
- pendingEventWrites.push(pending);
2066
- },
1999
+ errorEmissionPolicy: { queueErrorAlreadyEmitted: false },
2000
+ onAcpMessage: events.onAcpMessage,
2067
2001
  onSessionUpdate: (notification) => {
2068
2002
  acpxState = recordSessionUpdate(conversation, acpxState, notification);
2069
2003
  },
@@ -2072,10 +2006,8 @@ var FlowRunner = class {
2072
2006
  },
2073
2007
  suppressSdkConsoleErrors: this.suppressSdkConsoleErrors,
2074
2008
  timeoutMs,
2075
- verbose: this.verbose,
2076
2009
  sessionOptions: this.sessionOptions
2077
- });
2078
- await Promise.all(pendingEventWrites);
2010
+ }));
2079
2011
  const sessionInfo = {
2080
2012
  ...binding,
2081
2013
  acpxRecordId: result.sessionId,
@@ -2088,7 +2020,7 @@ var FlowRunner = class {
2088
2020
  updatedAt: conversation.updated_at,
2089
2021
  conversation,
2090
2022
  acpxState: cloneSessionAcpxState(acpxState),
2091
- lastSeq: eventEndSeq ?? 0
2023
+ lastSeq: eventEndSeq
2092
2024
  });
2093
2025
  await this.store.writeSessionRecord(runDir, state, sessionInfo, syntheticRecord);
2094
2026
  return {
@@ -2098,12 +2030,8 @@ var FlowRunner = class {
2098
2030
  sessionId: sessionInfo.bundleId,
2099
2031
  messageStart: 0,
2100
2032
  messageEnd: Math.max(0, conversation.messages.length - 1),
2101
- eventStartSeq: eventStartSeq ?? (() => {
2102
- throw new Error(`Missing ACP event capture for session ${sessionInfo.bundleId}`);
2103
- })(),
2104
- eventEndSeq: eventEndSeq ?? (() => {
2105
- throw new Error(`Missing ACP event capture for session ${sessionInfo.bundleId}`);
2106
- })()
2033
+ eventStartSeq,
2034
+ eventEndSeq
2107
2035
  }
2108
2036
  };
2109
2037
  }
@@ -2300,4 +2228,4 @@ function formatDecisionPrompt(question, choices, field) {
2300
2228
  //#endregion
2301
2229
  export { parseStrictJsonObject as a, validateFlowDefinition as c, checkpoint as d, compute as f, isDefinedFlow as h, parseJsonObject as i, acp as l, shell as m, decisionEdge as n, FlowRunner as o, defineFlow as p, extractJsonObject as r, flowRunsBaseDir as s, decision as t, action as u };
2302
2230
 
2303
- //# sourceMappingURL=flows-D-F3Y2o9.js.map
2231
+ //# sourceMappingURL=flows-Bxs4udrs.js.map