@anuma/sdk 10.1.1 → 10.2.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/expo/index.cjs +323 -277
- package/dist/expo/index.d.mts +3706 -3698
- package/dist/expo/index.d.ts +3706 -3698
- package/dist/expo/index.mjs +323 -277
- package/dist/react/index.cjs +323 -277
- package/dist/react/index.d.mts +4114 -4106
- package/dist/react/index.d.ts +4114 -4106
- package/dist/react/index.mjs +323 -277
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -12403,6 +12403,275 @@ async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
|
12403
12403
|
});
|
|
12404
12404
|
}
|
|
12405
12405
|
|
|
12406
|
+
// src/lib/chatStore/vaultRecords.ts
|
|
12407
|
+
var PINNED_SORT_BASE = 2 ** 51;
|
|
12408
|
+
var recordBudgetBytes = 104e4;
|
|
12409
|
+
var storedDims = 1536;
|
|
12410
|
+
var acceptedDims = /* @__PURE__ */ new Set([1536, 4096]);
|
|
12411
|
+
var maxChunks = 16;
|
|
12412
|
+
var droppable = ["thoughtProcess", "thinking", "sources", "toolCallEvents"];
|
|
12413
|
+
var messageMetadata = /* @__PURE__ */ new Set(["conversationId", "uniqueId", "vector", "chunks"]);
|
|
12414
|
+
var alwaysStored = /* @__PURE__ */ new Set(["role", "content", "responseDuration"]);
|
|
12415
|
+
function plain(value) {
|
|
12416
|
+
return JSON.parse(JSON.stringify(value ?? {}));
|
|
12417
|
+
}
|
|
12418
|
+
function text4(value) {
|
|
12419
|
+
return typeof value === "string" ? value : void 0;
|
|
12420
|
+
}
|
|
12421
|
+
function number(value) {
|
|
12422
|
+
return typeof value === "number" ? value : void 0;
|
|
12423
|
+
}
|
|
12424
|
+
function conversationSortKey(data, createdAt) {
|
|
12425
|
+
const pinnedAt = number(data.pinnedAt);
|
|
12426
|
+
if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
|
|
12427
|
+
return number(data.lastActivityAt) ?? createdAt;
|
|
12428
|
+
}
|
|
12429
|
+
function toConversation(record2) {
|
|
12430
|
+
const pinnedAt = number(record2.data.pinnedAt);
|
|
12431
|
+
const projectId = text4(record2.data.projectId);
|
|
12432
|
+
return {
|
|
12433
|
+
uniqueId: record2.id,
|
|
12434
|
+
conversationId: record2.id,
|
|
12435
|
+
title: text4(record2.data.title) ?? "",
|
|
12436
|
+
...projectId ? { projectId } : {},
|
|
12437
|
+
createdAt: new Date(record2.createdAt),
|
|
12438
|
+
updatedAt: new Date(record2.updatedAt),
|
|
12439
|
+
isDeleted: record2.isDeleted,
|
|
12440
|
+
pinnedAt: pinnedAt ? new Date(pinnedAt) : null
|
|
12441
|
+
};
|
|
12442
|
+
}
|
|
12443
|
+
function messageData(options) {
|
|
12444
|
+
return plain(
|
|
12445
|
+
Object.fromEntries(
|
|
12446
|
+
Object.entries(options).filter(
|
|
12447
|
+
([key3, value]) => !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
12448
|
+
)
|
|
12449
|
+
)
|
|
12450
|
+
);
|
|
12451
|
+
}
|
|
12452
|
+
function toMessage(record2) {
|
|
12453
|
+
const { chunkOffsets: _offsets, truncated: _truncated, ...fields } = record2.data;
|
|
12454
|
+
return {
|
|
12455
|
+
...fields,
|
|
12456
|
+
uniqueId: record2.id,
|
|
12457
|
+
messageId: record2.sortKey,
|
|
12458
|
+
conversationId: record2.conversationId,
|
|
12459
|
+
createdAt: new Date(record2.createdAt),
|
|
12460
|
+
updatedAt: new Date(record2.updatedAt)
|
|
12461
|
+
};
|
|
12462
|
+
}
|
|
12463
|
+
function chunkOffsets(record2) {
|
|
12464
|
+
const offsets = record2.data.chunkOffsets;
|
|
12465
|
+
return Array.isArray(offsets) ? offsets : void 0;
|
|
12466
|
+
}
|
|
12467
|
+
function toSkeletons(records) {
|
|
12468
|
+
const roleById = new Map(records.map((r) => [r.id, text4(r.data.role)]));
|
|
12469
|
+
return records.map((r) => {
|
|
12470
|
+
const parentMessageId = text4(r.data.parentMessageId);
|
|
12471
|
+
const model = text4(r.data.model);
|
|
12472
|
+
const artifact = r.data.role === "user" && !!parentMessageId && roleById.get(parentMessageId) === "user";
|
|
12473
|
+
return {
|
|
12474
|
+
uniqueId: r.id,
|
|
12475
|
+
messageId: r.sortKey,
|
|
12476
|
+
conversationId: r.conversationId,
|
|
12477
|
+
role: text4(r.data.role) ?? "",
|
|
12478
|
+
createdAt: new Date(r.createdAt),
|
|
12479
|
+
...parentMessageId ? { parentMessageId } : {},
|
|
12480
|
+
...model ? { model } : {},
|
|
12481
|
+
...artifact ? { content: text4(r.data.content) ?? "" } : {}
|
|
12482
|
+
};
|
|
12483
|
+
});
|
|
12484
|
+
}
|
|
12485
|
+
function toSummary(record2) {
|
|
12486
|
+
return {
|
|
12487
|
+
uniqueId: record2.id,
|
|
12488
|
+
conversationId: record2.id,
|
|
12489
|
+
summary: text4(record2.data.summary) ?? "",
|
|
12490
|
+
summarizedUpTo: text4(record2.data.summarizedUpTo) ?? "",
|
|
12491
|
+
tokenCount: number(record2.data.tokenCount) ?? 0,
|
|
12492
|
+
createdAt: new Date(record2.createdAt),
|
|
12493
|
+
updatedAt: new Date(record2.updatedAt)
|
|
12494
|
+
};
|
|
12495
|
+
}
|
|
12496
|
+
function links(data) {
|
|
12497
|
+
return Array.isArray(data.links) ? data.links : [];
|
|
12498
|
+
}
|
|
12499
|
+
function applyLinkOps(data, ops) {
|
|
12500
|
+
let current = links(data);
|
|
12501
|
+
for (const op of ops) {
|
|
12502
|
+
if ("clear" in op) {
|
|
12503
|
+
current = [];
|
|
12504
|
+
continue;
|
|
12505
|
+
}
|
|
12506
|
+
const byId = new Map(current.map((l) => [l.memoryId, l]));
|
|
12507
|
+
const turn = /* @__PURE__ */ new Set();
|
|
12508
|
+
op.add.forEach((item, i) => {
|
|
12509
|
+
if (!item.memoryId || turn.has(item.memoryId)) return;
|
|
12510
|
+
turn.add(item.memoryId);
|
|
12511
|
+
const known = byId.get(item.memoryId);
|
|
12512
|
+
if (known && known.createdAt >= op.at + i) return;
|
|
12513
|
+
byId.set(item.memoryId, { memoryId: item.memoryId, score: item.score, createdAt: op.at + i });
|
|
12514
|
+
});
|
|
12515
|
+
current = [...byId.values()].sort((a, b) => a.createdAt - b.createdAt).slice(-MAX_PER_CONVERSATION);
|
|
12516
|
+
}
|
|
12517
|
+
return plain({ links: current });
|
|
12518
|
+
}
|
|
12519
|
+
function toLinks(record2) {
|
|
12520
|
+
return links(record2.data).map((l) => ({
|
|
12521
|
+
uniqueId: `${record2.id}:${l.memoryId}`,
|
|
12522
|
+
conversationId: record2.id,
|
|
12523
|
+
memoryId: l.memoryId,
|
|
12524
|
+
score: l.score,
|
|
12525
|
+
createdAt: new Date(l.createdAt)
|
|
12526
|
+
}));
|
|
12527
|
+
}
|
|
12528
|
+
function bytes(value) {
|
|
12529
|
+
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
12530
|
+
}
|
|
12531
|
+
function fitRecord(record2) {
|
|
12532
|
+
if (record2.kind !== "message" || bytes(record2) <= recordBudgetBytes) return record2;
|
|
12533
|
+
const data = { ...record2.data };
|
|
12534
|
+
const truncated = [];
|
|
12535
|
+
for (const field10 of droppable) {
|
|
12536
|
+
if (bytes({ ...record2, data }) <= recordBudgetBytes) break;
|
|
12537
|
+
if (data[field10] === void 0) continue;
|
|
12538
|
+
delete data[field10];
|
|
12539
|
+
truncated.push(field10);
|
|
12540
|
+
}
|
|
12541
|
+
const content = text4(data.content) ?? "";
|
|
12542
|
+
const over = bytes({ ...record2, data }) - recordBudgetBytes;
|
|
12543
|
+
if (over > 0) {
|
|
12544
|
+
const encoded = new TextEncoder().encode(content);
|
|
12545
|
+
data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
|
|
12546
|
+
truncated.push("content");
|
|
12547
|
+
}
|
|
12548
|
+
return { ...record2, data: { ...data, truncated } };
|
|
12549
|
+
}
|
|
12550
|
+
function acceptedVector(vector2) {
|
|
12551
|
+
if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
|
|
12552
|
+
if (!vector2.every(Number.isFinite) || !vector2.slice(0, storedDims).some((x) => x !== 0))
|
|
12553
|
+
return void 0;
|
|
12554
|
+
return [...vector2];
|
|
12555
|
+
}
|
|
12556
|
+
function normalized(vector2) {
|
|
12557
|
+
const norm = Math.hypot(...vector2) || 1;
|
|
12558
|
+
return vector2.map((x) => x / norm);
|
|
12559
|
+
}
|
|
12560
|
+
function fitChunks(chunks3) {
|
|
12561
|
+
const usable = chunks3.map((c) => ({ ...c, vector: acceptedVector(c.vector) }));
|
|
12562
|
+
if (usable.length === 0 || usable.some((c) => !c.vector)) return void 0;
|
|
12563
|
+
if (usable.length <= maxChunks) return usable;
|
|
12564
|
+
const out = [];
|
|
12565
|
+
for (let g = 0; g < maxChunks; g++) {
|
|
12566
|
+
const group = usable.slice(
|
|
12567
|
+
Math.floor(g * usable.length / maxChunks),
|
|
12568
|
+
Math.floor((g + 1) * usable.length / maxChunks)
|
|
12569
|
+
);
|
|
12570
|
+
const dims = group[0].vector.length;
|
|
12571
|
+
const mean = new Array(dims).fill(0);
|
|
12572
|
+
for (const c of group) {
|
|
12573
|
+
const unit = normalized(c.vector);
|
|
12574
|
+
for (let d = 0; d < dims; d++) mean[d] += unit[d];
|
|
12575
|
+
}
|
|
12576
|
+
out.push({
|
|
12577
|
+
vector: normalized(mean),
|
|
12578
|
+
startOffset: group[0].startOffset,
|
|
12579
|
+
endOffset: group[group.length - 1].endOffset
|
|
12580
|
+
});
|
|
12581
|
+
}
|
|
12582
|
+
return out;
|
|
12583
|
+
}
|
|
12584
|
+
|
|
12585
|
+
// src/lib/chatStore/chatImports.ts
|
|
12586
|
+
var importBatch = 100;
|
|
12587
|
+
var importChunks = 200;
|
|
12588
|
+
var importPlaintextBytes = 39e5;
|
|
12589
|
+
function ms(date10, fallback = 1) {
|
|
12590
|
+
const value = date10?.getTime();
|
|
12591
|
+
return value && Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
|
|
12592
|
+
}
|
|
12593
|
+
function bytes2(value) {
|
|
12594
|
+
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
12595
|
+
}
|
|
12596
|
+
function conversationRecord(conversation, messages) {
|
|
12597
|
+
const createdAt = ms(conversation.createdAt);
|
|
12598
|
+
const data = plain({
|
|
12599
|
+
title: conversation.title,
|
|
12600
|
+
projectId: conversation.projectId || void 0,
|
|
12601
|
+
pinnedAt: conversation.pinnedAt ? ms(conversation.pinnedAt) : void 0,
|
|
12602
|
+
lastActivityAt: Math.max(
|
|
12603
|
+
ms(conversation.updatedAt, createdAt),
|
|
12604
|
+
...messages.map((m) => ms(m.createdAt))
|
|
12605
|
+
)
|
|
12606
|
+
});
|
|
12607
|
+
return {
|
|
12608
|
+
record: {
|
|
12609
|
+
kind: "conversation",
|
|
12610
|
+
id: conversation.conversationId,
|
|
12611
|
+
conversationId: "",
|
|
12612
|
+
sortKey: conversationSortKey(data, createdAt),
|
|
12613
|
+
createdAt,
|
|
12614
|
+
updatedAt: ms(conversation.updatedAt, createdAt),
|
|
12615
|
+
isDeleted: false,
|
|
12616
|
+
data
|
|
12617
|
+
}
|
|
12618
|
+
};
|
|
12619
|
+
}
|
|
12620
|
+
function messageRecord(message) {
|
|
12621
|
+
const {
|
|
12622
|
+
uniqueId: _uniqueId,
|
|
12623
|
+
messageId: _messageId,
|
|
12624
|
+
createdAt: _createdAt,
|
|
12625
|
+
updatedAt: _updatedAt,
|
|
12626
|
+
decryptionStatus: _status,
|
|
12627
|
+
chunks: chunks3,
|
|
12628
|
+
vector: vector2,
|
|
12629
|
+
...fields
|
|
12630
|
+
} = message;
|
|
12631
|
+
const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
|
|
12632
|
+
const single = fitted ? void 0 : acceptedVector(vector2);
|
|
12633
|
+
const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
|
|
12634
|
+
const record2 = fitRecord({
|
|
12635
|
+
kind: "message",
|
|
12636
|
+
id: message.uniqueId,
|
|
12637
|
+
conversationId: message.conversationId,
|
|
12638
|
+
sortKey: message.messageId,
|
|
12639
|
+
createdAt: ms(message.createdAt),
|
|
12640
|
+
updatedAt: ms(message.updatedAt, ms(message.createdAt)),
|
|
12641
|
+
isDeleted: false,
|
|
12642
|
+
data: {
|
|
12643
|
+
...messageData(fields),
|
|
12644
|
+
...fitted ? { chunkOffsets: fitted.map((c) => [c.startOffset, c.endOffset]) } : {}
|
|
12645
|
+
}
|
|
12646
|
+
});
|
|
12647
|
+
return {
|
|
12648
|
+
record: record2,
|
|
12649
|
+
...embeddings2 ? { embeddings: embeddings2 } : {},
|
|
12650
|
+
...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
|
|
12651
|
+
};
|
|
12652
|
+
}
|
|
12653
|
+
function batches(records) {
|
|
12654
|
+
const out = [];
|
|
12655
|
+
let batch = [];
|
|
12656
|
+
let chunks3 = 0;
|
|
12657
|
+
let size = 0;
|
|
12658
|
+
for (const item of records) {
|
|
12659
|
+
const vectors = item.embeddings?.length ?? 0;
|
|
12660
|
+
const itemSize = bytes2(item.record);
|
|
12661
|
+
if (batch.length > 0 && (batch.length >= importBatch || chunks3 + vectors > importChunks || size + itemSize > importPlaintextBytes)) {
|
|
12662
|
+
out.push(batch);
|
|
12663
|
+
batch = [];
|
|
12664
|
+
chunks3 = 0;
|
|
12665
|
+
size = 0;
|
|
12666
|
+
}
|
|
12667
|
+
batch.push(item);
|
|
12668
|
+
chunks3 += vectors;
|
|
12669
|
+
size += itemSize;
|
|
12670
|
+
}
|
|
12671
|
+
if (batch.length) out.push(batch);
|
|
12672
|
+
return out;
|
|
12673
|
+
}
|
|
12674
|
+
|
|
12406
12675
|
// src/lib/memory/store/remotePersistence.ts
|
|
12407
12676
|
init_portalLlm();
|
|
12408
12677
|
|
|
@@ -13145,7 +13414,7 @@ var ChatStoreError = class extends Error {
|
|
|
13145
13414
|
var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links"]);
|
|
13146
13415
|
var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
|
|
13147
13416
|
var maxPayload = 2 * 1024 * 1024;
|
|
13148
|
-
var
|
|
13417
|
+
var storedDims2 = 1536;
|
|
13149
13418
|
var maxRequestCiphertext = 8 * 1024 * 1024;
|
|
13150
13419
|
var maxGetRefs = 50;
|
|
13151
13420
|
var maxImportRecords = 100;
|
|
@@ -13213,24 +13482,24 @@ function vector(v) {
|
|
|
13213
13482
|
for (let i = 0; i < v.length; i++) {
|
|
13214
13483
|
const x = v[i];
|
|
13215
13484
|
if (typeof x !== "number" || !Number.isFinite(x)) return false;
|
|
13216
|
-
if (i <
|
|
13485
|
+
if (i < storedDims2 && x !== 0) nonZero = true;
|
|
13217
13486
|
}
|
|
13218
13487
|
return nonZero;
|
|
13219
13488
|
}
|
|
13220
13489
|
function vectorFields(write) {
|
|
13221
13490
|
return {
|
|
13222
|
-
...write.embeddings !== void 0 ? { embeddings: write.embeddings.map((v) => v.slice(0,
|
|
13491
|
+
...write.embeddings !== void 0 ? { embeddings: write.embeddings.map((v) => v.slice(0, storedDims2)) } : {},
|
|
13223
13492
|
...write.embeddingModel !== void 0 ? { embedding_model: write.embeddingModel } : {}
|
|
13224
13493
|
};
|
|
13225
13494
|
}
|
|
13226
|
-
function
|
|
13495
|
+
function text5(value) {
|
|
13227
13496
|
return typeof value === "string";
|
|
13228
13497
|
}
|
|
13229
13498
|
function timestamp(value) {
|
|
13230
13499
|
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
13231
13500
|
}
|
|
13232
13501
|
function presigned(value) {
|
|
13233
|
-
if (!object(value) || !
|
|
13502
|
+
if (!object(value) || !text5(value.url) || !/^https:\/\//.test(value.url) || !text5(value.method) || !object(value.headers) || !Object.values(value.headers).every(text5) || !timestamp(value.expires_at))
|
|
13234
13503
|
invalid();
|
|
13235
13504
|
return {
|
|
13236
13505
|
url: value.url,
|
|
@@ -13240,7 +13509,7 @@ function presigned(value) {
|
|
|
13240
13509
|
};
|
|
13241
13510
|
}
|
|
13242
13511
|
function attachment(value) {
|
|
13243
|
-
if (!object(value) || !
|
|
13512
|
+
if (!object(value) || !text5(value.attachment_id) || !attachmentIdPattern.test(value.attachment_id) || !integer(value.size_bytes, 1) || value.state !== "pending" && value.state !== "committed" || value.owner_kind !== void 0 && value.owner_kind !== "message" && value.owner_kind !== "summary" || value.owner_id !== void 0 && !id(value.owner_id) || !timestamp(value.created_at) || value.committed_at !== void 0 && !timestamp(value.committed_at))
|
|
13244
13513
|
invalid();
|
|
13245
13514
|
return {
|
|
13246
13515
|
id: value.attachment_id,
|
|
@@ -13253,7 +13522,7 @@ function attachment(value) {
|
|
|
13253
13522
|
};
|
|
13254
13523
|
}
|
|
13255
13524
|
function ref(value) {
|
|
13256
|
-
if (!object(value) || !
|
|
13525
|
+
if (!object(value) || !text5(value.kind) || !kinds.has(value.kind) || !id(value.id)) invalid();
|
|
13257
13526
|
return { kind: value.kind, id: value.id };
|
|
13258
13527
|
}
|
|
13259
13528
|
function sameMetadata(a, b) {
|
|
@@ -13476,7 +13745,7 @@ async function createRemoteChatStore(options) {
|
|
|
13476
13745
|
},
|
|
13477
13746
|
async account(signal) {
|
|
13478
13747
|
const value = await request("/account", {}, signal);
|
|
13479
|
-
if (!object(value) || value.account_id !== accountId || !
|
|
13748
|
+
if (!object(value) || value.account_id !== accountId || !text5(value.key_id) || value.state !== "none" && value.state !== "migrating" && value.state !== "active" || !integer(value.record_count) || !integer(value.storage_bytes) || !integer(value.vector_count) || value.changes_cursor !== void 0 && (!text5(value.changes_cursor) || value.changes_cursor.length > 2048))
|
|
13480
13749
|
invalid();
|
|
13481
13750
|
if (value.key_id && value.key_id !== keyId)
|
|
13482
13751
|
throw new ChatStoreError("Canonical chat key does not match", 409, "key_mismatch");
|
|
@@ -13551,12 +13820,12 @@ async function createRemoteChatStore(options) {
|
|
|
13551
13820
|
},
|
|
13552
13821
|
async changes(cursor, options2) {
|
|
13553
13822
|
const limit = options2?.limit ?? 100;
|
|
13554
|
-
if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!
|
|
13823
|
+
if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text5(cursor) || cursor.length > 2048))
|
|
13555
13824
|
invalid();
|
|
13556
13825
|
const params = new URLSearchParams({ account_id: String(accountId), limit: String(limit) });
|
|
13557
13826
|
if (cursor) params.set("cursor", cursor);
|
|
13558
13827
|
const value = await request(`/changes?${params}`, {}, options2?.signal);
|
|
13559
|
-
if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !
|
|
13828
|
+
if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !text5(value.next_cursor) || value.changes_cursor !== void 0 && !text5(value.changes_cursor))
|
|
13560
13829
|
invalid();
|
|
13561
13830
|
const items = [];
|
|
13562
13831
|
for (const item of value.items) items.push(await decode(item));
|
|
@@ -13573,7 +13842,7 @@ async function createRemoteChatStore(options) {
|
|
|
13573
13842
|
if (!Array.isArray(embedding2) || !embeddings({
|
|
13574
13843
|
record: { ...emptyMessage, isDeleted: false },
|
|
13575
13844
|
embeddings: [embedding2]
|
|
13576
|
-
}) || !integer(limit, 1) || limit > 50 || kindsFilter !== void 0 && (!Array.isArray(kindsFilter) || kindsFilter.length === 0 || kindsFilter.some((k) => k !== "message" && k !== "summary")) || options2?.conversationId !== void 0 && !id(options2.conversationId) || options2?.excludeConversationId !== void 0 && !id(options2.excludeConversationId) || options2?.embeddingModel !== void 0 && (!
|
|
13845
|
+
}) || !integer(limit, 1) || limit > 50 || kindsFilter !== void 0 && (!Array.isArray(kindsFilter) || kindsFilter.length === 0 || kindsFilter.some((k) => k !== "message" && k !== "summary")) || options2?.conversationId !== void 0 && !id(options2.conversationId) || options2?.excludeConversationId !== void 0 && !id(options2.excludeConversationId) || options2?.embeddingModel !== void 0 && (!text5(options2.embeddingModel) || options2.embeddingModel.length > 256))
|
|
13577
13846
|
invalid();
|
|
13578
13847
|
const value = await request(
|
|
13579
13848
|
"/search",
|
|
@@ -13581,7 +13850,7 @@ async function createRemoteChatStore(options) {
|
|
|
13581
13850
|
method: "POST",
|
|
13582
13851
|
body: JSON.stringify({
|
|
13583
13852
|
account_id: accountId,
|
|
13584
|
-
embedding: embedding2.slice(0,
|
|
13853
|
+
embedding: embedding2.slice(0, storedDims2),
|
|
13585
13854
|
limit,
|
|
13586
13855
|
...kindsFilter ? { kinds: kindsFilter } : {},
|
|
13587
13856
|
...options2?.conversationId ? { conversation_id: options2.conversationId } : {},
|
|
@@ -13685,199 +13954,13 @@ var emptyMessage = {
|
|
|
13685
13954
|
data: {}
|
|
13686
13955
|
};
|
|
13687
13956
|
|
|
13688
|
-
// src/lib/chatStore/vaultRecords.ts
|
|
13689
|
-
var PINNED_SORT_BASE = 2 ** 51;
|
|
13690
|
-
var recordBudgetBytes = 104e4;
|
|
13691
|
-
var storedDims2 = 1536;
|
|
13692
|
-
var acceptedDims = /* @__PURE__ */ new Set([1536, 4096]);
|
|
13693
|
-
var maxChunks = 16;
|
|
13694
|
-
var droppable = ["thoughtProcess", "thinking", "sources", "toolCallEvents"];
|
|
13695
|
-
var messageMetadata = /* @__PURE__ */ new Set(["conversationId", "uniqueId", "vector", "chunks"]);
|
|
13696
|
-
var alwaysStored = /* @__PURE__ */ new Set(["role", "content", "responseDuration"]);
|
|
13697
|
-
function plain(value) {
|
|
13698
|
-
return JSON.parse(JSON.stringify(value ?? {}));
|
|
13699
|
-
}
|
|
13700
|
-
function text5(value) {
|
|
13701
|
-
return typeof value === "string" ? value : void 0;
|
|
13702
|
-
}
|
|
13703
|
-
function number(value) {
|
|
13704
|
-
return typeof value === "number" ? value : void 0;
|
|
13705
|
-
}
|
|
13706
|
-
function conversationSortKey(data, createdAt) {
|
|
13707
|
-
const pinnedAt = number(data.pinnedAt);
|
|
13708
|
-
if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
|
|
13709
|
-
return number(data.lastActivityAt) ?? createdAt;
|
|
13710
|
-
}
|
|
13711
|
-
function toConversation(record2) {
|
|
13712
|
-
const pinnedAt = number(record2.data.pinnedAt);
|
|
13713
|
-
const projectId = text5(record2.data.projectId);
|
|
13714
|
-
return {
|
|
13715
|
-
uniqueId: record2.id,
|
|
13716
|
-
conversationId: record2.id,
|
|
13717
|
-
title: text5(record2.data.title) ?? "",
|
|
13718
|
-
...projectId ? { projectId } : {},
|
|
13719
|
-
createdAt: new Date(record2.createdAt),
|
|
13720
|
-
updatedAt: new Date(record2.updatedAt),
|
|
13721
|
-
isDeleted: record2.isDeleted,
|
|
13722
|
-
pinnedAt: pinnedAt ? new Date(pinnedAt) : null
|
|
13723
|
-
};
|
|
13724
|
-
}
|
|
13725
|
-
function messageData(options) {
|
|
13726
|
-
return plain(
|
|
13727
|
-
Object.fromEntries(
|
|
13728
|
-
Object.entries(options).filter(
|
|
13729
|
-
([key3, value]) => !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
13730
|
-
)
|
|
13731
|
-
)
|
|
13732
|
-
);
|
|
13733
|
-
}
|
|
13734
|
-
function toMessage(record2) {
|
|
13735
|
-
const { chunkOffsets: _offsets, truncated: _truncated, ...fields } = record2.data;
|
|
13736
|
-
return {
|
|
13737
|
-
...fields,
|
|
13738
|
-
uniqueId: record2.id,
|
|
13739
|
-
messageId: record2.sortKey,
|
|
13740
|
-
conversationId: record2.conversationId,
|
|
13741
|
-
createdAt: new Date(record2.createdAt),
|
|
13742
|
-
updatedAt: new Date(record2.updatedAt)
|
|
13743
|
-
};
|
|
13744
|
-
}
|
|
13745
|
-
function chunkOffsets(record2) {
|
|
13746
|
-
const offsets = record2.data.chunkOffsets;
|
|
13747
|
-
return Array.isArray(offsets) ? offsets : void 0;
|
|
13748
|
-
}
|
|
13749
|
-
function toSkeletons(records) {
|
|
13750
|
-
const roleById = new Map(records.map((r) => [r.id, text5(r.data.role)]));
|
|
13751
|
-
return records.map((r) => {
|
|
13752
|
-
const parentMessageId = text5(r.data.parentMessageId);
|
|
13753
|
-
const model = text5(r.data.model);
|
|
13754
|
-
const artifact = r.data.role === "user" && !!parentMessageId && roleById.get(parentMessageId) === "user";
|
|
13755
|
-
return {
|
|
13756
|
-
uniqueId: r.id,
|
|
13757
|
-
messageId: r.sortKey,
|
|
13758
|
-
conversationId: r.conversationId,
|
|
13759
|
-
role: text5(r.data.role) ?? "",
|
|
13760
|
-
createdAt: new Date(r.createdAt),
|
|
13761
|
-
...parentMessageId ? { parentMessageId } : {},
|
|
13762
|
-
...model ? { model } : {},
|
|
13763
|
-
...artifact ? { content: text5(r.data.content) ?? "" } : {}
|
|
13764
|
-
};
|
|
13765
|
-
});
|
|
13766
|
-
}
|
|
13767
|
-
function toSummary(record2) {
|
|
13768
|
-
return {
|
|
13769
|
-
uniqueId: record2.id,
|
|
13770
|
-
conversationId: record2.id,
|
|
13771
|
-
summary: text5(record2.data.summary) ?? "",
|
|
13772
|
-
summarizedUpTo: text5(record2.data.summarizedUpTo) ?? "",
|
|
13773
|
-
tokenCount: number(record2.data.tokenCount) ?? 0,
|
|
13774
|
-
createdAt: new Date(record2.createdAt),
|
|
13775
|
-
updatedAt: new Date(record2.updatedAt)
|
|
13776
|
-
};
|
|
13777
|
-
}
|
|
13778
|
-
function links(data) {
|
|
13779
|
-
return Array.isArray(data.links) ? data.links : [];
|
|
13780
|
-
}
|
|
13781
|
-
function applyLinkOps(data, ops) {
|
|
13782
|
-
let current = links(data);
|
|
13783
|
-
for (const op of ops) {
|
|
13784
|
-
if ("clear" in op) {
|
|
13785
|
-
current = [];
|
|
13786
|
-
continue;
|
|
13787
|
-
}
|
|
13788
|
-
const byId = new Map(current.map((l) => [l.memoryId, l]));
|
|
13789
|
-
const turn = /* @__PURE__ */ new Set();
|
|
13790
|
-
op.add.forEach((item, i) => {
|
|
13791
|
-
if (!item.memoryId || turn.has(item.memoryId)) return;
|
|
13792
|
-
turn.add(item.memoryId);
|
|
13793
|
-
const known = byId.get(item.memoryId);
|
|
13794
|
-
if (known && known.createdAt >= op.at + i) return;
|
|
13795
|
-
byId.set(item.memoryId, { memoryId: item.memoryId, score: item.score, createdAt: op.at + i });
|
|
13796
|
-
});
|
|
13797
|
-
current = [...byId.values()].sort((a, b) => a.createdAt - b.createdAt).slice(-MAX_PER_CONVERSATION);
|
|
13798
|
-
}
|
|
13799
|
-
return plain({ links: current });
|
|
13800
|
-
}
|
|
13801
|
-
function toLinks(record2) {
|
|
13802
|
-
return links(record2.data).map((l) => ({
|
|
13803
|
-
uniqueId: `${record2.id}:${l.memoryId}`,
|
|
13804
|
-
conversationId: record2.id,
|
|
13805
|
-
memoryId: l.memoryId,
|
|
13806
|
-
score: l.score,
|
|
13807
|
-
createdAt: new Date(l.createdAt)
|
|
13808
|
-
}));
|
|
13809
|
-
}
|
|
13810
|
-
function bytes(value) {
|
|
13811
|
-
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
13812
|
-
}
|
|
13813
|
-
function fitRecord(record2) {
|
|
13814
|
-
if (record2.kind !== "message" || bytes(record2) <= recordBudgetBytes) return record2;
|
|
13815
|
-
const data = { ...record2.data };
|
|
13816
|
-
const truncated = [];
|
|
13817
|
-
for (const field10 of droppable) {
|
|
13818
|
-
if (bytes({ ...record2, data }) <= recordBudgetBytes) break;
|
|
13819
|
-
if (data[field10] === void 0) continue;
|
|
13820
|
-
delete data[field10];
|
|
13821
|
-
truncated.push(field10);
|
|
13822
|
-
}
|
|
13823
|
-
const content = text5(data.content) ?? "";
|
|
13824
|
-
const over = bytes({ ...record2, data }) - recordBudgetBytes;
|
|
13825
|
-
if (over > 0) {
|
|
13826
|
-
const encoded = new TextEncoder().encode(content);
|
|
13827
|
-
data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
|
|
13828
|
-
truncated.push("content");
|
|
13829
|
-
}
|
|
13830
|
-
return { ...record2, data: { ...data, truncated } };
|
|
13831
|
-
}
|
|
13832
|
-
function acceptedVector(vector2) {
|
|
13833
|
-
if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
|
|
13834
|
-
if (!vector2.every(Number.isFinite) || !vector2.slice(0, storedDims2).some((x) => x !== 0))
|
|
13835
|
-
return void 0;
|
|
13836
|
-
return [...vector2];
|
|
13837
|
-
}
|
|
13838
|
-
function normalized(vector2) {
|
|
13839
|
-
const norm = Math.hypot(...vector2) || 1;
|
|
13840
|
-
return vector2.map((x) => x / norm);
|
|
13841
|
-
}
|
|
13842
|
-
function fitChunks(chunks3) {
|
|
13843
|
-
const usable = chunks3.map((c) => ({ ...c, vector: acceptedVector(c.vector) }));
|
|
13844
|
-
if (usable.length === 0 || usable.some((c) => !c.vector)) return void 0;
|
|
13845
|
-
if (usable.length <= maxChunks) return usable;
|
|
13846
|
-
const out = [];
|
|
13847
|
-
for (let g = 0; g < maxChunks; g++) {
|
|
13848
|
-
const group = usable.slice(
|
|
13849
|
-
Math.floor(g * usable.length / maxChunks),
|
|
13850
|
-
Math.floor((g + 1) * usable.length / maxChunks)
|
|
13851
|
-
);
|
|
13852
|
-
const dims = group[0].vector.length;
|
|
13853
|
-
const mean = new Array(dims).fill(0);
|
|
13854
|
-
for (const c of group) {
|
|
13855
|
-
const unit = normalized(c.vector);
|
|
13856
|
-
for (let d = 0; d < dims; d++) mean[d] += unit[d];
|
|
13857
|
-
}
|
|
13858
|
-
out.push({
|
|
13859
|
-
vector: normalized(mean),
|
|
13860
|
-
startOffset: group[0].startOffset,
|
|
13861
|
-
endOffset: group[group.length - 1].endOffset
|
|
13862
|
-
});
|
|
13863
|
-
}
|
|
13864
|
-
return out;
|
|
13865
|
-
}
|
|
13866
|
-
|
|
13867
13957
|
// src/lib/chatStore/migrateChats.ts
|
|
13868
13958
|
var maxPasses = 5;
|
|
13869
13959
|
var verifyBatch = 1e3;
|
|
13870
|
-
var importBatch = 100;
|
|
13871
|
-
var importChunks = 200;
|
|
13872
|
-
var importPlaintextBytes = 39e5;
|
|
13873
13960
|
var writeBatch = 25;
|
|
13874
13961
|
function key(record2) {
|
|
13875
13962
|
return `${record2.kind}/${record2.id}`;
|
|
13876
13963
|
}
|
|
13877
|
-
function ms(date10, fallback = 1) {
|
|
13878
|
-
const value = date10?.getTime();
|
|
13879
|
-
return value && Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
|
|
13880
|
-
}
|
|
13881
13964
|
function sealed(value) {
|
|
13882
13965
|
if (typeof value === "string") return isEncrypted(value);
|
|
13883
13966
|
if (Array.isArray(value)) return typeof value[0] !== "number" && value.some(sealed);
|
|
@@ -13885,42 +13968,6 @@ function sealed(value) {
|
|
|
13885
13968
|
return Object.values(value).some(sealed);
|
|
13886
13969
|
return false;
|
|
13887
13970
|
}
|
|
13888
|
-
function bytes2(value) {
|
|
13889
|
-
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
13890
|
-
}
|
|
13891
|
-
function messageRecord(message) {
|
|
13892
|
-
const {
|
|
13893
|
-
uniqueId: _uniqueId,
|
|
13894
|
-
messageId: _messageId,
|
|
13895
|
-
createdAt: _createdAt,
|
|
13896
|
-
updatedAt: _updatedAt,
|
|
13897
|
-
decryptionStatus: _status,
|
|
13898
|
-
chunks: chunks3,
|
|
13899
|
-
vector: vector2,
|
|
13900
|
-
...fields
|
|
13901
|
-
} = message;
|
|
13902
|
-
const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
|
|
13903
|
-
const single = fitted ? void 0 : acceptedVector(vector2);
|
|
13904
|
-
const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
|
|
13905
|
-
const record2 = fitRecord({
|
|
13906
|
-
kind: "message",
|
|
13907
|
-
id: message.uniqueId,
|
|
13908
|
-
conversationId: message.conversationId,
|
|
13909
|
-
sortKey: message.messageId,
|
|
13910
|
-
createdAt: ms(message.createdAt),
|
|
13911
|
-
updatedAt: ms(message.updatedAt, ms(message.createdAt)),
|
|
13912
|
-
isDeleted: false,
|
|
13913
|
-
data: {
|
|
13914
|
-
...messageData(fields),
|
|
13915
|
-
...fitted ? { chunkOffsets: fitted.map((c) => [c.startOffset, c.endOffset]) } : {}
|
|
13916
|
-
}
|
|
13917
|
-
});
|
|
13918
|
-
return {
|
|
13919
|
-
record: record2,
|
|
13920
|
-
...embeddings2 ? { embeddings: embeddings2 } : {},
|
|
13921
|
-
...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
|
|
13922
|
-
};
|
|
13923
|
-
}
|
|
13924
13971
|
async function readLocal(options) {
|
|
13925
13972
|
const { database } = options;
|
|
13926
13973
|
const ctx = {
|
|
@@ -13974,29 +14021,10 @@ async function readLocal(options) {
|
|
|
13974
14021
|
const messages = await getMessagesOp(ctx, conversationId);
|
|
13975
14022
|
const unreadableTitle = isEncrypted(conversation.title);
|
|
13976
14023
|
if (unreadableTitle) out.untitled++;
|
|
13977
|
-
const createdAt = ms(conversation.createdAt);
|
|
13978
|
-
const data = plain({
|
|
13979
|
-
title: unreadableTitle ? "" : conversation.title,
|
|
13980
|
-
projectId: conversation.projectId || void 0,
|
|
13981
|
-
pinnedAt: conversation.pinnedAt ? ms(conversation.pinnedAt) : void 0,
|
|
13982
|
-
lastActivityAt: Math.max(
|
|
13983
|
-
ms(conversation.updatedAt, createdAt),
|
|
13984
|
-
...messages.map((m) => ms(m.createdAt))
|
|
13985
|
-
)
|
|
13986
|
-
});
|
|
13987
14024
|
out.conversations++;
|
|
13988
|
-
out.records.push(
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
id: conversationId,
|
|
13992
|
-
conversationId: "",
|
|
13993
|
-
sortKey: conversationSortKey(data, createdAt),
|
|
13994
|
-
createdAt,
|
|
13995
|
-
updatedAt: ms(conversation.updatedAt, createdAt),
|
|
13996
|
-
isDeleted: false,
|
|
13997
|
-
data
|
|
13998
|
-
}
|
|
13999
|
-
});
|
|
14025
|
+
out.records.push(
|
|
14026
|
+
conversationRecord(unreadableTitle ? { ...conversation, title: "" } : conversation, messages)
|
|
14027
|
+
);
|
|
14000
14028
|
for (const message of messages) {
|
|
14001
14029
|
if (message.decryptionStatus || sealed(message)) {
|
|
14002
14030
|
skip("message", message.uniqueId, "unreadable");
|
|
@@ -14117,27 +14145,6 @@ async function deletedSinceUpload(store, journal, local, signal) {
|
|
|
14117
14145
|
};
|
|
14118
14146
|
});
|
|
14119
14147
|
}
|
|
14120
|
-
function batches(records) {
|
|
14121
|
-
const out = [];
|
|
14122
|
-
let batch = [];
|
|
14123
|
-
let chunks3 = 0;
|
|
14124
|
-
let size = 0;
|
|
14125
|
-
for (const item of records) {
|
|
14126
|
-
const vectors = item.embeddings?.length ?? 0;
|
|
14127
|
-
const itemSize = bytes2(item.record);
|
|
14128
|
-
if (batch.length > 0 && (batch.length >= importBatch || chunks3 + vectors > importChunks || size + itemSize > importPlaintextBytes)) {
|
|
14129
|
-
out.push(batch);
|
|
14130
|
-
batch = [];
|
|
14131
|
-
chunks3 = 0;
|
|
14132
|
-
size = 0;
|
|
14133
|
-
}
|
|
14134
|
-
batch.push(item);
|
|
14135
|
-
chunks3 += vectors;
|
|
14136
|
-
size += itemSize;
|
|
14137
|
-
}
|
|
14138
|
-
if (batch.length) out.push(batch);
|
|
14139
|
-
return out;
|
|
14140
|
-
}
|
|
14141
14148
|
function fitVectors(records, available2, unembedded) {
|
|
14142
14149
|
let total = records.reduce((sum, r) => sum + (r.embeddings?.length ?? 0), 0);
|
|
14143
14150
|
if (total <= available2) return records;
|
|
@@ -15218,6 +15225,45 @@ function createVaultChatBackend(options) {
|
|
|
15218
15225
|
},
|
|
15219
15226
|
flush,
|
|
15220
15227
|
poll,
|
|
15228
|
+
async importChats(chats) {
|
|
15229
|
+
await ready();
|
|
15230
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15231
|
+
const unique = (items) => items.filter(({ record: record2 }) => {
|
|
15232
|
+
const k = key2(record2.kind, record2.id);
|
|
15233
|
+
if (seen.has(k)) return false;
|
|
15234
|
+
seen.add(k);
|
|
15235
|
+
return true;
|
|
15236
|
+
});
|
|
15237
|
+
const valid = chats.filter((c) => validChatId(c.conversation.conversationId));
|
|
15238
|
+
const conversations = unique(
|
|
15239
|
+
valid.map((c) => conversationRecord(c.conversation, c.messages))
|
|
15240
|
+
);
|
|
15241
|
+
const messages = unique(
|
|
15242
|
+
valid.flatMap(
|
|
15243
|
+
(c) => c.messages.filter(
|
|
15244
|
+
(m) => m.conversationId === c.conversation.conversationId && validChatId(m.uniqueId) && Number.isSafeInteger(m.messageId)
|
|
15245
|
+
).map((m) => messageRecord({ ...m, vector: void 0, chunks: void 0 }))
|
|
15246
|
+
)
|
|
15247
|
+
);
|
|
15248
|
+
let conversationCount = 0;
|
|
15249
|
+
let messageCount = 0;
|
|
15250
|
+
try {
|
|
15251
|
+
for (const batch of batches(conversations))
|
|
15252
|
+
conversationCount += await store.importRecords(batch);
|
|
15253
|
+
for (const batch of batches(messages)) messageCount += await store.importRecords(batch);
|
|
15254
|
+
} finally {
|
|
15255
|
+
for (const { record: record2 } of messages) checked.delete(key2("message", record2.id));
|
|
15256
|
+
await refresh(conversations.map(({ record: record2 }) => key2("conversation", record2.id))).catch(
|
|
15257
|
+
() => void 0
|
|
15258
|
+
);
|
|
15259
|
+
for (const { record: record2 } of conversations) threads.delete(record2.id);
|
|
15260
|
+
channel?.postMessage("changed");
|
|
15261
|
+
emit({ type: "conversations", origin: "local" });
|
|
15262
|
+
for (const { record: record2 } of conversations)
|
|
15263
|
+
emit({ type: "messages", conversationId: record2.id, origin: "local" });
|
|
15264
|
+
}
|
|
15265
|
+
return { conversations: conversationCount, messages: messageCount };
|
|
15266
|
+
},
|
|
15221
15267
|
status: () => ({ pending: pending.size + inflight.size, ...stopped ? { stopped } : {} }),
|
|
15222
15268
|
close() {
|
|
15223
15269
|
closed = true;
|