@a5c-ai/babysitter-sdk 0.0.33 → 0.0.35

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.
@@ -1 +1 @@
1
- {"version":3,"file":"runIterate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/runIterate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0JtF"}
1
+ {"version":3,"file":"runIterate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/runIterate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8ItF"}
@@ -61,69 +61,60 @@ async function runIterate(options) {
61
61
  if (verbose) {
62
62
  console.error(`[run:iterate] Starting iteration ${iteration} for run ${runId}`);
63
63
  }
64
+ // First, advance the runtime one step to request pending effects (if any).
65
+ // This is what creates EFFECT_REQUESTED entries that hooks can observe via task:list.
66
+ const iterationResult = await (0, orchestrateIteration_1.orchestrateIteration)({ runDir });
67
+ if (iterationResult.status === "completed") {
68
+ await (0, runtime_1.callRuntimeHook)("on-iteration-end", {
69
+ runId,
70
+ iteration,
71
+ action: "none",
72
+ status: "completed",
73
+ reason: "completed",
74
+ timestamp: new Date().toISOString(),
75
+ }, { cwd: projectRoot, logger: verbose ? ((msg) => console.error(msg)) : undefined });
76
+ return {
77
+ iteration,
78
+ status: "completed",
79
+ action: "none",
80
+ reason: "completed",
81
+ metadata: { runId, processId: metadata.processId, hookStatus: "executed" },
82
+ };
83
+ }
84
+ if (iterationResult.status === "failed") {
85
+ await (0, runtime_1.callRuntimeHook)("on-iteration-end", {
86
+ runId,
87
+ iteration,
88
+ action: "none",
89
+ status: "failed",
90
+ reason: "failed",
91
+ timestamp: new Date().toISOString(),
92
+ }, { cwd: projectRoot, logger: verbose ? ((msg) => console.error(msg)) : undefined });
93
+ return {
94
+ iteration,
95
+ status: "failed",
96
+ action: "none",
97
+ reason: "failed",
98
+ metadata: { runId, processId: metadata.processId, hookStatus: "executed" },
99
+ };
100
+ }
64
101
  // === Call on-iteration-start hook ===
65
- // Hook analyzes state and returns orchestration decisions
102
+ // Hook may execute/post effects that were requested by orchestrateIteration().
66
103
  const iterationStartPayload = {
67
104
  runId,
68
105
  iteration,
106
+ status: iterationResult.status,
107
+ pending: iterationResult.status === "waiting" ? iterationResult.nextActions : [],
69
108
  timestamp: new Date().toISOString(),
70
109
  };
71
110
  const hookResult = await (0, runtime_1.callRuntimeHook)("on-iteration-start", iterationStartPayload, {
72
111
  cwd: projectRoot,
73
112
  logger: verbose ? ((msg) => console.error(msg)) : undefined,
74
113
  });
75
- // If no hooks executed, fall back to running one real orchestration step (runtime iteration).
76
- // This ensures `run:iterate` works even without a plugin install / hooks configuration.
77
- if (!hookResult.executedHooks?.length) {
78
- const iterationResult = await (0, orchestrateIteration_1.orchestrateIteration)({ runDir });
79
- const status = iterationResult.status === "waiting"
80
- ? "waiting"
81
- : iterationResult.status === "completed"
82
- ? "completed"
83
- : "failed";
84
- // Still call on-iteration-end (will be a no-op if no hooks are installed).
85
- await (0, runtime_1.callRuntimeHook)("on-iteration-end", {
86
- runId,
87
- iteration,
88
- action: status === "waiting" ? "waiting" : "none",
89
- status,
90
- reason: "no-hooks-fallback",
91
- count: iterationResult.status === "waiting" ? iterationResult.nextActions.length : undefined,
92
- timestamp: new Date().toISOString(),
93
- }, {
94
- cwd: projectRoot,
95
- logger: verbose ? ((msg) => console.error(msg)) : undefined,
96
- });
97
- return {
98
- iteration,
99
- status,
100
- action: status === "waiting" ? "waiting" : "none",
101
- reason: "no-hooks-fallback",
102
- count: iterationResult.status === "waiting" ? iterationResult.nextActions.length : undefined,
103
- nextActions: iterationResult.status === "waiting" ? iterationResult.nextActions : undefined,
104
- metadata: {
105
- runId,
106
- processId: metadata.processId,
107
- hookStatus: "none",
108
- },
109
- };
110
- }
111
114
  // Parse hook output
112
- let hookDecision = {};
113
- if (hookResult.output) {
114
- try {
115
- hookDecision = typeof hookResult.output === "string"
116
- ? JSON.parse(hookResult.output)
117
- : hookResult.output;
118
- }
119
- catch (e) {
120
- if (verbose) {
121
- console.error(`[run:iterate] Warning: Could not parse hook output:`, hookResult.output);
122
- }
123
- }
124
- }
125
- const action = hookDecision.action || "none";
126
- const reason = hookDecision.reason || "unknown";
115
+ const hookDecision = parseHookDecision(hookResult.output);
116
+ const action = hookDecision.action ?? "none";
117
+ const reason = hookDecision.reason ?? "unknown";
127
118
  const count = hookDecision.count;
128
119
  const until = hookDecision.until;
129
120
  if (verbose) {
@@ -131,21 +122,17 @@ async function runIterate(options) {
131
122
  }
132
123
  // Determine result status based on hook action
133
124
  let status;
134
- // Check for terminal state first
135
- if (reason === "terminal-state") {
136
- status = hookDecision.status === "failed" ? "failed" : "completed";
137
- }
138
- else if (action === "executed-tasks") {
125
+ if (action === "executed-tasks") {
139
126
  status = "executed";
140
127
  }
141
128
  else if (action === "waiting") {
142
129
  status = "waiting";
143
130
  }
144
- else if (action === "none") {
145
- status = "none";
131
+ else if (iterationResult.status === "waiting") {
132
+ // If the hook didn't execute anything, surface runtime waiting details.
133
+ status = "waiting";
146
134
  }
147
135
  else {
148
- // Default to none for unknown actions
149
136
  status = "none";
150
137
  }
151
138
  // === Call on-iteration-end hook ===
@@ -170,6 +157,7 @@ async function runIterate(options) {
170
157
  reason,
171
158
  count,
172
159
  until,
160
+ nextActions: iterationResult.status === "waiting" ? iterationResult.nextActions : undefined,
173
161
  metadata: {
174
162
  runId,
175
163
  processId: metadata.processId,
@@ -178,3 +166,30 @@ async function runIterate(options) {
178
166
  };
179
167
  return result;
180
168
  }
169
+ function parseHookDecision(output) {
170
+ const record = parseMaybeJsonRecord(output);
171
+ if (!record)
172
+ return {};
173
+ const action = typeof record.action === "string" ? record.action : undefined;
174
+ const reason = typeof record.reason === "string" ? record.reason : undefined;
175
+ const status = typeof record.status === "string" ? record.status : undefined;
176
+ const count = typeof record.count === "number" ? record.count : undefined;
177
+ const until = typeof record.until === "number" ? record.until : undefined;
178
+ return { action, reason, status, count, until };
179
+ }
180
+ function parseMaybeJsonRecord(output) {
181
+ if (!output)
182
+ return undefined;
183
+ if (typeof output === "object" && !Array.isArray(output)) {
184
+ return output;
185
+ }
186
+ if (typeof output !== "string")
187
+ return undefined;
188
+ try {
189
+ const parsed = JSON.parse(output);
190
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
191
+ }
192
+ catch {
193
+ return undefined;
194
+ }
195
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AA20CA,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBAyCpD,MAAM;EAIvB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAmwCA,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBAsCpD,MAAM;EAIvB"}
package/dist/cli/main.js CHANGED
@@ -38,7 +38,6 @@ exports.createBabysitterCli = createBabysitterCli;
38
38
  const node_fs_1 = require("node:fs");
39
39
  const path = __importStar(require("node:path"));
40
40
  const commitEffectResult_1 = require("../runtime/commitEffectResult");
41
- const orchestrateIteration_1 = require("../runtime/orchestrateIteration");
42
41
  const createRun_1 = require("../runtime/createRun");
43
42
  const effectIndex_1 = require("../runtime/replay/effectIndex");
44
43
  const stateCache_1 = require("../runtime/replay/stateCache");
@@ -53,7 +52,6 @@ const USAGE = `Usage:
53
52
  babysitter run:rebuild-state <runDir> [--runs-dir <dir>] [--json] [--dry-run]
54
53
  babysitter run:iterate <runDir> [--runs-dir <dir>] [--json] [--verbose] [--iteration <n>]
55
54
  babysitter task:post <runDir> <effectId> --status <ok|error> [--runs-dir <dir>] [--json] [--dry-run] [--value <file>] [--error <file>] [--stdout-ref <ref>] [--stderr-ref <ref>] [--stdout-file <file>] [--stderr-file <file>] [--started-at <iso8601>] [--finished-at <iso8601>] [--metadata <file>] [--invocation-key <key>]
56
- babysitter run:step <runDir> [--runs-dir <dir>] [--json] [--now <iso8601>]
57
55
  babysitter task:list <runDir> [--runs-dir <dir>] [--pending] [--kind <kind>] [--json]
58
56
  babysitter task:show <runDir> <effectId> [--runs-dir <dir>] [--json]
59
57
 
@@ -202,10 +200,6 @@ function parseArgs(argv) {
202
200
  parsed.requestId = expectFlagValue(rest, ++i, "--request");
203
201
  continue;
204
202
  }
205
- if (arg === "--now") {
206
- parsed.nowOverride = expectFlagValue(rest, ++i, "--now");
207
- continue;
208
- }
209
203
  positionals.push(arg);
210
204
  }
211
205
  if (parsed.command === "task:post") {
@@ -229,9 +223,6 @@ function parseArgs(argv) {
229
223
  else if (parsed.command === "run:rebuild-state") {
230
224
  [parsed.runDirArg] = positionals;
231
225
  }
232
- else if (parsed.command === "run:step") {
233
- [parsed.runDirArg] = positionals;
234
- }
235
226
  return parsed;
236
227
  }
237
228
  function resolveRunDir(baseDir, runDirArg) {
@@ -863,65 +854,6 @@ async function handleTaskPost(parsed) {
863
854
  }
864
855
  return parsed.taskStatus === "ok" ? 0 : 1;
865
856
  }
866
- function parseNowOverride(nowOverride) {
867
- if (!nowOverride)
868
- return null;
869
- const parsed = new Date(nowOverride);
870
- if (Number.isNaN(parsed.getTime())) {
871
- throw new Error(`--now must be a valid ISO 8601 timestamp (received: ${nowOverride})`);
872
- }
873
- return parsed;
874
- }
875
- async function handleRunStep(parsed) {
876
- if (!parsed.runDirArg) {
877
- console.error(USAGE);
878
- return 1;
879
- }
880
- const runDir = resolveRunDir(parsed.runsDir, parsed.runDirArg);
881
- logVerbose("run:step", parsed, {
882
- runDir,
883
- now: parsed.nowOverride ?? "auto",
884
- json: parsed.json,
885
- });
886
- if (!(await readRunMetadataSafe(runDir, "run:step")))
887
- return 1;
888
- let now;
889
- try {
890
- now = parseNowOverride(parsed.nowOverride) ?? new Date();
891
- }
892
- catch (error) {
893
- console.error(error instanceof Error ? error.message : String(error));
894
- return 1;
895
- }
896
- const iteration = await (0, orchestrateIteration_1.orchestrateIteration)({ runDir, now });
897
- const pendingActions = iteration.status === "waiting" ? iteration.nextActions : undefined;
898
- const metadata = enrichIterationMetadata(iteration.metadata, pendingActions);
899
- const formattedMetadata = formatIterationMetadata(metadata);
900
- if (parsed.json) {
901
- console.log(JSON.stringify({ ...iteration, metadata: formattedMetadata.jsonMetadata ?? null }));
902
- return iteration.status === "failed" ? 1 : 0;
903
- }
904
- if (iteration.status === "completed") {
905
- const output = JSON.stringify(iteration.output ?? null);
906
- const suffix = formattedMetadata.textParts.length ? ` ${formattedMetadata.textParts.join(" ")}` : "";
907
- console.error(`[run:step] status=completed output=${output}${suffix}`);
908
- return 0;
909
- }
910
- if (iteration.status === "waiting") {
911
- logPendingActions(iteration.nextActions, {
912
- command: "run:step",
913
- metadataParts: formattedMetadata.textParts,
914
- });
915
- logSleepHints("run:step", iteration.nextActions);
916
- return 0;
917
- }
918
- const suffix = formattedMetadata.textParts.length ? ` ${formattedMetadata.textParts.join(" ")}` : "";
919
- console.error(`[run:step] status=failed${suffix}`);
920
- if (iteration.error !== undefined) {
921
- console.error(iteration.error);
922
- }
923
- return 1;
924
- }
925
857
  async function handleTaskList(parsed) {
926
858
  if (!parsed.runDirArg) {
927
859
  console.error(USAGE);
@@ -1270,9 +1202,6 @@ function createBabysitterCli() {
1270
1202
  if (parsed.command === "task:post") {
1271
1203
  return await handleTaskPost(parsed);
1272
1204
  }
1273
- if (parsed.command === "run:step") {
1274
- return await handleRunStep(parsed);
1275
- }
1276
1205
  if (parsed.command === "task:list") {
1277
1206
  return await handleTaskList(parsed);
1278
1207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a5c-ai/babysitter-sdk",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "description": "Storage and run-registry primitives for event-sourced babysitter workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",