@axiom-lattice/core 1.0.50 → 2.0.0
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/index.d.mts +7 -40
- package/dist/index.d.ts +7 -40
- package/dist/index.js +71 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -2205,13 +2205,16 @@ var ThreadStatus = /* @__PURE__ */ ((ThreadStatus2) => {
|
|
|
2205
2205
|
})(ThreadStatus || {});
|
|
2206
2206
|
|
|
2207
2207
|
// src/chunk_buffer_lattice/InMemoryChunkBuffer.ts
|
|
2208
|
+
import { ReplaySubject } from "rxjs";
|
|
2208
2209
|
var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
2209
2210
|
constructor(config) {
|
|
2210
2211
|
super();
|
|
2211
2212
|
this.buffers = /* @__PURE__ */ new Map();
|
|
2212
2213
|
this.config = {
|
|
2213
2214
|
ttl: config?.ttl ?? 60 * 60 * 1e3,
|
|
2214
|
-
cleanupInterval: config?.cleanupInterval ?? 0
|
|
2215
|
+
cleanupInterval: config?.cleanupInterval ?? 0,
|
|
2216
|
+
maxChunks: config?.maxChunks ?? 1e3
|
|
2217
|
+
// Default max chunks per thread
|
|
2215
2218
|
};
|
|
2216
2219
|
if (this.config.cleanupInterval > 0) {
|
|
2217
2220
|
this.startCleanupTimer();
|
|
@@ -2260,11 +2263,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2260
2263
|
*/
|
|
2261
2264
|
getOrCreateBuffer(threadId) {
|
|
2262
2265
|
let buffer = this.getBufferIfValid(threadId);
|
|
2266
|
+
4;
|
|
2263
2267
|
if (!buffer) {
|
|
2264
2268
|
const now = Date.now();
|
|
2265
2269
|
buffer = {
|
|
2266
2270
|
threadId,
|
|
2267
|
-
chunks
|
|
2271
|
+
chunks$: new ReplaySubject(
|
|
2272
|
+
this.config.maxChunks ?? 1e4
|
|
2273
|
+
),
|
|
2268
2274
|
status: "active" /* ACTIVE */,
|
|
2269
2275
|
createdAt: now,
|
|
2270
2276
|
updatedAt: now,
|
|
@@ -2272,34 +2278,30 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2272
2278
|
};
|
|
2273
2279
|
this.buffers.set(threadId, buffer);
|
|
2274
2280
|
}
|
|
2281
|
+
if (buffer.status !== "active" /* ACTIVE */) {
|
|
2282
|
+
buffer.status = "active" /* ACTIVE */;
|
|
2283
|
+
buffer.chunks$ = new ReplaySubject(
|
|
2284
|
+
this.config.maxChunks ?? 1e4
|
|
2285
|
+
);
|
|
2286
|
+
buffer.updatedAt = Date.now();
|
|
2287
|
+
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
2288
|
+
}
|
|
2275
2289
|
return buffer;
|
|
2276
2290
|
}
|
|
2277
2291
|
async addChunk(threadId, content) {
|
|
2278
2292
|
const buffer = this.getOrCreateBuffer(threadId);
|
|
2279
2293
|
const chunk = content;
|
|
2280
|
-
buffer.chunks
|
|
2294
|
+
buffer.chunks$.next(chunk);
|
|
2281
2295
|
buffer.updatedAt = Date.now();
|
|
2282
2296
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
2283
|
-
|
|
2284
|
-
async getChunks(threadId) {
|
|
2285
|
-
const buffer = this.getBufferIfValid(threadId);
|
|
2286
|
-
return buffer ? [...buffer.chunks] : [];
|
|
2287
|
-
}
|
|
2288
|
-
async getAccumulatedContent(threadId) {
|
|
2289
|
-
const buffer = this.getBufferIfValid(threadId);
|
|
2290
|
-
if (!buffer) return "";
|
|
2291
|
-
return buffer.chunks.map((chunk) => chunk.data?.content).join("");
|
|
2292
|
-
}
|
|
2293
|
-
async getChunksByMessageId(threadId, messageId) {
|
|
2294
|
-
const buffer = this.getBufferIfValid(threadId);
|
|
2295
|
-
if (!buffer) return [];
|
|
2296
|
-
return buffer.chunks.filter((chunk) => chunk.data?.id === messageId);
|
|
2297
|
+
buffer.status = "active" /* ACTIVE */;
|
|
2297
2298
|
}
|
|
2298
2299
|
async completeThread(threadId) {
|
|
2299
2300
|
const buffer = this.getBufferIfValid(threadId);
|
|
2300
2301
|
if (buffer) {
|
|
2301
2302
|
buffer.status = "completed" /* COMPLETED */;
|
|
2302
2303
|
buffer.updatedAt = Date.now();
|
|
2304
|
+
buffer.chunks$.complete();
|
|
2303
2305
|
}
|
|
2304
2306
|
}
|
|
2305
2307
|
async abortThread(threadId) {
|
|
@@ -2307,6 +2309,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2307
2309
|
if (buffer) {
|
|
2308
2310
|
buffer.status = "aborted" /* ABORTED */;
|
|
2309
2311
|
buffer.updatedAt = Date.now();
|
|
2312
|
+
buffer.chunks$.error(new Error("Thread aborted"));
|
|
2310
2313
|
}
|
|
2311
2314
|
}
|
|
2312
2315
|
async isThreadActive(threadId) {
|
|
@@ -2319,10 +2322,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2319
2322
|
async getThreadBuffer(threadId) {
|
|
2320
2323
|
const buffer = this.getBufferIfValid(threadId);
|
|
2321
2324
|
if (!buffer) return void 0;
|
|
2322
|
-
return
|
|
2323
|
-
...buffer,
|
|
2324
|
-
chunks: [...buffer.chunks]
|
|
2325
|
-
};
|
|
2325
|
+
return buffer;
|
|
2326
2326
|
}
|
|
2327
2327
|
async clearThread(threadId) {
|
|
2328
2328
|
this.buffers.delete(threadId);
|
|
@@ -2369,9 +2369,6 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2369
2369
|
}
|
|
2370
2370
|
return cleanedCount;
|
|
2371
2371
|
}
|
|
2372
|
-
/**
|
|
2373
|
-
* Extend thread TTL
|
|
2374
|
-
*/
|
|
2375
2372
|
async extendThreadTTL(threadId, additionalMs) {
|
|
2376
2373
|
const buffer = this.getBufferIfValid(threadId);
|
|
2377
2374
|
if (buffer) {
|
|
@@ -2380,62 +2377,69 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2380
2377
|
buffer.updatedAt = Date.now();
|
|
2381
2378
|
}
|
|
2382
2379
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
* Used for resuming streams from a known position
|
|
2386
|
-
* Matches the known content and returns chunks after that position
|
|
2387
|
-
* Continues to yield new chunks as they are added until thread completes/aborts
|
|
2388
|
-
*/
|
|
2389
|
-
async *getNewChunksSinceContent(threadId, messageId, knownContent) {
|
|
2390
|
-
let buffer = this.getBufferIfValid(threadId);
|
|
2380
|
+
async *getNewChunksSinceContentIterator(threadId, messageId, knownContent) {
|
|
2381
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
2391
2382
|
if (!buffer) return;
|
|
2392
|
-
let lastYieldedIndex = -1;
|
|
2393
2383
|
let accumulatedContent = "";
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2384
|
+
const queue = [];
|
|
2385
|
+
let resolveNext = null;
|
|
2386
|
+
let errorNext = null;
|
|
2387
|
+
let isCompleted = false;
|
|
2388
|
+
const subscription = buffer.chunks$.subscribe({
|
|
2389
|
+
next: (chunk) => {
|
|
2390
|
+
queue.push(chunk);
|
|
2391
|
+
if (resolveNext) {
|
|
2392
|
+
const resolve = resolveNext;
|
|
2393
|
+
resolveNext = null;
|
|
2394
|
+
resolve();
|
|
2401
2395
|
}
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2396
|
+
},
|
|
2397
|
+
error: (err) => {
|
|
2398
|
+
if (errorNext) {
|
|
2399
|
+
const reject = errorNext;
|
|
2400
|
+
errorNext = null;
|
|
2401
|
+
reject(err);
|
|
2407
2402
|
}
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
for (let i = lastYieldedIndex + 1; i < buffer.chunks.length; i++) {
|
|
2416
|
-
const chunk = buffer.chunks[i];
|
|
2417
|
-
if (chunk.data?.id === messageId) {
|
|
2418
|
-
yield chunk;
|
|
2419
|
-
lastYieldedIndex = i;
|
|
2420
|
-
hasNewChunks = true;
|
|
2403
|
+
},
|
|
2404
|
+
complete: () => {
|
|
2405
|
+
isCompleted = true;
|
|
2406
|
+
if (resolveNext) {
|
|
2407
|
+
const resolve = resolveNext;
|
|
2408
|
+
resolveNext = null;
|
|
2409
|
+
resolve();
|
|
2421
2410
|
}
|
|
2422
2411
|
}
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2412
|
+
});
|
|
2413
|
+
try {
|
|
2414
|
+
while (true) {
|
|
2415
|
+
if (queue.length === 0) {
|
|
2416
|
+
if (isCompleted) break;
|
|
2417
|
+
await new Promise((resolve, reject) => {
|
|
2418
|
+
resolveNext = resolve;
|
|
2419
|
+
errorNext = reject;
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
while (queue.length > 0) {
|
|
2423
|
+
const chunk = queue.shift();
|
|
2424
|
+
if (!chunk) continue;
|
|
2425
|
+
if (chunk.data?.id === messageId) {
|
|
2426
|
+
accumulatedContent += chunk.data?.content || "";
|
|
2427
|
+
}
|
|
2428
|
+
if (accumulatedContent.length > knownContent.length) {
|
|
2429
|
+
if (accumulatedContent.startsWith(knownContent)) {
|
|
2430
|
+
yield chunk;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2428
2434
|
}
|
|
2435
|
+
} finally {
|
|
2436
|
+
subscription.unsubscribe();
|
|
2429
2437
|
}
|
|
2430
2438
|
}
|
|
2431
|
-
/**
|
|
2432
|
-
* Get statistics about the buffer
|
|
2433
|
-
*/
|
|
2434
2439
|
getStats() {
|
|
2435
2440
|
let activeCount = 0;
|
|
2436
2441
|
let completedCount = 0;
|
|
2437
2442
|
let abortedCount = 0;
|
|
2438
|
-
let totalChunks = 0;
|
|
2439
2443
|
const validBuffers = [];
|
|
2440
2444
|
for (const [threadId, buffer] of this.buffers.entries()) {
|
|
2441
2445
|
if (this.isExpired(buffer)) {
|
|
@@ -2445,7 +2449,6 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2445
2449
|
}
|
|
2446
2450
|
}
|
|
2447
2451
|
for (const buffer of validBuffers) {
|
|
2448
|
-
totalChunks += buffer.chunks.length;
|
|
2449
2452
|
switch (buffer.status) {
|
|
2450
2453
|
case "active" /* ACTIVE */:
|
|
2451
2454
|
activeCount++;
|
|
@@ -2463,13 +2466,9 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
2463
2466
|
activeThreads: activeCount,
|
|
2464
2467
|
completedThreads: completedCount,
|
|
2465
2468
|
abortedThreads: abortedCount,
|
|
2466
|
-
totalChunks,
|
|
2467
2469
|
config: this.config
|
|
2468
2470
|
};
|
|
2469
2471
|
}
|
|
2470
|
-
/**
|
|
2471
|
-
* Cleanup method for graceful shutdown
|
|
2472
|
-
*/
|
|
2473
2472
|
dispose() {
|
|
2474
2473
|
this.stopCleanupTimer();
|
|
2475
2474
|
this.buffers.clear();
|