zeitlich 0.2.37 → 0.2.38
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-Bb-nAjwQ.d.ts → activities-BKhMtKDd.d.ts} +4 -2
- package/dist/{activities-vkI4_3CC.d.cts → activities-CDcwkRZs.d.cts} +4 -2
- package/dist/adapters/sandbox/bedrock/index.cjs +3 -3
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +6 -6
- package/dist/adapters/sandbox/bedrock/index.d.ts +6 -6
- package/dist/adapters/sandbox/bedrock/index.js +3 -3
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
- package/dist/adapters/sandbox/daytona/index.cjs +3 -3
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +4 -4
- package/dist/adapters/sandbox/daytona/index.d.ts +4 -4
- package/dist/adapters/sandbox/daytona/index.js +3 -3
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- 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.cjs +26 -14
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +24 -4
- package/dist/adapters/sandbox/e2b/index.d.ts +24 -4
- package/dist/adapters/sandbox/e2b/index.js +26 -14
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +3 -3
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +4 -4
- package/dist/adapters/sandbox/inmemory/index.d.ts +4 -4
- package/dist/adapters/sandbox/inmemory/index.js +3 -3
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
- package/dist/adapters/thread/anthropic/index.cjs +23 -3
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +5 -5
- package/dist/adapters/thread/anthropic/index.d.ts +5 -5
- package/dist/adapters/thread/anthropic/index.js +23 -3
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +2 -1
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/anthropic/workflow.js +2 -1
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +27 -3
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +5 -5
- package/dist/adapters/thread/google-genai/index.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.js +27 -3
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +2 -1
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/workflow.js +2 -1
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +23 -3
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +5 -5
- package/dist/adapters/thread/langchain/index.d.ts +5 -5
- package/dist/adapters/thread/langchain/index.js +23 -3
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +2 -1
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/adapters/thread/langchain/workflow.js +2 -1
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +120 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +121 -31
- package/dist/index.js.map +1 -1
- package/dist/{proxy-0smGKvx8.d.ts → proxy-CUlKSvZS.d.ts} +1 -1
- package/dist/{proxy-DEtowJyd.d.cts → proxy-D_3x7RN4.d.cts} +1 -1
- package/dist/{thread-manager-C-C4pI2z.d.ts → thread-manager-CVu7o2cs.d.ts} +4 -2
- package/dist/{thread-manager-D4vgzYrh.d.cts → thread-manager-HSwyh28L.d.cts} +4 -2
- package/dist/{thread-manager-3fszQih4.d.ts → thread-manager-c1gPopAG.d.ts} +4 -2
- package/dist/{thread-manager-CzYln2OC.d.cts → thread-manager-wGi-LqIP.d.cts} +4 -2
- package/dist/{types-B37hKoWA.d.ts → types-BH_IRryz.d.ts} +10 -1
- package/dist/{types-D08CXPh8.d.cts → types-BaOw4hKI.d.cts} +10 -1
- package/dist/{types-CPKDl-y_.d.ts → types-C06FwR96.d.cts} +59 -4
- package/dist/{types-CNuWnvy9.d.ts → types-DAsQ21Rt.d.ts} +1 -1
- package/dist/{types-BO7Yju20.d.cts → types-DNr31FzL.d.ts} +59 -4
- package/dist/{types-DWEUmYAJ.d.cts → types-lm8tMNJQ.d.cts} +1 -1
- package/dist/{types-tQL9njTu.d.cts → types-yx0LzPGn.d.cts} +21 -7
- package/dist/{types-tQL9njTu.d.ts → types-yx0LzPGn.d.ts} +21 -7
- package/dist/{workflow-CjXHbZZc.d.ts → workflow-CSCkpwAL.d.ts} +2 -2
- package/dist/{workflow-Do_lzJpT.d.cts → workflow-DuvMZ8Vm.d.cts} +2 -2
- package/dist/workflow.cjs +94 -18
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3 -3
- package/dist/workflow.d.ts +3 -3
- package/dist/workflow.js +95 -19
- package/dist/workflow.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/sandbox/bedrock/index.ts +12 -3
- package/src/adapters/sandbox/daytona/index.ts +12 -3
- package/src/adapters/sandbox/e2b/index.ts +36 -14
- package/src/adapters/sandbox/e2b/types.ts +16 -0
- package/src/adapters/sandbox/inmemory/index.ts +12 -3
- package/src/adapters/thread/anthropic/activities.ts +9 -0
- package/src/adapters/thread/anthropic/model-invoker.ts +3 -1
- package/src/adapters/thread/anthropic/thread-manager.ts +3 -0
- package/src/adapters/thread/google-genai/activities.ts +13 -0
- package/src/adapters/thread/google-genai/model-invoker.ts +3 -1
- package/src/adapters/thread/google-genai/thread-manager.ts +3 -0
- package/src/adapters/thread/langchain/activities.ts +9 -0
- package/src/adapters/thread/langchain/model-invoker.ts +2 -1
- package/src/adapters/thread/langchain/thread-manager.ts +3 -0
- package/src/lib/lifecycle.ts +11 -4
- package/src/lib/model/types.ts +10 -0
- package/src/lib/sandbox/manager.ts +26 -18
- package/src/lib/sandbox/types.ts +27 -7
- package/src/lib/session/session-edge-cases.integration.test.ts +265 -1
- package/src/lib/session/session.integration.test.ts +22 -1
- package/src/lib/session/session.ts +61 -7
- package/src/lib/session/types.ts +12 -0
- package/src/lib/subagent/subagent.integration.test.ts +100 -104
- package/src/lib/thread/manager.ts +18 -0
- package/src/lib/thread/proxy.ts +1 -0
- package/src/lib/thread/types.ts +9 -0
- package/src/lib/tool-router/index.ts +2 -0
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +92 -0
- package/src/lib/tool-router/router.integration.test.ts +12 -0
- package/src/lib/tool-router/router.ts +89 -16
- package/src/lib/tool-router/types.ts +34 -1
- package/src/workflow.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zeitlich",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.38",
|
|
4
4
|
"description": "[EXPERIMENTAL] An opinionated AI agent implementation for Temporal",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -210,7 +210,7 @@
|
|
|
210
210
|
"node": ">=18"
|
|
211
211
|
},
|
|
212
212
|
"devDependencies": {
|
|
213
|
-
"@anthropic-ai/sdk": "^0.
|
|
213
|
+
"@anthropic-ai/sdk": "^0.81.0",
|
|
214
214
|
"@aws-sdk/client-bedrock-agentcore": "^3.900.0",
|
|
215
215
|
"@daytonaio/sdk": "^0.158.1",
|
|
216
216
|
"@e2b/code-interpreter": "^2.3.3",
|
|
@@ -239,15 +239,24 @@ export class BedrockSandboxProvider implements SandboxProvider<
|
|
|
239
239
|
// Bedrock sandboxes don't support pause, so resume is a no-op
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
async snapshot(
|
|
242
|
+
async snapshot(
|
|
243
|
+
_sandboxId: string,
|
|
244
|
+
_options?: BedrockSandboxCreateOptions
|
|
245
|
+
): Promise<SandboxSnapshot> {
|
|
243
246
|
throw new SandboxNotSupportedError("snapshot");
|
|
244
247
|
}
|
|
245
248
|
|
|
246
|
-
async restore(
|
|
249
|
+
async restore(
|
|
250
|
+
_snapshot: SandboxSnapshot,
|
|
251
|
+
_options?: BedrockSandboxCreateOptions
|
|
252
|
+
): Promise<never> {
|
|
247
253
|
throw new SandboxNotSupportedError("restore");
|
|
248
254
|
}
|
|
249
255
|
|
|
250
|
-
async fork(
|
|
256
|
+
async fork(
|
|
257
|
+
_sandboxId: string,
|
|
258
|
+
_options?: BedrockSandboxCreateOptions
|
|
259
|
+
): Promise<Sandbox> {
|
|
251
260
|
throw new SandboxNotSupportedError("fork");
|
|
252
261
|
}
|
|
253
262
|
|
|
@@ -149,17 +149,26 @@ export class DaytonaSandboxProvider implements SandboxProvider<
|
|
|
149
149
|
// Daytona sandboxes don't support pause, so resume is a no-op
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async fork(
|
|
152
|
+
async fork(
|
|
153
|
+
_sandboxId: string,
|
|
154
|
+
_options?: DaytonaSandboxCreateOptions
|
|
155
|
+
): Promise<Sandbox> {
|
|
153
156
|
throw new Error("Not implemented");
|
|
154
157
|
}
|
|
155
158
|
|
|
156
|
-
async snapshot(
|
|
159
|
+
async snapshot(
|
|
160
|
+
_sandboxId: string,
|
|
161
|
+
_options?: DaytonaSandboxCreateOptions
|
|
162
|
+
): Promise<SandboxSnapshot> {
|
|
157
163
|
throw new SandboxNotSupportedError(
|
|
158
164
|
"snapshot (use Daytona's native snapshot API directly)"
|
|
159
165
|
);
|
|
160
166
|
}
|
|
161
167
|
|
|
162
|
-
async restore(
|
|
168
|
+
async restore(
|
|
169
|
+
_snapshot: SandboxSnapshot,
|
|
170
|
+
_options?: DaytonaSandboxCreateOptions
|
|
171
|
+
): Promise<never> {
|
|
163
172
|
throw new SandboxNotSupportedError(
|
|
164
173
|
"restore (use Daytona's native snapshot API directly)"
|
|
165
174
|
);
|
|
@@ -76,11 +76,19 @@ export class E2bSandboxProvider implements SandboxProvider<
|
|
|
76
76
|
private readonly defaultTemplate?: string;
|
|
77
77
|
private readonly defaultWorkspaceBase: string;
|
|
78
78
|
private readonly defaultTimeoutMs?: number;
|
|
79
|
+
private readonly defaultAllowInternetAccess?: boolean;
|
|
80
|
+
private readonly defaultNetwork?: E2bSandboxConfig["network"];
|
|
81
|
+
private readonly defaultMetadata?: E2bSandboxConfig["metadata"];
|
|
82
|
+
private readonly defaultLifecycle?: E2bSandboxConfig["lifecycle"];
|
|
79
83
|
|
|
80
84
|
constructor(config?: E2bSandboxConfig) {
|
|
81
85
|
this.defaultTemplate = config?.template;
|
|
82
86
|
this.defaultWorkspaceBase = config?.workspaceBase ?? "/home/user";
|
|
83
87
|
this.defaultTimeoutMs = config?.timeoutMs;
|
|
88
|
+
this.defaultAllowInternetAccess = config?.allowInternetAccess;
|
|
89
|
+
this.defaultNetwork = config?.network;
|
|
90
|
+
this.defaultMetadata = config?.metadata;
|
|
91
|
+
this.defaultLifecycle = config?.lifecycle;
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
async create(
|
|
@@ -142,7 +150,10 @@ export class E2bSandboxProvider implements SandboxProvider<
|
|
|
142
150
|
await E2bSdkSandbox.connect(sandboxId);
|
|
143
151
|
}
|
|
144
152
|
|
|
145
|
-
async snapshot(
|
|
153
|
+
async snapshot(
|
|
154
|
+
sandboxId: string,
|
|
155
|
+
_options?: E2bSandboxCreateOptions
|
|
156
|
+
): Promise<SandboxSnapshot> {
|
|
146
157
|
const { snapshotId } = await E2bSdkSandbox.createSnapshot(sandboxId);
|
|
147
158
|
return {
|
|
148
159
|
sandboxId,
|
|
@@ -152,14 +163,18 @@ export class E2bSandboxProvider implements SandboxProvider<
|
|
|
152
163
|
};
|
|
153
164
|
}
|
|
154
165
|
|
|
155
|
-
async restore(
|
|
166
|
+
async restore(
|
|
167
|
+
snapshot: SandboxSnapshot,
|
|
168
|
+
options?: E2bSandboxCreateOptions
|
|
169
|
+
): Promise<Sandbox> {
|
|
156
170
|
const data = snapshot.data as { snapshotId?: string } | null;
|
|
157
171
|
if (!data?.snapshotId) {
|
|
158
172
|
throw new SandboxNotSupportedError(
|
|
159
173
|
"restore: snapshot is missing snapshotId"
|
|
160
174
|
);
|
|
161
175
|
}
|
|
162
|
-
const
|
|
176
|
+
const sdkOpts = this.buildSdkCreateOpts(options);
|
|
177
|
+
const sdkSandbox = await E2bSdkSandbox.create(data.snapshotId, sdkOpts);
|
|
163
178
|
return new E2bSandboxImpl(
|
|
164
179
|
sdkSandbox.sandboxId,
|
|
165
180
|
sdkSandbox,
|
|
@@ -177,9 +192,13 @@ export class E2bSandboxProvider implements SandboxProvider<
|
|
|
177
192
|
}
|
|
178
193
|
}
|
|
179
194
|
|
|
180
|
-
async fork(
|
|
195
|
+
async fork(
|
|
196
|
+
sandboxId: string,
|
|
197
|
+
options?: E2bSandboxCreateOptions
|
|
198
|
+
): Promise<Sandbox> {
|
|
181
199
|
const { snapshotId } = await E2bSdkSandbox.createSnapshot(sandboxId);
|
|
182
|
-
const
|
|
200
|
+
const sdkOpts = this.buildSdkCreateOpts(options);
|
|
201
|
+
const sdkSandbox = await E2bSdkSandbox.create(snapshotId, sdkOpts);
|
|
183
202
|
return new E2bSandboxImpl(
|
|
184
203
|
sdkSandbox.sandboxId,
|
|
185
204
|
sdkSandbox,
|
|
@@ -188,22 +207,25 @@ export class E2bSandboxProvider implements SandboxProvider<
|
|
|
188
207
|
}
|
|
189
208
|
|
|
190
209
|
private buildSdkCreateOpts(options?: E2bSandboxCreateOptions) {
|
|
210
|
+
const network = options?.network ?? this.defaultNetwork;
|
|
211
|
+
const lifecycle = options?.lifecycle ?? this.defaultLifecycle;
|
|
191
212
|
return {
|
|
192
213
|
envs: options?.env,
|
|
193
214
|
timeoutMs: options?.timeoutMs ?? this.defaultTimeoutMs,
|
|
194
|
-
metadata: options?.metadata,
|
|
195
|
-
allowInternetAccess:
|
|
196
|
-
|
|
215
|
+
metadata: options?.metadata ?? this.defaultMetadata,
|
|
216
|
+
allowInternetAccess:
|
|
217
|
+
options?.allowInternetAccess ?? this.defaultAllowInternetAccess,
|
|
218
|
+
network: network
|
|
197
219
|
? {
|
|
198
|
-
allowOut:
|
|
199
|
-
denyOut:
|
|
200
|
-
allowPublicTraffic:
|
|
220
|
+
allowOut: network.allowOut,
|
|
221
|
+
denyOut: network.denyOut,
|
|
222
|
+
allowPublicTraffic: network.allowPublicTraffic,
|
|
201
223
|
}
|
|
202
224
|
: undefined,
|
|
203
|
-
lifecycle:
|
|
225
|
+
lifecycle: lifecycle
|
|
204
226
|
? {
|
|
205
|
-
onTimeout:
|
|
206
|
-
autoResume:
|
|
227
|
+
onTimeout: lifecycle.onTimeout,
|
|
228
|
+
autoResume: lifecycle.autoResume,
|
|
207
229
|
}
|
|
208
230
|
: undefined,
|
|
209
231
|
};
|
|
@@ -6,6 +6,14 @@ import type { E2bSandboxFileSystem } from "./filesystem";
|
|
|
6
6
|
*/
|
|
7
7
|
export type E2bSandbox = Sandbox & { fs: E2bSandboxFileSystem };
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Provider-level defaults for E2B sandboxes. Every lifecycle op
|
|
11
|
+
* (`create` / `restore` / `fork`) merges per-call options on top of these —
|
|
12
|
+
* per-call options win per-field. This is how E2B preserves sandbox-level
|
|
13
|
+
* config (network policy, metadata, lifecycle, timeout) across
|
|
14
|
+
* snapshot/restore and fork, since the E2B API treats those as pure
|
|
15
|
+
* create-time inputs that aren't carried in the snapshot blob.
|
|
16
|
+
*/
|
|
9
17
|
export interface E2bSandboxConfig {
|
|
10
18
|
/** Sandbox template name or ID */
|
|
11
19
|
template?: string;
|
|
@@ -13,6 +21,14 @@ export interface E2bSandboxConfig {
|
|
|
13
21
|
workspaceBase?: string;
|
|
14
22
|
/** Sandbox idle timeout in milliseconds */
|
|
15
23
|
timeoutMs?: number;
|
|
24
|
+
/** Default outbound internet access policy */
|
|
25
|
+
allowInternetAccess?: boolean;
|
|
26
|
+
/** Default outbound network allow/deny rules */
|
|
27
|
+
network?: SandboxCreateOptions["network"];
|
|
28
|
+
/** Default metadata surfaced via provider list/query APIs */
|
|
29
|
+
metadata?: SandboxCreateOptions["metadata"];
|
|
30
|
+
/** Default sandbox timeout behaviour */
|
|
31
|
+
lifecycle?: SandboxCreateOptions["lifecycle"];
|
|
16
32
|
}
|
|
17
33
|
|
|
18
34
|
export interface E2bSandboxCreateOptions extends SandboxCreateOptions {
|
|
@@ -183,7 +183,10 @@ export class InMemorySandboxProvider implements SandboxProvider {
|
|
|
183
183
|
return { sandbox };
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
async snapshot(
|
|
186
|
+
async snapshot(
|
|
187
|
+
sandboxId: string,
|
|
188
|
+
_options?: SandboxCreateOptions
|
|
189
|
+
): Promise<SandboxSnapshot> {
|
|
187
190
|
const sandbox = this.sandboxes.get(sandboxId);
|
|
188
191
|
if (!sandbox) throw new SandboxNotFoundError(sandboxId);
|
|
189
192
|
|
|
@@ -210,7 +213,10 @@ export class InMemorySandboxProvider implements SandboxProvider {
|
|
|
210
213
|
};
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
async fork(
|
|
216
|
+
async fork(
|
|
217
|
+
sandboxId: string,
|
|
218
|
+
_options?: SandboxCreateOptions
|
|
219
|
+
): Promise<Sandbox> {
|
|
214
220
|
const sandbox = await this.get(sandboxId);
|
|
215
221
|
|
|
216
222
|
const entries = await sandbox.fs.readdirWithFileTypes("/");
|
|
@@ -228,7 +234,10 @@ export class InMemorySandboxProvider implements SandboxProvider {
|
|
|
228
234
|
return newSandbox.sandbox;
|
|
229
235
|
}
|
|
230
236
|
|
|
231
|
-
async restore(
|
|
237
|
+
async restore(
|
|
238
|
+
snapshot: SandboxSnapshot,
|
|
239
|
+
_options?: SandboxCreateOptions
|
|
240
|
+
): Promise<Sandbox> {
|
|
232
241
|
const { files } = snapshot.data as { files: Record<string, string> };
|
|
233
242
|
const initialFiles: InitialFiles = {};
|
|
234
243
|
for (const [path, content] of Object.entries(files)) {
|
|
@@ -212,6 +212,15 @@ export function createAnthropicAdapter(
|
|
|
212
212
|
});
|
|
213
213
|
await thread.fork(targetThreadId);
|
|
214
214
|
},
|
|
215
|
+
|
|
216
|
+
async truncateThread(
|
|
217
|
+
threadId: string,
|
|
218
|
+
length: number,
|
|
219
|
+
threadKey?: string,
|
|
220
|
+
): Promise<void> {
|
|
221
|
+
const thread = createAnthropicThreadManager({ redis, threadId, key: threadKey });
|
|
222
|
+
await thread.truncate(length);
|
|
223
|
+
},
|
|
215
224
|
};
|
|
216
225
|
|
|
217
226
|
function createActivities<S extends string = "">(
|
|
@@ -70,7 +70,8 @@ export function createAnthropicModelInvoker({
|
|
|
70
70
|
key: threadKey,
|
|
71
71
|
hooks,
|
|
72
72
|
});
|
|
73
|
-
const { messages, system } =
|
|
73
|
+
const { messages, system, storedLength } =
|
|
74
|
+
await thread.prepareForInvocation();
|
|
74
75
|
|
|
75
76
|
const anthropicTools = toAnthropicTools(state.tools);
|
|
76
77
|
const tools = anthropicTools.length > 0 ? anthropicTools : undefined;
|
|
@@ -110,6 +111,7 @@ export function createAnthropicModelInvoker({
|
|
|
110
111
|
response.usage.cache_creation_input_tokens ?? undefined,
|
|
111
112
|
cachedReadTokens: response.usage.cache_read_input_tokens ?? undefined,
|
|
112
113
|
},
|
|
114
|
+
threadLengthAtCall: storedLength,
|
|
113
115
|
};
|
|
114
116
|
};
|
|
115
117
|
}
|
|
@@ -41,6 +41,8 @@ export interface AnthropicThreadManagerConfig {
|
|
|
41
41
|
export interface AnthropicInvocationPayload {
|
|
42
42
|
messages: Anthropic.Messages.MessageParam[];
|
|
43
43
|
system?: string | Anthropic.Messages.TextBlockParam[];
|
|
44
|
+
/** Number of stored messages loaded from Redis before preparation. */
|
|
45
|
+
storedLength: number;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
/** Thread manager with Anthropic MessageParam convenience helpers */
|
|
@@ -220,6 +222,7 @@ export function createAnthropicThreadManager(
|
|
|
220
222
|
? messages.map((msg, i) => onPreparedMessage(msg, i, messages))
|
|
221
223
|
: messages,
|
|
222
224
|
...(system ? { system } : {}),
|
|
225
|
+
storedLength: stored.length,
|
|
223
226
|
};
|
|
224
227
|
},
|
|
225
228
|
};
|
|
@@ -222,6 +222,19 @@ export function createGoogleGenAIAdapter(
|
|
|
222
222
|
});
|
|
223
223
|
await thread.fork(targetThreadId);
|
|
224
224
|
},
|
|
225
|
+
|
|
226
|
+
async truncateThread(
|
|
227
|
+
threadId: string,
|
|
228
|
+
length: number,
|
|
229
|
+
threadKey?: string,
|
|
230
|
+
): Promise<void> {
|
|
231
|
+
const thread = createGoogleGenAIThreadManager({
|
|
232
|
+
redis,
|
|
233
|
+
threadId,
|
|
234
|
+
key: threadKey,
|
|
235
|
+
});
|
|
236
|
+
await thread.truncate(length);
|
|
237
|
+
},
|
|
225
238
|
};
|
|
226
239
|
|
|
227
240
|
function createActivities<S extends string = "">(
|
|
@@ -73,7 +73,8 @@ export function createGoogleGenAIModelInvoker({
|
|
|
73
73
|
key: threadKey,
|
|
74
74
|
hooks,
|
|
75
75
|
});
|
|
76
|
-
const { contents, systemInstruction } =
|
|
76
|
+
const { contents, systemInstruction, storedLength } =
|
|
77
|
+
await thread.prepareForInvocation();
|
|
77
78
|
|
|
78
79
|
const functionDeclarations = toFunctionDeclarations(state.tools);
|
|
79
80
|
const tools =
|
|
@@ -116,6 +117,7 @@ export function createGoogleGenAIModelInvoker({
|
|
|
116
117
|
outputTokens: lastChunk.usageMetadata?.candidatesTokenCount,
|
|
117
118
|
cachedReadTokens: lastChunk.usageMetadata?.cachedContentTokenCount,
|
|
118
119
|
},
|
|
120
|
+
threadLengthAtCall: storedLength,
|
|
119
121
|
};
|
|
120
122
|
};
|
|
121
123
|
}
|
|
@@ -37,6 +37,8 @@ export interface GoogleGenAIThreadManagerConfig {
|
|
|
37
37
|
export interface GoogleGenAIInvocationPayload {
|
|
38
38
|
contents: Content[];
|
|
39
39
|
systemInstruction?: Part[];
|
|
40
|
+
/** Number of stored messages loaded from Redis before preparation. */
|
|
41
|
+
storedLength: number;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
/** Thread manager with Google GenAI Content convenience helpers */
|
|
@@ -196,6 +198,7 @@ export function createGoogleGenAIThreadManager(
|
|
|
196
198
|
...(systemInstruction && systemInstruction.length > 0
|
|
197
199
|
? { systemInstruction }
|
|
198
200
|
: {}),
|
|
201
|
+
storedLength: stored.length,
|
|
199
202
|
};
|
|
200
203
|
},
|
|
201
204
|
};
|
|
@@ -195,6 +195,15 @@ export function createLangChainAdapter(
|
|
|
195
195
|
});
|
|
196
196
|
await thread.fork(targetThreadId);
|
|
197
197
|
},
|
|
198
|
+
|
|
199
|
+
async truncateThread(
|
|
200
|
+
threadId: string,
|
|
201
|
+
length: number,
|
|
202
|
+
threadKey?: string,
|
|
203
|
+
): Promise<void> {
|
|
204
|
+
const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
|
|
205
|
+
await thread.truncate(length);
|
|
206
|
+
},
|
|
198
207
|
};
|
|
199
208
|
|
|
200
209
|
function createActivities<S extends string = "">(
|
|
@@ -58,7 +58,7 @@ export function createLangChainModelInvoker<
|
|
|
58
58
|
});
|
|
59
59
|
const runId = uuidv4();
|
|
60
60
|
|
|
61
|
-
const { messages } = await thread.prepareForInvocation();
|
|
61
|
+
const { messages, storedLength } = await thread.prepareForInvocation();
|
|
62
62
|
|
|
63
63
|
const heartbeatInterval = heartbeat
|
|
64
64
|
? setInterval(() => heartbeat(), 30_000)
|
|
@@ -97,6 +97,7 @@ export function createLangChainModelInvoker<
|
|
|
97
97
|
response.usage_metadata?.input_token_details?.cache_read ||
|
|
98
98
|
(providerUsage.cacheReadInputTokens as number | undefined),
|
|
99
99
|
},
|
|
100
|
+
threadLengthAtCall: storedLength,
|
|
100
101
|
};
|
|
101
102
|
} finally {
|
|
102
103
|
if (heartbeatInterval) clearInterval(heartbeatInterval);
|
|
@@ -39,6 +39,8 @@ export interface LangChainThreadManagerConfig {
|
|
|
39
39
|
/** Prepared payload ready to send to a LangChain chat model */
|
|
40
40
|
export interface LangChainInvocationPayload {
|
|
41
41
|
messages: BaseMessage[];
|
|
42
|
+
/** Number of stored messages loaded from Redis before preparation. */
|
|
43
|
+
storedLength: number;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/** Thread manager with LangChain StoredMessage convenience helpers */
|
|
@@ -139,6 +141,7 @@ export function createLangChainThreadManager(
|
|
|
139
141
|
messages: onPreparedMessage
|
|
140
142
|
? messages.map((msg, i) => onPreparedMessage(msg, i, messages))
|
|
141
143
|
: messages,
|
|
144
|
+
storedLength: stored.length,
|
|
142
145
|
};
|
|
143
146
|
},
|
|
144
147
|
};
|
package/src/lib/lifecycle.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type ThreadInit =
|
|
|
19
19
|
// Sandbox lifecycle
|
|
20
20
|
// ============================================================================
|
|
21
21
|
|
|
22
|
-
import type { SandboxSnapshot } from "./sandbox/types";
|
|
22
|
+
import type { SandboxCreateOptions, SandboxSnapshot } from "./sandbox/types";
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Sandbox initialization strategy.
|
|
@@ -31,17 +31,24 @@ import type { SandboxSnapshot } from "./sandbox/types";
|
|
|
31
31
|
* Paused sandboxes are automatically resumed. The shutdown policy applies
|
|
32
32
|
* on exit.
|
|
33
33
|
* - `"fork"` — fork from an existing (or paused) sandbox; a new sandbox is
|
|
34
|
-
* created and owned by this session.
|
|
34
|
+
* created and owned by this session. `options` is an optional per-call
|
|
35
|
+
* override merged on top of the provider's static defaults.
|
|
35
36
|
* - `"from-snapshot"` — restore a fresh sandbox from a previously captured
|
|
36
37
|
* {@link SandboxSnapshot}. The new sandbox is owned by this session.
|
|
38
|
+
* `options` is an optional per-call override merged on top of the
|
|
39
|
+
* provider's static defaults.
|
|
37
40
|
* - `"inherit"` — use a sandbox owned by someone else (e.g. a parent agent).
|
|
38
41
|
* The session will **not** manage its lifecycle on exit.
|
|
39
42
|
*/
|
|
40
43
|
export type SandboxInit =
|
|
41
44
|
| { mode: "new"; ctx?: unknown }
|
|
42
45
|
| { mode: "continue"; sandboxId: string }
|
|
43
|
-
| { mode: "fork"; sandboxId: string }
|
|
44
|
-
| {
|
|
46
|
+
| { mode: "fork"; sandboxId: string; options?: SandboxCreateOptions }
|
|
47
|
+
| {
|
|
48
|
+
mode: "from-snapshot";
|
|
49
|
+
snapshot: SandboxSnapshot;
|
|
50
|
+
options?: SandboxCreateOptions;
|
|
51
|
+
}
|
|
45
52
|
| {
|
|
46
53
|
mode: "inherit";
|
|
47
54
|
sandboxId: string;
|
package/src/lib/model/types.ts
CHANGED
|
@@ -8,6 +8,16 @@ export interface AgentResponse<M = unknown> {
|
|
|
8
8
|
message: M;
|
|
9
9
|
rawToolCalls: RawToolCall[];
|
|
10
10
|
usage?: TokenUsage;
|
|
11
|
+
/**
|
|
12
|
+
* Number of stored messages in the thread at the moment the LLM was
|
|
13
|
+
* invoked — i.e. *before* the assistant message is appended. The
|
|
14
|
+
* session uses this as a rewind snapshot so it can roll the thread
|
|
15
|
+
* back to this exact state if a tool requests a rewind.
|
|
16
|
+
*
|
|
17
|
+
* Adapters compute this for free from the array of stored messages
|
|
18
|
+
* they load when preparing the payload.
|
|
19
|
+
*/
|
|
20
|
+
threadLengthAtCall?: number;
|
|
11
21
|
}
|
|
12
22
|
|
|
13
23
|
/**
|
|
@@ -120,9 +120,7 @@ export class SandboxManager<
|
|
|
120
120
|
async create(
|
|
121
121
|
options?: TOptions,
|
|
122
122
|
ctx?: TCtx
|
|
123
|
-
): Promise<{
|
|
124
|
-
sandboxId: string;
|
|
125
|
-
} | null> {
|
|
123
|
+
): Promise<{ sandboxId: string } | null> {
|
|
126
124
|
let providerOptions = options;
|
|
127
125
|
|
|
128
126
|
if (this.hooks.onPreCreate) {
|
|
@@ -175,12 +173,15 @@ export class SandboxManager<
|
|
|
175
173
|
await this.provider.resume(id);
|
|
176
174
|
}
|
|
177
175
|
|
|
178
|
-
async snapshot(id: string): Promise<SandboxSnapshot> {
|
|
179
|
-
return this.provider.snapshot(id);
|
|
176
|
+
async snapshot(id: string, options?: TOptions): Promise<SandboxSnapshot> {
|
|
177
|
+
return this.provider.snapshot(id, options);
|
|
180
178
|
}
|
|
181
179
|
|
|
182
|
-
async restore(
|
|
183
|
-
|
|
180
|
+
async restore(
|
|
181
|
+
snapshot: SandboxSnapshot,
|
|
182
|
+
options?: TOptions
|
|
183
|
+
): Promise<string> {
|
|
184
|
+
const sandbox = await this.provider.restore(snapshot, options);
|
|
184
185
|
return sandbox.id;
|
|
185
186
|
}
|
|
186
187
|
|
|
@@ -188,8 +189,8 @@ export class SandboxManager<
|
|
|
188
189
|
await this.provider.deleteSnapshot(snapshot);
|
|
189
190
|
}
|
|
190
191
|
|
|
191
|
-
async fork(sandboxId: string): Promise<string> {
|
|
192
|
-
const sandbox = await this.provider.fork(sandboxId);
|
|
192
|
+
async fork(sandboxId: string, options?: TOptions): Promise<string> {
|
|
193
|
+
const sandbox = await this.provider.fork(sandboxId, options);
|
|
193
194
|
return sandbox.id;
|
|
194
195
|
}
|
|
195
196
|
|
|
@@ -221,9 +222,7 @@ export class SandboxManager<
|
|
|
221
222
|
createSandbox: async (
|
|
222
223
|
options?: TOptions,
|
|
223
224
|
ctx?: TCtx
|
|
224
|
-
): Promise<{
|
|
225
|
-
sandboxId: string;
|
|
226
|
-
} | null> => {
|
|
225
|
+
): Promise<{ sandboxId: string } | null> => {
|
|
227
226
|
return this.create(options, ctx);
|
|
228
227
|
},
|
|
229
228
|
destroySandbox: async (sandboxId: string): Promise<void> => {
|
|
@@ -238,19 +237,28 @@ export class SandboxManager<
|
|
|
238
237
|
resumeSandbox: async (sandboxId: string): Promise<void> => {
|
|
239
238
|
await this.resume(sandboxId);
|
|
240
239
|
},
|
|
241
|
-
snapshotSandbox: async (
|
|
242
|
-
|
|
240
|
+
snapshotSandbox: async (
|
|
241
|
+
sandboxId: string,
|
|
242
|
+
options?: TOptions
|
|
243
|
+
): Promise<SandboxSnapshot> => {
|
|
244
|
+
return this.snapshot(sandboxId, options);
|
|
243
245
|
},
|
|
244
|
-
restoreSandbox: async (
|
|
245
|
-
|
|
246
|
+
restoreSandbox: async (
|
|
247
|
+
snapshot: SandboxSnapshot,
|
|
248
|
+
options?: TOptions
|
|
249
|
+
): Promise<string> => {
|
|
250
|
+
return this.restore(snapshot, options);
|
|
246
251
|
},
|
|
247
252
|
deleteSandboxSnapshot: async (
|
|
248
253
|
snapshot: SandboxSnapshot
|
|
249
254
|
): Promise<void> => {
|
|
250
255
|
await this.deleteSnapshot(snapshot);
|
|
251
256
|
},
|
|
252
|
-
forkSandbox: async (
|
|
253
|
-
|
|
257
|
+
forkSandbox: async (
|
|
258
|
+
sandboxId: string,
|
|
259
|
+
options?: TOptions
|
|
260
|
+
): Promise<string> => {
|
|
261
|
+
return this.fork(sandboxId, options);
|
|
254
262
|
},
|
|
255
263
|
};
|
|
256
264
|
const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);
|
package/src/lib/sandbox/types.ts
CHANGED
|
@@ -158,11 +158,23 @@ export interface SandboxProvider<
|
|
|
158
158
|
pause(sandboxId: string, ttlSeconds?: number): Promise<void>;
|
|
159
159
|
/** Resume a paused sandbox. No-op if already running. */
|
|
160
160
|
resume(sandboxId: string): Promise<void>;
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Capture a snapshot of a running sandbox. `options` is a per-call override
|
|
163
|
+
* merged on top of the provider's static defaults.
|
|
164
|
+
*/
|
|
165
|
+
snapshot(sandboxId: string, options?: TOptions): Promise<SandboxSnapshot>;
|
|
166
|
+
/**
|
|
167
|
+
* Restore a sandbox from a snapshot. `options` is a per-call override
|
|
168
|
+
* merged on top of the provider's static defaults.
|
|
169
|
+
*/
|
|
170
|
+
restore(snapshot: SandboxSnapshot, options?: TOptions): Promise<Sandbox>;
|
|
163
171
|
/** Delete a previously captured snapshot. No-op if already deleted. */
|
|
164
172
|
deleteSnapshot(snapshot: SandboxSnapshot): Promise<void>;
|
|
165
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Fork a running sandbox into a new one. `options` is a per-call override
|
|
175
|
+
* merged on top of the provider's static defaults.
|
|
176
|
+
*/
|
|
177
|
+
fork(sandboxId: string, options?: TOptions): Promise<Sandbox>;
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
// ============================================================================
|
|
@@ -181,12 +193,20 @@ export interface SandboxOps<
|
|
|
181
193
|
pauseSandbox(sandboxId: string): Promise<void>;
|
|
182
194
|
/** Resume a paused sandbox. No-op if already running. */
|
|
183
195
|
resumeSandbox(sandboxId: string): Promise<void>;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
/** Capture a snapshot. `options` is a per-call override merged on top of provider defaults. */
|
|
197
|
+
snapshotSandbox(
|
|
198
|
+
sandboxId: string,
|
|
199
|
+
options?: TOptions
|
|
200
|
+
): Promise<SandboxSnapshot>;
|
|
201
|
+
/** Create a fresh sandbox from a snapshot. `options` is a per-call override merged on top of provider defaults. */
|
|
202
|
+
restoreSandbox(
|
|
203
|
+
snapshot: SandboxSnapshot,
|
|
204
|
+
options?: TOptions
|
|
205
|
+
): Promise<string>;
|
|
187
206
|
/** Delete a previously captured snapshot. No-op if already deleted. */
|
|
188
207
|
deleteSandboxSnapshot(snapshot: SandboxSnapshot): Promise<void>;
|
|
189
|
-
|
|
208
|
+
/** Fork a running sandbox. `options` is a per-call override merged on top of provider defaults. */
|
|
209
|
+
forkSandbox(sandboxId: string, options?: TOptions): Promise<string>;
|
|
190
210
|
}
|
|
191
211
|
|
|
192
212
|
/**
|