@anuma/sdk 10.7.0 → 10.9.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 +336 -167
- package/dist/expo/index.d.mts +193 -151
- package/dist/expo/index.d.ts +193 -151
- package/dist/expo/index.mjs +321 -159
- package/dist/index.cjs +165 -16
- package/dist/index.d.mts +377 -151
- package/dist/index.d.ts +377 -151
- package/dist/index.mjs +158 -16
- package/dist/react/index.cjs +339 -170
- package/dist/react/index.d.mts +193 -151
- package/dist/react/index.d.ts +193 -151
- package/dist/react/index.mjs +324 -162
- package/dist/server/index.d.mts +20 -0
- package/dist/server/index.d.ts +20 -0
- package/package.json +2 -2
package/dist/expo/index.cjs
CHANGED
|
@@ -880,17 +880,17 @@ async function callPortalJsonCompletion(req) {
|
|
|
880
880
|
if (autoUpgraded) endpoint = endpointForTransport(endpoint, transport);
|
|
881
881
|
assertTransportMatchesEndpoint(transport, endpoint);
|
|
882
882
|
}
|
|
883
|
-
const
|
|
883
|
+
const maxAttempts2 = Math.max(1, req.maxAttempts ?? 3);
|
|
884
884
|
const startedAt = Date.now();
|
|
885
885
|
const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
|
|
886
886
|
const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
|
|
887
887
|
let lastFailure;
|
|
888
888
|
let reinforce = false;
|
|
889
889
|
const giveUp = () => {
|
|
890
|
-
req.onFailure?.(lastFailure ?? { reason: "network", attempts:
|
|
890
|
+
req.onFailure?.(lastFailure ?? { reason: "network", attempts: maxAttempts2 });
|
|
891
891
|
return null;
|
|
892
892
|
};
|
|
893
|
-
for (let attempt = 1; attempt <=
|
|
893
|
+
for (let attempt = 1; attempt <= maxAttempts2; attempt++) {
|
|
894
894
|
if (attempt > 1 && overBudget()) {
|
|
895
895
|
log.warn(`[${req.tag}] over time budget before attempt ${attempt}, giving up`);
|
|
896
896
|
lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
|
|
@@ -922,20 +922,20 @@ async function callPortalJsonCompletion(req) {
|
|
|
922
922
|
log.warn(`[${req.tag}] ${outcome2.reason}`);
|
|
923
923
|
return giveUp();
|
|
924
924
|
}
|
|
925
|
-
if (attempt >=
|
|
926
|
-
log.warn(`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${
|
|
925
|
+
if (attempt >= maxAttempts2) {
|
|
926
|
+
log.warn(`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${maxAttempts2}, giving up`);
|
|
927
927
|
break;
|
|
928
928
|
}
|
|
929
929
|
const backoff = (req.backoffMs ?? defaultBackoffMs)(attempt);
|
|
930
930
|
const delay = Math.max(backoff, outcome2.retryAfterMs ?? 0);
|
|
931
931
|
if (overBudget() || req.totalTimeoutMs !== void 0 && Date.now() - startedAt + delay >= req.totalTimeoutMs) {
|
|
932
932
|
log.warn(
|
|
933
|
-
`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${
|
|
933
|
+
`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${maxAttempts2}, over time budget, giving up`
|
|
934
934
|
);
|
|
935
935
|
lastFailure = { reason: "time-budget-exhausted", attempts: attempt };
|
|
936
936
|
break;
|
|
937
937
|
}
|
|
938
|
-
log.warn(`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${
|
|
938
|
+
log.warn(`[${req.tag}] ${outcome2.reason} \u2014 attempt ${attempt}/${maxAttempts2}, retrying`);
|
|
939
939
|
if (delay > 0) await sleep2(delay);
|
|
940
940
|
}
|
|
941
941
|
return giveUp();
|
|
@@ -1419,6 +1419,7 @@ CARRY FORWARD UNCHANGED DETAILS (every "update" and "supersede"): a memory can h
|
|
|
1419
1419
|
// src/expo/index.ts
|
|
1420
1420
|
var index_exports = {};
|
|
1421
1421
|
__export(index_exports, {
|
|
1422
|
+
ANUMA_CONVERSATION_ID: () => ANUMA_CONVERSATION_ID,
|
|
1422
1423
|
CHUNKS_DISCARDED_ORIGIN: () => CHUNKS_DISCARDED_ORIGIN,
|
|
1423
1424
|
ChatConversation: () => Conversation,
|
|
1424
1425
|
ChatMessage: () => Message,
|
|
@@ -1478,6 +1479,8 @@ __export(index_exports, {
|
|
|
1478
1479
|
WALLET_PAYMENT_TOOL_NAME: () => WALLET_PAYMENT_TOOL_NAME,
|
|
1479
1480
|
WalletPoller: () => WalletPoller,
|
|
1480
1481
|
addConversationMemoriesOp: () => addConversationMemoriesOp,
|
|
1482
|
+
anumaLastReadSortKey: () => anumaLastReadSortKey,
|
|
1483
|
+
anumaTurnContent: () => anumaTurnContent,
|
|
1481
1484
|
archiveVaultMemoryOp: () => archiveVaultMemoryOp,
|
|
1482
1485
|
assembleMemoryContext: () => assembleMemoryContext,
|
|
1483
1486
|
attachFileContextToLastUserMessage: () => attachFileContextToLastUserMessage,
|
|
@@ -1511,6 +1514,7 @@ __export(index_exports, {
|
|
|
1511
1514
|
consoleLogger: () => consoleLogger,
|
|
1512
1515
|
conversationMemoryToStored: () => conversationMemoryToStored,
|
|
1513
1516
|
cosineInt8: () => cosineInt8,
|
|
1517
|
+
countUnreadAnumaTurns: () => countUnreadAnumaTurns,
|
|
1514
1518
|
createAutoExtractor: () => createAutoExtractor,
|
|
1515
1519
|
createChunkVectorCache: () => createChunkVectorCache,
|
|
1516
1520
|
createCryptoPricePreProcessor: () => createCryptoPricePreProcessor,
|
|
@@ -1559,6 +1563,7 @@ __export(index_exports, {
|
|
|
1559
1563
|
embedMessage: () => embedMessage,
|
|
1560
1564
|
encodeChunkVector: () => encodeChunkVector,
|
|
1561
1565
|
encryptToolCallEventsOp: () => encryptToolCallEventsOp,
|
|
1566
|
+
ensureAnumaConversation: () => ensureAnumaConversation,
|
|
1562
1567
|
ensureDefaultFoldersOp: () => ensureDefaultFoldersOp,
|
|
1563
1568
|
exchangeNotionCode: () => exchangeNotionCode,
|
|
1564
1569
|
extractAndLinkEntitiesForMemoriesOp: () => extractAndLinkEntitiesForMemoriesOp,
|
|
@@ -1599,6 +1604,7 @@ __export(index_exports, {
|
|
|
1599
1604
|
isRerankerAvailable: () => isRerankerAvailable,
|
|
1600
1605
|
loadSettings: () => loadSettings,
|
|
1601
1606
|
localChatBackend: () => localChatBackend,
|
|
1607
|
+
markAnumaRead: () => markAnumaRead,
|
|
1602
1608
|
maskScopedEmbeddingCache: () => maskScopedEmbeddingCache,
|
|
1603
1609
|
maxVaultAttachmentBytes: () => maxVaultAttachmentBytes,
|
|
1604
1610
|
memoryCipher: () => memoryCipher,
|
|
@@ -1614,6 +1620,7 @@ __export(index_exports, {
|
|
|
1614
1620
|
quantizeEmbedding: () => quantizeEmbedding,
|
|
1615
1621
|
queueManager: () => queueManager,
|
|
1616
1622
|
rankProfileCandidates: () => rankProfileCandidates,
|
|
1623
|
+
readAnumaTurn: () => readAnumaTurn,
|
|
1617
1624
|
recall: () => recall,
|
|
1618
1625
|
reencryptMemoryField: () => reencryptMemoryField,
|
|
1619
1626
|
reflect: () => reflect,
|
|
@@ -11591,119 +11598,19 @@ var xhrTransport = (options) => {
|
|
|
11591
11598
|
return { stream: createStream() };
|
|
11592
11599
|
};
|
|
11593
11600
|
|
|
11594
|
-
// src/lib/
|
|
11595
|
-
var
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
};
|
|
11603
|
-
}
|
|
11604
|
-
function modelToStored(record2, summary) {
|
|
11605
|
-
return {
|
|
11606
|
-
uniqueId: record2.id,
|
|
11607
|
-
conversationId: record2.conversationId,
|
|
11608
|
-
summary,
|
|
11609
|
-
summarizedUpTo: record2.summarizedUpTo,
|
|
11610
|
-
tokenCount: record2.tokenCount,
|
|
11611
|
-
createdAt: record2.createdAt,
|
|
11612
|
-
updatedAt: record2.updatedAt
|
|
11613
|
-
};
|
|
11614
|
-
}
|
|
11615
|
-
async function getConversationSummaryOp(ctx, conversationId) {
|
|
11616
|
-
const results = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11617
|
-
if (results.length === 0) return null;
|
|
11618
|
-
const record2 = results[0];
|
|
11619
|
-
const stored2 = modelToStored(record2, record2.summary);
|
|
11620
|
-
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
11621
|
-
if (ctx.signMessage) {
|
|
11622
|
-
try {
|
|
11623
|
-
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
11624
|
-
} catch (error) {
|
|
11625
|
-
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
11626
|
-
}
|
|
11627
|
-
}
|
|
11628
|
-
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
11629
|
-
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
11630
|
-
try {
|
|
11631
|
-
const encryptedSummary = await encryptField(
|
|
11632
|
-
stored2.summary,
|
|
11633
|
-
ctx.walletAddress,
|
|
11634
|
-
ctx.signMessage,
|
|
11635
|
-
ctx.embeddedWalletSigner
|
|
11636
|
-
);
|
|
11637
|
-
await ctx.database.write(async () => {
|
|
11638
|
-
const current = await ctx.summariesCollection.query(import_watermelondb5.Q.where("id", record2.id)).fetch();
|
|
11639
|
-
if (current[0]?.summary === stored2.summary) {
|
|
11640
|
-
await current[0].update((rec) => {
|
|
11641
|
-
rec.summary = encryptedSummary;
|
|
11642
|
-
});
|
|
11643
|
-
}
|
|
11644
|
-
});
|
|
11645
|
-
} catch (error) {
|
|
11646
|
-
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
11647
|
-
}
|
|
11601
|
+
// src/lib/chatStore/types.ts
|
|
11602
|
+
var ChatStoreError = class extends Error {
|
|
11603
|
+
constructor(message, status, code, retryAfterMs) {
|
|
11604
|
+
super(message);
|
|
11605
|
+
this.status = status;
|
|
11606
|
+
this.code = code;
|
|
11607
|
+
this.retryAfterMs = retryAfterMs;
|
|
11608
|
+
this.name = "ChatStoreError";
|
|
11648
11609
|
}
|
|
11649
|
-
return stored2;
|
|
11650
|
-
}
|
|
11651
|
-
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
11652
|
-
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
11653
|
-
let record2;
|
|
11654
|
-
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
11655
|
-
await ctx.database.write(async () => {
|
|
11656
|
-
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
11657
|
-
const existing = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11658
|
-
if (existing.length > 0) {
|
|
11659
|
-
record2 = await existing[0].update((rec) => {
|
|
11660
|
-
rec.summary = encryptedSummary;
|
|
11661
|
-
rec.summarizedUpTo = summarizedUpTo;
|
|
11662
|
-
rec.tokenCount = tokenCount;
|
|
11663
|
-
});
|
|
11664
|
-
} else {
|
|
11665
|
-
record2 = await ctx.summariesCollection.create((rec) => {
|
|
11666
|
-
rec.conversationId = conversationId;
|
|
11667
|
-
rec.summary = encryptedSummary;
|
|
11668
|
-
rec.summarizedUpTo = summarizedUpTo;
|
|
11669
|
-
rec.tokenCount = tokenCount;
|
|
11670
|
-
});
|
|
11671
|
-
}
|
|
11672
|
-
});
|
|
11673
|
-
return modelToStored(record2, summary);
|
|
11674
|
-
}
|
|
11675
|
-
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
11676
|
-
await ctx.database.write(async () => {
|
|
11677
|
-
const existing = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11678
|
-
for (const record2 of existing) {
|
|
11679
|
-
await record2.destroyPermanently();
|
|
11680
|
-
}
|
|
11681
|
-
});
|
|
11682
|
-
}
|
|
11683
|
-
|
|
11684
|
-
// src/lib/db/conversationMemory/models.ts
|
|
11685
|
-
var import_watermelondb6 = require("@nozbe/watermelondb");
|
|
11686
|
-
var import_decorators2 = require("@nozbe/watermelondb/decorators");
|
|
11687
|
-
var ConversationMemory = class extends import_watermelondb6.Model {
|
|
11688
11610
|
};
|
|
11689
|
-
ConversationMemory.table = "conversation_memory";
|
|
11690
|
-
ConversationMemory.associations = {};
|
|
11691
|
-
__decorateClass([
|
|
11692
|
-
(0, import_decorators2.text)("conversation_id")
|
|
11693
|
-
], ConversationMemory.prototype, "conversationId", 2);
|
|
11694
|
-
__decorateClass([
|
|
11695
|
-
(0, import_decorators2.text)("memory_id")
|
|
11696
|
-
], ConversationMemory.prototype, "memoryId", 2);
|
|
11697
|
-
__decorateClass([
|
|
11698
|
-
(0, import_decorators2.field)("score")
|
|
11699
|
-
], ConversationMemory.prototype, "score", 2);
|
|
11700
|
-
__decorateClass([
|
|
11701
|
-
import_decorators2.readonly,
|
|
11702
|
-
(0, import_decorators2.date)("created_at")
|
|
11703
|
-
], ConversationMemory.prototype, "createdAt", 2);
|
|
11704
11611
|
|
|
11705
11612
|
// src/lib/db/conversationMemory/operations.ts
|
|
11706
|
-
var
|
|
11613
|
+
var import_watermelondb5 = require("@nozbe/watermelondb");
|
|
11707
11614
|
var MAX_PER_CONVERSATION = 200;
|
|
11708
11615
|
function conversationMemoryToStored(row) {
|
|
11709
11616
|
return {
|
|
@@ -11718,7 +11625,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
11718
11625
|
if (!conversationId || items.length === 0) return;
|
|
11719
11626
|
const now = Date.now();
|
|
11720
11627
|
await ctx.database.write(async () => {
|
|
11721
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
11628
|
+
const existing = await ctx.conversationMemoryCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId), import_watermelondb5.Q.sortBy("created_at", import_watermelondb5.Q.asc)).fetch();
|
|
11722
11629
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
11723
11630
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
11724
11631
|
const deduped = [];
|
|
@@ -11755,7 +11662,7 @@ async function recordConversationMemoriesOp(ctx, conversationId, items, now = Da
|
|
|
11755
11662
|
if (!conversationId || turn.size === 0) return;
|
|
11756
11663
|
const kept = new Map([...turn].slice(-MAX_PER_CONVERSATION));
|
|
11757
11664
|
await ctx.database.write(async () => {
|
|
11758
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
11665
|
+
const existing = await ctx.conversationMemoryCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId), import_watermelondb5.Q.sortBy("created_at", import_watermelondb5.Q.asc)).fetch();
|
|
11759
11666
|
const earlier = existing.filter((r) => !turn.has(r.memoryId));
|
|
11760
11667
|
const linked = new Set(existing.map((r) => r.memoryId));
|
|
11761
11668
|
await ctx.database.batch(
|
|
@@ -11780,13 +11687,13 @@ async function recordConversationMemoriesOp(ctx, conversationId, items, now = Da
|
|
|
11780
11687
|
}
|
|
11781
11688
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
11782
11689
|
if (!conversationId) return [];
|
|
11783
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
11690
|
+
const rows = await ctx.conversationMemoryCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId), import_watermelondb5.Q.sortBy("created_at", import_watermelondb5.Q.asc)).fetch();
|
|
11784
11691
|
return rows.map(conversationMemoryToStored);
|
|
11785
11692
|
}
|
|
11786
11693
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
11787
11694
|
if (!conversationId) return;
|
|
11788
11695
|
await ctx.database.write(async () => {
|
|
11789
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
11696
|
+
const rows = await ctx.conversationMemoryCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11790
11697
|
if (rows.length === 0) return;
|
|
11791
11698
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
11792
11699
|
});
|
|
@@ -11801,46 +11708,93 @@ var maxChunks = 16;
|
|
|
11801
11708
|
var droppable = ["thoughtProcess", "thinking", "sources", "toolCallEvents"];
|
|
11802
11709
|
var messageMetadata = /* @__PURE__ */ new Set(["conversationId", "uniqueId", "vector", "chunks"]);
|
|
11803
11710
|
var alwaysStored = /* @__PURE__ */ new Set(["role", "content", "responseDuration"]);
|
|
11711
|
+
var maxBubbles = 3;
|
|
11712
|
+
var maxTurnIdBytes = 128;
|
|
11713
|
+
var maxBubbleBytes = 16384;
|
|
11714
|
+
var anumaOrigins = /* @__PURE__ */ new Set(["intro", "reply"]);
|
|
11804
11715
|
function plain(value) {
|
|
11805
11716
|
return JSON.parse(JSON.stringify(value ?? {}));
|
|
11806
11717
|
}
|
|
11807
|
-
function
|
|
11718
|
+
function text3(value) {
|
|
11808
11719
|
return typeof value === "string" ? value : void 0;
|
|
11809
11720
|
}
|
|
11810
11721
|
function number(value) {
|
|
11811
11722
|
return typeof value === "number" ? value : void 0;
|
|
11812
11723
|
}
|
|
11724
|
+
function readAnumaTurn(value) {
|
|
11725
|
+
if (!isObject(value)) return void 0;
|
|
11726
|
+
const { turnId, bubbles, origin } = value;
|
|
11727
|
+
if (typeof turnId !== "string" || turnId.length === 0 || new TextEncoder().encode(turnId).length > maxTurnIdBytes)
|
|
11728
|
+
return void 0;
|
|
11729
|
+
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))
|
|
11730
|
+
return void 0;
|
|
11731
|
+
if (origin !== void 0 && (typeof origin !== "string" || !anumaOrigins.has(origin)))
|
|
11732
|
+
return void 0;
|
|
11733
|
+
return {
|
|
11734
|
+
turnId,
|
|
11735
|
+
...bubbles !== void 0 ? { bubbles: [...bubbles] } : {},
|
|
11736
|
+
...origin !== void 0 ? { origin } : {}
|
|
11737
|
+
};
|
|
11738
|
+
}
|
|
11739
|
+
function isObject(value) {
|
|
11740
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11741
|
+
}
|
|
11813
11742
|
function conversationSortKey(data, createdAt) {
|
|
11814
11743
|
const pinnedAt = number(data.pinnedAt);
|
|
11815
11744
|
if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
|
|
11816
11745
|
return number(data.lastActivityAt) ?? createdAt;
|
|
11817
11746
|
}
|
|
11747
|
+
var CONTEXT_FIELD_PREFIX = "context.";
|
|
11748
|
+
function contextField(key3) {
|
|
11749
|
+
return `${CONTEXT_FIELD_PREFIX}${key3}`;
|
|
11750
|
+
}
|
|
11751
|
+
function contextFields(context) {
|
|
11752
|
+
return plain(
|
|
11753
|
+
Object.fromEntries(Object.entries(context ?? {}).map(([k, value]) => [contextField(k), value]))
|
|
11754
|
+
);
|
|
11755
|
+
}
|
|
11756
|
+
function conversationContext(data) {
|
|
11757
|
+
const entries = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
|
|
11758
|
+
return entries.length > 0 ? plain(Object.fromEntries(entries)) : void 0;
|
|
11759
|
+
}
|
|
11818
11760
|
function toConversation(record2) {
|
|
11819
11761
|
const pinnedAt = number(record2.data.pinnedAt);
|
|
11820
|
-
const projectId =
|
|
11762
|
+
const projectId = text3(record2.data.projectId);
|
|
11763
|
+
const context = conversationContext(record2.data);
|
|
11821
11764
|
return {
|
|
11822
11765
|
uniqueId: record2.id,
|
|
11823
11766
|
conversationId: record2.id,
|
|
11824
|
-
title:
|
|
11767
|
+
title: text3(record2.data.title) ?? "",
|
|
11825
11768
|
...projectId ? { projectId } : {},
|
|
11826
11769
|
createdAt: new Date(record2.createdAt),
|
|
11827
11770
|
updatedAt: new Date(record2.updatedAt),
|
|
11828
11771
|
isDeleted: record2.isDeleted,
|
|
11829
|
-
pinnedAt: pinnedAt ? new Date(pinnedAt) : null
|
|
11772
|
+
pinnedAt: pinnedAt ? new Date(pinnedAt) : null,
|
|
11773
|
+
...context ? { context } : {}
|
|
11830
11774
|
};
|
|
11831
11775
|
}
|
|
11776
|
+
function anumaTurnData(value) {
|
|
11777
|
+
if (value === void 0) return void 0;
|
|
11778
|
+
const turn = readAnumaTurn(value);
|
|
11779
|
+
if (!turn) throw new ChatStoreError("Invalid Anuma turn", 0, "invalid_record");
|
|
11780
|
+
return turn;
|
|
11781
|
+
}
|
|
11832
11782
|
function messageData(options) {
|
|
11833
|
-
|
|
11834
|
-
|
|
11783
|
+
const anuma = anumaTurnData(options.anuma);
|
|
11784
|
+
return plain({
|
|
11785
|
+
...Object.fromEntries(
|
|
11835
11786
|
Object.entries(options).filter(
|
|
11836
|
-
([key3, value]) => !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
11787
|
+
([key3, value]) => key3 !== "anuma" && !messageMetadata.has(key3) && (!!value || alwaysStored.has(key3))
|
|
11837
11788
|
)
|
|
11838
|
-
)
|
|
11839
|
-
|
|
11789
|
+
),
|
|
11790
|
+
...anuma ? { anuma } : {}
|
|
11791
|
+
});
|
|
11840
11792
|
}
|
|
11841
11793
|
function toMessage(record2) {
|
|
11842
|
-
const { chunkOffsets: _offsets, truncated: _truncated, ...fields } = record2.data;
|
|
11794
|
+
const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record2.data;
|
|
11795
|
+
const anuma = readAnumaTurn(rawAnuma);
|
|
11843
11796
|
return {
|
|
11797
|
+
...anuma ? { anuma } : {},
|
|
11844
11798
|
...fields,
|
|
11845
11799
|
uniqueId: record2.id,
|
|
11846
11800
|
messageId: record2.sortKey,
|
|
@@ -11854,20 +11808,20 @@ function chunkOffsets(record2) {
|
|
|
11854
11808
|
return Array.isArray(offsets) ? offsets : void 0;
|
|
11855
11809
|
}
|
|
11856
11810
|
function toSkeletons(records) {
|
|
11857
|
-
const roleById = new Map(records.map((r) => [r.id,
|
|
11811
|
+
const roleById = new Map(records.map((r) => [r.id, text3(r.data.role)]));
|
|
11858
11812
|
return records.map((r) => {
|
|
11859
|
-
const parentMessageId =
|
|
11860
|
-
const model =
|
|
11813
|
+
const parentMessageId = text3(r.data.parentMessageId);
|
|
11814
|
+
const model = text3(r.data.model);
|
|
11861
11815
|
const artifact = r.data.role === "user" && !!parentMessageId && roleById.get(parentMessageId) === "user";
|
|
11862
11816
|
return {
|
|
11863
11817
|
uniqueId: r.id,
|
|
11864
11818
|
messageId: r.sortKey,
|
|
11865
11819
|
conversationId: r.conversationId,
|
|
11866
|
-
role:
|
|
11820
|
+
role: text3(r.data.role) ?? "",
|
|
11867
11821
|
createdAt: new Date(r.createdAt),
|
|
11868
11822
|
...parentMessageId ? { parentMessageId } : {},
|
|
11869
11823
|
...model ? { model } : {},
|
|
11870
|
-
...artifact ? { content:
|
|
11824
|
+
...artifact ? { content: text3(r.data.content) ?? "" } : {}
|
|
11871
11825
|
};
|
|
11872
11826
|
});
|
|
11873
11827
|
}
|
|
@@ -11875,8 +11829,8 @@ function toSummary(record2) {
|
|
|
11875
11829
|
return {
|
|
11876
11830
|
uniqueId: record2.id,
|
|
11877
11831
|
conversationId: record2.id,
|
|
11878
|
-
summary:
|
|
11879
|
-
summarizedUpTo:
|
|
11832
|
+
summary: text3(record2.data.summary) ?? "",
|
|
11833
|
+
summarizedUpTo: text3(record2.data.summarizedUpTo) ?? "",
|
|
11880
11834
|
tokenCount: number(record2.data.tokenCount) ?? 0,
|
|
11881
11835
|
createdAt: new Date(record2.createdAt),
|
|
11882
11836
|
updatedAt: new Date(record2.updatedAt)
|
|
@@ -11927,7 +11881,7 @@ function fitRecord(record2) {
|
|
|
11927
11881
|
delete data[field10];
|
|
11928
11882
|
truncated.push(field10);
|
|
11929
11883
|
}
|
|
11930
|
-
const content =
|
|
11884
|
+
const content = text3(data.content) ?? "";
|
|
11931
11885
|
const over = bytes({ ...record2, data }) - recordBudgetBytes;
|
|
11932
11886
|
if (over > 0) {
|
|
11933
11887
|
const encoded = new TextEncoder().encode(content);
|
|
@@ -11971,6 +11925,216 @@ function fitChunks(chunks3) {
|
|
|
11971
11925
|
return out;
|
|
11972
11926
|
}
|
|
11973
11927
|
|
|
11928
|
+
// src/lib/chatStore/anuma.ts
|
|
11929
|
+
var ANUMA_CONVERSATION_ID = "anuma-1on1";
|
|
11930
|
+
var maxAttempts = 3;
|
|
11931
|
+
function anumaTurnContent(bubbles) {
|
|
11932
|
+
return bubbles.join("\n\n");
|
|
11933
|
+
}
|
|
11934
|
+
function anumaLastReadSortKey(conversation) {
|
|
11935
|
+
const record2 = conversation && "record" in conversation ? conversation.record : conversation;
|
|
11936
|
+
const state = record2?.data.anuma;
|
|
11937
|
+
if (!isObject(state)) return 0;
|
|
11938
|
+
const sortKey = state.lastReadSortKey;
|
|
11939
|
+
return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
|
|
11940
|
+
}
|
|
11941
|
+
function conflict(error) {
|
|
11942
|
+
return error instanceof ChatStoreError && error.code === "version_conflict";
|
|
11943
|
+
}
|
|
11944
|
+
function live(snapshot) {
|
|
11945
|
+
if (snapshot?.record.isDeleted)
|
|
11946
|
+
throw new ChatStoreError("Anuma conversation was deleted", 409, "conversation_deleted");
|
|
11947
|
+
return snapshot;
|
|
11948
|
+
}
|
|
11949
|
+
async function ensureAnumaConversation(store, options = {}) {
|
|
11950
|
+
const existing = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
|
|
11951
|
+
if (existing) return existing;
|
|
11952
|
+
const at = (options.now ?? Date.now)();
|
|
11953
|
+
const data = plain({ title: "Anuma", lastActivityAt: at, anuma: { lastReadSortKey: 0 } });
|
|
11954
|
+
try {
|
|
11955
|
+
const [created] = await store.putMany(
|
|
11956
|
+
[
|
|
11957
|
+
{
|
|
11958
|
+
expectedVersion: 0,
|
|
11959
|
+
record: {
|
|
11960
|
+
kind: "conversation",
|
|
11961
|
+
id: ANUMA_CONVERSATION_ID,
|
|
11962
|
+
conversationId: "",
|
|
11963
|
+
sortKey: conversationSortKey(data, at),
|
|
11964
|
+
createdAt: at,
|
|
11965
|
+
updatedAt: at,
|
|
11966
|
+
isDeleted: false,
|
|
11967
|
+
data
|
|
11968
|
+
}
|
|
11969
|
+
}
|
|
11970
|
+
],
|
|
11971
|
+
options.signal
|
|
11972
|
+
);
|
|
11973
|
+
return created;
|
|
11974
|
+
} catch (error) {
|
|
11975
|
+
if (!conflict(error)) throw error;
|
|
11976
|
+
const winner = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
|
|
11977
|
+
if (!winner) throw error;
|
|
11978
|
+
return winner;
|
|
11979
|
+
}
|
|
11980
|
+
}
|
|
11981
|
+
async function markAnumaRead(store, sortKey, options = {}) {
|
|
11982
|
+
if (!Number.isSafeInteger(sortKey) || sortKey < 0)
|
|
11983
|
+
throw new ChatStoreError("Invalid Anuma read marker", 0, "invalid_record");
|
|
11984
|
+
const now = options.now ?? Date.now;
|
|
11985
|
+
for (let attempt = 1; ; attempt++) {
|
|
11986
|
+
const current = await ensureAnumaConversation(store, options);
|
|
11987
|
+
const read = anumaLastReadSortKey(current);
|
|
11988
|
+
if (sortKey <= read) return current;
|
|
11989
|
+
const record2 = current.record;
|
|
11990
|
+
const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
|
|
11991
|
+
const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
|
|
11992
|
+
try {
|
|
11993
|
+
const [written] = await store.putMany(
|
|
11994
|
+
[
|
|
11995
|
+
{
|
|
11996
|
+
expectedVersion: current.version,
|
|
11997
|
+
record: {
|
|
11998
|
+
...record2,
|
|
11999
|
+
data,
|
|
12000
|
+
sortKey: conversationSortKey(data, record2.createdAt),
|
|
12001
|
+
updatedAt: Math.max(record2.updatedAt, now())
|
|
12002
|
+
}
|
|
12003
|
+
}
|
|
12004
|
+
],
|
|
12005
|
+
options.signal
|
|
12006
|
+
);
|
|
12007
|
+
return written;
|
|
12008
|
+
} catch (error) {
|
|
12009
|
+
if (!conflict(error) || attempt >= maxAttempts) throw error;
|
|
12010
|
+
}
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
function countUnreadAnumaTurns(messages, lastReadSortKey) {
|
|
12014
|
+
const answered = Math.max(
|
|
12015
|
+
0,
|
|
12016
|
+
...messages.filter((m) => m.role === "user").map((m) => m.messageId)
|
|
12017
|
+
);
|
|
12018
|
+
const floor = Math.max(lastReadSortKey, answered);
|
|
12019
|
+
const turns = /* @__PURE__ */ new Set();
|
|
12020
|
+
for (const m of messages) {
|
|
12021
|
+
if (m.role !== "assistant" || m.messageId <= floor) continue;
|
|
12022
|
+
turns.add(m.anuma?.turnId ? `turn:${m.anuma.turnId}` : `message:${m.uniqueId}`);
|
|
12023
|
+
}
|
|
12024
|
+
return turns.size;
|
|
12025
|
+
}
|
|
12026
|
+
|
|
12027
|
+
// src/lib/db/chat/summaryOperations.ts
|
|
12028
|
+
var import_watermelondb6 = require("@nozbe/watermelondb");
|
|
12029
|
+
init_logger();
|
|
12030
|
+
function createSummaryContext(database, encryption = {}) {
|
|
12031
|
+
return {
|
|
12032
|
+
...encryption,
|
|
12033
|
+
database,
|
|
12034
|
+
summariesCollection: database.get("conversation_summaries")
|
|
12035
|
+
};
|
|
12036
|
+
}
|
|
12037
|
+
function modelToStored(record2, summary) {
|
|
12038
|
+
return {
|
|
12039
|
+
uniqueId: record2.id,
|
|
12040
|
+
conversationId: record2.conversationId,
|
|
12041
|
+
summary,
|
|
12042
|
+
summarizedUpTo: record2.summarizedUpTo,
|
|
12043
|
+
tokenCount: record2.tokenCount,
|
|
12044
|
+
createdAt: record2.createdAt,
|
|
12045
|
+
updatedAt: record2.updatedAt
|
|
12046
|
+
};
|
|
12047
|
+
}
|
|
12048
|
+
async function getConversationSummaryOp(ctx, conversationId) {
|
|
12049
|
+
const results = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
12050
|
+
if (results.length === 0) return null;
|
|
12051
|
+
const record2 = results[0];
|
|
12052
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
12053
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
12054
|
+
if (ctx.signMessage) {
|
|
12055
|
+
try {
|
|
12056
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
12057
|
+
} catch (error) {
|
|
12058
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
12059
|
+
}
|
|
12060
|
+
}
|
|
12061
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
12062
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
12063
|
+
try {
|
|
12064
|
+
const encryptedSummary = await encryptField(
|
|
12065
|
+
stored2.summary,
|
|
12066
|
+
ctx.walletAddress,
|
|
12067
|
+
ctx.signMessage,
|
|
12068
|
+
ctx.embeddedWalletSigner
|
|
12069
|
+
);
|
|
12070
|
+
await ctx.database.write(async () => {
|
|
12071
|
+
const current = await ctx.summariesCollection.query(import_watermelondb6.Q.where("id", record2.id)).fetch();
|
|
12072
|
+
if (current[0]?.summary === stored2.summary) {
|
|
12073
|
+
await current[0].update((rec) => {
|
|
12074
|
+
rec.summary = encryptedSummary;
|
|
12075
|
+
});
|
|
12076
|
+
}
|
|
12077
|
+
});
|
|
12078
|
+
} catch (error) {
|
|
12079
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
12080
|
+
}
|
|
12081
|
+
}
|
|
12082
|
+
return stored2;
|
|
12083
|
+
}
|
|
12084
|
+
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
12085
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
12086
|
+
let record2;
|
|
12087
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
12088
|
+
await ctx.database.write(async () => {
|
|
12089
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
12090
|
+
const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
12091
|
+
if (existing.length > 0) {
|
|
12092
|
+
record2 = await existing[0].update((rec) => {
|
|
12093
|
+
rec.summary = encryptedSummary;
|
|
12094
|
+
rec.summarizedUpTo = summarizedUpTo;
|
|
12095
|
+
rec.tokenCount = tokenCount;
|
|
12096
|
+
});
|
|
12097
|
+
} else {
|
|
12098
|
+
record2 = await ctx.summariesCollection.create((rec) => {
|
|
12099
|
+
rec.conversationId = conversationId;
|
|
12100
|
+
rec.summary = encryptedSummary;
|
|
12101
|
+
rec.summarizedUpTo = summarizedUpTo;
|
|
12102
|
+
rec.tokenCount = tokenCount;
|
|
12103
|
+
});
|
|
12104
|
+
}
|
|
12105
|
+
});
|
|
12106
|
+
return modelToStored(record2, summary);
|
|
12107
|
+
}
|
|
12108
|
+
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
12109
|
+
await ctx.database.write(async () => {
|
|
12110
|
+
const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
|
|
12111
|
+
for (const record2 of existing) {
|
|
12112
|
+
await record2.destroyPermanently();
|
|
12113
|
+
}
|
|
12114
|
+
});
|
|
12115
|
+
}
|
|
12116
|
+
|
|
12117
|
+
// src/lib/db/conversationMemory/models.ts
|
|
12118
|
+
var import_watermelondb7 = require("@nozbe/watermelondb");
|
|
12119
|
+
var import_decorators2 = require("@nozbe/watermelondb/decorators");
|
|
12120
|
+
var ConversationMemory = class extends import_watermelondb7.Model {
|
|
12121
|
+
};
|
|
12122
|
+
ConversationMemory.table = "conversation_memory";
|
|
12123
|
+
ConversationMemory.associations = {};
|
|
12124
|
+
__decorateClass([
|
|
12125
|
+
(0, import_decorators2.text)("conversation_id")
|
|
12126
|
+
], ConversationMemory.prototype, "conversationId", 2);
|
|
12127
|
+
__decorateClass([
|
|
12128
|
+
(0, import_decorators2.text)("memory_id")
|
|
12129
|
+
], ConversationMemory.prototype, "memoryId", 2);
|
|
12130
|
+
__decorateClass([
|
|
12131
|
+
(0, import_decorators2.field)("score")
|
|
12132
|
+
], ConversationMemory.prototype, "score", 2);
|
|
12133
|
+
__decorateClass([
|
|
12134
|
+
import_decorators2.readonly,
|
|
12135
|
+
(0, import_decorators2.date)("created_at")
|
|
12136
|
+
], ConversationMemory.prototype, "createdAt", 2);
|
|
12137
|
+
|
|
11974
12138
|
// src/lib/chatStore/chatImports.ts
|
|
11975
12139
|
var importBatch = 100;
|
|
11976
12140
|
var importChunks = 200;
|
|
@@ -11985,6 +12149,7 @@ function bytes2(value) {
|
|
|
11985
12149
|
function conversationRecord(conversation, messages) {
|
|
11986
12150
|
const createdAt = ms(conversation.createdAt);
|
|
11987
12151
|
const data = plain({
|
|
12152
|
+
...contextFields(conversation.context),
|
|
11988
12153
|
title: conversation.title,
|
|
11989
12154
|
projectId: conversation.projectId || void 0,
|
|
11990
12155
|
pinnedAt: conversation.pinnedAt ? ms(conversation.pinnedAt) : void 0,
|
|
@@ -12554,17 +12719,17 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
12554
12719
|
expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
|
|
12555
12720
|
if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
|
|
12556
12721
|
throw new Error("expectedVersion must be a nonnegative integer");
|
|
12557
|
-
const
|
|
12722
|
+
const conflict2 = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
|
|
12558
12723
|
let existing;
|
|
12559
12724
|
if (expectedVersion !== 0 && !snapshot) {
|
|
12560
12725
|
try {
|
|
12561
12726
|
existing = memoryRecord(await request(path, {}, signal));
|
|
12562
12727
|
} catch (error) {
|
|
12563
|
-
if (error instanceof RemoteMemoryError && error.status === 404) throw
|
|
12728
|
+
if (error instanceof RemoteMemoryError && error.status === 404) throw conflict2();
|
|
12564
12729
|
throw error;
|
|
12565
12730
|
}
|
|
12566
12731
|
}
|
|
12567
|
-
if (existing && existing.version !== expectedVersion) throw
|
|
12732
|
+
if (existing && existing.version !== expectedVersion) throw conflict2();
|
|
12568
12733
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
12569
12734
|
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
12570
12735
|
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
@@ -12789,17 +12954,6 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
12789
12954
|
};
|
|
12790
12955
|
}
|
|
12791
12956
|
|
|
12792
|
-
// src/lib/chatStore/types.ts
|
|
12793
|
-
var ChatStoreError = class extends Error {
|
|
12794
|
-
constructor(message, status, code, retryAfterMs) {
|
|
12795
|
-
super(message);
|
|
12796
|
-
this.status = status;
|
|
12797
|
-
this.code = code;
|
|
12798
|
-
this.retryAfterMs = retryAfterMs;
|
|
12799
|
-
this.name = "ChatStoreError";
|
|
12800
|
-
}
|
|
12801
|
-
};
|
|
12802
|
-
|
|
12803
12957
|
// src/lib/chatStore/remote.ts
|
|
12804
12958
|
var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links", "setting"]);
|
|
12805
12959
|
var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
|
|
@@ -13524,10 +13678,10 @@ async function deletedSinceUpload(store, journal, local, signal) {
|
|
|
13524
13678
|
const present = /* @__PURE__ */ new Set([...local.records.map((r) => key(r.record)), ...local.skipped.keys()]);
|
|
13525
13679
|
const gone = [...journal.keys].filter((k) => !present.has(k));
|
|
13526
13680
|
if (gone.length === 0) return [];
|
|
13527
|
-
const
|
|
13528
|
-
const tombstoning = new Set(
|
|
13681
|
+
const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
|
|
13682
|
+
const tombstoning = new Set(live2.map((s) => key(s.record)));
|
|
13529
13683
|
await journal.drop(gone.filter((k) => !tombstoning.has(k)));
|
|
13530
|
-
return
|
|
13684
|
+
return live2.map(({ record: record2, version }) => {
|
|
13531
13685
|
const empty = emptied[record2.kind];
|
|
13532
13686
|
return {
|
|
13533
13687
|
record: {
|
|
@@ -14187,12 +14341,13 @@ var resumableFields = [
|
|
|
14187
14341
|
"error",
|
|
14188
14342
|
"thoughtProcess",
|
|
14189
14343
|
"thinking",
|
|
14190
|
-
"toolCallEvents"
|
|
14344
|
+
"toolCallEvents",
|
|
14345
|
+
"anuma"
|
|
14191
14346
|
];
|
|
14192
14347
|
function resumedFields(options) {
|
|
14193
14348
|
return plain(
|
|
14194
14349
|
Object.fromEntries(
|
|
14195
|
-
resumableFields.filter((f) => options[f] !== void 0).map((f) => [f, options[f]])
|
|
14350
|
+
resumableFields.filter((f) => options[f] !== void 0).map((f) => [f, f === "anuma" ? anumaTurnData(options.anuma) : options[f]])
|
|
14196
14351
|
)
|
|
14197
14352
|
);
|
|
14198
14353
|
}
|
|
@@ -14846,7 +15001,7 @@ function createVaultChatBackend(options) {
|
|
|
14846
15001
|
},
|
|
14847
15002
|
async getConversations(query) {
|
|
14848
15003
|
await available2();
|
|
14849
|
-
return all("conversation").map(toConversation).filter(
|
|
15004
|
+
return all("conversation").filter((record2) => record2.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
|
|
14850
15005
|
(c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
|
|
14851
15006
|
).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
14852
15007
|
},
|
|
@@ -14882,7 +15037,14 @@ function createVaultChatBackend(options) {
|
|
|
14882
15037
|
async updateConversationPinned(conversationId, pinned) {
|
|
14883
15038
|
return updateConversation(conversationId, { pinnedAt: pinned ? now() : null });
|
|
14884
15039
|
},
|
|
15040
|
+
async updateConversationContext(conversationId, context) {
|
|
15041
|
+
const set = contextFields(context);
|
|
15042
|
+
if (Object.keys(set).length > 0) return updateConversation(conversationId, set);
|
|
15043
|
+
const record2 = await conversation(conversationId);
|
|
15044
|
+
return !!record2 && !record2.isDeleted;
|
|
15045
|
+
},
|
|
14885
15046
|
async deleteConversation(conversationId) {
|
|
15047
|
+
if (conversationId === ANUMA_CONVERSATION_ID) return false;
|
|
14886
15048
|
const record2 = await conversation(conversationId);
|
|
14887
15049
|
if (!record2 || record2.isDeleted) return false;
|
|
14888
15050
|
for (const [k, patch] of pending)
|
|
@@ -17886,7 +18048,7 @@ async function countActiveVaultMemoriesOp(ctx) {
|
|
|
17886
18048
|
return ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx)).fetchCount();
|
|
17887
18049
|
}
|
|
17888
18050
|
async function getVaultMemoryCountsOp(ctx) {
|
|
17889
|
-
const [
|
|
18051
|
+
const [live2, archived, quarantined] = await Promise.all([
|
|
17890
18052
|
countActiveVaultMemoriesOp(ctx),
|
|
17891
18053
|
ctx.vaultMemoryCollection.query(
|
|
17892
18054
|
...baseVaultConditions(ctx, { includeArchived: true }),
|
|
@@ -17897,7 +18059,7 @@ async function getVaultMemoryCountsOp(ctx) {
|
|
|
17897
18059
|
import_watermelondb21.Q.where("trust_tier", "quarantined")
|
|
17898
18060
|
).fetchCount()
|
|
17899
18061
|
]);
|
|
17900
|
-
return { live, archived, quarantined };
|
|
18062
|
+
return { live: live2, archived, quarantined };
|
|
17901
18063
|
}
|
|
17902
18064
|
async function getActiveVaultMemoryIdsOp(ctx, ids) {
|
|
17903
18065
|
if (ids.length === 0) return /* @__PURE__ */ new Set();
|
|
@@ -19184,12 +19346,12 @@ var WalletPoller = class {
|
|
|
19184
19346
|
* @param maxAttempts - Maximum polling attempts before giving up (default: 60)
|
|
19185
19347
|
* @returns Stop function to cancel polling
|
|
19186
19348
|
*/
|
|
19187
|
-
startPolling(checkWallet, onWalletReady, intervalMs = DEFAULT_INTERVAL_MS,
|
|
19349
|
+
startPolling(checkWallet, onWalletReady, intervalMs = DEFAULT_INTERVAL_MS, maxAttempts2 = DEFAULT_MAX_ATTEMPTS) {
|
|
19188
19350
|
this.stop();
|
|
19189
19351
|
this.attempts = 0;
|
|
19190
19352
|
const poll = async () => {
|
|
19191
19353
|
this.attempts++;
|
|
19192
|
-
if (this.attempts >
|
|
19354
|
+
if (this.attempts > maxAttempts2) {
|
|
19193
19355
|
this.stop();
|
|
19194
19356
|
return;
|
|
19195
19357
|
}
|
|
@@ -26599,13 +26761,13 @@ function createRemoteMemoryStore(options) {
|
|
|
26599
26761
|
});
|
|
26600
26762
|
return run;
|
|
26601
26763
|
};
|
|
26602
|
-
const
|
|
26764
|
+
const live2 = async (id2) => {
|
|
26603
26765
|
const record2 = await persistence.get(id2);
|
|
26604
26766
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
26605
26767
|
};
|
|
26606
26768
|
const mutateLocked = async (id2, change, edit, writeOptions) => {
|
|
26607
26769
|
writeOptions?.signal?.throwIfAborted();
|
|
26608
|
-
const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await
|
|
26770
|
+
const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
|
|
26609
26771
|
if (!record2) return null;
|
|
26610
26772
|
if (record2.memory.is_deleted) return null;
|
|
26611
26773
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
@@ -27403,7 +27565,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27403
27565
|
}, clear);
|
|
27404
27566
|
return snapshot.then((topics) => structuredClone(topics));
|
|
27405
27567
|
},
|
|
27406
|
-
get: async (id2) => asStored(await
|
|
27568
|
+
get: async (id2) => asStored(await live2(id2)),
|
|
27407
27569
|
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
27408
27570
|
(record2) => stored(record2.memory)
|
|
27409
27571
|
),
|
|
@@ -27488,7 +27650,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27488
27650
|
return serialized(
|
|
27489
27651
|
first,
|
|
27490
27652
|
() => serialized(second, async () => {
|
|
27491
|
-
const [old, next] = await Promise.all([
|
|
27653
|
+
const [old, next] = await Promise.all([live2(id2), live2(supersededById)]);
|
|
27492
27654
|
if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
|
|
27493
27655
|
if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
|
|
27494
27656
|
const saved = await persistence.putMany([
|
|
@@ -27509,7 +27671,7 @@ function createRemoteMemoryStore(options) {
|
|
|
27509
27671
|
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
27510
27672
|
),
|
|
27511
27673
|
restore: (id2) => serialized(id2, async () => {
|
|
27512
|
-
const record2 = await
|
|
27674
|
+
const record2 = await live2(id2);
|
|
27513
27675
|
if (!record2) return false;
|
|
27514
27676
|
if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
|
|
27515
27677
|
return true;
|
|
@@ -34682,6 +34844,7 @@ function useChatStorage(options) {
|
|
|
34682
34844
|
}
|
|
34683
34845
|
// Annotate the CommonJS export names for ESM import in node:
|
|
34684
34846
|
0 && (module.exports = {
|
|
34847
|
+
ANUMA_CONVERSATION_ID,
|
|
34685
34848
|
CHUNKS_DISCARDED_ORIGIN,
|
|
34686
34849
|
ChatConversation,
|
|
34687
34850
|
ChatMessage,
|
|
@@ -34741,6 +34904,8 @@ function useChatStorage(options) {
|
|
|
34741
34904
|
WALLET_PAYMENT_TOOL_NAME,
|
|
34742
34905
|
WalletPoller,
|
|
34743
34906
|
addConversationMemoriesOp,
|
|
34907
|
+
anumaLastReadSortKey,
|
|
34908
|
+
anumaTurnContent,
|
|
34744
34909
|
archiveVaultMemoryOp,
|
|
34745
34910
|
assembleMemoryContext,
|
|
34746
34911
|
attachFileContextToLastUserMessage,
|
|
@@ -34774,6 +34939,7 @@ function useChatStorage(options) {
|
|
|
34774
34939
|
consoleLogger,
|
|
34775
34940
|
conversationMemoryToStored,
|
|
34776
34941
|
cosineInt8,
|
|
34942
|
+
countUnreadAnumaTurns,
|
|
34777
34943
|
createAutoExtractor,
|
|
34778
34944
|
createChunkVectorCache,
|
|
34779
34945
|
createCryptoPricePreProcessor,
|
|
@@ -34822,6 +34988,7 @@ function useChatStorage(options) {
|
|
|
34822
34988
|
embedMessage,
|
|
34823
34989
|
encodeChunkVector,
|
|
34824
34990
|
encryptToolCallEventsOp,
|
|
34991
|
+
ensureAnumaConversation,
|
|
34825
34992
|
ensureDefaultFoldersOp,
|
|
34826
34993
|
exchangeNotionCode,
|
|
34827
34994
|
extractAndLinkEntitiesForMemoriesOp,
|
|
@@ -34862,6 +35029,7 @@ function useChatStorage(options) {
|
|
|
34862
35029
|
isRerankerAvailable,
|
|
34863
35030
|
loadSettings,
|
|
34864
35031
|
localChatBackend,
|
|
35032
|
+
markAnumaRead,
|
|
34865
35033
|
maskScopedEmbeddingCache,
|
|
34866
35034
|
maxVaultAttachmentBytes,
|
|
34867
35035
|
memoryCipher,
|
|
@@ -34877,6 +35045,7 @@ function useChatStorage(options) {
|
|
|
34877
35045
|
quantizeEmbedding,
|
|
34878
35046
|
queueManager,
|
|
34879
35047
|
rankProfileCandidates,
|
|
35048
|
+
readAnumaTurn,
|
|
34880
35049
|
recall,
|
|
34881
35050
|
reencryptMemoryField,
|
|
34882
35051
|
reflect,
|