zeitlich 0.2.42 → 0.2.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zeitlich",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "description": "[EXPERIMENTAL] An opinionated AI agent implementation for Temporal",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -176,9 +176,18 @@ describe("createSession edge cases", () => {
176
176
  idCounter = 0;
177
177
  });
178
178
 
179
- // --- WAITING_FOR_INPUT flow (condition returns false = timeout) ---
180
-
181
- it("cancels session when WAITING_FOR_INPUT times out (condition returns false)", async () => {
179
+ // NOTE: a previous test here ("cancels session when WAITING_FOR_INPUT
180
+ // times out") covered the condition-based wait + cancel-on-timeout flow
181
+ // that was removed in 7ab652b ("fix: stop halting workflow when
182
+ // waiting"). The session loop now exits cleanly the moment a tool puts
183
+ // the agent into WAITING_FOR_INPUT — there is no internal timeout to
184
+ // assert against — so the test was deleted rather than rewritten. The
185
+ // assertion below covers the surviving contract: the exit reason
186
+ // reflects the WAITING_FOR_INPUT state instead of the default
187
+ // "completed", so callers can distinguish a finished session from a
188
+ // parked one.
189
+
190
+ it("exits with 'waiting_for_input' when a tool parks the session", async () => {
182
191
  const { ops } = createMockThreadOps();
183
192
  let endReason: string | undefined;
184
193
  const capturedRef: {
@@ -191,10 +200,7 @@ describe("createSession edge cases", () => {
191
200
  schema: z.object({}),
192
201
  handler: async (_args: Record<string, never>, _ctx: RouterContext) => {
193
202
  capturedRef.stateManager?.waitForInput();
194
- return {
195
- toolResponse: "Please provide input.",
196
- data: null,
197
- };
203
+ return { toolResponse: "Please provide input.", data: null };
198
204
  },
199
205
  });
200
206
 
@@ -224,9 +230,9 @@ describe("createSession edge cases", () => {
224
230
 
225
231
  const result = await session.runSession({ stateManager });
226
232
 
227
- expect(result.exitReason).toBe("cancelled");
228
- expect(result.finalMessage).toBeNull();
229
- expect(endReason).toBe("cancelled");
233
+ expect(result.exitReason).toBe("waiting_for_input");
234
+ expect(endReason).toBe("waiting_for_input");
235
+ expect(stateManager.getStatus()).toBe("WAITING_FOR_INPUT");
230
236
  });
231
237
 
232
238
  // --- All tool calls are invalid ---
@@ -596,6 +596,14 @@ export async function createSession<
596
596
  threadId,
597
597
  maxTurns,
598
598
  });
599
+ } else if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
600
+ // A tool put the agent into WAITING_FOR_INPUT (e.g. an AskUser
601
+ // tool). The loop's `isRunning()` guard then exited cleanly; we
602
+ // report a dedicated exit reason rather than the misleading
603
+ // default `"completed"`, so callers can distinguish a finished
604
+ // session from one parked waiting on external input.
605
+ exitReason = "waiting_for_input";
606
+ log.info("session waiting for input", { agentName, threadId });
599
607
  }
600
608
  } catch (error) {
601
609
  exitReason = "failed";
@@ -168,9 +168,8 @@ export function defineSubagentWorkflow(
168
168
 
169
169
  // Auto-forward sandbox outputs captured from the session so user code
170
170
  // never has to thread them through manually. Explicit values on the fn
171
- // result take precedence.
171
+ // result take precedence, so spread `result` LAST.
172
172
  return {
173
- ...result,
174
173
  ...(capturedThreadId !== undefined && { threadId: capturedThreadId }),
175
174
  ...(capturedSandboxId !== undefined && { sandboxId: capturedSandboxId }),
176
175
  ...(capturedSnapshot !== undefined && { snapshot: capturedSnapshot }),
@@ -178,6 +177,7 @@ export function defineSubagentWorkflow(
178
177
  baseSnapshot: capturedBaseSnapshot,
179
178
  }),
180
179
  ...(capturedUsage !== undefined && { usage: capturedUsage }),
180
+ ...result,
181
181
  };
182
182
  };
183
183