@anuma/sdk 10.8.0 → 10.10.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/{consolidate-7QUL3TOE.mjs → consolidate-QBV3DDHU.mjs} +1 -1
- package/dist/expo/index.cjs +2370 -1898
- package/dist/expo/index.d.mts +1017 -893
- package/dist/expo/index.d.ts +1017 -893
- package/dist/expo/index.mjs +1886 -1425
- package/dist/index.cjs +165 -16
- package/dist/index.d.mts +223 -1
- package/dist/index.d.ts +223 -1
- package/dist/index.mjs +158 -16
- package/dist/react/index.cjs +431 -254
- package/dist/react/index.d.mts +747 -712
- package/dist/react/index.d.ts +747 -712
- package/dist/react/index.mjs +416 -246
- package/dist/server/index.cjs +19 -13
- package/dist/server/index.d.mts +16 -2
- package/dist/server/index.d.ts +16 -2
- package/dist/server/index.mjs +19 -13
- package/package.json +2 -2
- package/dist/expo/{chunk-4SOUKJD5.mjs → chunk-VNTEHEGI.mjs} +957 -957
package/dist/react/index.mjs
CHANGED
|
@@ -3538,7 +3538,7 @@ async function updateMessageErrorOp(ctx, uniqueId, error) {
|
|
|
3538
3538
|
}
|
|
3539
3539
|
await ctx.database.write(async () => {
|
|
3540
3540
|
await message.update((msg) => {
|
|
3541
|
-
msg._setRaw("error", error);
|
|
3541
|
+
msg._setRaw("error", error ?? "");
|
|
3542
3542
|
});
|
|
3543
3543
|
});
|
|
3544
3544
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
@@ -6163,17 +6163,17 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
6163
6163
|
expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
|
|
6164
6164
|
if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
|
|
6165
6165
|
throw new Error("expectedVersion must be a nonnegative integer");
|
|
6166
|
-
const
|
|
6166
|
+
const conflict2 = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
|
|
6167
6167
|
let existing;
|
|
6168
6168
|
if (expectedVersion !== 0 && !snapshot) {
|
|
6169
6169
|
try {
|
|
6170
6170
|
existing = memoryRecord(await request(path, {}, signal));
|
|
6171
6171
|
} catch (error) {
|
|
6172
|
-
if (error instanceof RemoteMemoryError && error.status === 404) throw
|
|
6172
|
+
if (error instanceof RemoteMemoryError && error.status === 404) throw conflict2();
|
|
6173
6173
|
throw error;
|
|
6174
6174
|
}
|
|
6175
6175
|
}
|
|
6176
|
-
if (existing && existing.version !== expectedVersion) throw
|
|
6176
|
+
if (existing && existing.version !== expectedVersion) throw conflict2();
|
|
6177
6177
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
6178
6178
|
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
6179
6179
|
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
@@ -6485,6 +6485,67 @@ async function openInboxItem(item, keyPair) {
|
|
|
6485
6485
|
}
|
|
6486
6486
|
return opened;
|
|
6487
6487
|
}
|
|
6488
|
+
function inboxReplaces(row, opened) {
|
|
6489
|
+
if (row.error) return true;
|
|
6490
|
+
return row.wasStopped === true && opened.status === "completed";
|
|
6491
|
+
}
|
|
6492
|
+
async function clearTurnErrors(backend, answer) {
|
|
6493
|
+
const parentId = answer.parentMessageId;
|
|
6494
|
+
if (parentId) {
|
|
6495
|
+
const [parent] = await backend.getMessagesByIds([parentId]);
|
|
6496
|
+
if (parent?.error) await backend.updateMessageError(parentId, null);
|
|
6497
|
+
}
|
|
6498
|
+
if (!answer.error) return answer;
|
|
6499
|
+
return await backend.updateMessageError(answer.uniqueId, null) ?? answer;
|
|
6500
|
+
}
|
|
6501
|
+
async function deliverInboxAnswers(options) {
|
|
6502
|
+
const { inbox, keyPair, backend, store } = options;
|
|
6503
|
+
const results = [];
|
|
6504
|
+
for (const item of await inbox.list()) {
|
|
6505
|
+
let opened;
|
|
6506
|
+
try {
|
|
6507
|
+
opened = await openInboxItem(item, keyPair);
|
|
6508
|
+
} catch (err) {
|
|
6509
|
+
results.push({
|
|
6510
|
+
id: item.id,
|
|
6511
|
+
conversationId: null,
|
|
6512
|
+
status: "unreadable",
|
|
6513
|
+
assistantMessage: null,
|
|
6514
|
+
error: err instanceof Error ? err.message : String(err)
|
|
6515
|
+
});
|
|
6516
|
+
continue;
|
|
6517
|
+
}
|
|
6518
|
+
const base = { id: item.id, conversationId: opened.conversation_id };
|
|
6519
|
+
try {
|
|
6520
|
+
const messageId = opened.assistant_message_id ?? `msg_bg_${opened.inference_id}`;
|
|
6521
|
+
const [found] = await backend.getMessagesByIds([messageId]);
|
|
6522
|
+
const existing = found && inboxReplaces(found, opened) ? void 0 : found;
|
|
6523
|
+
if (!found) {
|
|
6524
|
+
const parent = opened.parent_message_id;
|
|
6525
|
+
const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
|
|
6526
|
+
if (!ownsTurn) {
|
|
6527
|
+
results.push({ ...base, status: "elsewhere", assistantMessage: null });
|
|
6528
|
+
continue;
|
|
6529
|
+
}
|
|
6530
|
+
}
|
|
6531
|
+
const stored2 = existing ?? await store(opened, messageId);
|
|
6532
|
+
await inbox.remove(item.id);
|
|
6533
|
+
results.push({
|
|
6534
|
+
...base,
|
|
6535
|
+
status: existing ? "delivered" : "stored",
|
|
6536
|
+
assistantMessage: stored2
|
|
6537
|
+
});
|
|
6538
|
+
} catch (err) {
|
|
6539
|
+
results.push({
|
|
6540
|
+
...base,
|
|
6541
|
+
status: "retry",
|
|
6542
|
+
assistantMessage: null,
|
|
6543
|
+
error: err instanceof Error ? err.message : String(err)
|
|
6544
|
+
});
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
return results;
|
|
6548
|
+
}
|
|
6488
6549
|
|
|
6489
6550
|
// src/lib/chat/reservationReceipts.ts
|
|
6490
6551
|
var ACTIONS = [
|
|
@@ -7961,6 +8022,13 @@ function createErrorResult(message, onError) {
|
|
|
7961
8022
|
function isAbortError(err) {
|
|
7962
8023
|
return err instanceof Error && err.name === "AbortError";
|
|
7963
8024
|
}
|
|
8025
|
+
var ProviderStreamError = class extends Error {
|
|
8026
|
+
constructor(message, code) {
|
|
8027
|
+
super(message);
|
|
8028
|
+
this.name = "ProviderStreamError";
|
|
8029
|
+
this.code = code;
|
|
8030
|
+
}
|
|
8031
|
+
};
|
|
7964
8032
|
function getInStreamErrorMessage(chunk) {
|
|
7965
8033
|
if (!chunk || typeof chunk !== "object") return null;
|
|
7966
8034
|
const obj = chunk;
|
|
@@ -8247,7 +8315,7 @@ var CompletionsStrategy = class {
|
|
|
8247
8315
|
processStreamChunk(chunk, accumulator) {
|
|
8248
8316
|
const result = { content: null, thinking: null };
|
|
8249
8317
|
const inStreamErr = getInStreamErrorMessage(chunk);
|
|
8250
|
-
if (inStreamErr) throw new
|
|
8318
|
+
if (inStreamErr) throw new ProviderStreamError(inStreamErr);
|
|
8251
8319
|
const rawChunk = chunk;
|
|
8252
8320
|
const typedChunk = rawChunk.response && rawChunk.type === "response" ? rawChunk.response : chunk;
|
|
8253
8321
|
if (typedChunk.id && !accumulator.responseId) {
|
|
@@ -9098,7 +9166,7 @@ var ResponsesStrategy = class {
|
|
|
9098
9166
|
const result = { content: null, thinking: null };
|
|
9099
9167
|
const typedChunk = chunk;
|
|
9100
9168
|
const inStreamErr = getInStreamErrorMessage(chunk);
|
|
9101
|
-
if (inStreamErr) throw new
|
|
9169
|
+
if (inStreamErr) throw new ProviderStreamError(inStreamErr);
|
|
9102
9170
|
if (typedChunk.type === "response.failed") {
|
|
9103
9171
|
const resp = typedChunk.response;
|
|
9104
9172
|
const err = resp?.error;
|
|
@@ -9115,9 +9183,12 @@ var ResponsesStrategy = class {
|
|
|
9115
9183
|
}
|
|
9116
9184
|
}
|
|
9117
9185
|
const label = code ? `[${code}] ` : "";
|
|
9118
|
-
throw new
|
|
9186
|
+
throw new ProviderStreamError(
|
|
9187
|
+
`${label}${message || "Upstream request failed"}`,
|
|
9188
|
+
code || void 0
|
|
9189
|
+
);
|
|
9119
9190
|
}
|
|
9120
|
-
throw new
|
|
9191
|
+
throw new ProviderStreamError("Upstream request failed (response.failed)");
|
|
9121
9192
|
}
|
|
9122
9193
|
if (typedChunk.type === "response" && typedChunk.response) {
|
|
9123
9194
|
const resp = typedChunk.response;
|
|
@@ -9741,13 +9812,6 @@ function isRetriableStreamError(err) {
|
|
|
9741
9812
|
if (msg.includes("connection refused") || msg.includes("connect error")) return true;
|
|
9742
9813
|
return false;
|
|
9743
9814
|
}
|
|
9744
|
-
var ProviderStreamError = class extends Error {
|
|
9745
|
-
constructor(message, code) {
|
|
9746
|
-
super(message);
|
|
9747
|
-
this.name = "ProviderStreamError";
|
|
9748
|
-
this.code = code;
|
|
9749
|
-
}
|
|
9750
|
-
};
|
|
9751
9815
|
function extractProviderStreamError(chunk) {
|
|
9752
9816
|
if (!chunk || typeof chunk !== "object") return null;
|
|
9753
9817
|
const errField = chunk.error;
|
|
@@ -10128,6 +10192,7 @@ async function runToolLoop(options) {
|
|
|
10128
10192
|
thinking: redactor.deAnonymize(acc.thinking)
|
|
10129
10193
|
}) : strategy.buildFinalResponse(acc);
|
|
10130
10194
|
const finalContentText = (acc) => redactor ? redactor.deAnonymize(acc.content) : acc.content;
|
|
10195
|
+
let streamingAccumulator = null;
|
|
10131
10196
|
try {
|
|
10132
10197
|
let sseError = null;
|
|
10133
10198
|
let apiTools = toolsToApiFormat(tools, resolved);
|
|
@@ -10279,6 +10344,7 @@ async function runToolLoop(options) {
|
|
|
10279
10344
|
}
|
|
10280
10345
|
});
|
|
10281
10346
|
accumulator = createStreamAccumulator(model || void 0);
|
|
10347
|
+
streamingAccumulator = accumulator;
|
|
10282
10348
|
contentSmoother = new StreamSmoother((text16) => {
|
|
10283
10349
|
if (emitData) emitData(text16);
|
|
10284
10350
|
}, smoothing);
|
|
@@ -10789,6 +10855,7 @@ Executing tool: ${toolInfo}
|
|
|
10789
10855
|
}
|
|
10790
10856
|
});
|
|
10791
10857
|
currentAccumulator = createStreamAccumulator(model || void 0);
|
|
10858
|
+
streamingAccumulator = currentAccumulator;
|
|
10792
10859
|
contContentSmoother = new StreamSmoother((text16) => {
|
|
10793
10860
|
if (emitData) emitData(text16);
|
|
10794
10861
|
}, smoothing);
|
|
@@ -10986,7 +11053,7 @@ Executing tool: ${toolInfo}
|
|
|
10986
11053
|
const statusCode = err instanceof Error && "statusCode" in err ? err.statusCode : void 0;
|
|
10987
11054
|
const connectionLost = !(err instanceof ProviderStreamError) && !(err instanceof SseError);
|
|
10988
11055
|
return {
|
|
10989
|
-
data: null,
|
|
11056
|
+
data: connectionLost && streamingAccumulator ? buildResponseFinal(streamingAccumulator) : null,
|
|
10990
11057
|
error: errorMsg,
|
|
10991
11058
|
statusCode,
|
|
10992
11059
|
...connectionLost ? { connectionLost: true } : {}
|
|
@@ -11331,118 +11398,19 @@ function createWebSearchPreProcessor(options = {}) {
|
|
|
11331
11398
|
};
|
|
11332
11399
|
}
|
|
11333
11400
|
|
|
11334
|
-
// src/lib/
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
}
|
|
11343
|
-
function modelToStored(record2, summary) {
|
|
11344
|
-
return {
|
|
11345
|
-
uniqueId: record2.id,
|
|
11346
|
-
conversationId: record2.conversationId,
|
|
11347
|
-
summary,
|
|
11348
|
-
summarizedUpTo: record2.summarizedUpTo,
|
|
11349
|
-
tokenCount: record2.tokenCount,
|
|
11350
|
-
createdAt: record2.createdAt,
|
|
11351
|
-
updatedAt: record2.updatedAt
|
|
11352
|
-
};
|
|
11353
|
-
}
|
|
11354
|
-
async function getConversationSummaryOp(ctx, conversationId) {
|
|
11355
|
-
const results = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
11356
|
-
if (results.length === 0) return null;
|
|
11357
|
-
const record2 = results[0];
|
|
11358
|
-
const stored2 = modelToStored(record2, record2.summary);
|
|
11359
|
-
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
11360
|
-
if (ctx.signMessage) {
|
|
11361
|
-
try {
|
|
11362
|
-
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
11363
|
-
} catch (error) {
|
|
11364
|
-
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
11365
|
-
}
|
|
11366
|
-
}
|
|
11367
|
-
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
11368
|
-
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
11369
|
-
try {
|
|
11370
|
-
const encryptedSummary = await encryptField(
|
|
11371
|
-
stored2.summary,
|
|
11372
|
-
ctx.walletAddress,
|
|
11373
|
-
ctx.signMessage,
|
|
11374
|
-
ctx.embeddedWalletSigner
|
|
11375
|
-
);
|
|
11376
|
-
await ctx.database.write(async () => {
|
|
11377
|
-
const current = await ctx.summariesCollection.query(Q3.where("id", record2.id)).fetch();
|
|
11378
|
-
if (current[0]?.summary === stored2.summary) {
|
|
11379
|
-
await current[0].update((rec) => {
|
|
11380
|
-
rec.summary = encryptedSummary;
|
|
11381
|
-
});
|
|
11382
|
-
}
|
|
11383
|
-
});
|
|
11384
|
-
} catch (error) {
|
|
11385
|
-
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
11386
|
-
}
|
|
11401
|
+
// src/lib/chatStore/types.ts
|
|
11402
|
+
var ChatStoreError = class extends Error {
|
|
11403
|
+
constructor(message, status, code, retryAfterMs) {
|
|
11404
|
+
super(message);
|
|
11405
|
+
this.status = status;
|
|
11406
|
+
this.code = code;
|
|
11407
|
+
this.retryAfterMs = retryAfterMs;
|
|
11408
|
+
this.name = "ChatStoreError";
|
|
11387
11409
|
}
|
|
11388
|
-
return stored2;
|
|
11389
|
-
}
|
|
11390
|
-
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
11391
|
-
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
11392
|
-
let record2;
|
|
11393
|
-
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
11394
|
-
await ctx.database.write(async () => {
|
|
11395
|
-
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
11396
|
-
const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
11397
|
-
if (existing.length > 0) {
|
|
11398
|
-
record2 = await existing[0].update((rec) => {
|
|
11399
|
-
rec.summary = encryptedSummary;
|
|
11400
|
-
rec.summarizedUpTo = summarizedUpTo;
|
|
11401
|
-
rec.tokenCount = tokenCount;
|
|
11402
|
-
});
|
|
11403
|
-
} else {
|
|
11404
|
-
record2 = await ctx.summariesCollection.create((rec) => {
|
|
11405
|
-
rec.conversationId = conversationId;
|
|
11406
|
-
rec.summary = encryptedSummary;
|
|
11407
|
-
rec.summarizedUpTo = summarizedUpTo;
|
|
11408
|
-
rec.tokenCount = tokenCount;
|
|
11409
|
-
});
|
|
11410
|
-
}
|
|
11411
|
-
});
|
|
11412
|
-
return modelToStored(record2, summary);
|
|
11413
|
-
}
|
|
11414
|
-
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
11415
|
-
await ctx.database.write(async () => {
|
|
11416
|
-
const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
11417
|
-
for (const record2 of existing) {
|
|
11418
|
-
await record2.destroyPermanently();
|
|
11419
|
-
}
|
|
11420
|
-
});
|
|
11421
|
-
}
|
|
11422
|
-
|
|
11423
|
-
// src/lib/db/conversationMemory/models.ts
|
|
11424
|
-
import { Model as Model3 } from "@nozbe/watermelondb";
|
|
11425
|
-
import { date as date2, field as field2, readonly, text as text3 } from "@nozbe/watermelondb/decorators";
|
|
11426
|
-
var ConversationMemory = class extends Model3 {
|
|
11427
11410
|
};
|
|
11428
|
-
ConversationMemory.table = "conversation_memory";
|
|
11429
|
-
ConversationMemory.associations = {};
|
|
11430
|
-
__decorateClass([
|
|
11431
|
-
text3("conversation_id")
|
|
11432
|
-
], ConversationMemory.prototype, "conversationId", 2);
|
|
11433
|
-
__decorateClass([
|
|
11434
|
-
text3("memory_id")
|
|
11435
|
-
], ConversationMemory.prototype, "memoryId", 2);
|
|
11436
|
-
__decorateClass([
|
|
11437
|
-
field2("score")
|
|
11438
|
-
], ConversationMemory.prototype, "score", 2);
|
|
11439
|
-
__decorateClass([
|
|
11440
|
-
readonly,
|
|
11441
|
-
date2("created_at")
|
|
11442
|
-
], ConversationMemory.prototype, "createdAt", 2);
|
|
11443
11411
|
|
|
11444
11412
|
// src/lib/db/conversationMemory/operations.ts
|
|
11445
|
-
import { Q as
|
|
11413
|
+
import { Q as Q3 } from "@nozbe/watermelondb";
|
|
11446
11414
|
var MAX_PER_CONVERSATION = 200;
|
|
11447
11415
|
function conversationMemoryToStored(row) {
|
|
11448
11416
|
return {
|
|
@@ -11457,7 +11425,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
11457
11425
|
if (!conversationId || items.length === 0) return;
|
|
11458
11426
|
const now = Date.now();
|
|
11459
11427
|
await ctx.database.write(async () => {
|
|
11460
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
11428
|
+
const existing = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId), Q3.sortBy("created_at", Q3.asc)).fetch();
|
|
11461
11429
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
11462
11430
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
11463
11431
|
const deduped = [];
|
|
@@ -11494,7 +11462,7 @@ async function recordConversationMemoriesOp(ctx, conversationId, items, now = Da
|
|
|
11494
11462
|
if (!conversationId || turn.size === 0) return;
|
|
11495
11463
|
const kept = new Map([...turn].slice(-MAX_PER_CONVERSATION));
|
|
11496
11464
|
await ctx.database.write(async () => {
|
|
11497
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
11465
|
+
const existing = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId), Q3.sortBy("created_at", Q3.asc)).fetch();
|
|
11498
11466
|
const earlier = existing.filter((r) => !turn.has(r.memoryId));
|
|
11499
11467
|
const linked = new Set(existing.map((r) => r.memoryId));
|
|
11500
11468
|
await ctx.database.batch(
|
|
@@ -11519,13 +11487,13 @@ async function recordConversationMemoriesOp(ctx, conversationId, items, now = Da
|
|
|
11519
11487
|
}
|
|
11520
11488
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
11521
11489
|
if (!conversationId) return [];
|
|
11522
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
11490
|
+
const rows = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId), Q3.sortBy("created_at", Q3.asc)).fetch();
|
|
11523
11491
|
return rows.map(conversationMemoryToStored);
|
|
11524
11492
|
}
|
|
11525
11493
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
11526
11494
|
if (!conversationId) return;
|
|
11527
11495
|
await ctx.database.write(async () => {
|
|
11528
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
11496
|
+
const rows = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
11529
11497
|
if (rows.length === 0) return;
|
|
11530
11498
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
11531
11499
|
});
|
|
@@ -11540,15 +11508,37 @@ var maxChunks = 16;
|
|
|
11540
11508
|
var droppable = ["thoughtProcess", "thinking", "sources", "toolCallEvents"];
|
|
11541
11509
|
var messageMetadata = /* @__PURE__ */ new Set(["conversationId", "uniqueId", "vector", "chunks"]);
|
|
11542
11510
|
var alwaysStored = /* @__PURE__ */ new Set(["role", "content", "responseDuration"]);
|
|
11511
|
+
var maxBubbles = 3;
|
|
11512
|
+
var maxTurnIdBytes = 128;
|
|
11513
|
+
var maxBubbleBytes = 16384;
|
|
11514
|
+
var anumaOrigins = /* @__PURE__ */ new Set(["intro", "reply"]);
|
|
11543
11515
|
function plain(value) {
|
|
11544
11516
|
return JSON.parse(JSON.stringify(value ?? {}));
|
|
11545
11517
|
}
|
|
11546
|
-
function
|
|
11518
|
+
function text3(value) {
|
|
11547
11519
|
return typeof value === "string" ? value : void 0;
|
|
11548
11520
|
}
|
|
11549
11521
|
function number(value) {
|
|
11550
11522
|
return typeof value === "number" ? value : void 0;
|
|
11551
11523
|
}
|
|
11524
|
+
function readAnumaTurn(value) {
|
|
11525
|
+
if (!isObject(value)) return void 0;
|
|
11526
|
+
const { turnId, bubbles, origin } = value;
|
|
11527
|
+
if (typeof turnId !== "string" || turnId.length === 0 || new TextEncoder().encode(turnId).length > maxTurnIdBytes)
|
|
11528
|
+
return void 0;
|
|
11529
|
+
if (bubbles !== void 0 && (!Array.isArray(bubbles) || bubbles.length < 1 || bubbles.length > maxBubbles || !bubbles.every((b) => typeof b === "string") || bubbles.reduce((sum, b) => sum + new TextEncoder().encode(b).length, 0) > maxBubbleBytes))
|
|
11530
|
+
return void 0;
|
|
11531
|
+
if (origin !== void 0 && (typeof origin !== "string" || !anumaOrigins.has(origin)))
|
|
11532
|
+
return void 0;
|
|
11533
|
+
return {
|
|
11534
|
+
turnId,
|
|
11535
|
+
...bubbles !== void 0 ? { bubbles: [...bubbles] } : {},
|
|
11536
|
+
...origin !== void 0 ? { origin } : {}
|
|
11537
|
+
};
|
|
11538
|
+
}
|
|
11539
|
+
function isObject(value) {
|
|
11540
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11541
|
+
}
|
|
11552
11542
|
function conversationSortKey(data, createdAt) {
|
|
11553
11543
|
const pinnedAt = number(data.pinnedAt);
|
|
11554
11544
|
if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
|
|
@@ -11569,12 +11559,12 @@ function conversationContext(data) {
|
|
|
11569
11559
|
}
|
|
11570
11560
|
function toConversation(record2) {
|
|
11571
11561
|
const pinnedAt = number(record2.data.pinnedAt);
|
|
11572
|
-
const projectId =
|
|
11562
|
+
const projectId = text3(record2.data.projectId);
|
|
11573
11563
|
const context = conversationContext(record2.data);
|
|
11574
11564
|
return {
|
|
11575
11565
|
uniqueId: record2.id,
|
|
11576
11566
|
conversationId: record2.id,
|
|
11577
|
-
title:
|
|
11567
|
+
title: text3(record2.data.title) ?? "",
|
|
11578
11568
|
...projectId ? { projectId } : {},
|
|
11579
11569
|
createdAt: new Date(record2.createdAt),
|
|
11580
11570
|
updatedAt: new Date(record2.updatedAt),
|
|
@@ -11583,18 +11573,28 @@ function toConversation(record2) {
|
|
|
11583
11573
|
...context ? { context } : {}
|
|
11584
11574
|
};
|
|
11585
11575
|
}
|
|
11576
|
+
function anumaTurnData(value) {
|
|
11577
|
+
if (value === void 0) return void 0;
|
|
11578
|
+
const turn = readAnumaTurn(value);
|
|
11579
|
+
if (!turn) throw new ChatStoreError("Invalid Anuma turn", 0, "invalid_record");
|
|
11580
|
+
return turn;
|
|
11581
|
+
}
|
|
11586
11582
|
function messageData(options) {
|
|
11587
|
-
|
|
11588
|
-
|
|
11583
|
+
const anuma = anumaTurnData(options.anuma);
|
|
11584
|
+
return plain({
|
|
11585
|
+
...Object.fromEntries(
|
|
11589
11586
|
Object.entries(options).filter(
|
|
11590
|
-
([key3, value]) => !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
11587
|
+
([key3, value]) => key3 !== "anuma" && !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
11591
11588
|
)
|
|
11592
|
-
)
|
|
11593
|
-
|
|
11589
|
+
),
|
|
11590
|
+
...anuma ? { anuma } : {}
|
|
11591
|
+
});
|
|
11594
11592
|
}
|
|
11595
11593
|
function toMessage(record2) {
|
|
11596
|
-
const { chunkOffsets: _offsets, truncated: _truncated, ...fields } = record2.data;
|
|
11594
|
+
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record2.data;
|
|
11595
|
+
const anuma = readAnumaTurn(rawAnuma);
|
|
11597
11596
|
return {
|
|
11597
|
+
...anuma ? { anuma } : {},
|
|
11598
11598
|
...fields,
|
|
11599
11599
|
uniqueId: record2.id,
|
|
11600
11600
|
messageId: record2.sortKey,
|
|
@@ -11608,20 +11608,20 @@ function chunkOffsets(record2) {
|
|
|
11608
11608
|
return Array.isArray(offsets) ? offsets : void 0;
|
|
11609
11609
|
}
|
|
11610
11610
|
function toSkeletons(records) {
|
|
11611
|
-
const roleById = new Map(records.map((r) => [r.id,
|
|
11611
|
+
const roleById = new Map(records.map((r) => [r.id, text3(r.data.role)]));
|
|
11612
11612
|
return records.map((r) => {
|
|
11613
|
-
const parentMessageId =
|
|
11614
|
-
const model =
|
|
11613
|
+
const parentMessageId = text3(r.data.parentMessageId);
|
|
11614
|
+
const model = text3(r.data.model);
|
|
11615
11615
|
const artifact = r.data.role === "user" && !!parentMessageId && roleById.get(parentMessageId) === "user";
|
|
11616
11616
|
return {
|
|
11617
11617
|
uniqueId: r.id,
|
|
11618
11618
|
messageId: r.sortKey,
|
|
11619
11619
|
conversationId: r.conversationId,
|
|
11620
|
-
role:
|
|
11620
|
+
role: text3(r.data.role) ?? "",
|
|
11621
11621
|
createdAt: new Date(r.createdAt),
|
|
11622
11622
|
...parentMessageId ? { parentMessageId } : {},
|
|
11623
11623
|
...model ? { model } : {},
|
|
11624
|
-
...artifact ? { content:
|
|
11624
|
+
...artifact ? { content: text3(r.data.content) ?? "" } : {}
|
|
11625
11625
|
};
|
|
11626
11626
|
});
|
|
11627
11627
|
}
|
|
@@ -11629,8 +11629,8 @@ function toSummary(record2) {
|
|
|
11629
11629
|
return {
|
|
11630
11630
|
uniqueId: record2.id,
|
|
11631
11631
|
conversationId: record2.id,
|
|
11632
|
-
summary:
|
|
11633
|
-
summarizedUpTo:
|
|
11632
|
+
summary: text3(record2.data.summary) ?? "",
|
|
11633
|
+
summarizedUpTo: text3(record2.data.summarizedUpTo) ?? "",
|
|
11634
11634
|
tokenCount: number(record2.data.tokenCount) ?? 0,
|
|
11635
11635
|
createdAt: new Date(record2.createdAt),
|
|
11636
11636
|
updatedAt: new Date(record2.updatedAt)
|
|
@@ -11681,7 +11681,7 @@ function fitRecord(record2) {
|
|
|
11681
11681
|
delete data[field10];
|
|
11682
11682
|
truncated.push(field10);
|
|
11683
11683
|
}
|
|
11684
|
-
const content =
|
|
11684
|
+
const content = text3(data.content) ?? "";
|
|
11685
11685
|
const over = bytes({ ...record2, data }) - recordBudgetBytes;
|
|
11686
11686
|
if (over > 0) {
|
|
11687
11687
|
const encoded = new TextEncoder().encode(content);
|
|
@@ -11725,6 +11725,215 @@ function fitChunks(chunks3) {
|
|
|
11725
11725
|
return out;
|
|
11726
11726
|
}
|
|
11727
11727
|
|
|
11728
|
+
// src/lib/chatStore/anuma.ts
|
|
11729
|
+
var ANUMA_CONVERSATION_ID = "anuma-1on1";
|
|
11730
|
+
var maxAttempts = 3;
|
|
11731
|
+
function anumaTurnContent(bubbles) {
|
|
11732
|
+
return bubbles.join("\n\n");
|
|
11733
|
+
}
|
|
11734
|
+
function anumaLastReadSortKey(conversation) {
|
|
11735
|
+
const record2 = conversation && "record" in conversation ? conversation.record : conversation;
|
|
11736
|
+
const state = record2?.data.anuma;
|
|
11737
|
+
if (!isObject(state)) return 0;
|
|
11738
|
+
const sortKey = state.lastReadSortKey;
|
|
11739
|
+
return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
|
|
11740
|
+
}
|
|
11741
|
+
function conflict(error) {
|
|
11742
|
+
return error instanceof ChatStoreError && error.code === "version_conflict";
|
|
11743
|
+
}
|
|
11744
|
+
function live(snapshot) {
|
|
11745
|
+
if (snapshot?.record.isDeleted)
|
|
11746
|
+
throw new ChatStoreError("Anuma conversation was deleted", 409, "conversation_deleted");
|
|
11747
|
+
return snapshot;
|
|
11748
|
+
}
|
|
11749
|
+
async function ensureAnumaConversation(store, options = {}) {
|
|
11750
|
+
const existing = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
|
|
11751
|
+
if (existing) return existing;
|
|
11752
|
+
const at = (options.now ?? Date.now)();
|
|
11753
|
+
const data = plain({ title: "Anuma", lastActivityAt: at, anuma: { lastReadSortKey: 0 } });
|
|
11754
|
+
try {
|
|
11755
|
+
const [created] = await store.putMany(
|
|
11756
|
+
[
|
|
11757
|
+
{
|
|
11758
|
+
expectedVersion: 0,
|
|
11759
|
+
record: {
|
|
11760
|
+
kind: "conversation",
|
|
11761
|
+
id: ANUMA_CONVERSATION_ID,
|
|
11762
|
+
conversationId: "",
|
|
11763
|
+
sortKey: conversationSortKey(data, at),
|
|
11764
|
+
createdAt: at,
|
|
11765
|
+
updatedAt: at,
|
|
11766
|
+
isDeleted: false,
|
|
11767
|
+
data
|
|
11768
|
+
}
|
|
11769
|
+
}
|
|
11770
|
+
],
|
|
11771
|
+
options.signal
|
|
11772
|
+
);
|
|
11773
|
+
return created;
|
|
11774
|
+
} catch (error) {
|
|
11775
|
+
if (!conflict(error)) throw error;
|
|
11776
|
+
const winner = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
|
|
11777
|
+
if (!winner) throw error;
|
|
11778
|
+
return winner;
|
|
11779
|
+
}
|
|
11780
|
+
}
|
|
11781
|
+
async function markAnumaRead(store, sortKey, options = {}) {
|
|
11782
|
+
if (!Number.isSafeInteger(sortKey) || sortKey < 0)
|
|
11783
|
+
throw new ChatStoreError("Invalid Anuma read marker", 0, "invalid_record");
|
|
11784
|
+
const now = options.now ?? Date.now;
|
|
11785
|
+
for (let attempt = 1; ; attempt++) {
|
|
11786
|
+
const current = await ensureAnumaConversation(store, options);
|
|
11787
|
+
const read = anumaLastReadSortKey(current);
|
|
11788
|
+
if (sortKey <= read) return current;
|
|
11789
|
+
const record2 = current.record;
|
|
11790
|
+
const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
|
|
11791
|
+
const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
|
|
11792
|
+
try {
|
|
11793
|
+
const [written] = await store.putMany(
|
|
11794
|
+
[
|
|
11795
|
+
{
|
|
11796
|
+
expectedVersion: current.version,
|
|
11797
|
+
record: {
|
|
11798
|
+
...record2,
|
|
11799
|
+
data,
|
|
11800
|
+
sortKey: conversationSortKey(data, record2.createdAt),
|
|
11801
|
+
updatedAt: Math.max(record2.updatedAt, now())
|
|
11802
|
+
}
|
|
11803
|
+
}
|
|
11804
|
+
],
|
|
11805
|
+
options.signal
|
|
11806
|
+
);
|
|
11807
|
+
return written;
|
|
11808
|
+
} catch (error) {
|
|
11809
|
+
if (!conflict(error) || attempt >= maxAttempts) throw error;
|
|
11810
|
+
}
|
|
11811
|
+
}
|
|
11812
|
+
}
|
|
11813
|
+
function countUnreadAnumaTurns(messages, lastReadSortKey) {
|
|
11814
|
+
const answered = Math.max(
|
|
11815
|
+
0,
|
|
11816
|
+
...messages.filter((m) => m.role === "user").map((m) => m.messageId)
|
|
11817
|
+
);
|
|
11818
|
+
const floor = Math.max(lastReadSortKey, answered);
|
|
11819
|
+
const turns = /* @__PURE__ */ new Set();
|
|
11820
|
+
for (const m of messages) {
|
|
11821
|
+
if (m.role !== "assistant" || m.messageId <= floor) continue;
|
|
11822
|
+
turns.add(m.anuma?.turnId ? `turn:${m.anuma.turnId}` : `message:${m.uniqueId}`);
|
|
11823
|
+
}
|
|
11824
|
+
return turns.size;
|
|
11825
|
+
}
|
|
11826
|
+
|
|
11827
|
+
// src/lib/db/chat/summaryOperations.ts
|
|
11828
|
+
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
11829
|
+
function createSummaryContext(database, encryption = {}) {
|
|
11830
|
+
return {
|
|
11831
|
+
...encryption,
|
|
11832
|
+
database,
|
|
11833
|
+
summariesCollection: database.get("conversation_summaries")
|
|
11834
|
+
};
|
|
11835
|
+
}
|
|
11836
|
+
function modelToStored(record2, summary) {
|
|
11837
|
+
return {
|
|
11838
|
+
uniqueId: record2.id,
|
|
11839
|
+
conversationId: record2.conversationId,
|
|
11840
|
+
summary,
|
|
11841
|
+
summarizedUpTo: record2.summarizedUpTo,
|
|
11842
|
+
tokenCount: record2.tokenCount,
|
|
11843
|
+
createdAt: record2.createdAt,
|
|
11844
|
+
updatedAt: record2.updatedAt
|
|
11845
|
+
};
|
|
11846
|
+
}
|
|
11847
|
+
async function getConversationSummaryOp(ctx, conversationId) {
|
|
11848
|
+
const results = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11849
|
+
if (results.length === 0) return null;
|
|
11850
|
+
const record2 = results[0];
|
|
11851
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
11852
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
11853
|
+
if (ctx.signMessage) {
|
|
11854
|
+
try {
|
|
11855
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
11856
|
+
} catch (error) {
|
|
11857
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
11858
|
+
}
|
|
11859
|
+
}
|
|
11860
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
11861
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
11862
|
+
try {
|
|
11863
|
+
const encryptedSummary = await encryptField(
|
|
11864
|
+
stored2.summary,
|
|
11865
|
+
ctx.walletAddress,
|
|
11866
|
+
ctx.signMessage,
|
|
11867
|
+
ctx.embeddedWalletSigner
|
|
11868
|
+
);
|
|
11869
|
+
await ctx.database.write(async () => {
|
|
11870
|
+
const current = await ctx.summariesCollection.query(Q4.where("id", record2.id)).fetch();
|
|
11871
|
+
if (current[0]?.summary === stored2.summary) {
|
|
11872
|
+
await current[0].update((rec) => {
|
|
11873
|
+
rec.summary = encryptedSummary;
|
|
11874
|
+
});
|
|
11875
|
+
}
|
|
11876
|
+
});
|
|
11877
|
+
} catch (error) {
|
|
11878
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
11879
|
+
}
|
|
11880
|
+
}
|
|
11881
|
+
return stored2;
|
|
11882
|
+
}
|
|
11883
|
+
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
11884
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
11885
|
+
let record2;
|
|
11886
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
11887
|
+
await ctx.database.write(async () => {
|
|
11888
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
11889
|
+
const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11890
|
+
if (existing.length > 0) {
|
|
11891
|
+
record2 = await existing[0].update((rec) => {
|
|
11892
|
+
rec.summary = encryptedSummary;
|
|
11893
|
+
rec.summarizedUpTo = summarizedUpTo;
|
|
11894
|
+
rec.tokenCount = tokenCount;
|
|
11895
|
+
});
|
|
11896
|
+
} else {
|
|
11897
|
+
record2 = await ctx.summariesCollection.create((rec) => {
|
|
11898
|
+
rec.conversationId = conversationId;
|
|
11899
|
+
rec.summary = encryptedSummary;
|
|
11900
|
+
rec.summarizedUpTo = summarizedUpTo;
|
|
11901
|
+
rec.tokenCount = tokenCount;
|
|
11902
|
+
});
|
|
11903
|
+
}
|
|
11904
|
+
});
|
|
11905
|
+
return modelToStored(record2, summary);
|
|
11906
|
+
}
|
|
11907
|
+
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
11908
|
+
await ctx.database.write(async () => {
|
|
11909
|
+
const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
|
|
11910
|
+
for (const record2 of existing) {
|
|
11911
|
+
await record2.destroyPermanently();
|
|
11912
|
+
}
|
|
11913
|
+
});
|
|
11914
|
+
}
|
|
11915
|
+
|
|
11916
|
+
// src/lib/db/conversationMemory/models.ts
|
|
11917
|
+
import { Model as Model3 } from "@nozbe/watermelondb";
|
|
11918
|
+
import { date as date2, field as field2, readonly, text as text4 } from "@nozbe/watermelondb/decorators";
|
|
11919
|
+
var ConversationMemory = class extends Model3 {
|
|
11920
|
+
};
|
|
11921
|
+
ConversationMemory.table = "conversation_memory";
|
|
11922
|
+
ConversationMemory.associations = {};
|
|
11923
|
+
__decorateClass([
|
|
11924
|
+
text4("conversation_id")
|
|
11925
|
+
], ConversationMemory.prototype, "conversationId", 2);
|
|
11926
|
+
__decorateClass([
|
|
11927
|
+
text4("memory_id")
|
|
11928
|
+
], ConversationMemory.prototype, "memoryId", 2);
|
|
11929
|
+
__decorateClass([
|
|
11930
|
+
field2("score")
|
|
11931
|
+
], ConversationMemory.prototype, "score", 2);
|
|
11932
|
+
__decorateClass([
|
|
11933
|
+
readonly,
|
|
11934
|
+
date2("created_at")
|
|
11935
|
+
], ConversationMemory.prototype, "createdAt", 2);
|
|
11936
|
+
|
|
11728
11937
|
// src/lib/chatStore/chatImports.ts
|
|
11729
11938
|
var importBatch = 100;
|
|
11730
11939
|
var importChunks = 200;
|
|
@@ -11816,17 +12025,6 @@ function batches(records) {
|
|
|
11816
12025
|
return out;
|
|
11817
12026
|
}
|
|
11818
12027
|
|
|
11819
|
-
// src/lib/chatStore/types.ts
|
|
11820
|
-
var ChatStoreError = class extends Error {
|
|
11821
|
-
constructor(message, status, code, retryAfterMs) {
|
|
11822
|
-
super(message);
|
|
11823
|
-
this.status = status;
|
|
11824
|
-
this.code = code;
|
|
11825
|
-
this.retryAfterMs = retryAfterMs;
|
|
11826
|
-
this.name = "ChatStoreError";
|
|
11827
|
-
}
|
|
11828
|
-
};
|
|
11829
|
-
|
|
11830
12028
|
// src/lib/chatStore/remote.ts
|
|
11831
12029
|
var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links", "setting"]);
|
|
11832
12030
|
var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
|
|
@@ -12551,10 +12749,10 @@ async function deletedSinceUpload(store, journal, local, signal) {
|
|
|
12551
12749
|
const present = /* @__PURE__ */ new Set([...local.records.map((r) => key(r.record)), ...local.skipped.keys()]);
|
|
12552
12750
|
const gone = [...journal.keys].filter((k) => !present.has(k));
|
|
12553
12751
|
if (gone.length === 0) return [];
|
|
12554
|
-
const
|
|
12555
|
-
const tombstoning = new Set(
|
|
12752
|
+
const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
|
|
12753
|
+
const tombstoning = new Set(live2.map((s) => key(s.record)));
|
|
12556
12754
|
await journal.drop(gone.filter((k) => !tombstoning.has(k)));
|
|
12557
|
-
return
|
|
12755
|
+
return live2.map(({ record: record2, version }) => {
|
|
12558
12756
|
const empty = emptied[record2.kind];
|
|
12559
12757
|
return {
|
|
12560
12758
|
record: {
|
|
@@ -13214,12 +13412,13 @@ var resumableFields = [
|
|
|
13214
13412
|
"error",
|
|
13215
13413
|
"thoughtProcess",
|
|
13216
13414
|
"thinking",
|
|
13217
|
-
"toolCallEvents"
|
|
13415
|
+
"toolCallEvents",
|
|
13416
|
+
"anuma"
|
|
13218
13417
|
];
|
|
13219
13418
|
function resumedFields(options) {
|
|
13220
13419
|
return plain(
|
|
13221
13420
|
Object.fromEntries(
|
|
13222
|
-
resumableFields.filter((f) => options[f] !== void 0).map((f) => [f, options[f]])
|
|
13421
|
+
resumableFields.filter((f) => options[f] !== void 0).map((f) => [f, f === "anuma" ? anumaTurnData(options.anuma) : options[f]])
|
|
13223
13422
|
)
|
|
13224
13423
|
);
|
|
13225
13424
|
}
|
|
@@ -13873,7 +14072,7 @@ function createVaultChatBackend(options) {
|
|
|
13873
14072
|
},
|
|
13874
14073
|
async getConversations(query) {
|
|
13875
14074
|
await available2();
|
|
13876
|
-
return all("conversation").map(toConversation).filter(
|
|
14075
|
+
return all("conversation").filter((record2) => record2.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
|
|
13877
14076
|
(c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
|
|
13878
14077
|
).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
13879
14078
|
},
|
|
@@ -13916,6 +14115,7 @@ function createVaultChatBackend(options) {
|
|
|
13916
14115
|
return !!record2 && !record2.isDeleted;
|
|
13917
14116
|
},
|
|
13918
14117
|
async deleteConversation(conversationId) {
|
|
14118
|
+
if (conversationId === ANUMA_CONVERSATION_ID) return false;
|
|
13919
14119
|
const record2 = await conversation(conversationId);
|
|
13920
14120
|
if (!record2 || record2.isDeleted) return false;
|
|
13921
14121
|
for (const [k, patch] of pending)
|
|
@@ -17986,7 +18186,7 @@ async function countActiveVaultMemoriesOp(ctx) {
|
|
|
17986
18186
|
return ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx)).fetchCount();
|
|
17987
18187
|
}
|
|
17988
18188
|
async function getVaultMemoryCountsOp(ctx) {
|
|
17989
|
-
const [
|
|
18189
|
+
const [live2, archived, quarantined] = await Promise.all([
|
|
17990
18190
|
countActiveVaultMemoriesOp(ctx),
|
|
17991
18191
|
ctx.vaultMemoryCollection.query(
|
|
17992
18192
|
...baseVaultConditions(ctx, { includeArchived: true }),
|
|
@@ -17997,7 +18197,7 @@ async function getVaultMemoryCountsOp(ctx) {
|
|
|
17997
18197
|
Q9.where("trust_tier", "quarantined")
|
|
17998
18198
|
).fetchCount()
|
|
17999
18199
|
]);
|
|
18000
|
-
return { live, archived, quarantined };
|
|
18200
|
+
return { live: live2, archived, quarantined };
|
|
18001
18201
|
}
|
|
18002
18202
|
async function getActiveVaultMemoryIdsOp(ctx, ids) {
|
|
18003
18203
|
if (ids.length === 0) return /* @__PURE__ */ new Set();
|
|
@@ -19369,12 +19569,12 @@ var WalletPoller = class {
|
|
|
19369
19569
|
* @param maxAttempts - Maximum polling attempts before giving up (default: 60)
|
|
19370
19570
|
* @returns Stop function to cancel polling
|
|
19371
19571
|
*/
|
|
19372
|
-
startPolling(checkWallet, onWalletReady, intervalMs = DEFAULT_INTERVAL_MS,
|
|
19572
|
+
startPolling(checkWallet, onWalletReady, intervalMs = DEFAULT_INTERVAL_MS, maxAttempts2 = DEFAULT_MAX_ATTEMPTS) {
|
|
19373
19573
|
this.stop();
|
|
19374
19574
|
this.attempts = 0;
|
|
19375
19575
|
const poll = async () => {
|
|
19376
19576
|
this.attempts++;
|
|
19377
|
-
if (this.attempts >
|
|
19577
|
+
if (this.attempts > maxAttempts2) {
|
|
19378
19578
|
this.stop();
|
|
19379
19579
|
return;
|
|
19380
19580
|
}
|
|
@@ -27141,13 +27341,13 @@ function createRemoteMemoryStore(options) {
|
|
|
27141
27341
|
});
|
|
27142
27342
|
return run;
|
|
27143
27343
|
};
|
|
27144
|
-
const
|
|
27344
|
+
const live2 = async (id2) => {
|
|
27145
27345
|
const record2 = await persistence.get(id2);
|
|
27146
27346
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
27147
27347
|
};
|
|
27148
27348
|
const mutateLocked = async (id2, change, edit, writeOptions) => {
|
|
27149
27349
|
writeOptions?.signal?.throwIfAborted();
|
|
27150
|
-
const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await
|
|
27350
|
+
const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
|
|
27151
27351
|
if (!record2) return null;
|
|
27152
27352
|
if (record2.memory.is_deleted) return null;
|
|
27153
27353
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
@@ -27945,7 +28145,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27945
28145
|
}, clear);
|
|
27946
28146
|
return snapshot.then((topics) => structuredClone(topics));
|
|
27947
28147
|
},
|
|
27948
|
-
get: async (id2) => asStored(await
|
|
28148
|
+
get: async (id2) => asStored(await live2(id2)),
|
|
27949
28149
|
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
27950
28150
|
(record2) => stored(record2.memory)
|
|
27951
28151
|
),
|
|
@@ -28030,7 +28230,7 @@ function createRemoteMemoryStore(options) {
|
|
|
28030
28230
|
return serialized(
|
|
28031
28231
|
first,
|
|
28032
28232
|
() => serialized(second, async () => {
|
|
28033
|
-
const [old, next] = await Promise.all([
|
|
28233
|
+
const [old, next] = await Promise.all([live2(id2), live2(supersededById)]);
|
|
28034
28234
|
if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
|
|
28035
28235
|
if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
|
|
28036
28236
|
const saved = await persistence.putMany([
|
|
@@ -28051,7 +28251,7 @@ function createRemoteMemoryStore(options) {
|
|
|
28051
28251
|
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
28052
28252
|
),
|
|
28053
28253
|
restore: (id2) => serialized(id2, async () => {
|
|
28054
|
-
const record2 = await
|
|
28254
|
+
const record2 = await live2(id2);
|
|
28055
28255
|
if (!record2) return false;
|
|
28056
28256
|
if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
|
|
28057
28257
|
return true;
|
|
@@ -38100,82 +38300,45 @@ function useChatStorage(options) {
|
|
|
38100
38300
|
await inbox.putPublicKey(publicKey);
|
|
38101
38301
|
registeredInboxKeyRef.current = { inbox, publicKey };
|
|
38102
38302
|
}
|
|
38103
|
-
|
|
38104
|
-
|
|
38105
|
-
|
|
38106
|
-
|
|
38107
|
-
|
|
38108
|
-
|
|
38109
|
-
|
|
38110
|
-
|
|
38111
|
-
|
|
38112
|
-
|
|
38113
|
-
|
|
38114
|
-
|
|
38303
|
+
return deliverInboxAnswers({
|
|
38304
|
+
inbox,
|
|
38305
|
+
keyPair,
|
|
38306
|
+
backend,
|
|
38307
|
+
store: async (opened, messageId) => {
|
|
38308
|
+
const { redactor } = resolveCallPii(
|
|
38309
|
+
void 0,
|
|
38310
|
+
piiRedaction,
|
|
38311
|
+
() => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
|
|
38312
|
+
);
|
|
38313
|
+
const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
|
|
38314
|
+
const { fields, fileIds } = await toAssistantMessageFields(
|
|
38315
|
+
opened.response,
|
|
38316
|
+
opened.conversation_id,
|
|
38317
|
+
knownToolCallEventIds
|
|
38318
|
+
);
|
|
38319
|
+
const upserted = await backend.upsertMessage({
|
|
38320
|
+
...fields,
|
|
38321
|
+
content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
|
|
38322
|
+
thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
|
|
38323
|
+
conversationId: opened.conversation_id,
|
|
38324
|
+
role: "assistant",
|
|
38325
|
+
model: opened.model,
|
|
38326
|
+
parentMessageId: opened.parent_message_id ?? void 0,
|
|
38327
|
+
wasStopped: opened.status === "tool_request",
|
|
38328
|
+
uniqueId: messageId
|
|
38115
38329
|
});
|
|
38116
|
-
|
|
38117
|
-
|
|
38118
|
-
|
|
38119
|
-
|
|
38120
|
-
|
|
38121
|
-
|
|
38122
|
-
if (!existing) {
|
|
38123
|
-
const parent = opened.parent_message_id;
|
|
38124
|
-
const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
|
|
38125
|
-
if (!ownsTurn) {
|
|
38126
|
-
results.push({ ...base, status: "elsewhere", assistantMessage: null });
|
|
38127
|
-
continue;
|
|
38128
|
-
}
|
|
38129
|
-
}
|
|
38130
|
-
let stored2 = existing;
|
|
38131
|
-
if (!stored2) {
|
|
38132
|
-
const { redactor } = resolveCallPii(
|
|
38133
|
-
void 0,
|
|
38134
|
-
piiRedaction,
|
|
38135
|
-
() => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
|
|
38136
|
-
);
|
|
38137
|
-
const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
|
|
38138
|
-
const { fields, fileIds } = await toAssistantMessageFields(
|
|
38139
|
-
opened.response,
|
|
38140
|
-
opened.conversation_id,
|
|
38141
|
-
knownToolCallEventIds
|
|
38142
|
-
);
|
|
38143
|
-
stored2 = await backend.createMessage({
|
|
38144
|
-
...fields,
|
|
38145
|
-
content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
|
|
38146
|
-
thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
|
|
38147
|
-
conversationId: opened.conversation_id,
|
|
38148
|
-
role: "assistant",
|
|
38149
|
-
model: opened.model,
|
|
38150
|
-
parentMessageId: opened.parent_message_id ?? void 0,
|
|
38151
|
-
wasStopped: opened.status === "tool_request" ? true : void 0,
|
|
38152
|
-
uniqueId: messageId
|
|
38153
|
-
});
|
|
38154
|
-
if (fileIds.length > 0) {
|
|
38155
|
-
try {
|
|
38156
|
-
await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
|
|
38157
|
-
} catch (err) {
|
|
38158
|
-
getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
|
|
38159
|
-
}
|
|
38330
|
+
const stored2 = await clearTurnErrors(backend, upserted);
|
|
38331
|
+
if (fileIds.length > 0) {
|
|
38332
|
+
try {
|
|
38333
|
+
await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
|
|
38334
|
+
} catch (err) {
|
|
38335
|
+
getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
|
|
38160
38336
|
}
|
|
38161
|
-
void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
|
|
38162
38337
|
}
|
|
38163
|
-
|
|
38164
|
-
|
|
38165
|
-
...base,
|
|
38166
|
-
status: existing ? "delivered" : "stored",
|
|
38167
|
-
assistantMessage: stored2
|
|
38168
|
-
});
|
|
38169
|
-
} catch (err) {
|
|
38170
|
-
results.push({
|
|
38171
|
-
...base,
|
|
38172
|
-
status: "retry",
|
|
38173
|
-
assistantMessage: null,
|
|
38174
|
-
error: err instanceof Error ? err.message : String(err)
|
|
38175
|
-
});
|
|
38338
|
+
void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
|
|
38339
|
+
return stored2;
|
|
38176
38340
|
}
|
|
38177
|
-
}
|
|
38178
|
-
return results;
|
|
38341
|
+
});
|
|
38179
38342
|
}, [
|
|
38180
38343
|
inbox,
|
|
38181
38344
|
walletAddress,
|
|
@@ -39661,11 +39824,11 @@ function usePhoneCalls(options = {}) {
|
|
|
39661
39824
|
pollRunIdRef.current = runId;
|
|
39662
39825
|
setIsPolling(true);
|
|
39663
39826
|
const intervalMs = pollOptions.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
39664
|
-
const
|
|
39827
|
+
const maxAttempts2 = pollOptions.maxAttempts ?? DEFAULT_POLL_MAX_ATTEMPTS;
|
|
39665
39828
|
const stopWhenCompleted = pollOptions.stopWhenCompleted ?? true;
|
|
39666
39829
|
let latestCall = null;
|
|
39667
39830
|
try {
|
|
39668
|
-
for (let attempt = 0; attempt <
|
|
39831
|
+
for (let attempt = 0; attempt < maxAttempts2; attempt += 1) {
|
|
39669
39832
|
if (pollRunIdRef.current !== runId) {
|
|
39670
39833
|
break;
|
|
39671
39834
|
}
|
|
@@ -39695,7 +39858,7 @@ function usePhoneCalls(options = {}) {
|
|
|
39695
39858
|
break;
|
|
39696
39859
|
}
|
|
39697
39860
|
}
|
|
39698
|
-
if (attempt <
|
|
39861
|
+
if (attempt < maxAttempts2 - 1) {
|
|
39699
39862
|
await wait2(intervalMs);
|
|
39700
39863
|
}
|
|
39701
39864
|
}
|
|
@@ -41213,6 +41376,7 @@ function useWalletBinding(options = {}) {
|
|
|
41213
41376
|
};
|
|
41214
41377
|
}
|
|
41215
41378
|
export {
|
|
41379
|
+
ANUMA_CONVERSATION_ID,
|
|
41216
41380
|
Anuma,
|
|
41217
41381
|
AnumaJsxError,
|
|
41218
41382
|
AnumaShadowIsolationProvider,
|
|
@@ -41317,6 +41481,8 @@ export {
|
|
|
41317
41481
|
WordProcessor,
|
|
41318
41482
|
ZipProcessor,
|
|
41319
41483
|
addConversationMemoriesOp,
|
|
41484
|
+
anumaLastReadSortKey,
|
|
41485
|
+
anumaTurnContent,
|
|
41320
41486
|
appFileToStored,
|
|
41321
41487
|
archiveVaultMemoryOp,
|
|
41322
41488
|
assembleMemoryContext,
|
|
@@ -41356,6 +41522,7 @@ export {
|
|
|
41356
41522
|
consoleLogger,
|
|
41357
41523
|
conversationMemoryToStored,
|
|
41358
41524
|
cosineInt8,
|
|
41525
|
+
countUnreadAnumaTurns,
|
|
41359
41526
|
createAutoExtractor,
|
|
41360
41527
|
createChunkVectorCache,
|
|
41361
41528
|
createCryptoPricePreProcessor,
|
|
@@ -41425,6 +41592,7 @@ export {
|
|
|
41425
41592
|
encryptDataBytes,
|
|
41426
41593
|
encryptDataWithKey,
|
|
41427
41594
|
encryptToolCallEventsOp,
|
|
41595
|
+
ensureAnumaConversation,
|
|
41428
41596
|
ensureDefaultFoldersOp,
|
|
41429
41597
|
expandToolSetsAdditive,
|
|
41430
41598
|
exportElementToPdf,
|
|
@@ -41535,6 +41703,7 @@ export {
|
|
|
41535
41703
|
listActiveStreams,
|
|
41536
41704
|
loadSettings,
|
|
41537
41705
|
localChatBackend,
|
|
41706
|
+
markAnumaRead,
|
|
41538
41707
|
maskScopedEmbeddingCache,
|
|
41539
41708
|
maxVaultAttachmentBytes,
|
|
41540
41709
|
mediaToStored,
|
|
@@ -41560,6 +41729,7 @@ export {
|
|
|
41560
41729
|
quantizeEmbedding,
|
|
41561
41730
|
queueManager,
|
|
41562
41731
|
rankProfileCandidates,
|
|
41732
|
+
readAnumaTurn,
|
|
41563
41733
|
readEncryptedFile,
|
|
41564
41734
|
recall,
|
|
41565
41735
|
reencryptMemoryField,
|