zeitlich 0.2.45 → 0.2.46
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 +78 -10
- package/dist/{activities-CrN-ghLo.d.ts → activities-Bm4TLTid.d.ts} +22 -2
- package/dist/{activities-Coafq5zr.d.cts → activities-CyeiqK_f.d.cts} +22 -2
- package/dist/adapters/thread/anthropic/index.cjs +171 -65
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +19 -4
- package/dist/adapters/thread/anthropic/index.d.ts +19 -4
- package/dist/adapters/thread/anthropic/index.js +171 -65
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +3 -1
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
- package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
- package/dist/adapters/thread/anthropic/workflow.js +3 -1
- 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 +5 -4
- package/dist/adapters/thread/google-genai/index.d.ts +5 -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 +3 -1
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
- package/dist/adapters/thread/google-genai/workflow.js +3 -1
- 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 +18 -4
- package/dist/adapters/thread/langchain/index.d.ts +18 -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 +3 -1
- package/dist/adapters/thread/langchain/workflow.cjs.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/adapters/thread/langchain/workflow.js +3 -1
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/cold-store-BC5L5Z8A.d.cts +117 -0
- package/dist/cold-store-CFHwemBJ.d.ts +117 -0
- package/dist/index.cjs +226 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -8
- package/dist/index.d.ts +138 -8
- package/dist/index.js +220 -28
- package/dist/index.js.map +1 -1
- package/dist/{proxy-Bf7uI-Hw.d.cts → proxy-BxFyd6cg.d.cts} +1 -1
- package/dist/{proxy-COqA95FW.d.ts → proxy-Cskmj4Yx.d.ts} +1 -1
- package/dist/{thread-manager-BsLO3Fgc.d.cts → thread-manager-9tezUcLW.d.cts} +8 -2
- package/dist/{thread-manager-Bi1XlbpJ.d.ts → thread-manager-B-zy3xrs.d.ts} +8 -2
- package/dist/{thread-manager-wRVVBFgj.d.cts → thread-manager-D33SUmZa.d.cts} +8 -2
- package/dist/{thread-manager-BhkOyQ1I.d.ts → thread-manager-DduoSkvJ.d.ts} +8 -2
- package/dist/{types-CdALEF3z.d.cts → types-CnuN9T6t.d.cts} +22 -0
- package/dist/{types-ChAy_jSP.d.ts → types-CwN6_tAL.d.ts} +22 -0
- package/dist/{types-BkX4HLzi.d.ts → types-L5bvbF-n.d.ts} +17 -1
- package/dist/{types-C66-BVBr.d.cts → types-oxt8GN97.d.cts} +17 -1
- package/dist/{workflow-BwT5EybR.d.ts → workflow-B1TOcHbt.d.ts} +33 -2
- package/dist/{workflow-DMmiaw6w.d.cts → workflow-DIaIV7L2.d.cts} +33 -2
- package/dist/workflow.cjs +14 -1
- 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 +14 -1
- package/dist/workflow.js.map +1 -1
- package/package.json +6 -1
- package/src/adapters/thread/anthropic/activities.ts +72 -36
- 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/thread-manager.ts +9 -1
- package/src/adapters/thread/langchain/activities.ts +63 -36
- package/src/adapters/thread/langchain/thread-manager.ts +9 -1
- package/src/index.ts +20 -1
- 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/thread/cold-store.test.ts +193 -0
- package/src/lib/thread/cold-store.ts +250 -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 +2 -0
- 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/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@ 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 { gzipSync, gunzipSync } from 'zlib';
|
|
7
|
+
import { DeleteObjectCommand, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
6
8
|
import { Context } from '@temporalio/activity';
|
|
7
9
|
import { promises } from 'fs';
|
|
8
10
|
|
|
@@ -1032,7 +1034,9 @@ async function createSession(config) {
|
|
|
1032
1034
|
appendAgentMessage,
|
|
1033
1035
|
forkThread,
|
|
1034
1036
|
loadThreadState,
|
|
1035
|
-
saveThreadState
|
|
1037
|
+
saveThreadState,
|
|
1038
|
+
hydrateThread,
|
|
1039
|
+
flushThread
|
|
1036
1040
|
} = threadOps;
|
|
1037
1041
|
const plugins = [];
|
|
1038
1042
|
let destroySubagentSandboxes;
|
|
@@ -1176,10 +1180,12 @@ async function createSession(config) {
|
|
|
1176
1180
|
});
|
|
1177
1181
|
};
|
|
1178
1182
|
if (threadMode === "fork" && sourceThreadId) {
|
|
1183
|
+
await hydrateThread(sourceThreadId, threadKey);
|
|
1179
1184
|
await forkThread(sourceThreadId, threadId, threadKey);
|
|
1180
1185
|
const forkedSlice = await loadThreadState(threadId, threadKey);
|
|
1181
1186
|
if (forkedSlice) rehydrateFromSlice(forkedSlice);
|
|
1182
1187
|
} else if (threadMode === "continue") {
|
|
1188
|
+
await hydrateThread(threadId, threadKey);
|
|
1183
1189
|
const continuedSlice = await loadThreadState(threadId, threadKey);
|
|
1184
1190
|
if (continuedSlice) rehydrateFromSlice(continuedSlice);
|
|
1185
1191
|
} else {
|
|
@@ -1361,6 +1367,15 @@ async function createSession(config) {
|
|
|
1361
1367
|
error: persistError instanceof Error ? persistError.message : String(persistError)
|
|
1362
1368
|
});
|
|
1363
1369
|
}
|
|
1370
|
+
try {
|
|
1371
|
+
await flushThread(threadId, threadKey);
|
|
1372
|
+
} catch (flushError) {
|
|
1373
|
+
log.warn("failed to flush thread to cold tier", {
|
|
1374
|
+
agentName,
|
|
1375
|
+
threadId,
|
|
1376
|
+
error: flushError instanceof Error ? flushError.message : String(flushError)
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1364
1379
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
1365
1380
|
if (sandboxOwned && sandboxId && sandboxOps) {
|
|
1366
1381
|
switch (resolvedShutdown) {
|
|
@@ -1444,6 +1459,9 @@ function getThreadMetaKey(threadKey, threadId) {
|
|
|
1444
1459
|
function getThreadStateKey(threadKey, threadId) {
|
|
1445
1460
|
return `${threadKey}:state:thread:${threadId}`;
|
|
1446
1461
|
}
|
|
1462
|
+
function getThreadDedupKey(threadId, dedupId) {
|
|
1463
|
+
return `dedup:${dedupId}:thread:${threadId}`;
|
|
1464
|
+
}
|
|
1447
1465
|
|
|
1448
1466
|
// src/lib/types.ts
|
|
1449
1467
|
function isTerminalStatus(status) {
|
|
@@ -2588,9 +2606,6 @@ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
|
|
|
2588
2606
|
redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
|
|
2589
2607
|
return 1
|
|
2590
2608
|
`;
|
|
2591
|
-
function getDedupKey(threadId, id) {
|
|
2592
|
-
return `dedup:${id}:thread:${threadId}`;
|
|
2593
|
-
}
|
|
2594
2609
|
function createThreadManager(config) {
|
|
2595
2610
|
const {
|
|
2596
2611
|
redis,
|
|
@@ -2598,11 +2613,13 @@ function createThreadManager(config) {
|
|
|
2598
2613
|
key = "messages",
|
|
2599
2614
|
serialize = (m) => JSON.stringify(m),
|
|
2600
2615
|
deserialize = (raw) => JSON.parse(raw),
|
|
2601
|
-
idOf
|
|
2616
|
+
idOf,
|
|
2617
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2602
2618
|
} = config;
|
|
2603
2619
|
const redisKey = getThreadListKey(key, threadId);
|
|
2604
2620
|
const metaKey = getThreadMetaKey(key, threadId);
|
|
2605
2621
|
const stateKey = getThreadStateKey(key, threadId);
|
|
2622
|
+
const dedupKey = (id) => getThreadDedupKey(threadId, id);
|
|
2606
2623
|
async function assertThreadExists() {
|
|
2607
2624
|
const exists = await redis.exists(metaKey);
|
|
2608
2625
|
if (!exists) {
|
|
@@ -2612,7 +2629,7 @@ function createThreadManager(config) {
|
|
|
2612
2629
|
return {
|
|
2613
2630
|
async initialize() {
|
|
2614
2631
|
await redis.del(redisKey);
|
|
2615
|
-
await redis.set(metaKey, "1", "EX",
|
|
2632
|
+
await redis.set(metaKey, "1", "EX", ttlSeconds);
|
|
2616
2633
|
},
|
|
2617
2634
|
async load() {
|
|
2618
2635
|
await assertThreadExists();
|
|
@@ -2624,18 +2641,17 @@ function createThreadManager(config) {
|
|
|
2624
2641
|
await assertThreadExists();
|
|
2625
2642
|
if (idOf) {
|
|
2626
2643
|
const dedupId = messages.map(idOf).join(":");
|
|
2627
|
-
const dedupKey = getDedupKey(threadId, dedupId);
|
|
2628
2644
|
await redis.eval(
|
|
2629
2645
|
APPEND_IDEMPOTENT_SCRIPT,
|
|
2630
2646
|
2,
|
|
2631
|
-
dedupKey,
|
|
2647
|
+
dedupKey(dedupId),
|
|
2632
2648
|
redisKey,
|
|
2633
|
-
String(
|
|
2649
|
+
String(ttlSeconds),
|
|
2634
2650
|
...messages.map(serialize)
|
|
2635
2651
|
);
|
|
2636
2652
|
} else {
|
|
2637
2653
|
await redis.rpush(redisKey, ...messages.map(serialize));
|
|
2638
|
-
await redis.expire(redisKey,
|
|
2654
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2639
2655
|
}
|
|
2640
2656
|
},
|
|
2641
2657
|
async fork(newThreadId) {
|
|
@@ -2650,11 +2666,11 @@ function createThreadManager(config) {
|
|
|
2650
2666
|
if (data.length > 0) {
|
|
2651
2667
|
const newKey = getThreadListKey(key, newThreadId);
|
|
2652
2668
|
await redis.rpush(newKey, ...data);
|
|
2653
|
-
await redis.expire(newKey,
|
|
2669
|
+
await redis.expire(newKey, ttlSeconds);
|
|
2654
2670
|
}
|
|
2655
2671
|
if (stateRaw != null) {
|
|
2656
2672
|
const newStateKey = getThreadStateKey(key, newThreadId);
|
|
2657
|
-
await redis.set(newStateKey, stateRaw, "EX",
|
|
2673
|
+
await redis.set(newStateKey, stateRaw, "EX", ttlSeconds);
|
|
2658
2674
|
}
|
|
2659
2675
|
return forked;
|
|
2660
2676
|
},
|
|
@@ -2669,15 +2685,13 @@ function createThreadManager(config) {
|
|
|
2669
2685
|
const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
|
|
2670
2686
|
await redis.del(redisKey);
|
|
2671
2687
|
if (existingIds.length > 0) {
|
|
2672
|
-
await redis.del(
|
|
2673
|
-
...existingIds.map((id) => getDedupKey(threadId, id))
|
|
2674
|
-
);
|
|
2688
|
+
await redis.del(...existingIds.map(dedupKey));
|
|
2675
2689
|
}
|
|
2676
2690
|
if (messages.length > 0) {
|
|
2677
2691
|
await redis.rpush(redisKey, ...messages.map(serialize));
|
|
2678
|
-
await redis.expire(redisKey,
|
|
2692
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2679
2693
|
}
|
|
2680
|
-
await redis.expire(metaKey,
|
|
2694
|
+
await redis.expire(metaKey, ttlSeconds);
|
|
2681
2695
|
},
|
|
2682
2696
|
async delete() {
|
|
2683
2697
|
await redis.del(redisKey, metaKey, stateKey);
|
|
@@ -2689,12 +2703,7 @@ function createThreadManager(config) {
|
|
|
2689
2703
|
},
|
|
2690
2704
|
async saveState(state) {
|
|
2691
2705
|
await assertThreadExists();
|
|
2692
|
-
await redis.set(
|
|
2693
|
-
stateKey,
|
|
2694
|
-
JSON.stringify(state),
|
|
2695
|
-
"EX",
|
|
2696
|
-
THREAD_TTL_SECONDS
|
|
2697
|
-
);
|
|
2706
|
+
await redis.set(stateKey, JSON.stringify(state), "EX", ttlSeconds);
|
|
2698
2707
|
},
|
|
2699
2708
|
async deleteState() {
|
|
2700
2709
|
await redis.del(stateKey);
|
|
@@ -2723,19 +2732,202 @@ function createThreadManager(config) {
|
|
|
2723
2732
|
if (idx === -1) return;
|
|
2724
2733
|
if (idx === 0) {
|
|
2725
2734
|
await redis.del(redisKey);
|
|
2726
|
-
await redis.expire(metaKey,
|
|
2735
|
+
await redis.expire(metaKey, ttlSeconds);
|
|
2727
2736
|
} else {
|
|
2728
2737
|
await redis.ltrim(redisKey, 0, idx - 1);
|
|
2729
|
-
await redis.expire(redisKey,
|
|
2738
|
+
await redis.expire(redisKey, ttlSeconds);
|
|
2730
2739
|
}
|
|
2731
2740
|
if (removedIds.length > 0) {
|
|
2732
|
-
await redis.del(
|
|
2733
|
-
|
|
2741
|
+
await redis.del(...removedIds.map(dedupKey));
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
}
|
|
2746
|
+
function joinKey(parts) {
|
|
2747
|
+
return parts.map((p) => p.replace(/^\/+|\/+$/g, "")).filter((p) => p.length > 0).join("/");
|
|
2748
|
+
}
|
|
2749
|
+
function buildKey(prefix, threadKey, threadId, gzip) {
|
|
2750
|
+
const ext = gzip ? "json.gz" : "json";
|
|
2751
|
+
return joinKey([
|
|
2752
|
+
prefix ?? "threads",
|
|
2753
|
+
threadKey,
|
|
2754
|
+
`${threadId}.${ext}`
|
|
2755
|
+
]);
|
|
2756
|
+
}
|
|
2757
|
+
async function streamToBuffer(body) {
|
|
2758
|
+
if (body == null) return Buffer.alloc(0);
|
|
2759
|
+
if (body instanceof Uint8Array) return Buffer.from(body);
|
|
2760
|
+
if (typeof body.transformToByteArray === "function") {
|
|
2761
|
+
const bytes = await body.transformToByteArray();
|
|
2762
|
+
return Buffer.from(bytes);
|
|
2763
|
+
}
|
|
2764
|
+
if (typeof body.arrayBuffer === "function") {
|
|
2765
|
+
const ab = await body.arrayBuffer();
|
|
2766
|
+
return Buffer.from(ab);
|
|
2767
|
+
}
|
|
2768
|
+
const chunks = [];
|
|
2769
|
+
for await (const chunk of body) {
|
|
2770
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
2771
|
+
}
|
|
2772
|
+
return Buffer.concat(chunks);
|
|
2773
|
+
}
|
|
2774
|
+
function createS3ColdStore(config) {
|
|
2775
|
+
const { s3, bucket, prefix, gzip = true } = config;
|
|
2776
|
+
const contentType = config.contentType ?? (gzip ? "application/gzip" : "application/json");
|
|
2777
|
+
return {
|
|
2778
|
+
async read(threadKey, threadId) {
|
|
2779
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2780
|
+
try {
|
|
2781
|
+
const resp = await s3.send(
|
|
2782
|
+
new GetObjectCommand({ Bucket: bucket, Key })
|
|
2734
2783
|
);
|
|
2784
|
+
const buf = await streamToBuffer(resp.Body);
|
|
2785
|
+
const json = gzip ? gunzipSync(buf).toString("utf8") : buf.toString("utf8");
|
|
2786
|
+
return JSON.parse(json);
|
|
2787
|
+
} catch (err) {
|
|
2788
|
+
if (isNotFound(err)) return null;
|
|
2789
|
+
throw err;
|
|
2735
2790
|
}
|
|
2791
|
+
},
|
|
2792
|
+
async write(threadKey, threadId, snapshot) {
|
|
2793
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2794
|
+
const json = JSON.stringify(snapshot);
|
|
2795
|
+
const body = gzip ? gzipSync(Buffer.from(json, "utf8")) : json;
|
|
2796
|
+
await s3.send(
|
|
2797
|
+
new PutObjectCommand({
|
|
2798
|
+
Bucket: bucket,
|
|
2799
|
+
Key,
|
|
2800
|
+
Body: body,
|
|
2801
|
+
ContentType: contentType
|
|
2802
|
+
})
|
|
2803
|
+
);
|
|
2804
|
+
},
|
|
2805
|
+
async delete(threadKey, threadId) {
|
|
2806
|
+
const Key = buildKey(prefix, threadKey, threadId, gzip);
|
|
2807
|
+
await s3.send(new DeleteObjectCommand({ Bucket: bucket, Key }));
|
|
2736
2808
|
}
|
|
2737
2809
|
};
|
|
2738
2810
|
}
|
|
2811
|
+
function isNotFound(err) {
|
|
2812
|
+
if (typeof err !== "object" || err === null) return false;
|
|
2813
|
+
const e = err;
|
|
2814
|
+
return e.name === "NoSuchKey" || e.Code === "NoSuchKey" || e.code === "NoSuchKey" || e.name === "NotFound" || e.$metadata?.httpStatusCode === 404;
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
// src/lib/thread/snapshot.ts
|
|
2818
|
+
async function encodeSnapshot(config) {
|
|
2819
|
+
const { redis, threadKey, threadId, idOf } = config;
|
|
2820
|
+
const metaKey = getThreadMetaKey(threadKey, threadId);
|
|
2821
|
+
if (await redis.exists(metaKey) === 0) {
|
|
2822
|
+
return null;
|
|
2823
|
+
}
|
|
2824
|
+
const listKey = getThreadListKey(threadKey, threadId);
|
|
2825
|
+
const stateKey = getThreadStateKey(threadKey, threadId);
|
|
2826
|
+
const messages = await redis.lrange(listKey, 0, -1);
|
|
2827
|
+
const stateRaw = await redis.get(stateKey);
|
|
2828
|
+
const state = stateRaw == null ? null : JSON.parse(stateRaw);
|
|
2829
|
+
const dedupIds = idOf ? messages.map(idOf) : [];
|
|
2830
|
+
return { v: 1, messages, state, dedupIds };
|
|
2831
|
+
}
|
|
2832
|
+
async function applySnapshot(config) {
|
|
2833
|
+
const {
|
|
2834
|
+
redis,
|
|
2835
|
+
threadKey,
|
|
2836
|
+
threadId,
|
|
2837
|
+
snapshot,
|
|
2838
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2839
|
+
} = config;
|
|
2840
|
+
const metaKey = getThreadMetaKey(threadKey, threadId);
|
|
2841
|
+
if (await redis.exists(metaKey) === 1) {
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
const listKey = getThreadListKey(threadKey, threadId);
|
|
2845
|
+
const stateKey = getThreadStateKey(threadKey, threadId);
|
|
2846
|
+
await redis.del(listKey, stateKey);
|
|
2847
|
+
const pipeline = redis.pipeline();
|
|
2848
|
+
if (snapshot.messages.length > 0) {
|
|
2849
|
+
pipeline.rpush(listKey, ...snapshot.messages);
|
|
2850
|
+
pipeline.expire(listKey, ttlSeconds);
|
|
2851
|
+
}
|
|
2852
|
+
if (snapshot.state != null) {
|
|
2853
|
+
pipeline.set(stateKey, JSON.stringify(snapshot.state), "EX", ttlSeconds);
|
|
2854
|
+
}
|
|
2855
|
+
for (const id of snapshot.dedupIds) {
|
|
2856
|
+
pipeline.set(getThreadDedupKey(threadId, id), "1", "EX", ttlSeconds);
|
|
2857
|
+
}
|
|
2858
|
+
const results = await pipeline.exec();
|
|
2859
|
+
if (results) {
|
|
2860
|
+
const firstErr = results.find(([err]) => err)?.[0] ?? null;
|
|
2861
|
+
if (firstErr) {
|
|
2862
|
+
await redis.del(
|
|
2863
|
+
listKey,
|
|
2864
|
+
stateKey,
|
|
2865
|
+
...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id))
|
|
2866
|
+
).catch(() => void 0);
|
|
2867
|
+
throw firstErr;
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
await redis.set(metaKey, "1", "EX", ttlSeconds);
|
|
2871
|
+
}
|
|
2872
|
+
async function clearHotTier(config) {
|
|
2873
|
+
const { redis, threadKey, threadId, dedupIds = [] } = config;
|
|
2874
|
+
const keys = [
|
|
2875
|
+
getThreadListKey(threadKey, threadId),
|
|
2876
|
+
getThreadMetaKey(threadKey, threadId),
|
|
2877
|
+
getThreadStateKey(threadKey, threadId),
|
|
2878
|
+
...dedupIds.map((id) => getThreadDedupKey(threadId, id))
|
|
2879
|
+
];
|
|
2880
|
+
await redis.del(...keys);
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
// src/lib/thread/tiered.ts
|
|
2884
|
+
function createTieredThreadManager(config) {
|
|
2885
|
+
const {
|
|
2886
|
+
redis,
|
|
2887
|
+
threadId,
|
|
2888
|
+
key = "messages",
|
|
2889
|
+
coldStore,
|
|
2890
|
+
idOf,
|
|
2891
|
+
deserialize = (raw) => JSON.parse(raw),
|
|
2892
|
+
ttlSeconds = THREAD_TTL_SECONDS
|
|
2893
|
+
} = config;
|
|
2894
|
+
const base = createThreadManager(config);
|
|
2895
|
+
const rawIdOf = idOf ? (raw) => idOf(deserialize(raw)) : void 0;
|
|
2896
|
+
return Object.assign(base, {
|
|
2897
|
+
async hydrate() {
|
|
2898
|
+
if (!coldStore) return;
|
|
2899
|
+
const snapshot = await coldStore.read(key, threadId);
|
|
2900
|
+
if (!snapshot) return;
|
|
2901
|
+
await applySnapshot({
|
|
2902
|
+
redis,
|
|
2903
|
+
threadKey: key,
|
|
2904
|
+
threadId,
|
|
2905
|
+
snapshot,
|
|
2906
|
+
ttlSeconds
|
|
2907
|
+
});
|
|
2908
|
+
},
|
|
2909
|
+
async flush(opts) {
|
|
2910
|
+
if (!coldStore) return;
|
|
2911
|
+
const snapshot = await encodeSnapshot({
|
|
2912
|
+
redis,
|
|
2913
|
+
threadKey: key,
|
|
2914
|
+
threadId,
|
|
2915
|
+
...rawIdOf ? { idOf: rawIdOf } : {}
|
|
2916
|
+
});
|
|
2917
|
+
if (!snapshot) return;
|
|
2918
|
+
await coldStore.write(key, threadId, snapshot);
|
|
2919
|
+
const deleteHot = opts?.deleteHot ?? true;
|
|
2920
|
+
if (deleteHot) {
|
|
2921
|
+
await clearHotTier({
|
|
2922
|
+
redis,
|
|
2923
|
+
threadKey: key,
|
|
2924
|
+
threadId,
|
|
2925
|
+
dedupIds: snapshot.dedupIds
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2739
2931
|
function getActivityContext() {
|
|
2740
2932
|
try {
|
|
2741
2933
|
const ctx = Context.current();
|
|
@@ -3671,6 +3863,6 @@ var toTree = async (fs, opts = {}) => {
|
|
|
3671
3863
|
return base + subtree;
|
|
3672
3864
|
};
|
|
3673
3865
|
|
|
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 };
|
|
3866
|
+
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, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
3675
3867
|
//# sourceMappingURL=index.js.map
|
|
3676
3868
|
//# sourceMappingURL=index.js.map
|