@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/server/index.cjs
CHANGED
|
@@ -16828,7 +16828,7 @@ function onKeyAvailable(address, callback) {
|
|
|
16828
16828
|
callbacks.add(callback);
|
|
16829
16829
|
return () => {
|
|
16830
16830
|
callbacks.delete(callback);
|
|
16831
|
-
if (callbacks.size === 0) {
|
|
16831
|
+
if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
|
|
16832
16832
|
keyAvailableCallbacks.delete(address);
|
|
16833
16833
|
}
|
|
16834
16834
|
};
|
|
@@ -27777,6 +27777,67 @@ init_logger();
|
|
|
27777
27777
|
// src/lib/db/entities/operations.ts
|
|
27778
27778
|
var import_watermelondb18 = __toESM(require_watermelondb());
|
|
27779
27779
|
|
|
27780
|
+
// src/lib/db/memoryVault/types.ts
|
|
27781
|
+
var MEMORY_KINDS = [
|
|
27782
|
+
"display_name",
|
|
27783
|
+
"birth_date",
|
|
27784
|
+
"bio",
|
|
27785
|
+
"occupation",
|
|
27786
|
+
"interest",
|
|
27787
|
+
"gender",
|
|
27788
|
+
"height_cm",
|
|
27789
|
+
"looking_for",
|
|
27790
|
+
"politics",
|
|
27791
|
+
"religion",
|
|
27792
|
+
"ethnicity",
|
|
27793
|
+
"smoking",
|
|
27794
|
+
"drinking",
|
|
27795
|
+
"exercise",
|
|
27796
|
+
"sexuality",
|
|
27797
|
+
"prompt"
|
|
27798
|
+
];
|
|
27799
|
+
var MEMORY_LEVELS = ["private", "matching", "profile"];
|
|
27800
|
+
var MemoryLevelError = class extends Error {
|
|
27801
|
+
constructor(message) {
|
|
27802
|
+
super(message);
|
|
27803
|
+
this.name = "MemoryLevelError";
|
|
27804
|
+
}
|
|
27805
|
+
};
|
|
27806
|
+
var MemorySourceIneligibleError = class extends Error {
|
|
27807
|
+
constructor() {
|
|
27808
|
+
super("Memory source is no longer eligible");
|
|
27809
|
+
this.name = "MemorySourceIneligibleError";
|
|
27810
|
+
}
|
|
27811
|
+
};
|
|
27812
|
+
var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
|
|
27813
|
+
function levelFromScope(scope) {
|
|
27814
|
+
return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
|
|
27815
|
+
}
|
|
27816
|
+
function scopeForLevel(level) {
|
|
27817
|
+
return level === "private" ? "private" : "shared";
|
|
27818
|
+
}
|
|
27819
|
+
function resolveMemoryLevel(level, scope) {
|
|
27820
|
+
return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
|
|
27821
|
+
}
|
|
27822
|
+
function levelForScopeChange(current, nextScope) {
|
|
27823
|
+
const implied = levelFromScope(nextScope);
|
|
27824
|
+
return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
|
|
27825
|
+
}
|
|
27826
|
+
function parseMedia(value) {
|
|
27827
|
+
if (typeof value !== "string" || value === "") return null;
|
|
27828
|
+
try {
|
|
27829
|
+
const parsed = JSON.parse(value);
|
|
27830
|
+
if (!Array.isArray(parsed)) return null;
|
|
27831
|
+
const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
|
|
27832
|
+
feedItemId: Number(r.feedItemId ?? r.feed_item_id),
|
|
27833
|
+
objectKey: r.objectKey ?? r.object_key ?? null
|
|
27834
|
+
})).filter((r) => Number.isFinite(r.feedItemId));
|
|
27835
|
+
return refs.length > 0 ? refs : null;
|
|
27836
|
+
} catch {
|
|
27837
|
+
return null;
|
|
27838
|
+
}
|
|
27839
|
+
}
|
|
27840
|
+
|
|
27780
27841
|
// src/lib/db/entities/types.ts
|
|
27781
27842
|
var ENTITY_KINDS = [
|
|
27782
27843
|
"person",
|
|
@@ -27826,7 +27887,7 @@ function parseTopics(value) {
|
|
|
27826
27887
|
// src/lib/db/entities/operations.ts
|
|
27827
27888
|
async function assertCanWrite(ctx) {
|
|
27828
27889
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
27829
|
-
throw new
|
|
27890
|
+
throw new MemorySourceIneligibleError();
|
|
27830
27891
|
}
|
|
27831
27892
|
}
|
|
27832
27893
|
function entityToStored(e) {
|
|
@@ -28219,61 +28280,6 @@ function serializeSourceChunkIds(ids) {
|
|
|
28219
28280
|
return JSON.stringify(ids.slice(start));
|
|
28220
28281
|
}
|
|
28221
28282
|
|
|
28222
|
-
// src/lib/db/memoryVault/types.ts
|
|
28223
|
-
var MEMORY_KINDS = [
|
|
28224
|
-
"display_name",
|
|
28225
|
-
"birth_date",
|
|
28226
|
-
"bio",
|
|
28227
|
-
"occupation",
|
|
28228
|
-
"interest",
|
|
28229
|
-
"gender",
|
|
28230
|
-
"height_cm",
|
|
28231
|
-
"looking_for",
|
|
28232
|
-
"politics",
|
|
28233
|
-
"religion",
|
|
28234
|
-
"ethnicity",
|
|
28235
|
-
"smoking",
|
|
28236
|
-
"drinking",
|
|
28237
|
-
"exercise",
|
|
28238
|
-
"sexuality",
|
|
28239
|
-
"prompt"
|
|
28240
|
-
];
|
|
28241
|
-
var MEMORY_LEVELS = ["private", "matching", "profile"];
|
|
28242
|
-
var MemoryLevelError = class extends Error {
|
|
28243
|
-
constructor(message) {
|
|
28244
|
-
super(message);
|
|
28245
|
-
this.name = "MemoryLevelError";
|
|
28246
|
-
}
|
|
28247
|
-
};
|
|
28248
|
-
var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
|
|
28249
|
-
function levelFromScope(scope) {
|
|
28250
|
-
return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
|
|
28251
|
-
}
|
|
28252
|
-
function scopeForLevel(level) {
|
|
28253
|
-
return level === "private" ? "private" : "shared";
|
|
28254
|
-
}
|
|
28255
|
-
function resolveMemoryLevel(level, scope) {
|
|
28256
|
-
return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
|
|
28257
|
-
}
|
|
28258
|
-
function levelForScopeChange(current, nextScope) {
|
|
28259
|
-
const implied = levelFromScope(nextScope);
|
|
28260
|
-
return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
|
|
28261
|
-
}
|
|
28262
|
-
function parseMedia(value) {
|
|
28263
|
-
if (typeof value !== "string" || value === "") return null;
|
|
28264
|
-
try {
|
|
28265
|
-
const parsed = JSON.parse(value);
|
|
28266
|
-
if (!Array.isArray(parsed)) return null;
|
|
28267
|
-
const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
|
|
28268
|
-
feedItemId: Number(r.feedItemId ?? r.feed_item_id),
|
|
28269
|
-
objectKey: r.objectKey ?? r.object_key ?? null
|
|
28270
|
-
})).filter((r) => Number.isFinite(r.feedItemId));
|
|
28271
|
-
return refs.length > 0 ? refs : null;
|
|
28272
|
-
} catch {
|
|
28273
|
-
return null;
|
|
28274
|
-
}
|
|
28275
|
-
}
|
|
28276
|
-
|
|
28277
28283
|
// src/lib/db/memoryVault/operations.ts
|
|
28278
28284
|
function visibilityOrPrivate(value) {
|
|
28279
28285
|
return value === "public" ? value : "private";
|
|
@@ -28293,7 +28299,7 @@ function isKinded(record) {
|
|
|
28293
28299
|
}
|
|
28294
28300
|
async function assertCanWrite2(ctx) {
|
|
28295
28301
|
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
28296
|
-
throw new
|
|
28302
|
+
throw new MemorySourceIneligibleError();
|
|
28297
28303
|
}
|
|
28298
28304
|
}
|
|
28299
28305
|
function assertValidKindLevel(kind, level) {
|
|
@@ -28970,7 +28976,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
28970
28976
|
ctx.embeddedWalletSigner
|
|
28971
28977
|
);
|
|
28972
28978
|
} catch (err) {
|
|
28973
|
-
if (err instanceof MemoryLevelError) throw err;
|
|
28979
|
+
if (err instanceof MemoryLevelError || err instanceof MemorySourceIneligibleError) throw err;
|
|
28974
28980
|
return null;
|
|
28975
28981
|
}
|
|
28976
28982
|
}
|
|
@@ -32667,6 +32673,13 @@ var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
|
|
|
32667
32673
|
var DEFAULT_SCOPE = "private";
|
|
32668
32674
|
var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
|
|
32669
32675
|
var DEFAULT_CONSOLIDATE_TOP_K = 20;
|
|
32676
|
+
var RetainError = class extends Error {
|
|
32677
|
+
constructor(reason, message) {
|
|
32678
|
+
super(message);
|
|
32679
|
+
this.reason = reason;
|
|
32680
|
+
this.name = "RetainError";
|
|
32681
|
+
}
|
|
32682
|
+
};
|
|
32670
32683
|
async function retain(content, ctx, options = {}) {
|
|
32671
32684
|
const embeddingOptions = {
|
|
32672
32685
|
...ctx.embeddingOptions,
|
|
@@ -32722,7 +32735,8 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
32722
32735
|
});
|
|
32723
32736
|
prepared = withoutKindedRows(prepared);
|
|
32724
32737
|
if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
|
|
32725
|
-
throw new
|
|
32738
|
+
throw new RetainError(
|
|
32739
|
+
"embeddings-unavailable",
|
|
32726
32740
|
"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."
|
|
32727
32741
|
);
|
|
32728
32742
|
}
|
|
@@ -33092,7 +33106,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
33092
33106
|
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
33093
33107
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
33094
33108
|
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
33095
|
-
throw new
|
|
33109
|
+
throw new RetainError(
|
|
33110
|
+
"merge-not-persisted",
|
|
33111
|
+
`retain: merge into memory ${targetId} failed to persist`
|
|
33112
|
+
);
|
|
33096
33113
|
}
|
|
33097
33114
|
}
|
|
33098
33115
|
|
|
@@ -33250,6 +33267,12 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
33250
33267
|
(c) => c.candidate.content.length <= MAX_CONTENT_LENGTH && !c.unresolved && !isLowSignalContent(c.candidate.content, ownNames)
|
|
33251
33268
|
).map((c) => c.candidate);
|
|
33252
33269
|
}
|
|
33270
|
+
function writeFailureReasonOf(err) {
|
|
33271
|
+
if (err instanceof MemorySourceIneligibleError) return "source-ineligible";
|
|
33272
|
+
if (err instanceof RetainError) return err.reason;
|
|
33273
|
+
if (err?.name === "AbortError") return "aborted";
|
|
33274
|
+
return "unknown";
|
|
33275
|
+
}
|
|
33253
33276
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
33254
33277
|
const { memoryStore, signal } = options;
|
|
33255
33278
|
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
@@ -33339,6 +33362,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33339
33362
|
const results = [];
|
|
33340
33363
|
const quarantinedInfo = [];
|
|
33341
33364
|
let failedWrites = 0;
|
|
33365
|
+
let writeFailureReason;
|
|
33342
33366
|
let auditRows;
|
|
33343
33367
|
const tRetain = Date.now();
|
|
33344
33368
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
@@ -33434,6 +33458,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33434
33458
|
}
|
|
33435
33459
|
} catch (err) {
|
|
33436
33460
|
failedWrites++;
|
|
33461
|
+
writeFailureReason ?? (writeFailureReason = writeFailureReasonOf(err));
|
|
33437
33462
|
log.warn("[memory/extract] retain failed for one candidate", err);
|
|
33438
33463
|
options.onCandidateFailed?.(candidate, err);
|
|
33439
33464
|
}
|
|
@@ -33446,6 +33471,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33446
33471
|
candidates: succeededCandidates,
|
|
33447
33472
|
results,
|
|
33448
33473
|
failedCount: failedWrites,
|
|
33474
|
+
...writeFailureReason !== void 0 && { writeFailureReason },
|
|
33449
33475
|
outcome,
|
|
33450
33476
|
quarantined: quarantinedInfo,
|
|
33451
33477
|
funnel: {
|
|
@@ -33716,7 +33742,17 @@ function createAutoExtractor(options) {
|
|
|
33716
33742
|
const t0 = Date.now();
|
|
33717
33743
|
void (async () => {
|
|
33718
33744
|
try {
|
|
33719
|
-
const {
|
|
33745
|
+
const {
|
|
33746
|
+
candidates,
|
|
33747
|
+
results,
|
|
33748
|
+
failedCount,
|
|
33749
|
+
writeFailureReason,
|
|
33750
|
+
outcome,
|
|
33751
|
+
failure,
|
|
33752
|
+
funnel,
|
|
33753
|
+
timings,
|
|
33754
|
+
model
|
|
33755
|
+
} = await extractAndRetain(window2, retainCtx, {
|
|
33720
33756
|
extract,
|
|
33721
33757
|
memoryStore: options.memoryStore,
|
|
33722
33758
|
signal: options.signal,
|
|
@@ -33752,6 +33788,7 @@ function createAutoExtractor(options) {
|
|
|
33752
33788
|
candidates,
|
|
33753
33789
|
results,
|
|
33754
33790
|
failedCount,
|
|
33791
|
+
...writeFailureReason !== void 0 && { writeFailureReason },
|
|
33755
33792
|
durationMs: Date.now() - t0,
|
|
33756
33793
|
conversationId,
|
|
33757
33794
|
outcome,
|
|
@@ -35883,10 +35920,10 @@ function createLocalMemoryStore(options) {
|
|
|
35883
35920
|
const assertWrite = async (writeOptions) => {
|
|
35884
35921
|
writeOptions?.signal?.throwIfAborted();
|
|
35885
35922
|
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
35886
|
-
throw new
|
|
35923
|
+
throw new MemorySourceIneligibleError();
|
|
35887
35924
|
}
|
|
35888
35925
|
if (options.canWrite && !await options.canWrite()) {
|
|
35889
|
-
throw new
|
|
35926
|
+
throw new MemorySourceIneligibleError();
|
|
35890
35927
|
}
|
|
35891
35928
|
writeOptions?.signal?.throwIfAborted();
|
|
35892
35929
|
};
|
|
@@ -36843,10 +36880,20 @@ function batchError(result) {
|
|
|
36843
36880
|
var AccountFailureError = class extends Error {
|
|
36844
36881
|
};
|
|
36845
36882
|
var LockedSourcesError = class extends Error {
|
|
36846
|
-
constructor(persistentIds) {
|
|
36847
|
-
|
|
36883
|
+
constructor(persistentIds, locked) {
|
|
36884
|
+
const counts = /* @__PURE__ */ new Map();
|
|
36885
|
+
for (const message of locked) {
|
|
36886
|
+
const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
|
|
36887
|
+
const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
|
|
36888
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
36889
|
+
}
|
|
36890
|
+
const summary = [...counts].map(([key, count]) => `${key}=${count}`).join(", ");
|
|
36891
|
+
super(`Source messages are locked; retained for retry (${summary})`);
|
|
36848
36892
|
this.persistentIds = persistentIds;
|
|
36849
36893
|
}
|
|
36894
|
+
get awaitingKey() {
|
|
36895
|
+
return this.persistentIds.length === 0;
|
|
36896
|
+
}
|
|
36850
36897
|
};
|
|
36851
36898
|
function splitTurns(messages) {
|
|
36852
36899
|
const turns = [];
|
|
@@ -36900,6 +36947,8 @@ function createDurableAutoExtractor(options) {
|
|
|
36900
36947
|
const attempts = /* @__PURE__ */ new Map();
|
|
36901
36948
|
const sessionFailures = /* @__PURE__ */ new Map();
|
|
36902
36949
|
const skippedThisSession = /* @__PURE__ */ new Set();
|
|
36950
|
+
const awaitingKey = /* @__PURE__ */ new Set();
|
|
36951
|
+
let keyEpoch = 0;
|
|
36903
36952
|
const clock = options.now ?? Date.now;
|
|
36904
36953
|
const reportError = (error, conversationId) => {
|
|
36905
36954
|
try {
|
|
@@ -37093,13 +37142,15 @@ function createDurableAutoExtractor(options) {
|
|
|
37093
37142
|
for (const job of pending) {
|
|
37094
37143
|
if (disposed) break;
|
|
37095
37144
|
const attempted = attempts.get(job.id) ?? 0;
|
|
37096
|
-
if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id))
|
|
37145
|
+
if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
|
|
37146
|
+
continue;
|
|
37097
37147
|
if (processed >= MAX_JOBS_PER_PASS) {
|
|
37098
37148
|
scheduleAfterSuccess = true;
|
|
37099
37149
|
break;
|
|
37100
37150
|
}
|
|
37101
37151
|
processed++;
|
|
37102
37152
|
const conversationId = String(job._getRaw("conversation_id"));
|
|
37153
|
+
const epochAtRead = keyEpoch;
|
|
37103
37154
|
let ids = [];
|
|
37104
37155
|
let loaded = [];
|
|
37105
37156
|
try {
|
|
@@ -37133,16 +37184,39 @@ function createDurableAutoExtractor(options) {
|
|
|
37133
37184
|
);
|
|
37134
37185
|
continue;
|
|
37135
37186
|
}
|
|
37136
|
-
const
|
|
37187
|
+
const foreign = new Set(
|
|
37188
|
+
ids.filter((_id, index) => loaded[index]?.conversationId !== conversationId)
|
|
37189
|
+
);
|
|
37190
|
+
if (foreign.size) {
|
|
37191
|
+
await database.write(
|
|
37192
|
+
() => job.update(
|
|
37193
|
+
(r) => r._setRaw(
|
|
37194
|
+
"message_ids",
|
|
37195
|
+
JSON.stringify(idsOf(job).filter((id) => !foreign.has(id)))
|
|
37196
|
+
)
|
|
37197
|
+
)
|
|
37198
|
+
);
|
|
37199
|
+
attempts.delete(job.id);
|
|
37200
|
+
scheduleAfterSuccess = true;
|
|
37201
|
+
reportError(
|
|
37202
|
+
new Error(`Dropped ${foreign.size} source id(s) from another conversation`),
|
|
37203
|
+
conversationId
|
|
37204
|
+
);
|
|
37205
|
+
continue;
|
|
37206
|
+
}
|
|
37207
|
+
const locked = loaded.filter(
|
|
37208
|
+
(message) => !!message && isEncrypted(message.content)
|
|
37209
|
+
);
|
|
37137
37210
|
if (locked.length) {
|
|
37138
37211
|
throw new LockedSourcesError(
|
|
37139
37212
|
locked.flatMap(
|
|
37140
37213
|
(message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
|
|
37141
|
-
)
|
|
37214
|
+
),
|
|
37215
|
+
locked
|
|
37142
37216
|
);
|
|
37143
37217
|
}
|
|
37144
37218
|
const messages = loaded.flatMap(
|
|
37145
|
-
(m) => m &&
|
|
37219
|
+
(m) => m && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
|
|
37146
37220
|
);
|
|
37147
37221
|
const jobScope = currentScope() === "private" ? "private" : String(job._getRaw("scope"));
|
|
37148
37222
|
const jobFolderId = job._getRaw("folder_id") ?? null;
|
|
@@ -37192,6 +37266,12 @@ function createDurableAutoExtractor(options) {
|
|
|
37192
37266
|
scheduleAfterSuccess = true;
|
|
37193
37267
|
} catch (error) {
|
|
37194
37268
|
if (disposed) break;
|
|
37269
|
+
if (error instanceof LockedSourcesError && error.awaitingKey) {
|
|
37270
|
+
reportError(error, conversationId);
|
|
37271
|
+
if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
|
|
37272
|
+
else scheduleAfterSuccess = true;
|
|
37273
|
+
continue;
|
|
37274
|
+
}
|
|
37195
37275
|
attempts.set(job.id, attempted + 1);
|
|
37196
37276
|
retry = true;
|
|
37197
37277
|
reportError(error, conversationId);
|
|
@@ -37219,7 +37299,18 @@ function createDurableAutoExtractor(options) {
|
|
|
37219
37299
|
activeBatch?.abort(options.signal?.reason);
|
|
37220
37300
|
if (timer !== void 0) clearTimeout(timer);
|
|
37221
37301
|
options.signal?.removeEventListener("abort", dispose);
|
|
37302
|
+
unsubscribeKey?.();
|
|
37222
37303
|
}
|
|
37304
|
+
const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
|
|
37305
|
+
keyEpoch++;
|
|
37306
|
+
if (!awaitingKey.size) return;
|
|
37307
|
+
awaitingKey.clear();
|
|
37308
|
+
if (timer !== void 0) {
|
|
37309
|
+
clearTimeout(timer);
|
|
37310
|
+
timer = void 0;
|
|
37311
|
+
}
|
|
37312
|
+
schedule(0);
|
|
37313
|
+
}) : void 0;
|
|
37223
37314
|
if (options.signal?.aborted) dispose();
|
|
37224
37315
|
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
37225
37316
|
schedule(0);
|
|
@@ -37235,9 +37326,31 @@ function createDurableAutoExtractor(options) {
|
|
|
37235
37326
|
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
37236
37327
|
);
|
|
37237
37328
|
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
37329
|
+
const watermarks = existing.flatMap((prior) => {
|
|
37330
|
+
const watermark = prior._getRaw("watermark");
|
|
37331
|
+
return typeof watermark === "string" && watermark ? [watermark] : [];
|
|
37332
|
+
});
|
|
37333
|
+
if (watermarks.length) {
|
|
37334
|
+
const misplaced = new Set(
|
|
37335
|
+
await storage.messagesCollection.query(
|
|
37336
|
+
import_watermelondb25.Q.where("id", import_watermelondb25.Q.oneOf(watermarks)),
|
|
37337
|
+
import_watermelondb25.Q.where("conversation_id", import_watermelondb25.Q.notEq(conversationId))
|
|
37338
|
+
).fetchIds()
|
|
37339
|
+
);
|
|
37340
|
+
for (const prior of existing)
|
|
37341
|
+
if (misplaced.has(String(prior._getRaw("watermark"))))
|
|
37342
|
+
await prior.update((r) => {
|
|
37343
|
+
r._setRaw("watermark", null);
|
|
37344
|
+
r._setRaw("watermark_seq", null);
|
|
37345
|
+
});
|
|
37346
|
+
}
|
|
37238
37347
|
const rows = await storage.messagesCollection.query(import_watermelondb25.Q.where("id", import_watermelondb25.Q.oneOf(ids))).fetch();
|
|
37348
|
+
const foreignRows = new Set(
|
|
37349
|
+
rows.filter((row) => row._getRaw("conversation_id") !== conversationId).map((row) => row.id)
|
|
37350
|
+
);
|
|
37239
37351
|
const sequences = /* @__PURE__ */ new Map();
|
|
37240
37352
|
for (const row of rows) {
|
|
37353
|
+
if (foreignRows.has(row.id)) continue;
|
|
37241
37354
|
const sequence = Number(row._getRaw("message_id"));
|
|
37242
37355
|
if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
|
|
37243
37356
|
}
|
|
@@ -37280,13 +37393,14 @@ function createDurableAutoExtractor(options) {
|
|
|
37280
37393
|
const ownWatermark = job?._getRaw("watermark");
|
|
37281
37394
|
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));
|
|
37282
37395
|
const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
|
|
37283
|
-
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
|
|
37396
|
+
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id) && !foreignRows.has(id));
|
|
37284
37397
|
if (!fresh.length) return;
|
|
37285
37398
|
if (job) {
|
|
37286
37399
|
await job.update(
|
|
37287
37400
|
(r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
|
|
37288
37401
|
);
|
|
37289
37402
|
attempts.delete(job.id);
|
|
37403
|
+
awaitingKey.delete(job.id);
|
|
37290
37404
|
} else {
|
|
37291
37405
|
await jobs.create((r) => {
|
|
37292
37406
|
r._setRaw("owner_key", owner);
|
package/dist/server/index.d.mts
CHANGED
|
@@ -4931,6 +4931,7 @@ declare function extractFacts(messages: AutoExtractMessage[], options: ExtractFa
|
|
|
4931
4931
|
* look like `no-facts`.
|
|
4932
4932
|
*/
|
|
4933
4933
|
type ExtractOutcome = "extracted" | "no-facts" | "empty-after-retry" | "dropped-after-redaction";
|
|
4934
|
+
type WriteFailureReason = "source-ineligible" | "embeddings-unavailable" | "merge-not-persisted" | "aborted" | "unknown";
|
|
4934
4935
|
/**
|
|
4935
4936
|
* Stage 2 — for each extracted candidate, call retain() with auto-merge
|
|
4936
4937
|
* enabled. When `consolidateOptions` are wired, retain()'s consolidation pass
|
|
@@ -5001,6 +5002,7 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
5001
5002
|
candidates: ExtractedCandidate[];
|
|
5002
5003
|
results: RetainResult[];
|
|
5003
5004
|
failedCount: number;
|
|
5005
|
+
writeFailureReason?: WriteFailureReason;
|
|
5004
5006
|
outcome: ExtractOutcome;
|
|
5005
5007
|
/**
|
|
5006
5008
|
* Tier-0 security (PR3) — candidates quarantined by the injection screen and
|
|
@@ -9036,6 +9038,7 @@ interface TurnCompleteEvent {
|
|
|
9036
9038
|
results: RetainResult[];
|
|
9037
9039
|
/** Per-candidate retain() failures. `onError` only fires on pipeline throws. */
|
|
9038
9040
|
failedCount: number;
|
|
9041
|
+
writeFailureReason?: WriteFailureReason;
|
|
9039
9042
|
durationMs: number;
|
|
9040
9043
|
conversationId?: string;
|
|
9041
9044
|
/**
|
package/dist/server/index.d.ts
CHANGED
|
@@ -4931,6 +4931,7 @@ declare function extractFacts(messages: AutoExtractMessage[], options: ExtractFa
|
|
|
4931
4931
|
* look like `no-facts`.
|
|
4932
4932
|
*/
|
|
4933
4933
|
type ExtractOutcome = "extracted" | "no-facts" | "empty-after-retry" | "dropped-after-redaction";
|
|
4934
|
+
type WriteFailureReason = "source-ineligible" | "embeddings-unavailable" | "merge-not-persisted" | "aborted" | "unknown";
|
|
4934
4935
|
/**
|
|
4935
4936
|
* Stage 2 — for each extracted candidate, call retain() with auto-merge
|
|
4936
4937
|
* enabled. When `consolidateOptions` are wired, retain()'s consolidation pass
|
|
@@ -5001,6 +5002,7 @@ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: Ret
|
|
|
5001
5002
|
candidates: ExtractedCandidate[];
|
|
5002
5003
|
results: RetainResult[];
|
|
5003
5004
|
failedCount: number;
|
|
5005
|
+
writeFailureReason?: WriteFailureReason;
|
|
5004
5006
|
outcome: ExtractOutcome;
|
|
5005
5007
|
/**
|
|
5006
5008
|
* Tier-0 security (PR3) — candidates quarantined by the injection screen and
|
|
@@ -9036,6 +9038,7 @@ interface TurnCompleteEvent {
|
|
|
9036
9038
|
results: RetainResult[];
|
|
9037
9039
|
/** Per-candidate retain() failures. `onError` only fires on pipeline throws. */
|
|
9038
9040
|
failedCount: number;
|
|
9041
|
+
writeFailureReason?: WriteFailureReason;
|
|
9039
9042
|
durationMs: number;
|
|
9040
9043
|
conversationId?: string;
|
|
9041
9044
|
/**
|