@anuma/sdk 10.0.1 → 10.0.3
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 +280 -222
- package/dist/expo/index.mjs +226 -168
- package/dist/react/index.cjs +303 -245
- package/dist/react/index.mjs +234 -176
- package/dist/server/index.cjs +1429 -1371
- package/dist/server/index.d.mts +1 -8
- package/dist/server/index.d.ts +1 -8
- package/dist/server/index.mjs +262 -204
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -2079,7 +2079,7 @@ ${appendix}` : appendix;
|
|
|
2079
2079
|
}
|
|
2080
2080
|
|
|
2081
2081
|
// src/lib/db/chat/operations.ts
|
|
2082
|
-
var
|
|
2082
|
+
var import_watermelondb4 = require("@nozbe/watermelondb");
|
|
2083
2083
|
var import_uuid2 = require("uuid");
|
|
2084
2084
|
|
|
2085
2085
|
// src/react/useEncryption.ts
|
|
@@ -3302,8 +3302,162 @@ async function assembleDecryptedMessage(message, address) {
|
|
|
3302
3302
|
return result;
|
|
3303
3303
|
}
|
|
3304
3304
|
|
|
3305
|
-
// src/lib/db/chat/
|
|
3305
|
+
// src/lib/db/chat/models.ts
|
|
3306
3306
|
var import_watermelondb2 = require("@nozbe/watermelondb");
|
|
3307
|
+
var import_decorators = require("@nozbe/watermelondb/decorators");
|
|
3308
|
+
var Message = class extends import_watermelondb2.Model {
|
|
3309
|
+
};
|
|
3310
|
+
Message.table = "history";
|
|
3311
|
+
Message.associations = {
|
|
3312
|
+
conversations: { type: "belongs_to", key: "conversation_id" },
|
|
3313
|
+
media: { type: "has_many", foreignKey: "message_id" }
|
|
3314
|
+
};
|
|
3315
|
+
__decorateClass([
|
|
3316
|
+
(0, import_decorators.field)("message_id")
|
|
3317
|
+
], Message.prototype, "messageId", 2);
|
|
3318
|
+
__decorateClass([
|
|
3319
|
+
(0, import_decorators.text)("conversation_id")
|
|
3320
|
+
], Message.prototype, "conversationId", 2);
|
|
3321
|
+
__decorateClass([
|
|
3322
|
+
(0, import_decorators.text)("role")
|
|
3323
|
+
], Message.prototype, "role", 2);
|
|
3324
|
+
__decorateClass([
|
|
3325
|
+
(0, import_decorators.text)("content")
|
|
3326
|
+
], Message.prototype, "content", 2);
|
|
3327
|
+
__decorateClass([
|
|
3328
|
+
(0, import_decorators.text)("model")
|
|
3329
|
+
], Message.prototype, "model", 2);
|
|
3330
|
+
__decorateClass([
|
|
3331
|
+
(0, import_decorators.text)("image_model")
|
|
3332
|
+
], Message.prototype, "imageModel", 2);
|
|
3333
|
+
__decorateClass([
|
|
3334
|
+
(0, import_decorators.json)("files", (raw) => raw)
|
|
3335
|
+
], Message.prototype, "files", 2);
|
|
3336
|
+
__decorateClass([
|
|
3337
|
+
(0, import_decorators.json)("file_ids", (raw) => raw)
|
|
3338
|
+
], Message.prototype, "fileIds", 2);
|
|
3339
|
+
__decorateClass([
|
|
3340
|
+
(0, import_decorators.date)("created_at")
|
|
3341
|
+
], Message.prototype, "createdAt", 2);
|
|
3342
|
+
__decorateClass([
|
|
3343
|
+
(0, import_decorators.date)("updated_at")
|
|
3344
|
+
], Message.prototype, "updatedAt", 2);
|
|
3345
|
+
__decorateClass([
|
|
3346
|
+
(0, import_decorators.json)("vector", (raw) => raw)
|
|
3347
|
+
], Message.prototype, "vector", 2);
|
|
3348
|
+
__decorateClass([
|
|
3349
|
+
(0, import_decorators.text)("embedding_model")
|
|
3350
|
+
], Message.prototype, "embeddingModel", 2);
|
|
3351
|
+
__decorateClass([
|
|
3352
|
+
(0, import_decorators.json)("chunks", (raw) => raw)
|
|
3353
|
+
], Message.prototype, "chunks", 2);
|
|
3354
|
+
__decorateClass([
|
|
3355
|
+
(0, import_decorators.json)("usage", (raw) => raw)
|
|
3356
|
+
], Message.prototype, "usage", 2);
|
|
3357
|
+
__decorateClass([
|
|
3358
|
+
(0, import_decorators.json)("sources", (raw) => raw)
|
|
3359
|
+
], Message.prototype, "sources", 2);
|
|
3360
|
+
__decorateClass([
|
|
3361
|
+
(0, import_decorators.field)("response_duration")
|
|
3362
|
+
], Message.prototype, "responseDuration", 2);
|
|
3363
|
+
__decorateClass([
|
|
3364
|
+
(0, import_decorators.field)("was_stopped")
|
|
3365
|
+
], Message.prototype, "wasStopped", 2);
|
|
3366
|
+
__decorateClass([
|
|
3367
|
+
(0, import_decorators.text)("error")
|
|
3368
|
+
], Message.prototype, "error", 2);
|
|
3369
|
+
__decorateClass([
|
|
3370
|
+
(0, import_decorators.json)("thought_process", (raw) => raw)
|
|
3371
|
+
], Message.prototype, "thoughtProcess", 2);
|
|
3372
|
+
__decorateClass([
|
|
3373
|
+
(0, import_decorators.text)("thinking")
|
|
3374
|
+
], Message.prototype, "thinking", 2);
|
|
3375
|
+
__decorateClass([
|
|
3376
|
+
(0, import_decorators.text)("parent_message_id")
|
|
3377
|
+
], Message.prototype, "parentMessageId", 2);
|
|
3378
|
+
__decorateClass([
|
|
3379
|
+
(0, import_decorators.text)("feedback")
|
|
3380
|
+
], Message.prototype, "feedback", 2);
|
|
3381
|
+
__decorateClass([
|
|
3382
|
+
(0, import_decorators.json)("tool_call_events", (raw) => raw)
|
|
3383
|
+
], Message.prototype, "toolCallEvents", 2);
|
|
3384
|
+
__decorateClass([
|
|
3385
|
+
(0, import_decorators.text)("origin")
|
|
3386
|
+
], Message.prototype, "origin", 2);
|
|
3387
|
+
var Conversation = class extends import_watermelondb2.Model {
|
|
3388
|
+
};
|
|
3389
|
+
Conversation.table = "conversations";
|
|
3390
|
+
Conversation.associations = {
|
|
3391
|
+
history: { type: "has_many", foreignKey: "conversation_id" },
|
|
3392
|
+
projects: { type: "belongs_to", key: "project_id" }
|
|
3393
|
+
};
|
|
3394
|
+
__decorateClass([
|
|
3395
|
+
(0, import_decorators.text)("conversation_id")
|
|
3396
|
+
], Conversation.prototype, "conversationId", 2);
|
|
3397
|
+
__decorateClass([
|
|
3398
|
+
(0, import_decorators.text)("title")
|
|
3399
|
+
], Conversation.prototype, "title", 2);
|
|
3400
|
+
__decorateClass([
|
|
3401
|
+
(0, import_decorators.text)("project_id")
|
|
3402
|
+
], Conversation.prototype, "projectId", 2);
|
|
3403
|
+
__decorateClass([
|
|
3404
|
+
(0, import_decorators.date)("created_at")
|
|
3405
|
+
], Conversation.prototype, "createdAt", 2);
|
|
3406
|
+
__decorateClass([
|
|
3407
|
+
(0, import_decorators.date)("updated_at")
|
|
3408
|
+
], Conversation.prototype, "updatedAt", 2);
|
|
3409
|
+
__decorateClass([
|
|
3410
|
+
(0, import_decorators.field)("is_deleted")
|
|
3411
|
+
], Conversation.prototype, "isDeleted", 2);
|
|
3412
|
+
__decorateClass([
|
|
3413
|
+
(0, import_decorators.date)("pinned_at")
|
|
3414
|
+
], Conversation.prototype, "pinnedAt", 2);
|
|
3415
|
+
var ConversationSummary = class extends import_watermelondb2.Model {
|
|
3416
|
+
};
|
|
3417
|
+
ConversationSummary.table = "conversation_summaries";
|
|
3418
|
+
ConversationSummary.associations = {
|
|
3419
|
+
conversations: { type: "belongs_to", key: "conversation_id" }
|
|
3420
|
+
};
|
|
3421
|
+
__decorateClass([
|
|
3422
|
+
(0, import_decorators.text)("conversation_id")
|
|
3423
|
+
], ConversationSummary.prototype, "conversationId", 2);
|
|
3424
|
+
__decorateClass([
|
|
3425
|
+
(0, import_decorators.text)("summary")
|
|
3426
|
+
], ConversationSummary.prototype, "summary", 2);
|
|
3427
|
+
__decorateClass([
|
|
3428
|
+
(0, import_decorators.text)("summarized_up_to")
|
|
3429
|
+
], ConversationSummary.prototype, "summarizedUpTo", 2);
|
|
3430
|
+
__decorateClass([
|
|
3431
|
+
(0, import_decorators.field)("token_count")
|
|
3432
|
+
], ConversationSummary.prototype, "tokenCount", 2);
|
|
3433
|
+
__decorateClass([
|
|
3434
|
+
(0, import_decorators.date)("created_at")
|
|
3435
|
+
], ConversationSummary.prototype, "createdAt", 2);
|
|
3436
|
+
__decorateClass([
|
|
3437
|
+
(0, import_decorators.date)("updated_at")
|
|
3438
|
+
], ConversationSummary.prototype, "updatedAt", 2);
|
|
3439
|
+
|
|
3440
|
+
// src/lib/db/chat/summaryRevision.ts
|
|
3441
|
+
var conversationRevisions = /* @__PURE__ */ new WeakMap();
|
|
3442
|
+
function getConversationRevision(database, conversationId) {
|
|
3443
|
+
return conversationRevisions.get(database)?.get(conversationId) ?? 0;
|
|
3444
|
+
}
|
|
3445
|
+
function advanceConversationRevision(database, conversationId) {
|
|
3446
|
+
let revisions = conversationRevisions.get(database);
|
|
3447
|
+
if (!revisions) {
|
|
3448
|
+
revisions = /* @__PURE__ */ new Map();
|
|
3449
|
+
conversationRevisions.set(database, revisions);
|
|
3450
|
+
}
|
|
3451
|
+
revisions.set(conversationId, getConversationRevision(database, conversationId) + 1);
|
|
3452
|
+
}
|
|
3453
|
+
function assertConversationRevision(database, conversationId, revision2) {
|
|
3454
|
+
if (getConversationRevision(database, conversationId) !== revision2) {
|
|
3455
|
+
throw new Error("The conversation changed during summarization. Retry the request.");
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
// src/lib/db/chat/toolCallEventIndex.ts
|
|
3460
|
+
var import_watermelondb3 = require("@nozbe/watermelondb");
|
|
3307
3461
|
function parseEventIds(value) {
|
|
3308
3462
|
const ids = /* @__PURE__ */ new Set();
|
|
3309
3463
|
let events;
|
|
@@ -3323,7 +3477,7 @@ function parseEventIds(value) {
|
|
|
3323
3477
|
async function fetchEventRows(collection, conversationId) {
|
|
3324
3478
|
try {
|
|
3325
3479
|
return await collection.query(
|
|
3326
|
-
|
|
3480
|
+
import_watermelondb3.Q.unsafeSqlQuery(
|
|
3327
3481
|
`select "id", "tool_call_events" from "history" where "conversation_id" = ? and "_status" != 'deleted' and "tool_call_events" is not null and "tool_call_events" not in ('', '[]')`,
|
|
3328
3482
|
[conversationId]
|
|
3329
3483
|
)
|
|
@@ -3333,10 +3487,10 @@ async function fetchEventRows(collection, conversationId) {
|
|
|
3333
3487
|
throw error;
|
|
3334
3488
|
}
|
|
3335
3489
|
return await collection.query(
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3490
|
+
import_watermelondb3.Q.where("conversation_id", conversationId),
|
|
3491
|
+
import_watermelondb3.Q.where("tool_call_events", import_watermelondb3.Q.notEq(null)),
|
|
3492
|
+
import_watermelondb3.Q.where("tool_call_events", import_watermelondb3.Q.notIn(["", "[]"])),
|
|
3493
|
+
import_watermelondb3.Q.unsafeLokiTransform(
|
|
3340
3494
|
(rows) => rows.map(({ id: id2, tool_call_events }) => ({ id: id2, tool_call_events }))
|
|
3341
3495
|
)
|
|
3342
3496
|
).unsafeFetchRaw();
|
|
@@ -3806,7 +3960,7 @@ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation"
|
|
|
3806
3960
|
);
|
|
3807
3961
|
}
|
|
3808
3962
|
async function getConversationOp(ctx, id2) {
|
|
3809
|
-
const results = await ctx.conversationsCollection.query(
|
|
3963
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("conversation_id", id2), import_watermelondb4.Q.where("is_deleted", false)).fetch();
|
|
3810
3964
|
return results.length > 0 ? await conversationToStored(
|
|
3811
3965
|
results[0],
|
|
3812
3966
|
ctx.walletAddress,
|
|
@@ -3815,7 +3969,7 @@ async function getConversationOp(ctx, id2) {
|
|
|
3815
3969
|
) : null;
|
|
3816
3970
|
}
|
|
3817
3971
|
async function getConversationsOp(ctx) {
|
|
3818
|
-
const results = await ctx.conversationsCollection.query(
|
|
3972
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("is_deleted", false), import_watermelondb4.Q.sortBy("created_at", import_watermelondb4.Q.desc)).unsafeFetchRaw();
|
|
3819
3973
|
return Promise.all(
|
|
3820
3974
|
results.map(
|
|
3821
3975
|
(raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -3836,33 +3990,33 @@ function conversationRawToLazyStored(raw) {
|
|
|
3836
3990
|
};
|
|
3837
3991
|
}
|
|
3838
3992
|
async function getConversationsLazyOp(ctx) {
|
|
3839
|
-
const results = await ctx.conversationsCollection.query(
|
|
3993
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("is_deleted", false), import_watermelondb4.Q.sortBy("created_at", import_watermelondb4.Q.desc)).unsafeFetchRaw();
|
|
3840
3994
|
return results.map(conversationRawToLazyStored);
|
|
3841
3995
|
}
|
|
3842
3996
|
async function getConversationsPageOp(ctx, options) {
|
|
3843
3997
|
const limit = Math.floor(options?.limit ?? 200);
|
|
3844
3998
|
if (!Number.isFinite(limit) || limit < 1) return [];
|
|
3845
3999
|
const exclude = new Set(options?.boundaryExcludeUniqueIds ?? []);
|
|
3846
|
-
const clauses = [
|
|
4000
|
+
const clauses = [import_watermelondb4.Q.where("is_deleted", false)];
|
|
3847
4001
|
if (options?.before !== void 0) {
|
|
3848
4002
|
clauses.push(
|
|
3849
|
-
exclude.size > 0 ?
|
|
4003
|
+
exclude.size > 0 ? import_watermelondb4.Q.where("created_at", import_watermelondb4.Q.lte(options.before)) : import_watermelondb4.Q.where("created_at", import_watermelondb4.Q.lt(options.before))
|
|
3850
4004
|
);
|
|
3851
4005
|
}
|
|
3852
|
-
const fetched = await ctx.conversationsCollection.query(...clauses,
|
|
4006
|
+
const fetched = await ctx.conversationsCollection.query(...clauses, import_watermelondb4.Q.sortBy("created_at", import_watermelondb4.Q.desc), import_watermelondb4.Q.take(limit + exclude.size)).unsafeFetchRaw();
|
|
3853
4007
|
const results = exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched;
|
|
3854
4008
|
return results.slice(0, limit).map(conversationRawToLazyStored);
|
|
3855
4009
|
}
|
|
3856
4010
|
async function getConversationsByProjectLazyOp(ctx, projectId) {
|
|
3857
4011
|
const results = await ctx.conversationsCollection.query(
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
4012
|
+
import_watermelondb4.Q.where("project_id", projectId === null ? "" : projectId),
|
|
4013
|
+
import_watermelondb4.Q.where("is_deleted", false),
|
|
4014
|
+
import_watermelondb4.Q.sortBy("created_at", import_watermelondb4.Q.desc)
|
|
3861
4015
|
).unsafeFetchRaw();
|
|
3862
4016
|
return results.map(conversationRawToLazyStored);
|
|
3863
4017
|
}
|
|
3864
4018
|
async function updateConversationTitleOp(ctx, id2, title) {
|
|
3865
|
-
const results = await ctx.conversationsCollection.query(
|
|
4019
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("conversation_id", id2), import_watermelondb4.Q.where("is_deleted", false)).fetch();
|
|
3866
4020
|
if (results.length > 0) {
|
|
3867
4021
|
const encryptedOpts = ctx.walletAddress && ctx.signMessage ? await encryptConversationFields(
|
|
3868
4022
|
{ title },
|
|
@@ -3881,13 +4035,13 @@ async function updateConversationTitleOp(ctx, id2, title) {
|
|
|
3881
4035
|
return false;
|
|
3882
4036
|
}
|
|
3883
4037
|
async function deleteConversationOp(ctx, id2) {
|
|
3884
|
-
const results = await ctx.conversationsCollection.query(
|
|
4038
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("conversation_id", id2), import_watermelondb4.Q.where("is_deleted", false)).fetch();
|
|
3885
4039
|
if (results.length > 0) {
|
|
3886
4040
|
await ctx.database.write(async () => {
|
|
3887
4041
|
await results[0].update((conv) => {
|
|
3888
4042
|
conv._setRaw("is_deleted", true);
|
|
3889
4043
|
});
|
|
3890
|
-
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(
|
|
4044
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb4.Q.where("conversation_id", id2)).fetch() : [];
|
|
3891
4045
|
for (const job of jobs) await job.destroyPermanently();
|
|
3892
4046
|
});
|
|
3893
4047
|
return true;
|
|
@@ -3895,7 +4049,7 @@ async function deleteConversationOp(ctx, id2) {
|
|
|
3895
4049
|
return false;
|
|
3896
4050
|
}
|
|
3897
4051
|
async function updateConversationPinnedOp(ctx, id2, pinned) {
|
|
3898
|
-
const results = await ctx.conversationsCollection.query(
|
|
4052
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("conversation_id", id2), import_watermelondb4.Q.where("is_deleted", false)).fetch();
|
|
3899
4053
|
if (results.length > 0) {
|
|
3900
4054
|
await ctx.database.write(async () => {
|
|
3901
4055
|
await results[0].update((conv) => {
|
|
@@ -3907,7 +4061,7 @@ async function updateConversationPinnedOp(ctx, id2, pinned) {
|
|
|
3907
4061
|
return false;
|
|
3908
4062
|
}
|
|
3909
4063
|
async function getMessagesOp(ctx, convId, opts) {
|
|
3910
|
-
const fetched = await ctx.messagesCollection.query(
|
|
4064
|
+
const fetched = await ctx.messagesCollection.query(import_watermelondb4.Q.where("conversation_id", convId), import_watermelondb4.Q.sortBy("message_id", import_watermelondb4.Q.asc)).unsafeFetchRaw();
|
|
3911
4065
|
const results = opts?.rawFilter ? fetched.filter(opts.rawFilter) : fetched;
|
|
3912
4066
|
return Promise.all(
|
|
3913
4067
|
results.map(
|
|
@@ -3916,19 +4070,19 @@ async function getMessagesOp(ctx, convId, opts) {
|
|
|
3916
4070
|
);
|
|
3917
4071
|
}
|
|
3918
4072
|
async function getMessageCountOp(ctx, convId) {
|
|
3919
|
-
return await ctx.messagesCollection.query(
|
|
4073
|
+
return await ctx.messagesCollection.query(import_watermelondb4.Q.where("conversation_id", convId)).fetchCount();
|
|
3920
4074
|
}
|
|
3921
4075
|
async function getMessagesPageOp(ctx, convId, opts) {
|
|
3922
4076
|
const limit = Math.floor(opts.limit);
|
|
3923
4077
|
if (!Number.isFinite(limit) || limit < 1) return [];
|
|
3924
4078
|
const exclude = new Set(opts.boundaryExcludeUniqueIds ?? []);
|
|
3925
|
-
const clauses = [
|
|
4079
|
+
const clauses = [import_watermelondb4.Q.where("conversation_id", convId)];
|
|
3926
4080
|
if (opts.beforeMessageId !== void 0) {
|
|
3927
4081
|
clauses.push(
|
|
3928
|
-
exclude.size > 0 ?
|
|
4082
|
+
exclude.size > 0 ? import_watermelondb4.Q.where("message_id", import_watermelondb4.Q.lte(opts.beforeMessageId)) : import_watermelondb4.Q.where("message_id", import_watermelondb4.Q.lt(opts.beforeMessageId))
|
|
3929
4083
|
);
|
|
3930
4084
|
}
|
|
3931
|
-
const fetched = await ctx.messagesCollection.query(...clauses,
|
|
4085
|
+
const fetched = await ctx.messagesCollection.query(...clauses, import_watermelondb4.Q.sortBy("message_id", import_watermelondb4.Q.desc), import_watermelondb4.Q.take(limit + exclude.size)).unsafeFetchRaw();
|
|
3932
4086
|
const results = (exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched).slice(0, limit);
|
|
3933
4087
|
results.reverse();
|
|
3934
4088
|
return Promise.all(
|
|
@@ -3940,7 +4094,7 @@ async function getMessagesPageOp(ctx, convId, opts) {
|
|
|
3940
4094
|
);
|
|
3941
4095
|
}
|
|
3942
4096
|
async function getMessageSkeletonsOp(ctx, convId) {
|
|
3943
|
-
const results = await ctx.messagesCollection.query(
|
|
4097
|
+
const results = await ctx.messagesCollection.query(import_watermelondb4.Q.where("conversation_id", convId), import_watermelondb4.Q.sortBy("message_id", import_watermelondb4.Q.asc)).unsafeFetchRaw();
|
|
3944
4098
|
const roleById = /* @__PURE__ */ new Map();
|
|
3945
4099
|
for (const raw of results) {
|
|
3946
4100
|
roleById.set(raw.id, raw.role);
|
|
@@ -3987,10 +4141,22 @@ async function getMessageSkeletonsOp(ctx, convId) {
|
|
|
3987
4141
|
async function getToolCallEventIdsOp(ctx, convId) {
|
|
3988
4142
|
return getToolCallEventIds(ctx.messagesCollection, convId);
|
|
3989
4143
|
}
|
|
4144
|
+
async function invalidateConversationSummary(ctx, conversationId, changedMessageId) {
|
|
4145
|
+
if (!ctx.database.schema?.tables[ConversationSummary.table]) return;
|
|
4146
|
+
const summaries = await ctx.database.get(ConversationSummary.table).query(import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
4147
|
+
for (const summary of summaries) {
|
|
4148
|
+
if (changedMessageId !== void 0) {
|
|
4149
|
+
const [boundary] = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", summary.summarizedUpTo), import_watermelondb4.Q.where("conversation_id", conversationId)).fetch();
|
|
4150
|
+
if (boundary && changedMessageId > boundary.messageId) continue;
|
|
4151
|
+
}
|
|
4152
|
+
await summary.destroyPermanently();
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
3990
4155
|
async function clearMessagesOp(ctx, convId) {
|
|
3991
4156
|
await ctx.database.write(async () => {
|
|
3992
|
-
|
|
3993
|
-
const
|
|
4157
|
+
await invalidateConversationSummary(ctx, convId);
|
|
4158
|
+
const messages = await ctx.messagesCollection.query(import_watermelondb4.Q.where("conversation_id", convId)).fetch();
|
|
4159
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb4.Q.where("conversation_id", convId)).fetch() : [];
|
|
3994
4160
|
for (const job of jobs) {
|
|
3995
4161
|
await job.update((row) => {
|
|
3996
4162
|
row._setRaw("message_ids", "[]");
|
|
@@ -4000,11 +4166,12 @@ async function clearMessagesOp(ctx, convId) {
|
|
|
4000
4166
|
}
|
|
4001
4167
|
for (const message of messages) {
|
|
4002
4168
|
await message.update((msg) => {
|
|
4003
|
-
msg._setRaw("file_ids", null);
|
|
4169
|
+
if (ctx.messagesCollection.schema.columns.file_ids) msg._setRaw("file_ids", null);
|
|
4004
4170
|
msg._setRaw("files", null);
|
|
4005
4171
|
});
|
|
4006
4172
|
await message.destroyPermanently();
|
|
4007
4173
|
}
|
|
4174
|
+
advanceConversationRevision(ctx.database, convId);
|
|
4008
4175
|
});
|
|
4009
4176
|
}
|
|
4010
4177
|
async function deleteMessageOp(ctx, uniqueId) {
|
|
@@ -4015,7 +4182,8 @@ async function deleteMessageOp(ctx, uniqueId) {
|
|
|
4015
4182
|
return null;
|
|
4016
4183
|
}
|
|
4017
4184
|
await ctx.database.write(async () => {
|
|
4018
|
-
|
|
4185
|
+
await invalidateConversationSummary(ctx, message.conversationId, message.messageId);
|
|
4186
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb4.Q.where("conversation_id", message.conversationId)).fetch() : [];
|
|
4019
4187
|
for (const job of jobs) {
|
|
4020
4188
|
const ids = JSON.parse(String(job._getRaw("message_ids")));
|
|
4021
4189
|
await job.update((row) => {
|
|
@@ -4024,10 +4192,11 @@ async function deleteMessageOp(ctx, uniqueId) {
|
|
|
4024
4192
|
});
|
|
4025
4193
|
}
|
|
4026
4194
|
await message.update((msg) => {
|
|
4027
|
-
msg._setRaw("file_ids", null);
|
|
4195
|
+
if (ctx.messagesCollection.schema.columns.file_ids) msg._setRaw("file_ids", null);
|
|
4028
4196
|
msg._setRaw("files", null);
|
|
4029
4197
|
});
|
|
4030
4198
|
await message.destroyPermanently();
|
|
4199
|
+
advanceConversationRevision(ctx.database, message.conversationId);
|
|
4031
4200
|
});
|
|
4032
4201
|
return uniqueId;
|
|
4033
4202
|
}
|
|
@@ -4088,9 +4257,9 @@ async function createMessageOp(ctx, opts) {
|
|
|
4088
4257
|
}
|
|
4089
4258
|
}
|
|
4090
4259
|
const newest = await ctx.messagesCollection.query(
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4260
|
+
import_watermelondb4.Q.where("conversation_id", opts.conversationId),
|
|
4261
|
+
import_watermelondb4.Q.sortBy("message_id", import_watermelondb4.Q.desc),
|
|
4262
|
+
import_watermelondb4.Q.take(1)
|
|
4094
4263
|
).fetch();
|
|
4095
4264
|
const messageId = (newest[0]?.messageId ?? 0) + 1;
|
|
4096
4265
|
const encryptedOpts = await encryptMessageOptsIfNeeded(ctx, opts);
|
|
@@ -4104,7 +4273,7 @@ async function createMessageOp(ctx, opts) {
|
|
|
4104
4273
|
return messageToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
4105
4274
|
}
|
|
4106
4275
|
async function upsertMessageOp(ctx, opts) {
|
|
4107
|
-
const results = await ctx.messagesCollection.query(
|
|
4276
|
+
const results = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", opts.uniqueId)).fetch();
|
|
4108
4277
|
const existing = results.length > 0 ? results[0] : null;
|
|
4109
4278
|
if (!existing) {
|
|
4110
4279
|
return createMessageOp(ctx, opts);
|
|
@@ -4212,13 +4381,13 @@ async function decryptMessageEmbeddingFields(raw, walletAddress) {
|
|
|
4212
4381
|
async function sealLegacyMessageEmbeddingsOp(ctx) {
|
|
4213
4382
|
if (!ctx.walletAddress) return 0;
|
|
4214
4383
|
const candidateIds = await ctx.messagesCollection.query(
|
|
4215
|
-
|
|
4216
|
-
|
|
4384
|
+
import_watermelondb4.Q.where("content", import_watermelondb4.Q.like("enc:%")),
|
|
4385
|
+
import_watermelondb4.Q.or(
|
|
4217
4386
|
...["vector", "chunks"].map(
|
|
4218
|
-
(column) =>
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4387
|
+
(column) => import_watermelondb4.Q.and(
|
|
4388
|
+
import_watermelondb4.Q.where(column, import_watermelondb4.Q.notEq(null)),
|
|
4389
|
+
import_watermelondb4.Q.where(column, import_watermelondb4.Q.notEq("")),
|
|
4390
|
+
import_watermelondb4.Q.where(column, import_watermelondb4.Q.notLike("enc:%"))
|
|
4222
4391
|
)
|
|
4223
4392
|
)
|
|
4224
4393
|
)
|
|
@@ -4228,7 +4397,7 @@ async function sealLegacyMessageEmbeddingsOp(ctx) {
|
|
|
4228
4397
|
for (let start = 0; start < candidateIds.length; start += 50) {
|
|
4229
4398
|
const pageIds = candidateIds.slice(start, start + 50);
|
|
4230
4399
|
await ctx.database.write(async () => {
|
|
4231
|
-
const pageMessages = await ctx.messagesCollection.query(
|
|
4400
|
+
const pageMessages = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf(pageIds))).fetch();
|
|
4232
4401
|
for (const message of pageMessages) {
|
|
4233
4402
|
if (!isEncrypted(message.content)) continue;
|
|
4234
4403
|
const content = await decryptFieldDetailed(message.content, ctx.walletAddress);
|
|
@@ -4309,15 +4478,15 @@ function chunksWithoutText(raw) {
|
|
|
4309
4478
|
});
|
|
4310
4479
|
}
|
|
4311
4480
|
async function stripLegacyChunkTextOp(ctx) {
|
|
4312
|
-
const candidateIds = await ctx.messagesCollection.query(
|
|
4481
|
+
const candidateIds = await ctx.messagesCollection.query(import_watermelondb4.Q.where("chunks", import_watermelondb4.Q.like(`%${import_watermelondb4.Q.sanitizeLikeString('"text":')}%`))).fetchIds();
|
|
4313
4482
|
let stripped = 0;
|
|
4314
4483
|
for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
|
|
4315
4484
|
const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
|
|
4316
|
-
const rows = await ctx.messagesCollection.query(
|
|
4485
|
+
const rows = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf(pageIds))).unsafeFetchRaw();
|
|
4317
4486
|
const changedIds = rows.filter((row) => chunksWithoutText(row.chunks) !== null).map((row) => String(row.id));
|
|
4318
4487
|
if (changedIds.length === 0) continue;
|
|
4319
4488
|
await ctx.database.write(async () => {
|
|
4320
|
-
const messages = await ctx.messagesCollection.query(
|
|
4489
|
+
const messages = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf(changedIds))).fetch();
|
|
4321
4490
|
const updates = messages.flatMap((message) => {
|
|
4322
4491
|
const raw = message._raw;
|
|
4323
4492
|
const chunks3 = chunksWithoutText(raw.chunks);
|
|
@@ -4364,13 +4533,13 @@ async function encryptToolCallEventsOp(ctx) {
|
|
|
4364
4533
|
return 0;
|
|
4365
4534
|
}
|
|
4366
4535
|
const candidateIds = await ctx.messagesCollection.query(
|
|
4367
|
-
|
|
4368
|
-
|
|
4536
|
+
import_watermelondb4.Q.where("tool_call_events", import_watermelondb4.Q.notEq(null)),
|
|
4537
|
+
import_watermelondb4.Q.where("tool_call_events", import_watermelondb4.Q.notIn(["", "[]"]))
|
|
4369
4538
|
).fetchIds();
|
|
4370
4539
|
let encrypted = 0;
|
|
4371
4540
|
for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
|
|
4372
4541
|
const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
|
|
4373
|
-
const rows = await ctx.messagesCollection.query(
|
|
4542
|
+
const rows = await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf(pageIds))).unsafeFetchRaw();
|
|
4374
4543
|
const repairs = /* @__PURE__ */ new Map();
|
|
4375
4544
|
for (const row of rows) {
|
|
4376
4545
|
const column = await encryptedToolCallEventsColumn(
|
|
@@ -4383,12 +4552,12 @@ async function encryptToolCallEventsOp(ctx) {
|
|
|
4383
4552
|
}
|
|
4384
4553
|
if (repairs.size === 0) continue;
|
|
4385
4554
|
await ctx.database.write(async () => {
|
|
4386
|
-
const messages = (await ctx.messagesCollection.query(
|
|
4555
|
+
const messages = (await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf([...repairs.keys()]))).fetch()).filter(
|
|
4387
4556
|
(message) => message._raw.tool_call_events === repairs.get(message.id)?.raw
|
|
4388
4557
|
);
|
|
4389
4558
|
if (messages.length === 0) return;
|
|
4390
4559
|
const conversationIds = [...new Set(messages.map((message) => message.conversationId))];
|
|
4391
|
-
const conversations = await ctx.conversationsCollection.query(
|
|
4560
|
+
const conversations = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("conversation_id", import_watermelondb4.Q.oneOf(conversationIds))).fetch();
|
|
4392
4561
|
await ctx.database.batch(
|
|
4393
4562
|
...messages.map(
|
|
4394
4563
|
(message) => message.prepareUpdate((msg) => {
|
|
@@ -4415,7 +4584,7 @@ async function savedKeyOpensExistingData(ctx, address, signMessage, embeddedWall
|
|
|
4415
4584
|
return refreshEncryptionKeyIfMatches(address, v2Probe, signMessage, embeddedWalletSigner);
|
|
4416
4585
|
}
|
|
4417
4586
|
async function findEncryptedContent(ctx, pattern) {
|
|
4418
|
-
const [row] = await ctx.messagesCollection.query(
|
|
4587
|
+
const [row] = await ctx.messagesCollection.query(import_watermelondb4.Q.where("content", import_watermelondb4.Q.like(pattern)), import_watermelondb4.Q.take(1)).unsafeFetchRaw();
|
|
4419
4588
|
return row ? String(row.content) : null;
|
|
4420
4589
|
}
|
|
4421
4590
|
async function updateMessageErrorOp(ctx, uniqueId, error) {
|
|
@@ -4446,6 +4615,14 @@ async function _updateMessageOp(ctx, uniqueId, opts) {
|
|
|
4446
4615
|
ctx.embeddedWalletSigner
|
|
4447
4616
|
) : opts;
|
|
4448
4617
|
await ctx.database.write(async () => {
|
|
4618
|
+
let contentChanged = false;
|
|
4619
|
+
if (opts.content !== void 0) {
|
|
4620
|
+
const originalContent = ctx.walletAddress ? await decryptField(message.content, ctx.walletAddress) : message.content;
|
|
4621
|
+
contentChanged = opts.content !== originalContent;
|
|
4622
|
+
if (contentChanged) {
|
|
4623
|
+
await invalidateConversationSummary(ctx, message.conversationId, message.messageId);
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4449
4626
|
await message.update((msg) => {
|
|
4450
4627
|
if (encryptedOpts.content !== void 0)
|
|
4451
4628
|
msg._setRaw("content", encryptedOpts.content);
|
|
@@ -4490,6 +4667,7 @@ async function _updateMessageOp(ctx, uniqueId, opts) {
|
|
|
4490
4667
|
msg._setRaw("tool_call_events", tceValue);
|
|
4491
4668
|
}
|
|
4492
4669
|
});
|
|
4670
|
+
if (contentChanged) advanceConversationRevision(ctx.database, message.conversationId);
|
|
4493
4671
|
});
|
|
4494
4672
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
4495
4673
|
}
|
|
@@ -4528,7 +4706,7 @@ function toChunkCandidateKey(raw) {
|
|
|
4528
4706
|
}
|
|
4529
4707
|
async function fetchRowsByIds(ctx, ids) {
|
|
4530
4708
|
if (ids.length === 0) return [];
|
|
4531
|
-
return await ctx.messagesCollection.query(
|
|
4709
|
+
return await ctx.messagesCollection.query(import_watermelondb4.Q.where("id", import_watermelondb4.Q.oneOf(ids))).unsafeFetchRaw();
|
|
4532
4710
|
}
|
|
4533
4711
|
async function projectedChunkRowSource(ctx, filter) {
|
|
4534
4712
|
const clauses = [
|
|
@@ -4546,7 +4724,7 @@ async function projectedChunkRowSource(ctx, filter) {
|
|
|
4546
4724
|
args.push(filter.excludeConversationId);
|
|
4547
4725
|
}
|
|
4548
4726
|
const keyRows = await ctx.messagesCollection.query(
|
|
4549
|
-
|
|
4727
|
+
import_watermelondb4.Q.unsafeSqlQuery(
|
|
4550
4728
|
`select "id", "conversation_id", "updated_at", "embedding_model" from "history" where ${clauses.join(" and ")}`,
|
|
4551
4729
|
args
|
|
4552
4730
|
)
|
|
@@ -4556,7 +4734,7 @@ async function projectedChunkRowSource(ctx, filter) {
|
|
|
4556
4734
|
loadVectorRows: async (ids) => {
|
|
4557
4735
|
if (ids.length === 0) return [];
|
|
4558
4736
|
return await ctx.messagesCollection.query(
|
|
4559
|
-
|
|
4737
|
+
import_watermelondb4.Q.unsafeSqlQuery(
|
|
4560
4738
|
`select "id", "updated_at", "chunks", "vector" from "history" where "_status" is not 'deleted' and "id" in (${ids.map(() => "?").join(",")})`,
|
|
4561
4739
|
ids
|
|
4562
4740
|
)
|
|
@@ -4566,11 +4744,11 @@ async function projectedChunkRowSource(ctx, filter) {
|
|
|
4566
4744
|
};
|
|
4567
4745
|
}
|
|
4568
4746
|
async function fullScanChunkRowSource(ctx, filter) {
|
|
4569
|
-
const activeConversations = await ctx.conversationsCollection.query(
|
|
4747
|
+
const activeConversations = await ctx.conversationsCollection.query(import_watermelondb4.Q.where("is_deleted", false)).fetch();
|
|
4570
4748
|
const activeConversationIds = new Set(
|
|
4571
4749
|
activeConversations.map((c) => String(c._getRaw("conversation_id")))
|
|
4572
4750
|
);
|
|
4573
|
-
const queryConditions = filter.conversationId !== void 0 ? [
|
|
4751
|
+
const queryConditions = filter.conversationId !== void 0 ? [import_watermelondb4.Q.where("conversation_id", filter.conversationId)] : [];
|
|
4574
4752
|
const rows = await ctx.messagesCollection.query(...queryConditions).unsafeFetchRaw();
|
|
4575
4753
|
const rowsById = /* @__PURE__ */ new Map();
|
|
4576
4754
|
for (const row of rows) {
|
|
@@ -6427,22 +6605,22 @@ function toReceipt(action, argumentsJson, output) {
|
|
|
6427
6605
|
const result = parseObject(output);
|
|
6428
6606
|
return {
|
|
6429
6607
|
kind: action.kind,
|
|
6430
|
-
venueName:
|
|
6431
|
-
day:
|
|
6432
|
-
time:
|
|
6608
|
+
venueName: text2(args.venue_name) ?? "",
|
|
6609
|
+
day: text2(args.day) ?? "",
|
|
6610
|
+
time: text2(args.time) ?? "",
|
|
6433
6611
|
partySize: count(args.party_size),
|
|
6434
|
-
reservationId:
|
|
6435
|
-
resyUrl:
|
|
6436
|
-
feeSummary:
|
|
6612
|
+
reservationId: text2(result.reservation_id) ?? text2(args.reservation_id),
|
|
6613
|
+
resyUrl: text2(result.reservations_url),
|
|
6614
|
+
feeSummary: text2(result.fee_summary),
|
|
6437
6615
|
...outcome(action, output, result)
|
|
6438
6616
|
};
|
|
6439
6617
|
}
|
|
6440
6618
|
function outcome(action, output, result) {
|
|
6441
6619
|
if (action.alreadyDone.test(output)) return { status: "already_done" };
|
|
6442
|
-
const reason =
|
|
6620
|
+
const reason = text2(result.error);
|
|
6443
6621
|
if (action.kind === "booking") {
|
|
6444
6622
|
if (BOOKING_OUTCOME_UNKNOWN.test(output)) return { status: "unknown" };
|
|
6445
|
-
const held = result.success === true ||
|
|
6623
|
+
const held = result.success === true || text2(result.reservation_id) !== void 0;
|
|
6446
6624
|
return held ? { status: "made" } : { status: "not_made", reason };
|
|
6447
6625
|
}
|
|
6448
6626
|
if (result.error_code === CANCEL_OUTCOME_UNKNOWN) return { status: "unknown", reason };
|
|
@@ -6457,7 +6635,7 @@ function parseObject(json5) {
|
|
|
6457
6635
|
return {};
|
|
6458
6636
|
}
|
|
6459
6637
|
}
|
|
6460
|
-
function
|
|
6638
|
+
function text2(value) {
|
|
6461
6639
|
if (typeof value === "number") return String(value);
|
|
6462
6640
|
return typeof value === "string" && value ? value : void 0;
|
|
6463
6641
|
}
|
|
@@ -11942,7 +12120,7 @@ function hasControl(value) {
|
|
|
11942
12120
|
function integer(value, minimum = 0) {
|
|
11943
12121
|
return Number.isSafeInteger(value) && value >= minimum;
|
|
11944
12122
|
}
|
|
11945
|
-
function
|
|
12123
|
+
function json2(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
11946
12124
|
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
11947
12125
|
if (typeof value === "number") return Number.isFinite(value);
|
|
11948
12126
|
if (typeof value !== "object" || ancestors.has(value)) return false;
|
|
@@ -11950,12 +12128,12 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
|
11950
12128
|
if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
|
|
11951
12129
|
return false;
|
|
11952
12130
|
ancestors.add(value);
|
|
11953
|
-
const valid = Object.values(value).every((v) =>
|
|
12131
|
+
const valid = Object.values(value).every((v) => json2(v, ancestors));
|
|
11954
12132
|
ancestors.delete(value);
|
|
11955
12133
|
return valid;
|
|
11956
12134
|
}
|
|
11957
12135
|
function validRecord(value) {
|
|
11958
|
-
if (!object(value) || typeof value.kind !== "string" || !kinds.has(value.kind) || !id(value.id) || !integer(value.sortKey) || !integer(value.createdAt, 1) || !integer(value.updatedAt, 1) || typeof value.isDeleted !== "boolean" || !object(value.data) || !
|
|
12136
|
+
if (!object(value) || typeof value.kind !== "string" || !kinds.has(value.kind) || !id(value.id) || !integer(value.sortKey) || !integer(value.createdAt, 1) || !integer(value.updatedAt, 1) || typeof value.isDeleted !== "boolean" || !object(value.data) || !json2(value.data) || Object.keys(value).some(
|
|
11959
12137
|
(key) => ![...metadata, "data"].includes(key)
|
|
11960
12138
|
))
|
|
11961
12139
|
return false;
|
|
@@ -11984,14 +12162,14 @@ function vectorFields(write) {
|
|
|
11984
12162
|
...write.embeddingModel !== void 0 ? { embedding_model: write.embeddingModel } : {}
|
|
11985
12163
|
};
|
|
11986
12164
|
}
|
|
11987
|
-
function
|
|
12165
|
+
function text3(value) {
|
|
11988
12166
|
return typeof value === "string";
|
|
11989
12167
|
}
|
|
11990
12168
|
function timestamp(value) {
|
|
11991
12169
|
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
11992
12170
|
}
|
|
11993
12171
|
function presigned(value) {
|
|
11994
|
-
if (!object(value) || !
|
|
12172
|
+
if (!object(value) || !text3(value.url) || !/^https:\/\//.test(value.url) || !text3(value.method) || !object(value.headers) || !Object.values(value.headers).every(text3) || !timestamp(value.expires_at))
|
|
11995
12173
|
invalid();
|
|
11996
12174
|
return {
|
|
11997
12175
|
url: value.url,
|
|
@@ -12001,7 +12179,7 @@ function presigned(value) {
|
|
|
12001
12179
|
};
|
|
12002
12180
|
}
|
|
12003
12181
|
function attachment(value) {
|
|
12004
|
-
if (!object(value) || !
|
|
12182
|
+
if (!object(value) || !text3(value.attachment_id) || !attachmentIdPattern.test(value.attachment_id) || !integer(value.size_bytes, 1) || value.state !== "pending" && value.state !== "committed" || value.owner_kind !== void 0 && value.owner_kind !== "message" && value.owner_kind !== "summary" || value.owner_id !== void 0 && !id(value.owner_id) || !timestamp(value.created_at) || value.committed_at !== void 0 && !timestamp(value.committed_at))
|
|
12005
12183
|
invalid();
|
|
12006
12184
|
return {
|
|
12007
12185
|
id: value.attachment_id,
|
|
@@ -12014,7 +12192,7 @@ function attachment(value) {
|
|
|
12014
12192
|
};
|
|
12015
12193
|
}
|
|
12016
12194
|
function ref(value) {
|
|
12017
|
-
if (!object(value) || !
|
|
12195
|
+
if (!object(value) || !text3(value.kind) || !kinds.has(value.kind) || !id(value.id)) invalid();
|
|
12018
12196
|
return { kind: value.kind, id: value.id };
|
|
12019
12197
|
}
|
|
12020
12198
|
function sameMetadata(a, b) {
|
|
@@ -12237,7 +12415,7 @@ async function createRemoteChatStore(options) {
|
|
|
12237
12415
|
},
|
|
12238
12416
|
async account(signal) {
|
|
12239
12417
|
const value = await request("/account", {}, signal);
|
|
12240
|
-
if (!object(value) || value.account_id !== accountId || !
|
|
12418
|
+
if (!object(value) || value.account_id !== accountId || !text3(value.key_id) || value.state !== "none" && value.state !== "migrating" && value.state !== "active" || !integer(value.record_count) || !integer(value.storage_bytes) || !integer(value.vector_count))
|
|
12241
12419
|
invalid();
|
|
12242
12420
|
if (value.key_id && value.key_id !== keyId)
|
|
12243
12421
|
throw new ChatStoreError("Canonical chat key does not match", 409, "key_mismatch");
|
|
@@ -12311,12 +12489,12 @@ async function createRemoteChatStore(options) {
|
|
|
12311
12489
|
},
|
|
12312
12490
|
async changes(cursor, options2) {
|
|
12313
12491
|
const limit = options2?.limit ?? 100;
|
|
12314
|
-
if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!
|
|
12492
|
+
if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text3(cursor) || cursor.length > 2048))
|
|
12315
12493
|
invalid();
|
|
12316
12494
|
const params = new URLSearchParams({ account_id: String(accountId), limit: String(limit) });
|
|
12317
12495
|
if (cursor) params.set("cursor", cursor);
|
|
12318
12496
|
const value = await request(`/changes?${params}`, {}, options2?.signal);
|
|
12319
|
-
if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !
|
|
12497
|
+
if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !text3(value.next_cursor) || value.changes_cursor !== void 0 && !text3(value.changes_cursor))
|
|
12320
12498
|
invalid();
|
|
12321
12499
|
const items = [];
|
|
12322
12500
|
for (const item of value.items) items.push(await decode(item));
|
|
@@ -12507,141 +12685,6 @@ async function decryptConversationTitle(encryptedTitle, address) {
|
|
|
12507
12685
|
}
|
|
12508
12686
|
}
|
|
12509
12687
|
|
|
12510
|
-
// src/lib/db/chat/models.ts
|
|
12511
|
-
var import_watermelondb4 = require("@nozbe/watermelondb");
|
|
12512
|
-
var import_decorators = require("@nozbe/watermelondb/decorators");
|
|
12513
|
-
var Message = class extends import_watermelondb4.Model {
|
|
12514
|
-
};
|
|
12515
|
-
Message.table = "history";
|
|
12516
|
-
Message.associations = {
|
|
12517
|
-
conversations: { type: "belongs_to", key: "conversation_id" },
|
|
12518
|
-
media: { type: "has_many", foreignKey: "message_id" }
|
|
12519
|
-
};
|
|
12520
|
-
__decorateClass([
|
|
12521
|
-
(0, import_decorators.field)("message_id")
|
|
12522
|
-
], Message.prototype, "messageId", 2);
|
|
12523
|
-
__decorateClass([
|
|
12524
|
-
(0, import_decorators.text)("conversation_id")
|
|
12525
|
-
], Message.prototype, "conversationId", 2);
|
|
12526
|
-
__decorateClass([
|
|
12527
|
-
(0, import_decorators.text)("role")
|
|
12528
|
-
], Message.prototype, "role", 2);
|
|
12529
|
-
__decorateClass([
|
|
12530
|
-
(0, import_decorators.text)("content")
|
|
12531
|
-
], Message.prototype, "content", 2);
|
|
12532
|
-
__decorateClass([
|
|
12533
|
-
(0, import_decorators.text)("model")
|
|
12534
|
-
], Message.prototype, "model", 2);
|
|
12535
|
-
__decorateClass([
|
|
12536
|
-
(0, import_decorators.text)("image_model")
|
|
12537
|
-
], Message.prototype, "imageModel", 2);
|
|
12538
|
-
__decorateClass([
|
|
12539
|
-
(0, import_decorators.json)("files", (raw) => raw)
|
|
12540
|
-
], Message.prototype, "files", 2);
|
|
12541
|
-
__decorateClass([
|
|
12542
|
-
(0, import_decorators.json)("file_ids", (raw) => raw)
|
|
12543
|
-
], Message.prototype, "fileIds", 2);
|
|
12544
|
-
__decorateClass([
|
|
12545
|
-
(0, import_decorators.date)("created_at")
|
|
12546
|
-
], Message.prototype, "createdAt", 2);
|
|
12547
|
-
__decorateClass([
|
|
12548
|
-
(0, import_decorators.date)("updated_at")
|
|
12549
|
-
], Message.prototype, "updatedAt", 2);
|
|
12550
|
-
__decorateClass([
|
|
12551
|
-
(0, import_decorators.json)("vector", (raw) => raw)
|
|
12552
|
-
], Message.prototype, "vector", 2);
|
|
12553
|
-
__decorateClass([
|
|
12554
|
-
(0, import_decorators.text)("embedding_model")
|
|
12555
|
-
], Message.prototype, "embeddingModel", 2);
|
|
12556
|
-
__decorateClass([
|
|
12557
|
-
(0, import_decorators.json)("chunks", (raw) => raw)
|
|
12558
|
-
], Message.prototype, "chunks", 2);
|
|
12559
|
-
__decorateClass([
|
|
12560
|
-
(0, import_decorators.json)("usage", (raw) => raw)
|
|
12561
|
-
], Message.prototype, "usage", 2);
|
|
12562
|
-
__decorateClass([
|
|
12563
|
-
(0, import_decorators.json)("sources", (raw) => raw)
|
|
12564
|
-
], Message.prototype, "sources", 2);
|
|
12565
|
-
__decorateClass([
|
|
12566
|
-
(0, import_decorators.field)("response_duration")
|
|
12567
|
-
], Message.prototype, "responseDuration", 2);
|
|
12568
|
-
__decorateClass([
|
|
12569
|
-
(0, import_decorators.field)("was_stopped")
|
|
12570
|
-
], Message.prototype, "wasStopped", 2);
|
|
12571
|
-
__decorateClass([
|
|
12572
|
-
(0, import_decorators.text)("error")
|
|
12573
|
-
], Message.prototype, "error", 2);
|
|
12574
|
-
__decorateClass([
|
|
12575
|
-
(0, import_decorators.json)("thought_process", (raw) => raw)
|
|
12576
|
-
], Message.prototype, "thoughtProcess", 2);
|
|
12577
|
-
__decorateClass([
|
|
12578
|
-
(0, import_decorators.text)("thinking")
|
|
12579
|
-
], Message.prototype, "thinking", 2);
|
|
12580
|
-
__decorateClass([
|
|
12581
|
-
(0, import_decorators.text)("parent_message_id")
|
|
12582
|
-
], Message.prototype, "parentMessageId", 2);
|
|
12583
|
-
__decorateClass([
|
|
12584
|
-
(0, import_decorators.text)("feedback")
|
|
12585
|
-
], Message.prototype, "feedback", 2);
|
|
12586
|
-
__decorateClass([
|
|
12587
|
-
(0, import_decorators.json)("tool_call_events", (raw) => raw)
|
|
12588
|
-
], Message.prototype, "toolCallEvents", 2);
|
|
12589
|
-
__decorateClass([
|
|
12590
|
-
(0, import_decorators.text)("origin")
|
|
12591
|
-
], Message.prototype, "origin", 2);
|
|
12592
|
-
var Conversation = class extends import_watermelondb4.Model {
|
|
12593
|
-
};
|
|
12594
|
-
Conversation.table = "conversations";
|
|
12595
|
-
Conversation.associations = {
|
|
12596
|
-
history: { type: "has_many", foreignKey: "conversation_id" },
|
|
12597
|
-
projects: { type: "belongs_to", key: "project_id" }
|
|
12598
|
-
};
|
|
12599
|
-
__decorateClass([
|
|
12600
|
-
(0, import_decorators.text)("conversation_id")
|
|
12601
|
-
], Conversation.prototype, "conversationId", 2);
|
|
12602
|
-
__decorateClass([
|
|
12603
|
-
(0, import_decorators.text)("title")
|
|
12604
|
-
], Conversation.prototype, "title", 2);
|
|
12605
|
-
__decorateClass([
|
|
12606
|
-
(0, import_decorators.text)("project_id")
|
|
12607
|
-
], Conversation.prototype, "projectId", 2);
|
|
12608
|
-
__decorateClass([
|
|
12609
|
-
(0, import_decorators.date)("created_at")
|
|
12610
|
-
], Conversation.prototype, "createdAt", 2);
|
|
12611
|
-
__decorateClass([
|
|
12612
|
-
(0, import_decorators.date)("updated_at")
|
|
12613
|
-
], Conversation.prototype, "updatedAt", 2);
|
|
12614
|
-
__decorateClass([
|
|
12615
|
-
(0, import_decorators.field)("is_deleted")
|
|
12616
|
-
], Conversation.prototype, "isDeleted", 2);
|
|
12617
|
-
__decorateClass([
|
|
12618
|
-
(0, import_decorators.date)("pinned_at")
|
|
12619
|
-
], Conversation.prototype, "pinnedAt", 2);
|
|
12620
|
-
var ConversationSummary = class extends import_watermelondb4.Model {
|
|
12621
|
-
};
|
|
12622
|
-
ConversationSummary.table = "conversation_summaries";
|
|
12623
|
-
ConversationSummary.associations = {
|
|
12624
|
-
conversations: { type: "belongs_to", key: "conversation_id" }
|
|
12625
|
-
};
|
|
12626
|
-
__decorateClass([
|
|
12627
|
-
(0, import_decorators.text)("conversation_id")
|
|
12628
|
-
], ConversationSummary.prototype, "conversationId", 2);
|
|
12629
|
-
__decorateClass([
|
|
12630
|
-
(0, import_decorators.text)("summary")
|
|
12631
|
-
], ConversationSummary.prototype, "summary", 2);
|
|
12632
|
-
__decorateClass([
|
|
12633
|
-
(0, import_decorators.text)("summarized_up_to")
|
|
12634
|
-
], ConversationSummary.prototype, "summarizedUpTo", 2);
|
|
12635
|
-
__decorateClass([
|
|
12636
|
-
(0, import_decorators.field)("token_count")
|
|
12637
|
-
], ConversationSummary.prototype, "tokenCount", 2);
|
|
12638
|
-
__decorateClass([
|
|
12639
|
-
(0, import_decorators.date)("created_at")
|
|
12640
|
-
], ConversationSummary.prototype, "createdAt", 2);
|
|
12641
|
-
__decorateClass([
|
|
12642
|
-
(0, import_decorators.date)("updated_at")
|
|
12643
|
-
], ConversationSummary.prototype, "updatedAt", 2);
|
|
12644
|
-
|
|
12645
12688
|
// src/lib/db/chat/schema.ts
|
|
12646
12689
|
var import_watermelondb5 = require("@nozbe/watermelondb");
|
|
12647
12690
|
var import_migrations = require("@nozbe/watermelondb/Schema/migrations");
|
|
@@ -29207,6 +29250,13 @@ var lastCompactionTime = /* @__PURE__ */ new Map();
|
|
|
29207
29250
|
var COMPACTION_COOLDOWN_MS = 6e4;
|
|
29208
29251
|
var MAX_SUMMARY_TOKEN_RATIO = 0.8;
|
|
29209
29252
|
async function maybeSummarizeHistory(options) {
|
|
29253
|
+
const { database, conversationId } = options;
|
|
29254
|
+
const revision2 = getConversationRevision(database, conversationId);
|
|
29255
|
+
const result = await summarizeHistoryAtRevision(options, revision2);
|
|
29256
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29257
|
+
return result;
|
|
29258
|
+
}
|
|
29259
|
+
async function summarizeHistoryAtRevision(options, revision2) {
|
|
29210
29260
|
const { database, conversationId, messages, summarizeHistory, summaryMinWindowMessages, token } = options;
|
|
29211
29261
|
if (!summarizeHistory) {
|
|
29212
29262
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
@@ -29247,7 +29297,7 @@ async function maybeSummarizeHistory(options) {
|
|
|
29247
29297
|
clearTimeout(staleGuardTimerId);
|
|
29248
29298
|
}
|
|
29249
29299
|
}
|
|
29250
|
-
const promise = doSummarizeHistory(options);
|
|
29300
|
+
const promise = doSummarizeHistory(options, revision2);
|
|
29251
29301
|
summarizationLocks.set(conversationId, promise);
|
|
29252
29302
|
try {
|
|
29253
29303
|
return await promise;
|
|
@@ -29261,7 +29311,7 @@ Summary to condense:
|
|
|
29261
29311
|
{summary}
|
|
29262
29312
|
|
|
29263
29313
|
Condensed summary:`;
|
|
29264
|
-
async function doSummarizeHistory(options) {
|
|
29314
|
+
async function doSummarizeHistory(options, revision2) {
|
|
29265
29315
|
const {
|
|
29266
29316
|
database,
|
|
29267
29317
|
conversationId,
|
|
@@ -29276,7 +29326,20 @@ async function doSummarizeHistory(options) {
|
|
|
29276
29326
|
} = options;
|
|
29277
29327
|
try {
|
|
29278
29328
|
const summaryCtx = createSummaryContext(database);
|
|
29329
|
+
const persistSummary = (summary, summarizedUpTo, tokenCount) => database.write(async (writer) => {
|
|
29330
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29331
|
+
await writer.callWriter(
|
|
29332
|
+
() => upsertConversationSummaryOp(
|
|
29333
|
+
summaryCtx,
|
|
29334
|
+
conversationId,
|
|
29335
|
+
summary,
|
|
29336
|
+
summarizedUpTo,
|
|
29337
|
+
tokenCount
|
|
29338
|
+
)
|
|
29339
|
+
);
|
|
29340
|
+
});
|
|
29279
29341
|
let cachedSummary = await getConversationSummaryOp(summaryCtx, conversationId);
|
|
29342
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29280
29343
|
const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
|
|
29281
29344
|
const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
|
|
29282
29345
|
if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
|
|
@@ -29292,13 +29355,7 @@ async function doSummarizeHistory(options) {
|
|
|
29292
29355
|
);
|
|
29293
29356
|
const compactedSummary = redactor ? redactor.deAnonymize(rawCompacted) : rawCompacted;
|
|
29294
29357
|
const compactedTokens = estimateTokens(compactedSummary);
|
|
29295
|
-
await
|
|
29296
|
-
summaryCtx,
|
|
29297
|
-
conversationId,
|
|
29298
|
-
compactedSummary,
|
|
29299
|
-
cachedSummary.summarizedUpTo,
|
|
29300
|
-
compactedTokens
|
|
29301
|
-
);
|
|
29358
|
+
await persistSummary(compactedSummary, cachedSummary.summarizedUpTo, compactedTokens);
|
|
29302
29359
|
cachedSummary = {
|
|
29303
29360
|
...cachedSummary,
|
|
29304
29361
|
summary: compactedSummary,
|
|
@@ -29306,6 +29363,7 @@ async function doSummarizeHistory(options) {
|
|
|
29306
29363
|
};
|
|
29307
29364
|
lastCompactionTime.set(conversationId, Date.now());
|
|
29308
29365
|
} catch {
|
|
29366
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29309
29367
|
lastCompactionTime.set(conversationId, Date.now());
|
|
29310
29368
|
getLogger().warn(
|
|
29311
29369
|
"[summarize] Summary compaction failed, proceeding with oversized summary"
|
|
@@ -29337,10 +29395,9 @@ async function doSummarizeHistory(options) {
|
|
|
29337
29395
|
redactor,
|
|
29338
29396
|
onPiiRedacted
|
|
29339
29397
|
});
|
|
29398
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29340
29399
|
if (summarizeResult.didSummarize && summarizeResult.summary && summarizeResult.summarizedUpTo) {
|
|
29341
|
-
await
|
|
29342
|
-
summaryCtx,
|
|
29343
|
-
conversationId,
|
|
29400
|
+
await persistSummary(
|
|
29344
29401
|
summarizeResult.summary,
|
|
29345
29402
|
summarizeResult.summarizedUpTo,
|
|
29346
29403
|
summarizeResult.summaryTokenCount
|
|
@@ -29359,6 +29416,7 @@ async function doSummarizeHistory(options) {
|
|
|
29359
29416
|
summarySystemMessage: summarizeResult.summary ? summaryToSystemMessage(summarizeResult.summary) : null
|
|
29360
29417
|
};
|
|
29361
29418
|
} catch (err) {
|
|
29419
|
+
assertConversationRevision(database, conversationId, revision2);
|
|
29362
29420
|
getLogger().warn("[summarize] Summarization failed, falling back to verbatim:", err);
|
|
29363
29421
|
return { messagesToConvert: messages, summarySystemMessage: null };
|
|
29364
29422
|
}
|