zeitlich 0.2.45 → 0.2.47
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/README.md +137 -11
- package/dist/{activities-Coafq5zr.d.cts → activities-CPwKoUlD.d.cts} +22 -2
- package/dist/{activities-CrN-ghLo.d.ts → activities-DlaBxNID.d.ts} +22 -2
- package/dist/adapters/thread/anthropic/index.cjs +276 -71
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +62 -8
- package/dist/adapters/thread/anthropic/index.d.ts +62 -8
- package/dist/adapters/thread/anthropic/index.js +275 -72
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +38 -20
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
- package/dist/adapters/thread/anthropic/workflow.js +38 -20
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +171 -69
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +6 -4
- package/dist/adapters/thread/google-genai/index.d.ts +6 -4
- package/dist/adapters/thread/google-genai/index.js +171 -69
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +38 -20
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +7 -4
- package/dist/adapters/thread/google-genai/workflow.d.ts +7 -4
- package/dist/adapters/thread/google-genai/workflow.js +38 -20
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +170 -66
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +19 -4
- package/dist/adapters/thread/langchain/index.d.ts +19 -4
- package/dist/adapters/thread/langchain/index.js +170 -66
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +38 -20
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
- package/dist/adapters/thread/langchain/workflow.js +38 -20
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/cold-store-BDgJpwLI.d.ts +114 -0
- package/dist/cold-store-Z2wvK2cV.d.cts +114 -0
- package/dist/index.cjs +440 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +150 -8
- package/dist/index.d.ts +150 -8
- package/dist/index.js +432 -68
- package/dist/index.js.map +1 -1
- package/dist/proxy-CDh3Rsa7.d.cts +40 -0
- package/dist/proxy-Du8ggERu.d.ts +40 -0
- package/dist/{thread-manager-wRVVBFgj.d.cts → thread-manager-BjoYYXgd.d.cts} +8 -2
- package/dist/{thread-manager-BsLO3Fgc.d.cts → thread-manager-D8zKNFZ9.d.cts} +8 -2
- package/dist/{thread-manager-Bi1XlbpJ.d.ts → thread-manager-DtHYws2F.d.ts} +8 -2
- package/dist/{thread-manager-BhkOyQ1I.d.ts → thread-manager-Dw96FKH1.d.ts} +8 -2
- package/dist/{types-C66-BVBr.d.cts → types-BMJrsHo0.d.cts} +17 -1
- package/dist/{types-BkX4HLzi.d.ts → types-CtdOquo3.d.ts} +17 -1
- package/dist/{types-CdALEF3z.d.cts → types-DNEl5uxQ.d.cts} +38 -0
- package/dist/{types-ChAy_jSP.d.ts → types-qQVZfhoT.d.ts} +38 -0
- package/dist/{workflow-DMmiaw6w.d.cts → workflow-BH9ImDGq.d.cts} +48 -2
- package/dist/{workflow-BwT5EybR.d.ts → workflow-Cdw3-RNB.d.ts} +48 -2
- package/dist/workflow.cjs +47 -4
- 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 +47 -5
- package/dist/workflow.js.map +1 -1
- package/package.json +14 -3
- package/src/adapters/thread/anthropic/activities.ts +82 -39
- package/src/adapters/thread/anthropic/index.ts +8 -0
- package/src/adapters/thread/anthropic/model-invoker.test.ts +110 -0
- package/src/adapters/thread/anthropic/model-invoker.ts +26 -5
- package/src/adapters/thread/anthropic/prompt-cache.test.ts +134 -0
- package/src/adapters/thread/anthropic/prompt-cache.ts +163 -0
- package/src/adapters/thread/anthropic/proxy.ts +1 -0
- package/src/adapters/thread/anthropic/thread-manager.ts +9 -1
- package/src/adapters/thread/google-genai/activities.ts +64 -40
- package/src/adapters/thread/google-genai/proxy.ts +1 -0
- package/src/adapters/thread/google-genai/thread-manager.ts +9 -1
- package/src/adapters/thread/langchain/activities.ts +63 -36
- package/src/adapters/thread/langchain/proxy.ts +1 -0
- package/src/adapters/thread/langchain/thread-manager.ts +9 -1
- package/src/index.ts +21 -2
- package/src/lib/session/session-edge-cases.integration.test.ts +12 -0
- package/src/lib/session/session.integration.test.ts +138 -0
- package/src/lib/session/session.ts +29 -0
- package/src/lib/session/types.ts +22 -0
- package/src/lib/subagent/define.ts +1 -0
- package/src/lib/subagent/handler.ts +11 -2
- package/src/lib/subagent/subagent.integration.test.ts +139 -0
- package/src/lib/subagent/types.ts +16 -0
- package/src/lib/thread/cold-store.test.ts +221 -0
- package/src/lib/thread/cold-store.ts +269 -0
- package/src/lib/thread/index.ts +32 -0
- package/src/lib/thread/keys.ts +20 -0
- package/src/lib/thread/manager.ts +16 -27
- package/src/lib/thread/proxy.ts +79 -27
- package/src/lib/thread/snapshot.test.ts +443 -0
- package/src/lib/thread/snapshot.ts +163 -0
- package/src/lib/thread/test-utils.ts +228 -0
- package/src/lib/thread/tiered.test.ts +281 -0
- package/src/lib/thread/tiered.ts +135 -0
- package/src/lib/thread/types.ts +16 -0
- package/src/tools/edit/handler.test.ts +177 -0
- package/src/tools/edit/handler.ts +249 -47
- package/src/tools/edit/tool.ts +40 -0
- package/src/tools/task-create/handler.ts +1 -1
- package/src/tools/task-update/handler.ts +1 -1
- package/src/workflow.ts +2 -2
- package/dist/proxy-Bf7uI-Hw.d.cts +0 -24
- package/dist/proxy-COqA95FW.d.ts +0 -24
package/dist/index.js
CHANGED
|
@@ -3,6 +3,10 @@ import z14, { z } from 'zod';
|
|
|
3
3
|
import { randomUUID, randomFillSync } from 'crypto';
|
|
4
4
|
import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
|
|
5
5
|
import { join, resolve, posix } from 'path';
|
|
6
|
+
import { gzip, gunzip } from 'zlib';
|
|
7
|
+
import { promisify } from 'util';
|
|
8
|
+
import { DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
9
|
+
import { Upload } from '@aws-sdk/lib-storage';
|
|
6
10
|
import { Context } from '@temporalio/activity';
|
|
7
11
|
import { promises } from 'fs';
|
|
8
12
|
|
|
@@ -564,7 +568,8 @@ function createSubagentHandler(subagents) {
|
|
|
564
568
|
}
|
|
565
569
|
const threadMode = config.thread ?? "new";
|
|
566
570
|
const allowsContinuation = threadMode !== "new";
|
|
567
|
-
const
|
|
571
|
+
const newThreadSource = config.newThreadSource ?? "new";
|
|
572
|
+
const continuationThreadId = !allowsContinuation ? void 0 : args.threadId ?? (newThreadSource === "from-parent" ? context.threadId : void 0);
|
|
568
573
|
let thread;
|
|
569
574
|
if (continuationThreadId) {
|
|
570
575
|
thread = {
|
|
@@ -1032,7 +1037,9 @@ async function createSession(config) {
|
|
|
1032
1037
|
appendAgentMessage,
|
|
1033
1038
|
forkThread,
|
|
1034
1039
|
loadThreadState,
|
|
1035
|
-
saveThreadState
|
|
1040
|
+
saveThreadState,
|
|
1041
|
+
hydrateThread,
|
|
1042
|
+
flushThread
|
|
1036
1043
|
} = threadOps;
|
|
1037
1044
|
const plugins = [];
|
|
1038
1045
|
let destroySubagentSandboxes;
|
|
@@ -1176,10 +1183,12 @@ async function createSession(config) {
|
|
|
1176
1183
|
});
|
|
1177
1184
|
};
|
|
1178
1185
|
if (threadMode === "fork" && sourceThreadId) {
|
|
1186
|
+
await hydrateThread(sourceThreadId, threadKey);
|
|
1179
1187
|
await forkThread(sourceThreadId, threadId, threadKey);
|
|
1180
1188
|
const forkedSlice = await loadThreadState(threadId, threadKey);
|
|
1181
1189
|
if (forkedSlice) rehydrateFromSlice(forkedSlice);
|
|
1182
1190
|
} else if (threadMode === "continue") {
|
|
1191
|
+
await hydrateThread(threadId, threadKey);
|
|
1183
1192
|
const continuedSlice = await loadThreadState(threadId, threadKey);
|
|
1184
1193
|
if (continuedSlice) rehydrateFromSlice(continuedSlice);
|
|
1185
1194
|
} else {
|
|
@@ -1361,6 +1370,15 @@ async function createSession(config) {
|
|
|
1361
1370
|
error: persistError instanceof Error ? persistError.message : String(persistError)
|
|
1362
1371
|
});
|
|
1363
1372
|
}
|
|
1373
|
+
try {
|
|
1374
|
+
await flushThread(threadId, threadKey);
|
|
1375
|
+
} catch (flushError) {
|
|
1376
|
+
log.warn("failed to flush thread to cold tier", {
|
|
1377
|
+
agentName,
|
|
1378
|
+
threadId,
|
|
1379
|
+
error: flushError instanceof Error ? flushError.message : String(flushError)
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1364
1382
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
1365
1383
|
if (sandboxOwned && sandboxId && sandboxOps) {
|
|
1366
1384
|
switch (resolvedShutdown) {
|
|
@@ -1444,6 +1462,9 @@ function getThreadMetaKey(threadKey, threadId) {
|
|
|
1444
1462
|
function getThreadStateKey(threadKey, threadId) {
|
|
1445
1463
|
return `${threadKey}:state:thread:${threadId}`;
|
|
1446
1464
|
}
|
|
1465
|
+
function getThreadDedupKey(threadId, dedupId) {
|
|
1466
|
+
return `dedup:${dedupId}:thread:${threadId}`;
|
|
1467
|
+
}
|
|
1447
1468
|
|
|
1448
1469
|
// src/lib/types.ts
|
|
1449
1470
|
function isTerminalStatus(status) {
|
|
@@ -2196,6 +2217,13 @@ IMPORTANT:
|
|
|
2196
2217
|
}),
|
|
2197
2218
|
strict: true
|
|
2198
2219
|
};
|
|
2220
|
+
var textEditSchema = z.object({
|
|
2221
|
+
old_string: z.string().describe("The exact text to replace"),
|
|
2222
|
+
new_string: z.string().describe("The text to replace it with"),
|
|
2223
|
+
replace_all: z.boolean().optional().describe(
|
|
2224
|
+
"If true, replace all occurrences of old_string for this edit (default: false)"
|
|
2225
|
+
)
|
|
2226
|
+
});
|
|
2199
2227
|
var editTool = {
|
|
2200
2228
|
name: "FileEdit",
|
|
2201
2229
|
description: `Edit specific sections of a file by replacing text.
|
|
@@ -2224,6 +2252,27 @@ IMPORTANT:
|
|
|
2224
2252
|
}),
|
|
2225
2253
|
strict: true
|
|
2226
2254
|
};
|
|
2255
|
+
var multiEditTool = {
|
|
2256
|
+
name: "FileMultiEdit",
|
|
2257
|
+
description: `Apply multiple exact text replacements to one file in order.
|
|
2258
|
+
|
|
2259
|
+
Usage:
|
|
2260
|
+
- Use this when a task needs several related edits in the same file
|
|
2261
|
+
- Each edit is applied to the file content produced by the prior edit
|
|
2262
|
+
- The operation is atomic: if any edit fails, the file is left unchanged
|
|
2263
|
+
|
|
2264
|
+
IMPORTANT:
|
|
2265
|
+
- You must read the file first (in this session) before editing it
|
|
2266
|
+
- Each old_string must match exactly (whitespace-sensitive)
|
|
2267
|
+
- Each old_string must be unique unless that edit uses replace_all: true
|
|
2268
|
+
- old_string and new_string must be different for every edit
|
|
2269
|
+
`,
|
|
2270
|
+
schema: z.object({
|
|
2271
|
+
file_path: z.string().describe("The absolute virtual path to the file to modify"),
|
|
2272
|
+
edits: z.array(textEditSchema).min(1).describe("Exact replacements to apply sequentially to the file")
|
|
2273
|
+
}),
|
|
2274
|
+
strict: true
|
|
2275
|
+
};
|
|
2227
2276
|
var taskCreateTool = {
|
|
2228
2277
|
name: "TaskCreate",
|
|
2229
2278
|
description: `Use this tool to create a structured task list. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
@@ -2294,7 +2343,7 @@ function createTaskCreateHandler(stateManager) {
|
|
|
2294
2343
|
};
|
|
2295
2344
|
stateManager.setTask(task);
|
|
2296
2345
|
return {
|
|
2297
|
-
toolResponse:
|
|
2346
|
+
toolResponse: `Task ${task.id} created`,
|
|
2298
2347
|
data: task
|
|
2299
2348
|
};
|
|
2300
2349
|
};
|
|
@@ -2393,7 +2442,7 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
2393
2442
|
}
|
|
2394
2443
|
stateManager.setTask(task);
|
|
2395
2444
|
return {
|
|
2396
|
-
toolResponse:
|
|
2445
|
+
toolResponse: `Task ${task.id} updated`,
|
|
2397
2446
|
data: task
|
|
2398
2447
|
};
|
|
2399
2448
|
};
|
|
@@ -2588,9 +2637,6 @@ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
|
|
|
2588
2637
|
redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
|
|
2589
2638
|
return 1
|
|
2590
2639
|
`;
|
|
2591
|
-
function getDedupKey(threadId, id) {
|
|
2592
|
-
return `dedup:${id}:thread:${threadId}`;
|
|
2593
|
-
}
|
|
2594
2640
|
function createThreadManager(config) {
|
|
2595
2641
|
const {
|
|
2596
2642
|
redis,
|
|
@@ -2598,11 +2644,13 @@ function createThreadManager(config) {
|
|
|
2598
2644
|
key = "messages",
|
|
2599
2645
|
serialize = (m) => JSON.stringify(m),
|
|
2600
2646
|
deserialize = (raw) => JSON.parse(raw),
|
|
2601
|
-
idOf
|
|
2647
|
+
idOf,
|
|
2648
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2602
2649
|
} = config;
|
|
2603
2650
|
const redisKey = getThreadListKey(key, threadId);
|
|
2604
2651
|
const metaKey = getThreadMetaKey(key, threadId);
|
|
2605
2652
|
const stateKey = getThreadStateKey(key, threadId);
|
|
2653
|
+
const dedupKey = (id) => getThreadDedupKey(threadId, id);
|
|
2606
2654
|
async function assertThreadExists() {
|
|
2607
2655
|
const exists = await redis.exists(metaKey);
|
|
2608
2656
|
if (!exists) {
|
|
@@ -2612,7 +2660,7 @@ function createThreadManager(config) {
|
|
|
2612
2660
|
return {
|
|
2613
2661
|
async initialize() {
|
|
2614
2662
|
await redis.del(redisKey);
|
|
2615
|
-
await redis.set(metaKey, "1", "EX",
|
|
2663
|
+
await redis.set(metaKey, "1", "EX", ttlSeconds);
|
|
2616
2664
|
},
|
|
2617
2665
|
async load() {
|
|
2618
2666
|
await assertThreadExists();
|
|
@@ -2624,18 +2672,17 @@ function createThreadManager(config) {
|
|
|
2624
2672
|
await assertThreadExists();
|
|
2625
2673
|
if (idOf) {
|
|
2626
2674
|
const dedupId = messages.map(idOf).join(":");
|
|
2627
|
-
const dedupKey = getDedupKey(threadId, dedupId);
|
|
2628
2675
|
await redis.eval(
|
|
2629
2676
|
APPEND_IDEMPOTENT_SCRIPT,
|
|
2630
2677
|
2,
|
|
2631
|
-
dedupKey,
|
|
2678
|
+
dedupKey(dedupId),
|
|
2632
2679
|
redisKey,
|
|
2633
|
-
String(
|
|
2680
|
+
String(ttlSeconds),
|
|
2634
2681
|
...messages.map(serialize)
|
|
2635
2682
|
);
|
|
2636
2683
|
} else {
|
|
2637
2684
|
await redis.rpush(redisKey, ...messages.map(serialize));
|
|
2638
|
-
await redis.expire(redisKey,
|
|
2685
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2639
2686
|
}
|
|
2640
2687
|
},
|
|
2641
2688
|
async fork(newThreadId) {
|
|
@@ -2650,11 +2697,11 @@ function createThreadManager(config) {
|
|
|
2650
2697
|
if (data.length > 0) {
|
|
2651
2698
|
const newKey = getThreadListKey(key, newThreadId);
|
|
2652
2699
|
await redis.rpush(newKey, ...data);
|
|
2653
|
-
await redis.expire(newKey,
|
|
2700
|
+
await redis.expire(newKey, ttlSeconds);
|
|
2654
2701
|
}
|
|
2655
2702
|
if (stateRaw != null) {
|
|
2656
2703
|
const newStateKey = getThreadStateKey(key, newThreadId);
|
|
2657
|
-
await redis.set(newStateKey, stateRaw, "EX",
|
|
2704
|
+
await redis.set(newStateKey, stateRaw, "EX", ttlSeconds);
|
|
2658
2705
|
}
|
|
2659
2706
|
return forked;
|
|
2660
2707
|
},
|
|
@@ -2669,15 +2716,13 @@ function createThreadManager(config) {
|
|
|
2669
2716
|
const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
|
|
2670
2717
|
await redis.del(redisKey);
|
|
2671
2718
|
if (existingIds.length > 0) {
|
|
2672
|
-
await redis.del(
|
|
2673
|
-
...existingIds.map((id) => getDedupKey(threadId, id))
|
|
2674
|
-
);
|
|
2719
|
+
await redis.del(...existingIds.map(dedupKey));
|
|
2675
2720
|
}
|
|
2676
2721
|
if (messages.length > 0) {
|
|
2677
2722
|
await redis.rpush(redisKey, ...messages.map(serialize));
|
|
2678
|
-
await redis.expire(redisKey,
|
|
2723
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2679
2724
|
}
|
|
2680
|
-
await redis.expire(metaKey,
|
|
2725
|
+
await redis.expire(metaKey, ttlSeconds);
|
|
2681
2726
|
},
|
|
2682
2727
|
async delete() {
|
|
2683
2728
|
await redis.del(redisKey, metaKey, stateKey);
|
|
@@ -2689,12 +2734,7 @@ function createThreadManager(config) {
|
|
|
2689
2734
|
},
|
|
2690
2735
|
async saveState(state) {
|
|
2691
2736
|
await assertThreadExists();
|
|
2692
|
-
await redis.set(
|
|
2693
|
-
stateKey,
|
|
2694
|
-
JSON.stringify(state),
|
|
2695
|
-
"EX",
|
|
2696
|
-
THREAD_TTL_SECONDS
|
|
2697
|
-
);
|
|
2737
|
+
await redis.set(stateKey, JSON.stringify(state), "EX", ttlSeconds);
|
|
2698
2738
|
},
|
|
2699
2739
|
async deleteState() {
|
|
2700
2740
|
await redis.del(stateKey);
|
|
@@ -2723,15 +2763,13 @@ function createThreadManager(config) {
|
|
|
2723
2763
|
if (idx === -1) return;
|
|
2724
2764
|
if (idx === 0) {
|
|
2725
2765
|
await redis.del(redisKey);
|
|
2726
|
-
await redis.expire(metaKey,
|
|
2766
|
+
await redis.expire(metaKey, ttlSeconds);
|
|
2727
2767
|
} else {
|
|
2728
2768
|
await redis.ltrim(redisKey, 0, idx - 1);
|
|
2729
|
-
await redis.expire(redisKey,
|
|
2769
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2730
2770
|
}
|
|
2731
2771
|
if (removedIds.length > 0) {
|
|
2732
|
-
await redis.del(
|
|
2733
|
-
...removedIds.map((id) => getDedupKey(threadId, id))
|
|
2734
|
-
);
|
|
2772
|
+
await redis.del(...removedIds.map(dedupKey));
|
|
2735
2773
|
}
|
|
2736
2774
|
}
|
|
2737
2775
|
};
|
|
@@ -2771,6 +2809,199 @@ function withParentWorkflowState(client, handler) {
|
|
|
2771
2809
|
};
|
|
2772
2810
|
}
|
|
2773
2811
|
|
|
2812
|
+
// src/lib/thread/cold-store.ts
|
|
2813
|
+
var gzipAsync = promisify(gzip);
|
|
2814
|
+
var gunzipAsync = promisify(gunzip);
|
|
2815
|
+
function joinKey(parts) {
|
|
2816
|
+
return parts.map((p) => p.replace(/^\/+|\/+$/g, "")).filter((p) => p.length > 0).join("/");
|
|
2817
|
+
}
|
|
2818
|
+
function buildKey(prefix, threadKey, threadId, gzip) {
|
|
2819
|
+
const ext = gzip ? "json.gz" : "json";
|
|
2820
|
+
return joinKey([
|
|
2821
|
+
prefix ?? "threads",
|
|
2822
|
+
threadKey,
|
|
2823
|
+
`${threadId}.${ext}`
|
|
2824
|
+
]);
|
|
2825
|
+
}
|
|
2826
|
+
async function streamToBuffer(body, onChunk) {
|
|
2827
|
+
if (body == null) return Buffer.alloc(0);
|
|
2828
|
+
if (body instanceof Uint8Array) return Buffer.from(body);
|
|
2829
|
+
if (typeof body[Symbol.asyncIterator] === "function") {
|
|
2830
|
+
const chunks = [];
|
|
2831
|
+
for await (const chunk of body) {
|
|
2832
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
2833
|
+
onChunk?.();
|
|
2834
|
+
}
|
|
2835
|
+
return Buffer.concat(chunks);
|
|
2836
|
+
}
|
|
2837
|
+
if (typeof body.transformToByteArray === "function") {
|
|
2838
|
+
const bytes = await body.transformToByteArray();
|
|
2839
|
+
return Buffer.from(bytes);
|
|
2840
|
+
}
|
|
2841
|
+
if (typeof body.arrayBuffer === "function") {
|
|
2842
|
+
const ab = await body.arrayBuffer();
|
|
2843
|
+
return Buffer.from(ab);
|
|
2844
|
+
}
|
|
2845
|
+
return Buffer.alloc(0);
|
|
2846
|
+
}
|
|
2847
|
+
function createS3ColdStore(config) {
|
|
2848
|
+
const { s3, bucket, prefix, gzip = true } = config;
|
|
2849
|
+
const contentType = config.contentType ?? (gzip ? "application/gzip" : "application/json");
|
|
2850
|
+
return {
|
|
2851
|
+
async read(threadKey, threadId) {
|
|
2852
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2853
|
+
try {
|
|
2854
|
+
const resp = await s3.send(
|
|
2855
|
+
new GetObjectCommand({ Bucket: bucket, Key })
|
|
2856
|
+
);
|
|
2857
|
+
const { heartbeat } = getActivityContext();
|
|
2858
|
+
const buf = await streamToBuffer(resp.Body, heartbeat);
|
|
2859
|
+
const json = gzip ? (await gunzipAsync(buf)).toString("utf8") : buf.toString("utf8");
|
|
2860
|
+
return JSON.parse(json);
|
|
2861
|
+
} catch (err) {
|
|
2862
|
+
if (isNotFound(err)) return null;
|
|
2863
|
+
throw err;
|
|
2864
|
+
}
|
|
2865
|
+
},
|
|
2866
|
+
async write(threadKey, threadId, snapshot) {
|
|
2867
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2868
|
+
const json = JSON.stringify(snapshot);
|
|
2869
|
+
const body = gzip ? await gzipAsync(Buffer.from(json, "utf8")) : json;
|
|
2870
|
+
const upload = new Upload({
|
|
2871
|
+
client: s3,
|
|
2872
|
+
params: { Bucket: bucket, Key, Body: body, ContentType: contentType }
|
|
2873
|
+
});
|
|
2874
|
+
const { heartbeat } = getActivityContext();
|
|
2875
|
+
if (heartbeat) upload.on("httpUploadProgress", heartbeat);
|
|
2876
|
+
await upload.done();
|
|
2877
|
+
},
|
|
2878
|
+
async delete(threadKey, threadId) {
|
|
2879
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2880
|
+
await s3.send(new DeleteObjectCommand({ Bucket: bucket, Key }));
|
|
2881
|
+
}
|
|
2882
|
+
};
|
|
2883
|
+
}
|
|
2884
|
+
function isNotFound(err) {
|
|
2885
|
+
if (typeof err !== "object" || err === null) return false;
|
|
2886
|
+
const e = err;
|
|
2887
|
+
return e.name === "NoSuchKey" || e.Code === "NoSuchKey" || e.code === "NoSuchKey" || e.name === "NotFound" || e.$metadata?.httpStatusCode === 404;
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
// src/lib/thread/snapshot.ts
|
|
2891
|
+
async function encodeSnapshot(config) {
|
|
2892
|
+
const { redis, threadKey, threadId, idOf } = config;
|
|
2893
|
+
const metaKey = getThreadMetaKey(threadKey, threadId);
|
|
2894
|
+
if (await redis.exists(metaKey) === 0) {
|
|
2895
|
+
return null;
|
|
2896
|
+
}
|
|
2897
|
+
const listKey = getThreadListKey(threadKey, threadId);
|
|
2898
|
+
const stateKey = getThreadStateKey(threadKey, threadId);
|
|
2899
|
+
const messages = await redis.lrange(listKey, 0, -1);
|
|
2900
|
+
const stateRaw = await redis.get(stateKey);
|
|
2901
|
+
const state = stateRaw == null ? null : JSON.parse(stateRaw);
|
|
2902
|
+
const dedupIds = idOf ? messages.map(idOf) : [];
|
|
2903
|
+
return { v: 1, messages, state, dedupIds };
|
|
2904
|
+
}
|
|
2905
|
+
async function applySnapshot(config) {
|
|
2906
|
+
const {
|
|
2907
|
+
redis,
|
|
2908
|
+
threadKey,
|
|
2909
|
+
threadId,
|
|
2910
|
+
snapshot,
|
|
2911
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2912
|
+
} = config;
|
|
2913
|
+
const metaKey = getThreadMetaKey(threadKey, threadId);
|
|
2914
|
+
if (await redis.exists(metaKey) === 1) {
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2917
|
+
const listKey = getThreadListKey(threadKey, threadId);
|
|
2918
|
+
const stateKey = getThreadStateKey(threadKey, threadId);
|
|
2919
|
+
await redis.del(listKey, stateKey);
|
|
2920
|
+
const pipeline = redis.pipeline();
|
|
2921
|
+
if (snapshot.messages.length > 0) {
|
|
2922
|
+
pipeline.rpush(listKey, ...snapshot.messages);
|
|
2923
|
+
pipeline.expire(listKey, ttlSeconds);
|
|
2924
|
+
}
|
|
2925
|
+
if (snapshot.state != null) {
|
|
2926
|
+
pipeline.set(stateKey, JSON.stringify(snapshot.state), "EX", ttlSeconds);
|
|
2927
|
+
}
|
|
2928
|
+
for (const id of snapshot.dedupIds) {
|
|
2929
|
+
pipeline.set(getThreadDedupKey(threadId, id), "1", "EX", ttlSeconds);
|
|
2930
|
+
}
|
|
2931
|
+
const results = await pipeline.exec();
|
|
2932
|
+
if (results) {
|
|
2933
|
+
const firstErr = results.find(([err]) => err)?.[0] ?? null;
|
|
2934
|
+
if (firstErr) {
|
|
2935
|
+
await redis.del(
|
|
2936
|
+
listKey,
|
|
2937
|
+
stateKey,
|
|
2938
|
+
...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id))
|
|
2939
|
+
).catch(() => void 0);
|
|
2940
|
+
throw firstErr;
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
await redis.set(metaKey, "1", "EX", ttlSeconds);
|
|
2944
|
+
}
|
|
2945
|
+
async function clearHotTier(config) {
|
|
2946
|
+
const { redis, threadKey, threadId, dedupIds = [] } = config;
|
|
2947
|
+
const keys = [
|
|
2948
|
+
getThreadListKey(threadKey, threadId),
|
|
2949
|
+
getThreadMetaKey(threadKey, threadId),
|
|
2950
|
+
getThreadStateKey(threadKey, threadId),
|
|
2951
|
+
...dedupIds.map((id) => getThreadDedupKey(threadId, id))
|
|
2952
|
+
];
|
|
2953
|
+
await redis.del(...keys);
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
// src/lib/thread/tiered.ts
|
|
2957
|
+
function createTieredThreadManager(config) {
|
|
2958
|
+
const {
|
|
2959
|
+
redis,
|
|
2960
|
+
threadId,
|
|
2961
|
+
key = "messages",
|
|
2962
|
+
coldStore,
|
|
2963
|
+
idOf,
|
|
2964
|
+
deserialize = (raw) => JSON.parse(raw),
|
|
2965
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2966
|
+
} = config;
|
|
2967
|
+
const base = createThreadManager(config);
|
|
2968
|
+
const rawIdOf = idOf ? (raw) => idOf(deserialize(raw)) : void 0;
|
|
2969
|
+
return Object.assign(base, {
|
|
2970
|
+
async hydrate() {
|
|
2971
|
+
if (!coldStore) return;
|
|
2972
|
+
const snapshot = await coldStore.read(key, threadId);
|
|
2973
|
+
if (!snapshot) return;
|
|
2974
|
+
await applySnapshot({
|
|
2975
|
+
redis,
|
|
2976
|
+
threadKey: key,
|
|
2977
|
+
threadId,
|
|
2978
|
+
snapshot,
|
|
2979
|
+
ttlSeconds
|
|
2980
|
+
});
|
|
2981
|
+
},
|
|
2982
|
+
async flush(opts) {
|
|
2983
|
+
if (!coldStore) return;
|
|
2984
|
+
const snapshot = await encodeSnapshot({
|
|
2985
|
+
redis,
|
|
2986
|
+
threadKey: key,
|
|
2987
|
+
threadId,
|
|
2988
|
+
...rawIdOf ? { idOf: rawIdOf } : {}
|
|
2989
|
+
});
|
|
2990
|
+
if (!snapshot) return;
|
|
2991
|
+
await coldStore.write(key, threadId, snapshot);
|
|
2992
|
+
const deleteHot = opts?.deleteHot ?? true;
|
|
2993
|
+
if (deleteHot) {
|
|
2994
|
+
await clearHotTier({
|
|
2995
|
+
redis,
|
|
2996
|
+
threadKey: key,
|
|
2997
|
+
threadId,
|
|
2998
|
+
dedupIds: snapshot.dedupIds
|
|
2999
|
+
});
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3003
|
+
}
|
|
3004
|
+
|
|
2774
3005
|
// src/lib/sandbox/manager.ts
|
|
2775
3006
|
var CAP_METHOD_TO_CAPABILITY = [
|
|
2776
3007
|
{ method: "pause", capability: "pause" },
|
|
@@ -3441,57 +3672,190 @@ ${result.stderr}`,
|
|
|
3441
3672
|
};
|
|
3442
3673
|
|
|
3443
3674
|
// src/tools/edit/handler.ts
|
|
3444
|
-
function
|
|
3445
|
-
|
|
3675
|
+
function splitLines(text) {
|
|
3676
|
+
if (text.length === 0) return [];
|
|
3677
|
+
return text.replace(/\r\n/g, "\n").split("\n");
|
|
3678
|
+
}
|
|
3679
|
+
function lineNumberAt(content, index) {
|
|
3680
|
+
let line = 1;
|
|
3681
|
+
for (let i = 0; i < index; i++) {
|
|
3682
|
+
if (content.charCodeAt(i) === 10) line++;
|
|
3683
|
+
}
|
|
3684
|
+
return line;
|
|
3685
|
+
}
|
|
3686
|
+
function lineEnd(startLine, lines) {
|
|
3687
|
+
return lines.length === 0 ? startLine : startLine + lines.length - 1;
|
|
3688
|
+
}
|
|
3689
|
+
function indicesOf(content, needle) {
|
|
3690
|
+
const indices = [];
|
|
3691
|
+
let cursor = 0;
|
|
3692
|
+
while (cursor <= content.length) {
|
|
3693
|
+
const index = content.indexOf(needle, cursor);
|
|
3694
|
+
if (index === -1) break;
|
|
3695
|
+
indices.push(index);
|
|
3696
|
+
cursor = index + needle.length;
|
|
3697
|
+
}
|
|
3698
|
+
return indices;
|
|
3699
|
+
}
|
|
3700
|
+
function makeHunk(editIndex, beforeContent, replacementIndex, oldString, newString) {
|
|
3701
|
+
const oldStartLine = lineNumberAt(beforeContent, replacementIndex);
|
|
3702
|
+
const oldLines = splitLines(oldString);
|
|
3703
|
+
const newLines = splitLines(newString);
|
|
3704
|
+
return {
|
|
3705
|
+
editIndex,
|
|
3706
|
+
oldStartLine,
|
|
3707
|
+
oldEndLine: lineEnd(oldStartLine, oldLines),
|
|
3708
|
+
newStartLine: oldStartLine,
|
|
3709
|
+
newEndLine: lineEnd(oldStartLine, newLines),
|
|
3710
|
+
oldLines,
|
|
3711
|
+
newLines
|
|
3712
|
+
};
|
|
3713
|
+
}
|
|
3714
|
+
function applyOneEdit(content, edit, editIndex) {
|
|
3715
|
+
const { old_string, new_string, replace_all = false } = edit;
|
|
3716
|
+
if (old_string.length === 0) {
|
|
3717
|
+
return {
|
|
3718
|
+
ok: false,
|
|
3719
|
+
editIndex,
|
|
3720
|
+
message: `Error: old_string for edit ${editIndex} must not be empty.`
|
|
3721
|
+
};
|
|
3722
|
+
}
|
|
3723
|
+
if (old_string === new_string) {
|
|
3724
|
+
return {
|
|
3725
|
+
ok: false,
|
|
3726
|
+
editIndex,
|
|
3727
|
+
message: `Error: old_string and new_string must be different for edit ${editIndex}.`
|
|
3728
|
+
};
|
|
3729
|
+
}
|
|
3730
|
+
const matches = indicesOf(content, old_string);
|
|
3731
|
+
if (matches.length === 0) {
|
|
3732
|
+
return {
|
|
3733
|
+
ok: false,
|
|
3734
|
+
editIndex,
|
|
3735
|
+
message: `Error: Could not find old_string for edit ${editIndex}. Make sure it matches exactly (whitespace-sensitive).`
|
|
3736
|
+
};
|
|
3737
|
+
}
|
|
3738
|
+
if (!replace_all && matches.length > 1) {
|
|
3739
|
+
return {
|
|
3740
|
+
ok: false,
|
|
3741
|
+
editIndex,
|
|
3742
|
+
message: `Error: old_string for edit ${editIndex} appears ${matches.length} times. Provide more context to make it unique, or use replace_all: true for that edit.`
|
|
3743
|
+
};
|
|
3744
|
+
}
|
|
3745
|
+
if (replace_all) {
|
|
3746
|
+
const hunks = matches.map(
|
|
3747
|
+
(index2) => makeHunk(editIndex, content, index2, old_string, new_string)
|
|
3748
|
+
);
|
|
3749
|
+
return {
|
|
3750
|
+
ok: true,
|
|
3751
|
+
content: content.split(old_string).join(new_string),
|
|
3752
|
+
replacements: matches.length,
|
|
3753
|
+
hunks
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
const index = matches[0];
|
|
3757
|
+
if (index === void 0) {
|
|
3758
|
+
return {
|
|
3759
|
+
ok: false,
|
|
3760
|
+
editIndex,
|
|
3761
|
+
message: `Error: Could not find old_string for edit ${editIndex}.`
|
|
3762
|
+
};
|
|
3763
|
+
}
|
|
3764
|
+
return {
|
|
3765
|
+
ok: true,
|
|
3766
|
+
content: content.slice(0, index) + new_string + content.slice(index + old_string.length),
|
|
3767
|
+
replacements: 1,
|
|
3768
|
+
hunks: [makeHunk(editIndex, content, index, old_string, new_string)]
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
function applyEditPlan(content, edits) {
|
|
3772
|
+
if (edits.length === 0) {
|
|
3773
|
+
return {
|
|
3774
|
+
ok: false,
|
|
3775
|
+
message: "Error: edits must contain at least one edit."
|
|
3776
|
+
};
|
|
3777
|
+
}
|
|
3778
|
+
let current = content;
|
|
3779
|
+
let replacements = 0;
|
|
3780
|
+
const hunks = [];
|
|
3781
|
+
for (const [index, edit] of edits.entries()) {
|
|
3782
|
+
const result = applyOneEdit(current, edit, index);
|
|
3783
|
+
if (!result.ok) return result;
|
|
3784
|
+
current = result.content;
|
|
3785
|
+
replacements += result.replacements;
|
|
3786
|
+
hunks.push(...result.hunks);
|
|
3787
|
+
}
|
|
3788
|
+
return { ok: true, content: current, replacements, hunks };
|
|
3789
|
+
}
|
|
3790
|
+
function editFailureResult(filePath, message) {
|
|
3791
|
+
return {
|
|
3792
|
+
toolResponse: message,
|
|
3793
|
+
data: { path: filePath, success: false, replacements: 0 }
|
|
3794
|
+
};
|
|
3446
3795
|
}
|
|
3447
3796
|
var editHandler = async (args, { sandbox }) => {
|
|
3448
3797
|
const { fs } = sandbox;
|
|
3449
3798
|
const { file_path, old_string, new_string, replace_all = false } = args;
|
|
3450
|
-
|
|
3799
|
+
try {
|
|
3800
|
+
const exists = await fs.exists(file_path);
|
|
3801
|
+
if (!exists) {
|
|
3802
|
+
return editFailureResult(
|
|
3803
|
+
file_path,
|
|
3804
|
+
`Error: File "${file_path}" does not exist.`
|
|
3805
|
+
);
|
|
3806
|
+
}
|
|
3807
|
+
const content = await fs.readFile(file_path);
|
|
3808
|
+
const result = applyEditPlan(content, [
|
|
3809
|
+
{ old_string, new_string, replace_all }
|
|
3810
|
+
]);
|
|
3811
|
+
if (!result.ok) {
|
|
3812
|
+
return editFailureResult(file_path, result.message);
|
|
3813
|
+
}
|
|
3814
|
+
await fs.writeFile(file_path, result.content);
|
|
3815
|
+
const summary = replace_all ? `Replaced ${result.replacements} occurrence(s)` : `Replaced 1 occurrence`;
|
|
3816
|
+
return {
|
|
3817
|
+
toolResponse: `${summary} in ${file_path}`,
|
|
3818
|
+
data: {
|
|
3819
|
+
path: file_path,
|
|
3820
|
+
success: true,
|
|
3821
|
+
replacements: result.replacements,
|
|
3822
|
+
hunks: result.hunks
|
|
3823
|
+
}
|
|
3824
|
+
};
|
|
3825
|
+
} catch (error) {
|
|
3826
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
3451
3827
|
return {
|
|
3452
|
-
toolResponse: `Error
|
|
3828
|
+
toolResponse: `Error editing file "${file_path}": ${message}`,
|
|
3453
3829
|
data: { path: file_path, success: false, replacements: 0 }
|
|
3454
3830
|
};
|
|
3455
3831
|
}
|
|
3832
|
+
};
|
|
3833
|
+
var multiEditHandler = async (args, { sandbox }) => {
|
|
3834
|
+
const { fs } = sandbox;
|
|
3835
|
+
const { file_path, edits } = args;
|
|
3456
3836
|
try {
|
|
3457
3837
|
const exists = await fs.exists(file_path);
|
|
3458
3838
|
if (!exists) {
|
|
3459
|
-
return
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3839
|
+
return editFailureResult(
|
|
3840
|
+
file_path,
|
|
3841
|
+
`Error: File "${file_path}" does not exist.`
|
|
3842
|
+
);
|
|
3463
3843
|
}
|
|
3464
3844
|
const content = await fs.readFile(file_path);
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
};
|
|
3845
|
+
const result = applyEditPlan(content, edits);
|
|
3846
|
+
if (!result.ok) {
|
|
3847
|
+
const suffix = result.editIndex === void 0 ? "" : ` in ${file_path}`;
|
|
3848
|
+
return editFailureResult(file_path, `${result.message}${suffix}`);
|
|
3470
3849
|
}
|
|
3471
|
-
|
|
3472
|
-
const globalRegex = new RegExp(escapedOldString, "g");
|
|
3473
|
-
const occurrences = (content.match(globalRegex) || []).length;
|
|
3474
|
-
if (!replace_all && occurrences > 1) {
|
|
3475
|
-
return {
|
|
3476
|
-
toolResponse: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
|
|
3477
|
-
data: { path: file_path, success: false, replacements: 0 }
|
|
3478
|
-
};
|
|
3479
|
-
}
|
|
3480
|
-
let newContent;
|
|
3481
|
-
let replacements;
|
|
3482
|
-
if (replace_all) {
|
|
3483
|
-
newContent = content.split(old_string).join(new_string);
|
|
3484
|
-
replacements = occurrences;
|
|
3485
|
-
} else {
|
|
3486
|
-
const index = content.indexOf(old_string);
|
|
3487
|
-
newContent = content.slice(0, index) + new_string + content.slice(index + old_string.length);
|
|
3488
|
-
replacements = 1;
|
|
3489
|
-
}
|
|
3490
|
-
await fs.writeFile(file_path, newContent);
|
|
3491
|
-
const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
|
|
3850
|
+
await fs.writeFile(file_path, result.content);
|
|
3492
3851
|
return {
|
|
3493
|
-
toolResponse:
|
|
3494
|
-
data: {
|
|
3852
|
+
toolResponse: `Applied ${edits.length} edit(s), ${result.replacements} replacement(s) in ${file_path}`,
|
|
3853
|
+
data: {
|
|
3854
|
+
path: file_path,
|
|
3855
|
+
success: true,
|
|
3856
|
+
replacements: result.replacements,
|
|
3857
|
+
hunks: result.hunks
|
|
3858
|
+
}
|
|
3495
3859
|
};
|
|
3496
3860
|
} catch (error) {
|
|
3497
3861
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -3671,6 +4035,6 @@ var toTree = async (fs, opts = {}) => {
|
|
|
3671
4035
|
return base + subtree;
|
|
3672
4036
|
};
|
|
3673
4037
|
|
|
3674
|
-
export { DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, THREAD_TTL_SECONDS, VirtualFileSystem, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, getThreadListKey, getThreadMetaKey, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
4038
|
+
export { DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, THREAD_TTL_SECONDS, VirtualFileSystem, applySnapshot, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, clearHotTier, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createS3ColdStore, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createTieredThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, encodeSnapshot, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, getThreadDedupKey, getThreadListKey, getThreadMetaKey, getThreadStateKey, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, multiEditHandler, multiEditTool, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
3675
4039
|
//# sourceMappingURL=index.js.map
|
|
3676
4040
|
//# sourceMappingURL=index.js.map
|