@anuma/sdk 7.3.0 → 7.3.2
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 +189 -73
- package/dist/expo/index.d.mts +4 -1
- package/dist/expo/index.d.ts +4 -1
- package/dist/expo/index.mjs +189 -73
- package/dist/react/index.cjs +187 -73
- package/dist/react/index.d.mts +4 -1
- package/dist/react/index.d.ts +4 -1
- package/dist/react/index.mjs +187 -73
- package/dist/server/index.cjs +185 -71
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.mjs +185 -71
- package/package.json +1 -1
package/dist/expo/index.mjs
CHANGED
|
@@ -503,7 +503,7 @@ function onKeyAvailable(address, callback) {
|
|
|
503
503
|
callbacks.add(callback);
|
|
504
504
|
return () => {
|
|
505
505
|
callbacks.delete(callback);
|
|
506
|
-
if (callbacks.size === 0) {
|
|
506
|
+
if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
|
|
507
507
|
keyAvailableCallbacks.delete(address);
|
|
508
508
|
}
|
|
509
509
|
};
|
|
@@ -11131,9 +11131,72 @@ import { Q as Q5 } from "@nozbe/watermelondb";
|
|
|
11131
11131
|
|
|
11132
11132
|
// src/lib/db/entities/operations.ts
|
|
11133
11133
|
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
11134
|
+
|
|
11135
|
+
// src/lib/db/memoryVault/types.ts
|
|
11136
|
+
var MEMORY_KINDS = [
|
|
11137
|
+
"display_name",
|
|
11138
|
+
"birth_date",
|
|
11139
|
+
"bio",
|
|
11140
|
+
"occupation",
|
|
11141
|
+
"interest",
|
|
11142
|
+
"gender",
|
|
11143
|
+
"height_cm",
|
|
11144
|
+
"looking_for",
|
|
11145
|
+
"politics",
|
|
11146
|
+
"religion",
|
|
11147
|
+
"ethnicity",
|
|
11148
|
+
"smoking",
|
|
11149
|
+
"drinking",
|
|
11150
|
+
"exercise",
|
|
11151
|
+
"sexuality",
|
|
11152
|
+
"prompt"
|
|
11153
|
+
];
|
|
11154
|
+
var MEMORY_LEVELS = ["private", "matching", "profile"];
|
|
11155
|
+
var MemoryLevelError = class extends Error {
|
|
11156
|
+
constructor(message) {
|
|
11157
|
+
super(message);
|
|
11158
|
+
this.name = "MemoryLevelError";
|
|
11159
|
+
}
|
|
11160
|
+
};
|
|
11161
|
+
var MemorySourceIneligibleError = class extends Error {
|
|
11162
|
+
constructor() {
|
|
11163
|
+
super("Memory source is no longer eligible");
|
|
11164
|
+
this.name = "MemorySourceIneligibleError";
|
|
11165
|
+
}
|
|
11166
|
+
};
|
|
11167
|
+
var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
|
|
11168
|
+
function levelFromScope(scope) {
|
|
11169
|
+
return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
|
|
11170
|
+
}
|
|
11171
|
+
function scopeForLevel(level) {
|
|
11172
|
+
return level === "private" ? "private" : "shared";
|
|
11173
|
+
}
|
|
11174
|
+
function resolveMemoryLevel(level, scope) {
|
|
11175
|
+
return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
|
|
11176
|
+
}
|
|
11177
|
+
function levelForScopeChange(current, nextScope) {
|
|
11178
|
+
const implied = levelFromScope(nextScope);
|
|
11179
|
+
return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
|
|
11180
|
+
}
|
|
11181
|
+
function parseMedia(value) {
|
|
11182
|
+
if (typeof value !== "string" || value === "") return null;
|
|
11183
|
+
try {
|
|
11184
|
+
const parsed = JSON.parse(value);
|
|
11185
|
+
if (!Array.isArray(parsed)) return null;
|
|
11186
|
+
const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
|
|
11187
|
+
feedItemId: Number(r.feedItemId ?? r.feed_item_id),
|
|
11188
|
+
objectKey: r.objectKey ?? r.object_key ?? null
|
|
11189
|
+
})).filter((r) => Number.isFinite(r.feedItemId));
|
|
11190
|
+
return refs.length > 0 ? refs : null;
|
|
11191
|
+
} catch {
|
|
11192
|
+
return null;
|
|
11193
|
+
}
|
|
11194
|
+
}
|
|
11195
|
+
|
|
11196
|
+
// src/lib/db/entities/operations.ts
|
|
11134
11197
|
async function assertCanWrite(ctx) {
|
|
11135
11198
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
11136
|
-
throw new
|
|
11199
|
+
throw new MemorySourceIneligibleError();
|
|
11137
11200
|
}
|
|
11138
11201
|
}
|
|
11139
11202
|
function entityToStored(e) {
|
|
@@ -11525,61 +11588,6 @@ function serializeSourceChunkIds(ids) {
|
|
|
11525
11588
|
return JSON.stringify(ids.slice(start));
|
|
11526
11589
|
}
|
|
11527
11590
|
|
|
11528
|
-
// src/lib/db/memoryVault/types.ts
|
|
11529
|
-
var MEMORY_KINDS = [
|
|
11530
|
-
"display_name",
|
|
11531
|
-
"birth_date",
|
|
11532
|
-
"bio",
|
|
11533
|
-
"occupation",
|
|
11534
|
-
"interest",
|
|
11535
|
-
"gender",
|
|
11536
|
-
"height_cm",
|
|
11537
|
-
"looking_for",
|
|
11538
|
-
"politics",
|
|
11539
|
-
"religion",
|
|
11540
|
-
"ethnicity",
|
|
11541
|
-
"smoking",
|
|
11542
|
-
"drinking",
|
|
11543
|
-
"exercise",
|
|
11544
|
-
"sexuality",
|
|
11545
|
-
"prompt"
|
|
11546
|
-
];
|
|
11547
|
-
var MEMORY_LEVELS = ["private", "matching", "profile"];
|
|
11548
|
-
var MemoryLevelError = class extends Error {
|
|
11549
|
-
constructor(message) {
|
|
11550
|
-
super(message);
|
|
11551
|
-
this.name = "MemoryLevelError";
|
|
11552
|
-
}
|
|
11553
|
-
};
|
|
11554
|
-
var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
|
|
11555
|
-
function levelFromScope(scope) {
|
|
11556
|
-
return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
|
|
11557
|
-
}
|
|
11558
|
-
function scopeForLevel(level) {
|
|
11559
|
-
return level === "private" ? "private" : "shared";
|
|
11560
|
-
}
|
|
11561
|
-
function resolveMemoryLevel(level, scope) {
|
|
11562
|
-
return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
|
|
11563
|
-
}
|
|
11564
|
-
function levelForScopeChange(current, nextScope) {
|
|
11565
|
-
const implied = levelFromScope(nextScope);
|
|
11566
|
-
return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
|
|
11567
|
-
}
|
|
11568
|
-
function parseMedia(value) {
|
|
11569
|
-
if (typeof value !== "string" || value === "") return null;
|
|
11570
|
-
try {
|
|
11571
|
-
const parsed = JSON.parse(value);
|
|
11572
|
-
if (!Array.isArray(parsed)) return null;
|
|
11573
|
-
const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
|
|
11574
|
-
feedItemId: Number(r.feedItemId ?? r.feed_item_id),
|
|
11575
|
-
objectKey: r.objectKey ?? r.object_key ?? null
|
|
11576
|
-
})).filter((r) => Number.isFinite(r.feedItemId));
|
|
11577
|
-
return refs.length > 0 ? refs : null;
|
|
11578
|
-
} catch {
|
|
11579
|
-
return null;
|
|
11580
|
-
}
|
|
11581
|
-
}
|
|
11582
|
-
|
|
11583
11591
|
// src/lib/db/memoryVault/operations.ts
|
|
11584
11592
|
function visibilityOrPrivate(value) {
|
|
11585
11593
|
return value === "public" ? value : "private";
|
|
@@ -11599,7 +11607,7 @@ function isKinded(record2) {
|
|
|
11599
11607
|
}
|
|
11600
11608
|
async function assertCanWrite2(ctx) {
|
|
11601
11609
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
11602
|
-
throw new
|
|
11610
|
+
throw new MemorySourceIneligibleError();
|
|
11603
11611
|
}
|
|
11604
11612
|
}
|
|
11605
11613
|
function assertValidKindLevel(kind, level) {
|
|
@@ -12290,7 +12298,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
12290
12298
|
ctx.embeddedWalletSigner
|
|
12291
12299
|
);
|
|
12292
12300
|
} catch (err) {
|
|
12293
|
-
if (err instanceof MemoryLevelError) throw err;
|
|
12301
|
+
if (err instanceof MemoryLevelError || err instanceof MemorySourceIneligibleError) throw err;
|
|
12294
12302
|
return null;
|
|
12295
12303
|
}
|
|
12296
12304
|
}
|
|
@@ -15807,6 +15815,13 @@ var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
|
15807
15815
|
var DEFAULT_SCOPE = "private";
|
|
15808
15816
|
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
15809
15817
|
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
15818
|
+
var RetainError = class extends Error {
|
|
15819
|
+
constructor(reason, message) {
|
|
15820
|
+
super(message);
|
|
15821
|
+
this.reason = reason;
|
|
15822
|
+
this.name = "RetainError";
|
|
15823
|
+
}
|
|
15824
|
+
};
|
|
15810
15825
|
async function retain(content, ctx, options = {}) {
|
|
15811
15826
|
const embeddingOptions = {
|
|
15812
15827
|
...ctx.embeddingOptions,
|
|
@@ -15862,7 +15877,8 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
15862
15877
|
});
|
|
15863
15878
|
prepared = withoutKindedRows(prepared);
|
|
15864
15879
|
if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
|
|
15865
|
-
throw new
|
|
15880
|
+
throw new RetainError(
|
|
15881
|
+
"embeddings-unavailable",
|
|
15866
15882
|
"retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
|
|
15867
15883
|
);
|
|
15868
15884
|
}
|
|
@@ -16232,7 +16248,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16232
16248
|
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
16233
16249
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
16234
16250
|
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
16235
|
-
throw new
|
|
16251
|
+
throw new RetainError(
|
|
16252
|
+
"merge-not-persisted",
|
|
16253
|
+
`retain: merge into memory ${targetId} failed to persist`
|
|
16254
|
+
);
|
|
16236
16255
|
}
|
|
16237
16256
|
}
|
|
16238
16257
|
|
|
@@ -16390,6 +16409,12 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
16390
16409
|
(c) => c.candidate.content.length <= MAX_CONTENT_LENGTH && !c.unresolved && !isLowSignalContent(c.candidate.content, ownNames)
|
|
16391
16410
|
).map((c) => c.candidate);
|
|
16392
16411
|
}
|
|
16412
|
+
function writeFailureReasonOf(err) {
|
|
16413
|
+
if (err instanceof MemorySourceIneligibleError) return "source-ineligible";
|
|
16414
|
+
if (err instanceof RetainError) return err.reason;
|
|
16415
|
+
if (err?.name === "AbortError") return "aborted";
|
|
16416
|
+
return "unknown";
|
|
16417
|
+
}
|
|
16393
16418
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
16394
16419
|
const { memoryStore, signal } = options;
|
|
16395
16420
|
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
@@ -16479,6 +16504,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
16479
16504
|
const results = [];
|
|
16480
16505
|
const quarantinedInfo = [];
|
|
16481
16506
|
let failedWrites = 0;
|
|
16507
|
+
let writeFailureReason;
|
|
16482
16508
|
let auditRows;
|
|
16483
16509
|
const tRetain = Date.now();
|
|
16484
16510
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
@@ -16574,6 +16600,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
16574
16600
|
}
|
|
16575
16601
|
} catch (err) {
|
|
16576
16602
|
failedWrites++;
|
|
16603
|
+
writeFailureReason ?? (writeFailureReason = writeFailureReasonOf(err));
|
|
16577
16604
|
log.warn("[memory/extract] retain failed for one candidate", err);
|
|
16578
16605
|
options.onCandidateFailed?.(candidate, err);
|
|
16579
16606
|
}
|
|
@@ -16586,6 +16613,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
16586
16613
|
candidates: succeededCandidates,
|
|
16587
16614
|
results,
|
|
16588
16615
|
failedCount: failedWrites,
|
|
16616
|
+
...writeFailureReason !== void 0 && { writeFailureReason },
|
|
16589
16617
|
outcome: outcome2,
|
|
16590
16618
|
quarantined: quarantinedInfo,
|
|
16591
16619
|
funnel: {
|
|
@@ -16854,7 +16882,17 @@ function createAutoExtractor(options) {
|
|
|
16854
16882
|
const t0 = Date.now();
|
|
16855
16883
|
void (async () => {
|
|
16856
16884
|
try {
|
|
16857
|
-
const {
|
|
16885
|
+
const {
|
|
16886
|
+
candidates,
|
|
16887
|
+
results,
|
|
16888
|
+
failedCount,
|
|
16889
|
+
writeFailureReason,
|
|
16890
|
+
outcome: outcome2,
|
|
16891
|
+
failure,
|
|
16892
|
+
funnel,
|
|
16893
|
+
timings,
|
|
16894
|
+
model
|
|
16895
|
+
} = await extractAndRetain(window2, retainCtx, {
|
|
16858
16896
|
extract,
|
|
16859
16897
|
memoryStore: options.memoryStore,
|
|
16860
16898
|
signal: options.signal,
|
|
@@ -16890,6 +16928,7 @@ function createAutoExtractor(options) {
|
|
|
16890
16928
|
candidates,
|
|
16891
16929
|
results,
|
|
16892
16930
|
failedCount,
|
|
16931
|
+
...writeFailureReason !== void 0 && { writeFailureReason },
|
|
16893
16932
|
durationMs: Date.now() - t0,
|
|
16894
16933
|
conversationId,
|
|
16895
16934
|
outcome: outcome2,
|
|
@@ -18976,10 +19015,10 @@ function createLocalMemoryStore(options) {
|
|
|
18976
19015
|
const assertWrite = async (writeOptions) => {
|
|
18977
19016
|
writeOptions?.signal?.throwIfAborted();
|
|
18978
19017
|
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
18979
|
-
throw new
|
|
19018
|
+
throw new MemorySourceIneligibleError();
|
|
18980
19019
|
}
|
|
18981
19020
|
if (options.canWrite && !await options.canWrite()) {
|
|
18982
|
-
throw new
|
|
19021
|
+
throw new MemorySourceIneligibleError();
|
|
18983
19022
|
}
|
|
18984
19023
|
writeOptions?.signal?.throwIfAborted();
|
|
18985
19024
|
};
|
|
@@ -19788,7 +19827,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
19788
19827
|
const assertWrite = async () => {
|
|
19789
19828
|
signal?.throwIfAborted();
|
|
19790
19829
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
19791
|
-
throw new
|
|
19830
|
+
throw new MemorySourceIneligibleError();
|
|
19792
19831
|
signal?.throwIfAborted();
|
|
19793
19832
|
};
|
|
19794
19833
|
const rejectUndecryptable = (failed) => {
|
|
@@ -20794,7 +20833,7 @@ function createRemoteMemoryStore(options) {
|
|
|
20794
20833
|
if (!record2) return null;
|
|
20795
20834
|
if (record2.memory.is_deleted) return null;
|
|
20796
20835
|
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
20797
|
-
throw new
|
|
20836
|
+
throw new MemorySourceIneligibleError();
|
|
20798
20837
|
writeOptions?.signal?.throwIfAborted();
|
|
20799
20838
|
const next = edit(structuredClone(record2.memory));
|
|
20800
20839
|
if (!next) return null;
|
|
@@ -22132,10 +22171,20 @@ function batchError(result) {
|
|
|
22132
22171
|
var AccountFailureError = class extends Error {
|
|
22133
22172
|
};
|
|
22134
22173
|
var LockedSourcesError = class extends Error {
|
|
22135
|
-
constructor(persistentIds) {
|
|
22136
|
-
|
|
22174
|
+
constructor(persistentIds, locked) {
|
|
22175
|
+
const counts = /* @__PURE__ */ new Map();
|
|
22176
|
+
for (const message of locked) {
|
|
22177
|
+
const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
|
|
22178
|
+
const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
|
|
22179
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
22180
|
+
}
|
|
22181
|
+
const summary = [...counts].map(([key, count2]) => `${key}=${count2}`).join(", ");
|
|
22182
|
+
super(`Source messages are locked; retained for retry (${summary})`);
|
|
22137
22183
|
this.persistentIds = persistentIds;
|
|
22138
22184
|
}
|
|
22185
|
+
get awaitingKey() {
|
|
22186
|
+
return this.persistentIds.length === 0;
|
|
22187
|
+
}
|
|
22139
22188
|
};
|
|
22140
22189
|
function splitTurns(messages) {
|
|
22141
22190
|
const turns = [];
|
|
@@ -22189,6 +22238,8 @@ function createDurableAutoExtractor(options) {
|
|
|
22189
22238
|
const attempts = /* @__PURE__ */ new Map();
|
|
22190
22239
|
const sessionFailures = /* @__PURE__ */ new Map();
|
|
22191
22240
|
const skippedThisSession = /* @__PURE__ */ new Set();
|
|
22241
|
+
const awaitingKey = /* @__PURE__ */ new Set();
|
|
22242
|
+
let keyEpoch = 0;
|
|
22192
22243
|
const clock = options.now ?? Date.now;
|
|
22193
22244
|
const reportError = (error, conversationId) => {
|
|
22194
22245
|
try {
|
|
@@ -22382,13 +22433,15 @@ function createDurableAutoExtractor(options) {
|
|
|
22382
22433
|
for (const job of pending) {
|
|
22383
22434
|
if (disposed) break;
|
|
22384
22435
|
const attempted = attempts.get(job.id) ?? 0;
|
|
22385
|
-
if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id))
|
|
22436
|
+
if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
|
|
22437
|
+
continue;
|
|
22386
22438
|
if (processed >= MAX_JOBS_PER_PASS) {
|
|
22387
22439
|
scheduleAfterSuccess = true;
|
|
22388
22440
|
break;
|
|
22389
22441
|
}
|
|
22390
22442
|
processed++;
|
|
22391
22443
|
const conversationId = String(job._getRaw("conversation_id"));
|
|
22444
|
+
const epochAtRead = keyEpoch;
|
|
22392
22445
|
let ids = [];
|
|
22393
22446
|
let loaded = [];
|
|
22394
22447
|
try {
|
|
@@ -22422,16 +22475,39 @@ function createDurableAutoExtractor(options) {
|
|
|
22422
22475
|
);
|
|
22423
22476
|
continue;
|
|
22424
22477
|
}
|
|
22425
|
-
const
|
|
22478
|
+
const foreign = new Set(
|
|
22479
|
+
ids.filter((_id, index) => loaded[index]?.conversationId !== conversationId)
|
|
22480
|
+
);
|
|
22481
|
+
if (foreign.size) {
|
|
22482
|
+
await database.write(
|
|
22483
|
+
() => job.update(
|
|
22484
|
+
(r) => r._setRaw(
|
|
22485
|
+
"message_ids",
|
|
22486
|
+
JSON.stringify(idsOf(job).filter((id) => !foreign.has(id)))
|
|
22487
|
+
)
|
|
22488
|
+
)
|
|
22489
|
+
);
|
|
22490
|
+
attempts.delete(job.id);
|
|
22491
|
+
scheduleAfterSuccess = true;
|
|
22492
|
+
reportError(
|
|
22493
|
+
new Error(`Dropped ${foreign.size} source id(s) from another conversation`),
|
|
22494
|
+
conversationId
|
|
22495
|
+
);
|
|
22496
|
+
continue;
|
|
22497
|
+
}
|
|
22498
|
+
const locked = loaded.filter(
|
|
22499
|
+
(message) => !!message && isEncrypted(message.content)
|
|
22500
|
+
);
|
|
22426
22501
|
if (locked.length) {
|
|
22427
22502
|
throw new LockedSourcesError(
|
|
22428
22503
|
locked.flatMap(
|
|
22429
22504
|
(message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
|
|
22430
|
-
)
|
|
22505
|
+
),
|
|
22506
|
+
locked
|
|
22431
22507
|
);
|
|
22432
22508
|
}
|
|
22433
22509
|
const messages = loaded.flatMap(
|
|
22434
|
-
(m) => m &&
|
|
22510
|
+
(m) => m && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
|
|
22435
22511
|
);
|
|
22436
22512
|
const jobScope = currentScope() === "private" ? "private" : String(job._getRaw("scope"));
|
|
22437
22513
|
const jobFolderId = job._getRaw("folder_id") ?? null;
|
|
@@ -22481,6 +22557,12 @@ function createDurableAutoExtractor(options) {
|
|
|
22481
22557
|
scheduleAfterSuccess = true;
|
|
22482
22558
|
} catch (error) {
|
|
22483
22559
|
if (disposed) break;
|
|
22560
|
+
if (error instanceof LockedSourcesError && error.awaitingKey) {
|
|
22561
|
+
reportError(error, conversationId);
|
|
22562
|
+
if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
|
|
22563
|
+
else scheduleAfterSuccess = true;
|
|
22564
|
+
continue;
|
|
22565
|
+
}
|
|
22484
22566
|
attempts.set(job.id, attempted + 1);
|
|
22485
22567
|
retry = true;
|
|
22486
22568
|
reportError(error, conversationId);
|
|
@@ -22508,7 +22590,18 @@ function createDurableAutoExtractor(options) {
|
|
|
22508
22590
|
activeBatch?.abort(options.signal?.reason);
|
|
22509
22591
|
if (timer !== void 0) clearTimeout(timer);
|
|
22510
22592
|
options.signal?.removeEventListener("abort", dispose);
|
|
22593
|
+
unsubscribeKey?.();
|
|
22511
22594
|
}
|
|
22595
|
+
const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
|
|
22596
|
+
keyEpoch++;
|
|
22597
|
+
if (!awaitingKey.size) return;
|
|
22598
|
+
awaitingKey.clear();
|
|
22599
|
+
if (timer !== void 0) {
|
|
22600
|
+
clearTimeout(timer);
|
|
22601
|
+
timer = void 0;
|
|
22602
|
+
}
|
|
22603
|
+
schedule(0);
|
|
22604
|
+
}) : void 0;
|
|
22512
22605
|
if (options.signal?.aborted) dispose();
|
|
22513
22606
|
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
22514
22607
|
schedule(0);
|
|
@@ -22524,9 +22617,31 @@ function createDurableAutoExtractor(options) {
|
|
|
22524
22617
|
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
22525
22618
|
);
|
|
22526
22619
|
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
22620
|
+
const watermarks = existing.flatMap((prior) => {
|
|
22621
|
+
const watermark = prior._getRaw("watermark");
|
|
22622
|
+
return typeof watermark === "string" && watermark ? [watermark] : [];
|
|
22623
|
+
});
|
|
22624
|
+
if (watermarks.length) {
|
|
22625
|
+
const misplaced = new Set(
|
|
22626
|
+
await storage.messagesCollection.query(
|
|
22627
|
+
Q9.where("id", Q9.oneOf(watermarks)),
|
|
22628
|
+
Q9.where("conversation_id", Q9.notEq(conversationId))
|
|
22629
|
+
).fetchIds()
|
|
22630
|
+
);
|
|
22631
|
+
for (const prior of existing)
|
|
22632
|
+
if (misplaced.has(String(prior._getRaw("watermark"))))
|
|
22633
|
+
await prior.update((r) => {
|
|
22634
|
+
r._setRaw("watermark", null);
|
|
22635
|
+
r._setRaw("watermark_seq", null);
|
|
22636
|
+
});
|
|
22637
|
+
}
|
|
22527
22638
|
const rows = await storage.messagesCollection.query(Q9.where("id", Q9.oneOf(ids))).fetch();
|
|
22639
|
+
const foreignRows = new Set(
|
|
22640
|
+
rows.filter((row) => row._getRaw("conversation_id") !== conversationId).map((row) => row.id)
|
|
22641
|
+
);
|
|
22528
22642
|
const sequences = /* @__PURE__ */ new Map();
|
|
22529
22643
|
for (const row of rows) {
|
|
22644
|
+
if (foreignRows.has(row.id)) continue;
|
|
22530
22645
|
const sequence = Number(row._getRaw("message_id"));
|
|
22531
22646
|
if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
|
|
22532
22647
|
}
|
|
@@ -22569,13 +22684,14 @@ function createDurableAutoExtractor(options) {
|
|
|
22569
22684
|
const ownWatermark = job?._getRaw("watermark");
|
|
22570
22685
|
const atOwnWatermark = !!job && boundary >= 0 && failedSessionsOf(job, String(ownWatermark)) < MAX_FAILED_SESSIONS && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
|
|
22571
22686
|
const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
|
|
22572
|
-
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
|
|
22687
|
+
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id) && !foreignRows.has(id));
|
|
22573
22688
|
if (!fresh.length) return;
|
|
22574
22689
|
if (job) {
|
|
22575
22690
|
await job.update(
|
|
22576
22691
|
(r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
|
|
22577
22692
|
);
|
|
22578
22693
|
attempts.delete(job.id);
|
|
22694
|
+
awaitingKey.delete(job.id);
|
|
22579
22695
|
} else {
|
|
22580
22696
|
await jobs.create((r) => {
|
|
22581
22697
|
r._setRaw("owner_key", owner);
|