@anuma/sdk 10.1.0 → 10.1.1
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 +59 -17
- package/dist/expo/index.mjs +58 -17
- package/dist/react/index.cjs +59 -17
- package/dist/react/index.mjs +58 -17
- package/dist/server/index.cjs +50 -13
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.mjs +49 -13
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -11434,17 +11434,19 @@ var xhrTransport = (options) => {
|
|
|
11434
11434
|
|
|
11435
11435
|
// src/lib/db/chat/summaryOperations.ts
|
|
11436
11436
|
var import_watermelondb5 = require("@nozbe/watermelondb");
|
|
11437
|
-
|
|
11437
|
+
init_logger();
|
|
11438
|
+
function createSummaryContext(database, encryption = {}) {
|
|
11438
11439
|
return {
|
|
11440
|
+
...encryption,
|
|
11439
11441
|
database,
|
|
11440
11442
|
summariesCollection: database.get("conversation_summaries")
|
|
11441
11443
|
};
|
|
11442
11444
|
}
|
|
11443
|
-
function modelToStored(record2) {
|
|
11445
|
+
function modelToStored(record2, summary) {
|
|
11444
11446
|
return {
|
|
11445
11447
|
uniqueId: record2.id,
|
|
11446
11448
|
conversationId: record2.conversationId,
|
|
11447
|
-
summary
|
|
11449
|
+
summary,
|
|
11448
11450
|
summarizedUpTo: record2.summarizedUpTo,
|
|
11449
11451
|
tokenCount: record2.tokenCount,
|
|
11450
11452
|
createdAt: record2.createdAt,
|
|
@@ -11454,28 +11456,62 @@ function modelToStored(record2) {
|
|
|
11454
11456
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
11455
11457
|
const results = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11456
11458
|
if (results.length === 0) return null;
|
|
11457
|
-
|
|
11459
|
+
const record2 = results[0];
|
|
11460
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
11461
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
11462
|
+
if (ctx.signMessage) {
|
|
11463
|
+
try {
|
|
11464
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
11465
|
+
} catch (error) {
|
|
11466
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
11467
|
+
}
|
|
11468
|
+
}
|
|
11469
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
11470
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
11471
|
+
try {
|
|
11472
|
+
const encryptedSummary = await encryptField(
|
|
11473
|
+
stored2.summary,
|
|
11474
|
+
ctx.walletAddress,
|
|
11475
|
+
ctx.signMessage,
|
|
11476
|
+
ctx.embeddedWalletSigner
|
|
11477
|
+
);
|
|
11478
|
+
await ctx.database.write(async () => {
|
|
11479
|
+
const current = await ctx.summariesCollection.query(import_watermelondb5.Q.where("id", record2.id)).fetch();
|
|
11480
|
+
if (current[0]?.summary === stored2.summary) {
|
|
11481
|
+
await current[0].update((rec) => {
|
|
11482
|
+
rec.summary = encryptedSummary;
|
|
11483
|
+
});
|
|
11484
|
+
}
|
|
11485
|
+
});
|
|
11486
|
+
} catch (error) {
|
|
11487
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
11488
|
+
}
|
|
11489
|
+
}
|
|
11490
|
+
return stored2;
|
|
11458
11491
|
}
|
|
11459
11492
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
11493
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
11460
11494
|
let record2;
|
|
11495
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
11461
11496
|
await ctx.database.write(async () => {
|
|
11497
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
11462
11498
|
const existing = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
11463
11499
|
if (existing.length > 0) {
|
|
11464
11500
|
record2 = await existing[0].update((rec) => {
|
|
11465
|
-
rec.summary =
|
|
11501
|
+
rec.summary = encryptedSummary;
|
|
11466
11502
|
rec.summarizedUpTo = summarizedUpTo;
|
|
11467
11503
|
rec.tokenCount = tokenCount;
|
|
11468
11504
|
});
|
|
11469
11505
|
} else {
|
|
11470
11506
|
record2 = await ctx.summariesCollection.create((rec) => {
|
|
11471
11507
|
rec.conversationId = conversationId;
|
|
11472
|
-
rec.summary =
|
|
11508
|
+
rec.summary = encryptedSummary;
|
|
11473
11509
|
rec.summarizedUpTo = summarizedUpTo;
|
|
11474
11510
|
rec.tokenCount = tokenCount;
|
|
11475
11511
|
});
|
|
11476
11512
|
}
|
|
11477
11513
|
});
|
|
11478
|
-
return modelToStored(record2);
|
|
11514
|
+
return modelToStored(record2, summary);
|
|
11479
11515
|
}
|
|
11480
11516
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
11481
11517
|
await ctx.database.write(async () => {
|
|
@@ -13125,7 +13161,7 @@ async function readLocal(options) {
|
|
|
13125
13161
|
signMessage: options.signMessage,
|
|
13126
13162
|
embeddedWalletSigner: options.embeddedWalletSigner
|
|
13127
13163
|
};
|
|
13128
|
-
const summaries = createSummaryContext(database);
|
|
13164
|
+
const summaries = createSummaryContext(database, ctx);
|
|
13129
13165
|
const memory = {
|
|
13130
13166
|
database,
|
|
13131
13167
|
conversationMemoryCollection: database.get(ConversationMemory.table)
|
|
@@ -13206,7 +13242,9 @@ async function readLocal(options) {
|
|
|
13206
13242
|
out.records.push(prepared);
|
|
13207
13243
|
}
|
|
13208
13244
|
const summary = await getConversationSummaryOp(summaries, conversationId);
|
|
13209
|
-
if (summary)
|
|
13245
|
+
if (summary && isEncrypted(summary.summary)) {
|
|
13246
|
+
skip("summary", conversationId, "unreadable");
|
|
13247
|
+
} else if (summary)
|
|
13210
13248
|
out.records.push({
|
|
13211
13249
|
record: {
|
|
13212
13250
|
kind: "summary",
|
|
@@ -28988,11 +29026,14 @@ var WatermelonChatStorageAdapter = class {
|
|
|
28988
29026
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
28989
29027
|
}
|
|
28990
29028
|
getSummary(conversationId) {
|
|
28991
|
-
return getConversationSummaryOp(
|
|
29029
|
+
return getConversationSummaryOp(
|
|
29030
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
29031
|
+
conversationId
|
|
29032
|
+
);
|
|
28992
29033
|
}
|
|
28993
29034
|
upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
28994
29035
|
return upsertConversationSummaryOp(
|
|
28995
|
-
createSummaryContext(this.ctx.database),
|
|
29036
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
28996
29037
|
conversationId,
|
|
28997
29038
|
summary,
|
|
28998
29039
|
summarizedUpTo,
|
|
@@ -31138,7 +31179,7 @@ async function summarizeHistoryAtRevision(options, revision2) {
|
|
|
31138
31179
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
31139
31180
|
return {
|
|
31140
31181
|
messagesToConvert: messages,
|
|
31141
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
31182
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
31142
31183
|
};
|
|
31143
31184
|
} catch {
|
|
31144
31185
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -31193,14 +31234,15 @@ async function doSummarizeHistory(options, revision2) {
|
|
|
31193
31234
|
} = options;
|
|
31194
31235
|
try {
|
|
31195
31236
|
const summaries = summaryStore(options);
|
|
31196
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
31237
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
31197
31238
|
assertConversationRevision(database, conversationId, revision2);
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
);
|
|
31201
|
-
});
|
|
31239
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
31240
|
+
};
|
|
31202
31241
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
31203
31242
|
assertConversationRevision(database, conversationId, revision2);
|
|
31243
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
31244
|
+
throw new Error("The cached summary could not be decrypted");
|
|
31245
|
+
}
|
|
31204
31246
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
31205
31247
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
31206
31248
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
package/dist/expo/index.mjs
CHANGED
|
@@ -9780,17 +9780,18 @@ var xhrTransport = (options) => {
|
|
|
9780
9780
|
|
|
9781
9781
|
// src/lib/db/chat/summaryOperations.ts
|
|
9782
9782
|
import { Q as Q3 } from "@nozbe/watermelondb";
|
|
9783
|
-
function createSummaryContext(database) {
|
|
9783
|
+
function createSummaryContext(database, encryption = {}) {
|
|
9784
9784
|
return {
|
|
9785
|
+
...encryption,
|
|
9785
9786
|
database,
|
|
9786
9787
|
summariesCollection: database.get("conversation_summaries")
|
|
9787
9788
|
};
|
|
9788
9789
|
}
|
|
9789
|
-
function modelToStored(record2) {
|
|
9790
|
+
function modelToStored(record2, summary) {
|
|
9790
9791
|
return {
|
|
9791
9792
|
uniqueId: record2.id,
|
|
9792
9793
|
conversationId: record2.conversationId,
|
|
9793
|
-
summary
|
|
9794
|
+
summary,
|
|
9794
9795
|
summarizedUpTo: record2.summarizedUpTo,
|
|
9795
9796
|
tokenCount: record2.tokenCount,
|
|
9796
9797
|
createdAt: record2.createdAt,
|
|
@@ -9800,28 +9801,62 @@ function modelToStored(record2) {
|
|
|
9800
9801
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
9801
9802
|
const results = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
9802
9803
|
if (results.length === 0) return null;
|
|
9803
|
-
|
|
9804
|
+
const record2 = results[0];
|
|
9805
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
9806
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
9807
|
+
if (ctx.signMessage) {
|
|
9808
|
+
try {
|
|
9809
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
9810
|
+
} catch (error) {
|
|
9811
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
9812
|
+
}
|
|
9813
|
+
}
|
|
9814
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
9815
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
9816
|
+
try {
|
|
9817
|
+
const encryptedSummary = await encryptField(
|
|
9818
|
+
stored2.summary,
|
|
9819
|
+
ctx.walletAddress,
|
|
9820
|
+
ctx.signMessage,
|
|
9821
|
+
ctx.embeddedWalletSigner
|
|
9822
|
+
);
|
|
9823
|
+
await ctx.database.write(async () => {
|
|
9824
|
+
const current = await ctx.summariesCollection.query(Q3.where("id", record2.id)).fetch();
|
|
9825
|
+
if (current[0]?.summary === stored2.summary) {
|
|
9826
|
+
await current[0].update((rec) => {
|
|
9827
|
+
rec.summary = encryptedSummary;
|
|
9828
|
+
});
|
|
9829
|
+
}
|
|
9830
|
+
});
|
|
9831
|
+
} catch (error) {
|
|
9832
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
return stored2;
|
|
9804
9836
|
}
|
|
9805
9837
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
9838
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
9806
9839
|
let record2;
|
|
9840
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
9807
9841
|
await ctx.database.write(async () => {
|
|
9842
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
9808
9843
|
const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
9809
9844
|
if (existing.length > 0) {
|
|
9810
9845
|
record2 = await existing[0].update((rec) => {
|
|
9811
|
-
rec.summary =
|
|
9846
|
+
rec.summary = encryptedSummary;
|
|
9812
9847
|
rec.summarizedUpTo = summarizedUpTo;
|
|
9813
9848
|
rec.tokenCount = tokenCount;
|
|
9814
9849
|
});
|
|
9815
9850
|
} else {
|
|
9816
9851
|
record2 = await ctx.summariesCollection.create((rec) => {
|
|
9817
9852
|
rec.conversationId = conversationId;
|
|
9818
|
-
rec.summary =
|
|
9853
|
+
rec.summary = encryptedSummary;
|
|
9819
9854
|
rec.summarizedUpTo = summarizedUpTo;
|
|
9820
9855
|
rec.tokenCount = tokenCount;
|
|
9821
9856
|
});
|
|
9822
9857
|
}
|
|
9823
9858
|
});
|
|
9824
|
-
return modelToStored(record2);
|
|
9859
|
+
return modelToStored(record2, summary);
|
|
9825
9860
|
}
|
|
9826
9861
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
9827
9862
|
await ctx.database.write(async () => {
|
|
@@ -11467,7 +11502,7 @@ async function readLocal(options) {
|
|
|
11467
11502
|
signMessage: options.signMessage,
|
|
11468
11503
|
embeddedWalletSigner: options.embeddedWalletSigner
|
|
11469
11504
|
};
|
|
11470
|
-
const summaries = createSummaryContext(database);
|
|
11505
|
+
const summaries = createSummaryContext(database, ctx);
|
|
11471
11506
|
const memory = {
|
|
11472
11507
|
database,
|
|
11473
11508
|
conversationMemoryCollection: database.get(ConversationMemory.table)
|
|
@@ -11548,7 +11583,9 @@ async function readLocal(options) {
|
|
|
11548
11583
|
out.records.push(prepared);
|
|
11549
11584
|
}
|
|
11550
11585
|
const summary = await getConversationSummaryOp(summaries, conversationId);
|
|
11551
|
-
if (summary)
|
|
11586
|
+
if (summary && isEncrypted(summary.summary)) {
|
|
11587
|
+
skip("summary", conversationId, "unreadable");
|
|
11588
|
+
} else if (summary)
|
|
11552
11589
|
out.records.push({
|
|
11553
11590
|
record: {
|
|
11554
11591
|
kind: "summary",
|
|
@@ -27274,11 +27311,14 @@ var WatermelonChatStorageAdapter = class {
|
|
|
27274
27311
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
27275
27312
|
}
|
|
27276
27313
|
getSummary(conversationId) {
|
|
27277
|
-
return getConversationSummaryOp(
|
|
27314
|
+
return getConversationSummaryOp(
|
|
27315
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
27316
|
+
conversationId
|
|
27317
|
+
);
|
|
27278
27318
|
}
|
|
27279
27319
|
upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
27280
27320
|
return upsertConversationSummaryOp(
|
|
27281
|
-
createSummaryContext(this.ctx.database),
|
|
27321
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
27282
27322
|
conversationId,
|
|
27283
27323
|
summary,
|
|
27284
27324
|
summarizedUpTo,
|
|
@@ -29413,7 +29453,7 @@ async function summarizeHistoryAtRevision(options, revision2) {
|
|
|
29413
29453
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
29414
29454
|
return {
|
|
29415
29455
|
messagesToConvert: messages,
|
|
29416
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
29456
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
29417
29457
|
};
|
|
29418
29458
|
} catch {
|
|
29419
29459
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -29468,14 +29508,15 @@ async function doSummarizeHistory(options, revision2) {
|
|
|
29468
29508
|
} = options;
|
|
29469
29509
|
try {
|
|
29470
29510
|
const summaries = summaryStore(options);
|
|
29471
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
29511
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
29472
29512
|
assertConversationRevision(database, conversationId, revision2);
|
|
29473
|
-
|
|
29474
|
-
|
|
29475
|
-
);
|
|
29476
|
-
});
|
|
29513
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
29514
|
+
};
|
|
29477
29515
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
29478
29516
|
assertConversationRevision(database, conversationId, revision2);
|
|
29517
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
29518
|
+
throw new Error("The cached summary could not be decrypted");
|
|
29519
|
+
}
|
|
29479
29520
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
29480
29521
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
29481
29522
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
package/dist/react/index.cjs
CHANGED
|
@@ -12204,17 +12204,19 @@ function createWebSearchPreProcessor(options = {}) {
|
|
|
12204
12204
|
|
|
12205
12205
|
// src/lib/db/chat/summaryOperations.ts
|
|
12206
12206
|
var import_watermelondb5 = require("@nozbe/watermelondb");
|
|
12207
|
-
|
|
12207
|
+
init_logger();
|
|
12208
|
+
function createSummaryContext(database, encryption = {}) {
|
|
12208
12209
|
return {
|
|
12210
|
+
...encryption,
|
|
12209
12211
|
database,
|
|
12210
12212
|
summariesCollection: database.get("conversation_summaries")
|
|
12211
12213
|
};
|
|
12212
12214
|
}
|
|
12213
|
-
function modelToStored(record2) {
|
|
12215
|
+
function modelToStored(record2, summary) {
|
|
12214
12216
|
return {
|
|
12215
12217
|
uniqueId: record2.id,
|
|
12216
12218
|
conversationId: record2.conversationId,
|
|
12217
|
-
summary
|
|
12219
|
+
summary,
|
|
12218
12220
|
summarizedUpTo: record2.summarizedUpTo,
|
|
12219
12221
|
tokenCount: record2.tokenCount,
|
|
12220
12222
|
createdAt: record2.createdAt,
|
|
@@ -12224,28 +12226,62 @@ function modelToStored(record2) {
|
|
|
12224
12226
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
12225
12227
|
const results = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
12226
12228
|
if (results.length === 0) return null;
|
|
12227
|
-
|
|
12229
|
+
const record2 = results[0];
|
|
12230
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
12231
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
12232
|
+
if (ctx.signMessage) {
|
|
12233
|
+
try {
|
|
12234
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
12235
|
+
} catch (error) {
|
|
12236
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
12237
|
+
}
|
|
12238
|
+
}
|
|
12239
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
12240
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
12241
|
+
try {
|
|
12242
|
+
const encryptedSummary = await encryptField(
|
|
12243
|
+
stored2.summary,
|
|
12244
|
+
ctx.walletAddress,
|
|
12245
|
+
ctx.signMessage,
|
|
12246
|
+
ctx.embeddedWalletSigner
|
|
12247
|
+
);
|
|
12248
|
+
await ctx.database.write(async () => {
|
|
12249
|
+
const current = await ctx.summariesCollection.query(import_watermelondb5.Q.where("id", record2.id)).fetch();
|
|
12250
|
+
if (current[0]?.summary === stored2.summary) {
|
|
12251
|
+
await current[0].update((rec) => {
|
|
12252
|
+
rec.summary = encryptedSummary;
|
|
12253
|
+
});
|
|
12254
|
+
}
|
|
12255
|
+
});
|
|
12256
|
+
} catch (error) {
|
|
12257
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
12258
|
+
}
|
|
12259
|
+
}
|
|
12260
|
+
return stored2;
|
|
12228
12261
|
}
|
|
12229
12262
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
12263
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
12230
12264
|
let record2;
|
|
12265
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
12231
12266
|
await ctx.database.write(async () => {
|
|
12267
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
12232
12268
|
const existing = await ctx.summariesCollection.query(import_watermelondb5.Q.where("conversation_id", conversationId)).fetch();
|
|
12233
12269
|
if (existing.length > 0) {
|
|
12234
12270
|
record2 = await existing[0].update((rec) => {
|
|
12235
|
-
rec.summary =
|
|
12271
|
+
rec.summary = encryptedSummary;
|
|
12236
12272
|
rec.summarizedUpTo = summarizedUpTo;
|
|
12237
12273
|
rec.tokenCount = tokenCount;
|
|
12238
12274
|
});
|
|
12239
12275
|
} else {
|
|
12240
12276
|
record2 = await ctx.summariesCollection.create((rec) => {
|
|
12241
12277
|
rec.conversationId = conversationId;
|
|
12242
|
-
rec.summary =
|
|
12278
|
+
rec.summary = encryptedSummary;
|
|
12243
12279
|
rec.summarizedUpTo = summarizedUpTo;
|
|
12244
12280
|
rec.tokenCount = tokenCount;
|
|
12245
12281
|
});
|
|
12246
12282
|
}
|
|
12247
12283
|
});
|
|
12248
|
-
return modelToStored(record2);
|
|
12284
|
+
return modelToStored(record2, summary);
|
|
12249
12285
|
}
|
|
12250
12286
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
12251
12287
|
await ctx.database.write(async () => {
|
|
@@ -13895,7 +13931,7 @@ async function readLocal(options) {
|
|
|
13895
13931
|
signMessage: options.signMessage,
|
|
13896
13932
|
embeddedWalletSigner: options.embeddedWalletSigner
|
|
13897
13933
|
};
|
|
13898
|
-
const summaries = createSummaryContext(database);
|
|
13934
|
+
const summaries = createSummaryContext(database, ctx);
|
|
13899
13935
|
const memory = {
|
|
13900
13936
|
database,
|
|
13901
13937
|
conversationMemoryCollection: database.get(ConversationMemory.table)
|
|
@@ -13976,7 +14012,9 @@ async function readLocal(options) {
|
|
|
13976
14012
|
out.records.push(prepared);
|
|
13977
14013
|
}
|
|
13978
14014
|
const summary = await getConversationSummaryOp(summaries, conversationId);
|
|
13979
|
-
if (summary)
|
|
14015
|
+
if (summary && isEncrypted(summary.summary)) {
|
|
14016
|
+
skip("summary", conversationId, "unreadable");
|
|
14017
|
+
} else if (summary)
|
|
13980
14018
|
out.records.push({
|
|
13981
14019
|
record: {
|
|
13982
14020
|
kind: "summary",
|
|
@@ -17654,11 +17692,14 @@ var WatermelonChatStorageAdapter = class {
|
|
|
17654
17692
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
17655
17693
|
}
|
|
17656
17694
|
getSummary(conversationId) {
|
|
17657
|
-
return getConversationSummaryOp(
|
|
17695
|
+
return getConversationSummaryOp(
|
|
17696
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
17697
|
+
conversationId
|
|
17698
|
+
);
|
|
17658
17699
|
}
|
|
17659
17700
|
upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
17660
17701
|
return upsertConversationSummaryOp(
|
|
17661
|
-
createSummaryContext(this.ctx.database),
|
|
17702
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
17662
17703
|
conversationId,
|
|
17663
17704
|
summary,
|
|
17664
17705
|
summarizedUpTo,
|
|
@@ -36017,7 +36058,7 @@ async function summarizeHistoryAtRevision(options, revision2) {
|
|
|
36017
36058
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
36018
36059
|
return {
|
|
36019
36060
|
messagesToConvert: messages,
|
|
36020
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
36061
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
36021
36062
|
};
|
|
36022
36063
|
} catch {
|
|
36023
36064
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -36072,14 +36113,15 @@ async function doSummarizeHistory(options, revision2) {
|
|
|
36072
36113
|
} = options;
|
|
36073
36114
|
try {
|
|
36074
36115
|
const summaries = summaryStore(options);
|
|
36075
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
36116
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
36076
36117
|
assertConversationRevision(database, conversationId, revision2);
|
|
36077
|
-
|
|
36078
|
-
|
|
36079
|
-
);
|
|
36080
|
-
});
|
|
36118
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
36119
|
+
};
|
|
36081
36120
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
36082
36121
|
assertConversationRevision(database, conversationId, revision2);
|
|
36122
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
36123
|
+
throw new Error("The cached summary could not be decrypted");
|
|
36124
|
+
}
|
|
36083
36125
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
36084
36126
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
36085
36127
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
package/dist/react/index.mjs
CHANGED
|
@@ -10348,17 +10348,18 @@ function createWebSearchPreProcessor(options = {}) {
|
|
|
10348
10348
|
|
|
10349
10349
|
// src/lib/db/chat/summaryOperations.ts
|
|
10350
10350
|
import { Q as Q3 } from "@nozbe/watermelondb";
|
|
10351
|
-
function createSummaryContext(database) {
|
|
10351
|
+
function createSummaryContext(database, encryption = {}) {
|
|
10352
10352
|
return {
|
|
10353
|
+
...encryption,
|
|
10353
10354
|
database,
|
|
10354
10355
|
summariesCollection: database.get("conversation_summaries")
|
|
10355
10356
|
};
|
|
10356
10357
|
}
|
|
10357
|
-
function modelToStored(record2) {
|
|
10358
|
+
function modelToStored(record2, summary) {
|
|
10358
10359
|
return {
|
|
10359
10360
|
uniqueId: record2.id,
|
|
10360
10361
|
conversationId: record2.conversationId,
|
|
10361
|
-
summary
|
|
10362
|
+
summary,
|
|
10362
10363
|
summarizedUpTo: record2.summarizedUpTo,
|
|
10363
10364
|
tokenCount: record2.tokenCount,
|
|
10364
10365
|
createdAt: record2.createdAt,
|
|
@@ -10368,28 +10369,62 @@ function modelToStored(record2) {
|
|
|
10368
10369
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
10369
10370
|
const results = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
10370
10371
|
if (results.length === 0) return null;
|
|
10371
|
-
|
|
10372
|
+
const record2 = results[0];
|
|
10373
|
+
const stored2 = modelToStored(record2, record2.summary);
|
|
10374
|
+
if (ctx.walletAddress && isEncrypted(stored2.summary)) {
|
|
10375
|
+
if (ctx.signMessage) {
|
|
10376
|
+
try {
|
|
10377
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
10378
|
+
} catch (error) {
|
|
10379
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
10380
|
+
}
|
|
10381
|
+
}
|
|
10382
|
+
stored2.summary = await decryptField(stored2.summary, ctx.walletAddress);
|
|
10383
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored2.summary) {
|
|
10384
|
+
try {
|
|
10385
|
+
const encryptedSummary = await encryptField(
|
|
10386
|
+
stored2.summary,
|
|
10387
|
+
ctx.walletAddress,
|
|
10388
|
+
ctx.signMessage,
|
|
10389
|
+
ctx.embeddedWalletSigner
|
|
10390
|
+
);
|
|
10391
|
+
await ctx.database.write(async () => {
|
|
10392
|
+
const current = await ctx.summariesCollection.query(Q3.where("id", record2.id)).fetch();
|
|
10393
|
+
if (current[0]?.summary === stored2.summary) {
|
|
10394
|
+
await current[0].update((rec) => {
|
|
10395
|
+
rec.summary = encryptedSummary;
|
|
10396
|
+
});
|
|
10397
|
+
}
|
|
10398
|
+
});
|
|
10399
|
+
} catch (error) {
|
|
10400
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
10401
|
+
}
|
|
10402
|
+
}
|
|
10403
|
+
return stored2;
|
|
10372
10404
|
}
|
|
10373
10405
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
10406
|
+
const revision2 = getConversationRevision(ctx.database, conversationId);
|
|
10374
10407
|
let record2;
|
|
10408
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
10375
10409
|
await ctx.database.write(async () => {
|
|
10410
|
+
assertConversationRevision(ctx.database, conversationId, revision2);
|
|
10376
10411
|
const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
|
|
10377
10412
|
if (existing.length > 0) {
|
|
10378
10413
|
record2 = await existing[0].update((rec) => {
|
|
10379
|
-
rec.summary =
|
|
10414
|
+
rec.summary = encryptedSummary;
|
|
10380
10415
|
rec.summarizedUpTo = summarizedUpTo;
|
|
10381
10416
|
rec.tokenCount = tokenCount;
|
|
10382
10417
|
});
|
|
10383
10418
|
} else {
|
|
10384
10419
|
record2 = await ctx.summariesCollection.create((rec) => {
|
|
10385
10420
|
rec.conversationId = conversationId;
|
|
10386
|
-
rec.summary =
|
|
10421
|
+
rec.summary = encryptedSummary;
|
|
10387
10422
|
rec.summarizedUpTo = summarizedUpTo;
|
|
10388
10423
|
rec.tokenCount = tokenCount;
|
|
10389
10424
|
});
|
|
10390
10425
|
}
|
|
10391
10426
|
});
|
|
10392
|
-
return modelToStored(record2);
|
|
10427
|
+
return modelToStored(record2, summary);
|
|
10393
10428
|
}
|
|
10394
10429
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
10395
10430
|
await ctx.database.write(async () => {
|
|
@@ -12035,7 +12070,7 @@ async function readLocal(options) {
|
|
|
12035
12070
|
signMessage: options.signMessage,
|
|
12036
12071
|
embeddedWalletSigner: options.embeddedWalletSigner
|
|
12037
12072
|
};
|
|
12038
|
-
const summaries = createSummaryContext(database);
|
|
12073
|
+
const summaries = createSummaryContext(database, ctx);
|
|
12039
12074
|
const memory = {
|
|
12040
12075
|
database,
|
|
12041
12076
|
conversationMemoryCollection: database.get(ConversationMemory.table)
|
|
@@ -12116,7 +12151,9 @@ async function readLocal(options) {
|
|
|
12116
12151
|
out.records.push(prepared);
|
|
12117
12152
|
}
|
|
12118
12153
|
const summary = await getConversationSummaryOp(summaries, conversationId);
|
|
12119
|
-
if (summary)
|
|
12154
|
+
if (summary && isEncrypted(summary.summary)) {
|
|
12155
|
+
skip("summary", conversationId, "unreadable");
|
|
12156
|
+
} else if (summary)
|
|
12120
12157
|
out.records.push({
|
|
12121
12158
|
record: {
|
|
12122
12159
|
kind: "summary",
|
|
@@ -15797,11 +15834,14 @@ var WatermelonChatStorageAdapter = class {
|
|
|
15797
15834
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
15798
15835
|
}
|
|
15799
15836
|
getSummary(conversationId) {
|
|
15800
|
-
return getConversationSummaryOp(
|
|
15837
|
+
return getConversationSummaryOp(
|
|
15838
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
15839
|
+
conversationId
|
|
15840
|
+
);
|
|
15801
15841
|
}
|
|
15802
15842
|
upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
|
|
15803
15843
|
return upsertConversationSummaryOp(
|
|
15804
|
-
createSummaryContext(this.ctx.database),
|
|
15844
|
+
createSummaryContext(this.ctx.database, this.ctx),
|
|
15805
15845
|
conversationId,
|
|
15806
15846
|
summary,
|
|
15807
15847
|
summarizedUpTo,
|
|
@@ -34098,7 +34138,7 @@ async function summarizeHistoryAtRevision(options, revision2) {
|
|
|
34098
34138
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
34099
34139
|
return {
|
|
34100
34140
|
messagesToConvert: messages,
|
|
34101
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
34141
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
34102
34142
|
};
|
|
34103
34143
|
} catch {
|
|
34104
34144
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -34153,14 +34193,15 @@ async function doSummarizeHistory(options, revision2) {
|
|
|
34153
34193
|
} = options;
|
|
34154
34194
|
try {
|
|
34155
34195
|
const summaries = summaryStore(options);
|
|
34156
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
34196
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
34157
34197
|
assertConversationRevision(database, conversationId, revision2);
|
|
34158
|
-
|
|
34159
|
-
|
|
34160
|
-
);
|
|
34161
|
-
});
|
|
34198
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
34199
|
+
};
|
|
34162
34200
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
34163
34201
|
assertConversationRevision(database, conversationId, revision2);
|
|
34202
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
34203
|
+
throw new Error("The cached summary could not be decrypted");
|
|
34204
|
+
}
|
|
34164
34205
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
34165
34206
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
34166
34207
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
package/dist/server/index.cjs
CHANGED
|
@@ -25480,17 +25480,19 @@ init_clientConfig();
|
|
|
25480
25480
|
|
|
25481
25481
|
// src/lib/db/chat/summaryOperations.ts
|
|
25482
25482
|
var import_watermelondb4 = __toESM(require_watermelondb());
|
|
25483
|
-
|
|
25483
|
+
init_logger();
|
|
25484
|
+
function createSummaryContext(database, encryption = {}) {
|
|
25484
25485
|
return {
|
|
25486
|
+
...encryption,
|
|
25485
25487
|
database,
|
|
25486
25488
|
summariesCollection: database.get("conversation_summaries")
|
|
25487
25489
|
};
|
|
25488
25490
|
}
|
|
25489
|
-
function modelToStored(record) {
|
|
25491
|
+
function modelToStored(record, summary) {
|
|
25490
25492
|
return {
|
|
25491
25493
|
uniqueId: record.id,
|
|
25492
25494
|
conversationId: record.conversationId,
|
|
25493
|
-
summary
|
|
25495
|
+
summary,
|
|
25494
25496
|
summarizedUpTo: record.summarizedUpTo,
|
|
25495
25497
|
tokenCount: record.tokenCount,
|
|
25496
25498
|
createdAt: record.createdAt,
|
|
@@ -25500,28 +25502,62 @@ function modelToStored(record) {
|
|
|
25500
25502
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
25501
25503
|
const results = await ctx.summariesCollection.query(import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
25502
25504
|
if (results.length === 0) return null;
|
|
25503
|
-
|
|
25505
|
+
const record = results[0];
|
|
25506
|
+
const stored = modelToStored(record, record.summary);
|
|
25507
|
+
if (ctx.walletAddress && isEncrypted(stored.summary)) {
|
|
25508
|
+
if (ctx.signMessage) {
|
|
25509
|
+
try {
|
|
25510
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
25511
|
+
} catch (error) {
|
|
25512
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
25513
|
+
}
|
|
25514
|
+
}
|
|
25515
|
+
stored.summary = await decryptField(stored.summary, ctx.walletAddress);
|
|
25516
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored.summary) {
|
|
25517
|
+
try {
|
|
25518
|
+
const encryptedSummary = await encryptField(
|
|
25519
|
+
stored.summary,
|
|
25520
|
+
ctx.walletAddress,
|
|
25521
|
+
ctx.signMessage,
|
|
25522
|
+
ctx.embeddedWalletSigner
|
|
25523
|
+
);
|
|
25524
|
+
await ctx.database.write(async () => {
|
|
25525
|
+
const current = await ctx.summariesCollection.query(import_watermelondb4.Q.where("id", record.id)).fetch();
|
|
25526
|
+
if (current[0]?.summary === stored.summary) {
|
|
25527
|
+
await current[0].update((rec) => {
|
|
25528
|
+
rec.summary = encryptedSummary;
|
|
25529
|
+
});
|
|
25530
|
+
}
|
|
25531
|
+
});
|
|
25532
|
+
} catch (error) {
|
|
25533
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
25534
|
+
}
|
|
25535
|
+
}
|
|
25536
|
+
return stored;
|
|
25504
25537
|
}
|
|
25505
25538
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
25539
|
+
const revision = getConversationRevision(ctx.database, conversationId);
|
|
25506
25540
|
let record;
|
|
25541
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
25507
25542
|
await ctx.database.write(async () => {
|
|
25543
|
+
assertConversationRevision(ctx.database, conversationId, revision);
|
|
25508
25544
|
const existing = await ctx.summariesCollection.query(import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
25509
25545
|
if (existing.length > 0) {
|
|
25510
25546
|
record = await existing[0].update((rec) => {
|
|
25511
|
-
rec.summary =
|
|
25547
|
+
rec.summary = encryptedSummary;
|
|
25512
25548
|
rec.summarizedUpTo = summarizedUpTo;
|
|
25513
25549
|
rec.tokenCount = tokenCount;
|
|
25514
25550
|
});
|
|
25515
25551
|
} else {
|
|
25516
25552
|
record = await ctx.summariesCollection.create((rec) => {
|
|
25517
25553
|
rec.conversationId = conversationId;
|
|
25518
|
-
rec.summary =
|
|
25554
|
+
rec.summary = encryptedSummary;
|
|
25519
25555
|
rec.summarizedUpTo = summarizedUpTo;
|
|
25520
25556
|
rec.tokenCount = tokenCount;
|
|
25521
25557
|
});
|
|
25522
25558
|
}
|
|
25523
25559
|
});
|
|
25524
|
-
return modelToStored(record);
|
|
25560
|
+
return modelToStored(record, summary);
|
|
25525
25561
|
}
|
|
25526
25562
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
25527
25563
|
await ctx.database.write(async () => {
|
|
@@ -25789,7 +25825,7 @@ async function summarizeHistoryAtRevision(options, revision) {
|
|
|
25789
25825
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
25790
25826
|
return {
|
|
25791
25827
|
messagesToConvert: messages,
|
|
25792
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
25828
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
25793
25829
|
};
|
|
25794
25830
|
} catch {
|
|
25795
25831
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -25844,14 +25880,15 @@ async function doSummarizeHistory(options, revision) {
|
|
|
25844
25880
|
} = options;
|
|
25845
25881
|
try {
|
|
25846
25882
|
const summaries = summaryStore(options);
|
|
25847
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
25883
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
25848
25884
|
assertConversationRevision(database, conversationId, revision);
|
|
25849
|
-
|
|
25850
|
-
|
|
25851
|
-
);
|
|
25852
|
-
});
|
|
25885
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
25886
|
+
};
|
|
25853
25887
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
25854
25888
|
assertConversationRevision(database, conversationId, revision);
|
|
25889
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
25890
|
+
throw new Error("The cached summary could not be decrypted");
|
|
25891
|
+
}
|
|
25855
25892
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
25856
25893
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
25857
25894
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
package/dist/server/index.d.mts
CHANGED
|
@@ -8028,12 +8028,12 @@ declare function clearLazyTitleCache(): void;
|
|
|
8028
8028
|
declare function decryptConversationTitle(encryptedTitle: string, address: string): Promise<string>;
|
|
8029
8029
|
|
|
8030
8030
|
/** Context needed for summary operations */
|
|
8031
|
-
interface SummaryOperationsContext {
|
|
8031
|
+
interface SummaryOperationsContext extends Pick<StorageOperationsContext, "walletAddress" | "signMessage" | "embeddedWalletSigner"> {
|
|
8032
8032
|
database: Database;
|
|
8033
8033
|
summariesCollection: Collection<ConversationSummary>;
|
|
8034
8034
|
}
|
|
8035
8035
|
/** Create a summary operations context from a database instance */
|
|
8036
|
-
declare function createSummaryContext(database: Database): SummaryOperationsContext;
|
|
8036
|
+
declare function createSummaryContext(database: Database, encryption?: Pick<SummaryOperationsContext, "walletAddress" | "signMessage" | "embeddedWalletSigner">): SummaryOperationsContext;
|
|
8037
8037
|
/**
|
|
8038
8038
|
* Get the cached summary for a conversation.
|
|
8039
8039
|
* Returns null if no summary exists yet.
|
package/dist/server/index.d.ts
CHANGED
|
@@ -8028,12 +8028,12 @@ declare function clearLazyTitleCache(): void;
|
|
|
8028
8028
|
declare function decryptConversationTitle(encryptedTitle: string, address: string): Promise<string>;
|
|
8029
8029
|
|
|
8030
8030
|
/** Context needed for summary operations */
|
|
8031
|
-
interface SummaryOperationsContext {
|
|
8031
|
+
interface SummaryOperationsContext extends Pick<StorageOperationsContext, "walletAddress" | "signMessage" | "embeddedWalletSigner"> {
|
|
8032
8032
|
database: Database;
|
|
8033
8033
|
summariesCollection: Collection<ConversationSummary>;
|
|
8034
8034
|
}
|
|
8035
8035
|
/** Create a summary operations context from a database instance */
|
|
8036
|
-
declare function createSummaryContext(database: Database): SummaryOperationsContext;
|
|
8036
|
+
declare function createSummaryContext(database: Database, encryption?: Pick<SummaryOperationsContext, "walletAddress" | "signMessage" | "embeddedWalletSigner">): SummaryOperationsContext;
|
|
8037
8037
|
/**
|
|
8038
8038
|
* Get the cached summary for a conversation.
|
|
8039
8039
|
* Returns null if no summary exists yet.
|
package/dist/server/index.mjs
CHANGED
|
@@ -23753,17 +23753,18 @@ function createStockPricePreProcessor(options = {}) {
|
|
|
23753
23753
|
|
|
23754
23754
|
// src/lib/db/chat/summaryOperations.ts
|
|
23755
23755
|
var import_watermelondb4 = __toESM(require_watermelondb());
|
|
23756
|
-
function createSummaryContext(database) {
|
|
23756
|
+
function createSummaryContext(database, encryption = {}) {
|
|
23757
23757
|
return {
|
|
23758
|
+
...encryption,
|
|
23758
23759
|
database,
|
|
23759
23760
|
summariesCollection: database.get("conversation_summaries")
|
|
23760
23761
|
};
|
|
23761
23762
|
}
|
|
23762
|
-
function modelToStored(record) {
|
|
23763
|
+
function modelToStored(record, summary) {
|
|
23763
23764
|
return {
|
|
23764
23765
|
uniqueId: record.id,
|
|
23765
23766
|
conversationId: record.conversationId,
|
|
23766
|
-
summary
|
|
23767
|
+
summary,
|
|
23767
23768
|
summarizedUpTo: record.summarizedUpTo,
|
|
23768
23769
|
tokenCount: record.tokenCount,
|
|
23769
23770
|
createdAt: record.createdAt,
|
|
@@ -23773,28 +23774,62 @@ function modelToStored(record) {
|
|
|
23773
23774
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
23774
23775
|
const results = await ctx.summariesCollection.query(import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
23775
23776
|
if (results.length === 0) return null;
|
|
23776
|
-
|
|
23777
|
+
const record = results[0];
|
|
23778
|
+
const stored = modelToStored(record, record.summary);
|
|
23779
|
+
if (ctx.walletAddress && isEncrypted(stored.summary)) {
|
|
23780
|
+
if (ctx.signMessage) {
|
|
23781
|
+
try {
|
|
23782
|
+
await requestEncryptionKey(ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
23783
|
+
} catch (error) {
|
|
23784
|
+
getLogger().warn("Failed to request the encryption key for the summary:", error);
|
|
23785
|
+
}
|
|
23786
|
+
}
|
|
23787
|
+
stored.summary = await decryptField(stored.summary, ctx.walletAddress);
|
|
23788
|
+
} else if (ctx.walletAddress && ctx.signMessage && stored.summary) {
|
|
23789
|
+
try {
|
|
23790
|
+
const encryptedSummary = await encryptField(
|
|
23791
|
+
stored.summary,
|
|
23792
|
+
ctx.walletAddress,
|
|
23793
|
+
ctx.signMessage,
|
|
23794
|
+
ctx.embeddedWalletSigner
|
|
23795
|
+
);
|
|
23796
|
+
await ctx.database.write(async () => {
|
|
23797
|
+
const current = await ctx.summariesCollection.query(import_watermelondb4.Q.where("id", record.id)).fetch();
|
|
23798
|
+
if (current[0]?.summary === stored.summary) {
|
|
23799
|
+
await current[0].update((rec) => {
|
|
23800
|
+
rec.summary = encryptedSummary;
|
|
23801
|
+
});
|
|
23802
|
+
}
|
|
23803
|
+
});
|
|
23804
|
+
} catch (error) {
|
|
23805
|
+
getLogger().warn("Failed to encrypt the legacy summary:", error);
|
|
23806
|
+
}
|
|
23807
|
+
}
|
|
23808
|
+
return stored;
|
|
23777
23809
|
}
|
|
23778
23810
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
23811
|
+
const revision = getConversationRevision(ctx.database, conversationId);
|
|
23779
23812
|
let record;
|
|
23813
|
+
const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
|
|
23780
23814
|
await ctx.database.write(async () => {
|
|
23815
|
+
assertConversationRevision(ctx.database, conversationId, revision);
|
|
23781
23816
|
const existing = await ctx.summariesCollection.query(import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
23782
23817
|
if (existing.length > 0) {
|
|
23783
23818
|
record = await existing[0].update((rec) => {
|
|
23784
|
-
rec.summary =
|
|
23819
|
+
rec.summary = encryptedSummary;
|
|
23785
23820
|
rec.summarizedUpTo = summarizedUpTo;
|
|
23786
23821
|
rec.tokenCount = tokenCount;
|
|
23787
23822
|
});
|
|
23788
23823
|
} else {
|
|
23789
23824
|
record = await ctx.summariesCollection.create((rec) => {
|
|
23790
23825
|
rec.conversationId = conversationId;
|
|
23791
|
-
rec.summary =
|
|
23826
|
+
rec.summary = encryptedSummary;
|
|
23792
23827
|
rec.summarizedUpTo = summarizedUpTo;
|
|
23793
23828
|
rec.tokenCount = tokenCount;
|
|
23794
23829
|
});
|
|
23795
23830
|
}
|
|
23796
23831
|
});
|
|
23797
|
-
return modelToStored(record);
|
|
23832
|
+
return modelToStored(record, summary);
|
|
23798
23833
|
}
|
|
23799
23834
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
23800
23835
|
await ctx.database.write(async () => {
|
|
@@ -24059,7 +24094,7 @@ async function summarizeHistoryAtRevision(options, revision) {
|
|
|
24059
24094
|
const cachedSummary = await summaryStore(options).getSummary(conversationId);
|
|
24060
24095
|
return {
|
|
24061
24096
|
messagesToConvert: messages,
|
|
24062
|
-
summarySystemMessage: cachedSummary?.summary ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
24097
|
+
summarySystemMessage: cachedSummary?.summary && !isEncrypted(cachedSummary.summary) ? summaryToSystemMessage(cachedSummary.summary) : null
|
|
24063
24098
|
};
|
|
24064
24099
|
} catch {
|
|
24065
24100
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -24114,14 +24149,15 @@ async function doSummarizeHistory(options, revision) {
|
|
|
24114
24149
|
} = options;
|
|
24115
24150
|
try {
|
|
24116
24151
|
const summaries = summaryStore(options);
|
|
24117
|
-
const persistSummary = (summary, summarizedUpTo, tokenCount) =>
|
|
24152
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => {
|
|
24118
24153
|
assertConversationRevision(database, conversationId, revision);
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
);
|
|
24122
|
-
});
|
|
24154
|
+
return summaries.upsertSummary(conversationId, summary, summarizedUpTo, tokenCount);
|
|
24155
|
+
};
|
|
24123
24156
|
let cachedSummary = await summaries.getSummary(conversationId);
|
|
24124
24157
|
assertConversationRevision(database, conversationId, revision);
|
|
24158
|
+
if (cachedSummary && isEncrypted(cachedSummary.summary)) {
|
|
24159
|
+
throw new Error("The cached summary could not be decrypted");
|
|
24160
|
+
}
|
|
24125
24161
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
24126
24162
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
24127
24163
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|