zeitlich 0.2.43 → 0.2.44
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/dist/{activities-CrN-ghLo.d.ts → activities-CPIB2v2C.d.ts} +4 -4
- package/dist/{activities-Coafq5zr.d.cts → activities-DnmNOnq4.d.cts} +4 -4
- package/dist/adapters/sandbox/daytona/index.d.cts +2 -2
- package/dist/adapters/sandbox/daytona/index.d.ts +2 -2
- package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/index.d.ts +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +4 -4
- package/dist/adapters/thread/anthropic/index.d.ts +4 -4
- package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
- package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
- package/dist/adapters/thread/google-genai/index.d.cts +4 -4
- package/dist/adapters/thread/google-genai/index.d.ts +4 -4
- package/dist/adapters/thread/google-genai/workflow.d.cts +4 -4
- package/dist/adapters/thread/google-genai/workflow.d.ts +4 -4
- package/dist/adapters/thread/langchain/index.cjs +11 -11
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +4 -4
- package/dist/adapters/thread/langchain/index.d.ts +4 -4
- package/dist/adapters/thread/langchain/index.js +8 -12
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +4 -4
- package/dist/adapters/thread/langchain/workflow.d.ts +4 -4
- package/dist/index.cjs +68 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +68 -49
- package/dist/index.js.map +1 -1
- package/dist/{proxy-COqA95FW.d.ts → proxy-B7Xi1znZ.d.ts} +1 -1
- package/dist/{proxy-Bf7uI-Hw.d.cts → proxy-DTnc5rqT.d.cts} +1 -1
- package/dist/{thread-manager-Bi1XlbpJ.d.ts → thread-manager-BAv340mi.d.ts} +3 -3
- package/dist/{thread-manager-wRVVBFgj.d.cts → thread-manager-BWv6ZXI3.d.cts} +4 -4
- package/dist/{thread-manager-BsLO3Fgc.d.cts → thread-manager-BlX2TwRN.d.cts} +3 -3
- package/dist/{thread-manager-BhkOyQ1I.d.ts → thread-manager-D2xorI-J.d.ts} +4 -4
- package/dist/{types-CdALEF3z.d.cts → types-4Wmk-wRq.d.cts} +1 -1
- package/dist/{types-CjY93AWZ.d.cts → types-C90VoEpt.d.cts} +1 -1
- package/dist/{types-BkX4HLzi.d.ts → types-Clhqautb.d.ts} +1 -1
- package/dist/{types-ChAy_jSP.d.ts → types-DKsCdAtQ.d.ts} +1 -1
- package/dist/{types-C66-BVBr.d.cts → types-DRJt1TMi.d.cts} +1 -1
- package/dist/{types-gVa5XCWD.d.ts → types-DpFD8ofR.d.ts} +1 -1
- package/dist/{workflow-BwT5EybR.d.ts → workflow-D32TRMr-.d.ts} +2 -2
- package/dist/{workflow-DMmiaw6w.d.cts → workflow-XVt0ww8K.d.cts} +2 -2
- package/dist/workflow.cjs +60 -37
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +60 -37
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/.env +1 -0
- package/src/lib/session/session.ts +46 -40
- package/src/lib/state/manager.integration.test.ts +27 -0
- package/src/lib/state/manager.ts +39 -1
- package/src/tools/bash/.env +1 -0
package/package.json
CHANGED
package/src/lib/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
E2B_API_KEY=e2b_39af116424059782e2aee6942fd70237cc2126c9
|
|
@@ -383,46 +383,6 @@ export async function createSession<
|
|
|
383
383
|
});
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
// --- Virtual filesystem init (independent of sandbox) ----------------
|
|
387
|
-
if (virtualFsConfig) {
|
|
388
|
-
if (!virtualFsOps) {
|
|
389
|
-
throw ApplicationFailure.create({
|
|
390
|
-
message: "No virtualFsOps provided — cannot resolve file tree",
|
|
391
|
-
nonRetryable: true,
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
const result = await virtualFsOps.resolveFileTree(virtualFsConfig.ctx);
|
|
395
|
-
const skillFiles = skills ? collectSkillFiles(skills) : undefined;
|
|
396
|
-
const fileTree = skillFiles
|
|
397
|
-
? [
|
|
398
|
-
...result.fileTree,
|
|
399
|
-
...Object.entries(skillFiles).map(([path, content]) => ({
|
|
400
|
-
id: `skill:${path}`,
|
|
401
|
-
path,
|
|
402
|
-
size: content.length,
|
|
403
|
-
mtime: new Date().toISOString(),
|
|
404
|
-
metadata: {},
|
|
405
|
-
// Carry the content directly on the entry so any handler that
|
|
406
|
-
// constructs a VirtualFileSystem from `fileTree` can read it
|
|
407
|
-
// without needing to also wire up `inlineFiles` from state.
|
|
408
|
-
inlineContent: content,
|
|
409
|
-
})),
|
|
410
|
-
]
|
|
411
|
-
: result.fileTree;
|
|
412
|
-
stateManager.mergeUpdate({
|
|
413
|
-
fileTree,
|
|
414
|
-
virtualFsCtx: virtualFsConfig.ctx,
|
|
415
|
-
// `inlineFiles` is still the source of truth at read time:
|
|
416
|
-
// VirtualFileSystem checks the inlineFiles map first and only
|
|
417
|
-
// falls through to entry.inlineContent. Embedding the content on
|
|
418
|
-
// the entry is the migration target so that handlers building a
|
|
419
|
-
// VirtualFileSystem from `fileTree` alone (without forwarding
|
|
420
|
-
// `inlineFiles` from state) can read skill resources. Until a
|
|
421
|
-
// follow-up drops `inlineFiles`, both fields are populated.
|
|
422
|
-
...(skillFiles && { inlineFiles: skillFiles }),
|
|
423
|
-
} as Partial<AgentState<TState>>);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
386
|
if (hooks.onSessionStart) {
|
|
427
387
|
await hooks.onSessionStart({
|
|
428
388
|
threadId,
|
|
@@ -474,6 +434,52 @@ export async function createSession<
|
|
|
474
434
|
await initializeThread(threadId, threadKey);
|
|
475
435
|
}
|
|
476
436
|
}
|
|
437
|
+
|
|
438
|
+
// --- Virtual filesystem init (independent of sandbox) ----------------
|
|
439
|
+
// Runs AFTER thread rehydration so the freshly resolved tree is
|
|
440
|
+
// authoritative. Otherwise a stale `fileTree` carried in a persisted
|
|
441
|
+
// slice (from a run on older code that didn't strip it) could
|
|
442
|
+
// overwrite entries that no longer exist in the backing store and
|
|
443
|
+
// cause subsequent FileWrite calls to fail with "not_found".
|
|
444
|
+
if (virtualFsConfig) {
|
|
445
|
+
if (!virtualFsOps) {
|
|
446
|
+
throw ApplicationFailure.create({
|
|
447
|
+
message: "No virtualFsOps provided — cannot resolve file tree",
|
|
448
|
+
nonRetryable: true,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
const result = await virtualFsOps.resolveFileTree(virtualFsConfig.ctx);
|
|
452
|
+
const skillFiles = skills ? collectSkillFiles(skills) : undefined;
|
|
453
|
+
const fileTree = skillFiles
|
|
454
|
+
? [
|
|
455
|
+
...result.fileTree,
|
|
456
|
+
...Object.entries(skillFiles).map(([path, content]) => ({
|
|
457
|
+
id: `skill:${path}`,
|
|
458
|
+
path,
|
|
459
|
+
size: content.length,
|
|
460
|
+
mtime: new Date().toISOString(),
|
|
461
|
+
metadata: {},
|
|
462
|
+
// Carry the content directly on the entry so any handler that
|
|
463
|
+
// constructs a VirtualFileSystem from `fileTree` can read it
|
|
464
|
+
// without needing to also wire up `inlineFiles` from state.
|
|
465
|
+
inlineContent: content,
|
|
466
|
+
})),
|
|
467
|
+
]
|
|
468
|
+
: result.fileTree;
|
|
469
|
+
stateManager.mergeUpdate({
|
|
470
|
+
fileTree,
|
|
471
|
+
virtualFsCtx: virtualFsConfig.ctx,
|
|
472
|
+
// `inlineFiles` is still the source of truth at read time:
|
|
473
|
+
// VirtualFileSystem checks the inlineFiles map first and only
|
|
474
|
+
// falls through to entry.inlineContent. Embedding the content on
|
|
475
|
+
// the entry is the migration target so that handlers building a
|
|
476
|
+
// VirtualFileSystem from `fileTree` alone (without forwarding
|
|
477
|
+
// `inlineFiles` from state) can read skill resources. Until a
|
|
478
|
+
// follow-up drops `inlineFiles`, both fields are populated.
|
|
479
|
+
...(skillFiles && { inlineFiles: skillFiles }),
|
|
480
|
+
} as Partial<AgentState<TState>>);
|
|
481
|
+
}
|
|
482
|
+
|
|
477
483
|
await appendHumanMessage(
|
|
478
484
|
threadId,
|
|
479
485
|
uuid4(),
|
|
@@ -385,6 +385,33 @@ describe("createAgentStateManager integration", () => {
|
|
|
385
385
|
expect("tools" in slice.custom).toBe(false);
|
|
386
386
|
});
|
|
387
387
|
|
|
388
|
+
it("getPersistedSlice strips runtime fields injected via mergeUpdate", () => {
|
|
389
|
+
const sm = createAgentStateManager<{ label: string }>({
|
|
390
|
+
initialState: { systemPrompt: "test", label: "original" },
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
sm.mergeUpdate({
|
|
394
|
+
label: "updated",
|
|
395
|
+
fileTree: [
|
|
396
|
+
{
|
|
397
|
+
id: "f1",
|
|
398
|
+
path: "/a.txt",
|
|
399
|
+
size: 1,
|
|
400
|
+
mtime: "2026-01-01T00:00:00Z",
|
|
401
|
+
metadata: {},
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
virtualFsCtx: { workspaceBase: "/tmp" },
|
|
405
|
+
inlineFiles: { "/a.txt": "hi" },
|
|
406
|
+
} as Parameters<typeof sm.mergeUpdate>[0]);
|
|
407
|
+
|
|
408
|
+
const slice = sm.getPersistedSlice();
|
|
409
|
+
expect(slice.custom).toEqual({ label: "updated" });
|
|
410
|
+
expect("fileTree" in slice.custom).toBe(false);
|
|
411
|
+
expect("virtualFsCtx" in slice.custom).toBe(false);
|
|
412
|
+
expect("inlineFiles" in slice.custom).toBe(false);
|
|
413
|
+
});
|
|
414
|
+
|
|
388
415
|
it("mergeUpdate replaces the task map when given a tasks field", () => {
|
|
389
416
|
const sm = createAgentStateManager<{ label: string; extra?: string }>({
|
|
390
417
|
initialState: {
|
package/src/lib/state/manager.ts
CHANGED
|
@@ -20,6 +20,32 @@ import type {
|
|
|
20
20
|
} from "./types";
|
|
21
21
|
import { z } from "zod";
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Fields that live on `AgentState` at runtime but must NOT be persisted into
|
|
25
|
+
* `PersistedThreadState`. They're either managed by the state manager itself
|
|
26
|
+
* (status/version/turns/tasks/tools/usage), kept in their own slot
|
|
27
|
+
* (systemPrompt), or rebuilt on each run (the virtual-fs trio).
|
|
28
|
+
*
|
|
29
|
+
* Centralizing the list keeps the constructor's destructure-omit and
|
|
30
|
+
* `getPersistedSlice` in lockstep.
|
|
31
|
+
*/
|
|
32
|
+
const RESERVED_STATE_KEYS = [
|
|
33
|
+
"status",
|
|
34
|
+
"version",
|
|
35
|
+
"turns",
|
|
36
|
+
"tasks",
|
|
37
|
+
"tools",
|
|
38
|
+
"systemPrompt",
|
|
39
|
+
"fileTree",
|
|
40
|
+
"inlineFiles",
|
|
41
|
+
"virtualFsCtx",
|
|
42
|
+
"totalInputTokens",
|
|
43
|
+
"totalOutputTokens",
|
|
44
|
+
"totalReasonTokens",
|
|
45
|
+
"cachedWriteTokens",
|
|
46
|
+
"cachedReadTokens",
|
|
47
|
+
] as const;
|
|
48
|
+
|
|
23
49
|
/**
|
|
24
50
|
* Creates an agent state manager for tracking workflow state.
|
|
25
51
|
* Automatically registers Temporal query and update handlers for the agent.
|
|
@@ -238,9 +264,21 @@ export function createAgentStateManager<
|
|
|
238
264
|
},
|
|
239
265
|
|
|
240
266
|
getPersistedSlice(): PersistedThreadState {
|
|
267
|
+
// `customState` can pick up reserved/runtime fields via `mergeUpdate`
|
|
268
|
+
// (e.g. `fileTree`, `virtualFsCtx`, `inlineFiles` written by the
|
|
269
|
+
// virtual-fs bootstrap on every run). Those are rebuilt per run and
|
|
270
|
+
// must never round-trip through the thread store, so strip them here
|
|
271
|
+
// rather than relying on callers to remember.
|
|
272
|
+
const source = customState as unknown as Record<string, JsonValue>;
|
|
273
|
+
const custom: Record<string, JsonValue> = {};
|
|
274
|
+
const reserved = new Set<string>(RESERVED_STATE_KEYS);
|
|
275
|
+
for (const [key, value] of Object.entries(source)) {
|
|
276
|
+
if (reserved.has(key)) continue;
|
|
277
|
+
custom[key] = value;
|
|
278
|
+
}
|
|
241
279
|
return {
|
|
242
280
|
tasks: Array.from(tasks.entries()),
|
|
243
|
-
custom
|
|
281
|
+
custom,
|
|
244
282
|
};
|
|
245
283
|
},
|
|
246
284
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
E2B_API_KEY=e2b_39af116424059782e2aee6942fd70237cc2126c9
|