@anuma/sdk 9.1.0 → 9.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +309 -86
- package/dist/expo/index.d.mts +9 -1
- package/dist/expo/index.d.ts +9 -1
- package/dist/expo/index.mjs +308 -85
- package/dist/index.cjs +37 -3
- package/dist/index.mjs +37 -3
- package/dist/react/index.cjs +309 -86
- package/dist/react/index.d.mts +9 -1
- package/dist/react/index.d.ts +9 -1
- package/dist/react/index.mjs +309 -86
- package/package.json +1 -1
package/dist/react/index.d.ts
CHANGED
|
@@ -11607,7 +11607,8 @@ declare class RemoteMemoryError extends Error {
|
|
|
11607
11607
|
readonly status: number;
|
|
11608
11608
|
readonly code?: string | undefined;
|
|
11609
11609
|
readonly retryAfterMs?: number | undefined;
|
|
11610
|
-
|
|
11610
|
+
readonly rateLimitBucket?: string | undefined;
|
|
11611
|
+
constructor(message: string, status: number, code?: string | undefined, retryAfterMs?: number | undefined, rateLimitBucket?: string | undefined);
|
|
11611
11612
|
}
|
|
11612
11613
|
/**
|
|
11613
11614
|
* Remote persistence foundation for MemoryStore, not yet its recall/retain implementation.
|
|
@@ -11616,6 +11617,7 @@ declare class RemoteMemoryError extends Error {
|
|
|
11616
11617
|
* Migration must have activated the account under the canonical key before construction.
|
|
11617
11618
|
*/
|
|
11618
11619
|
interface RemoteMemoryPersistence extends RemoteTopicPersistence, RemoteMemoryWorkPersistence {
|
|
11620
|
+
supportsRealtimeChanges?: boolean;
|
|
11619
11621
|
counts(): Promise<MemoryCounts>;
|
|
11620
11622
|
temporal(window: {
|
|
11621
11623
|
start: number;
|
|
@@ -11747,6 +11749,12 @@ interface RemoteMemoryStoreOptions {
|
|
|
11747
11749
|
graphRanking?: RecallFactSource["graphRanking"];
|
|
11748
11750
|
temporalRanking?: RecallFactSource["temporalRanking"];
|
|
11749
11751
|
pollIntervalMs?: number;
|
|
11752
|
+
activity?: {
|
|
11753
|
+
isActive: () => boolean;
|
|
11754
|
+
subscribe: (onChange: () => void) => () => void;
|
|
11755
|
+
};
|
|
11756
|
+
/** Report connection state on subscribe/reconnect and true on each account memory change. */
|
|
11757
|
+
subscribeChanges?: (onChange: (connected: boolean) => void) => () => void;
|
|
11750
11758
|
}
|
|
11751
11759
|
declare class RemoteMemoryPartialCreateError extends Error {
|
|
11752
11760
|
readonly created: StoredVaultMemory[];
|
package/dist/react/index.mjs
CHANGED
|
@@ -10287,11 +10287,12 @@ function isRemoteWorkLeaseExpired(error) {
|
|
|
10287
10287
|
|
|
10288
10288
|
// src/lib/memory/store/remotePersistence.ts
|
|
10289
10289
|
var RemoteMemoryError = class extends Error {
|
|
10290
|
-
constructor(message, status, code, retryAfterMs) {
|
|
10290
|
+
constructor(message, status, code, retryAfterMs, rateLimitBucket) {
|
|
10291
10291
|
super(message);
|
|
10292
10292
|
this.status = status;
|
|
10293
10293
|
this.code = code;
|
|
10294
10294
|
this.retryAfterMs = retryAfterMs;
|
|
10295
|
+
this.rateLimitBucket = rateLimitBucket;
|
|
10295
10296
|
this.name = "RemoteMemoryError";
|
|
10296
10297
|
}
|
|
10297
10298
|
};
|
|
@@ -10386,6 +10387,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
|
|
|
10386
10387
|
throw new Error("timeoutMs must be a positive number");
|
|
10387
10388
|
const root = base.href.replace(/\/$/, "") + apiPath;
|
|
10388
10389
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
10390
|
+
const cooldowns = /* @__PURE__ */ new Map();
|
|
10391
|
+
const memoryBudget = (path, method) => {
|
|
10392
|
+
if (method === "PUT")
|
|
10393
|
+
return path === "/topics" ? "private-memory-import" : "private-memory-write";
|
|
10394
|
+
if (method === "POST" && ["/import", "/memories/batch", "/topics/import"].includes(path))
|
|
10395
|
+
return "private-memory-import";
|
|
10396
|
+
return "private-memory-read";
|
|
10397
|
+
};
|
|
10389
10398
|
const request = async (path, init = {}, signal) => {
|
|
10390
10399
|
const controller = new AbortController();
|
|
10391
10400
|
let timedOut = false;
|
|
@@ -10409,6 +10418,25 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
|
|
|
10409
10418
|
const token = await Promise.race([options.getToken(), aborted2]);
|
|
10410
10419
|
if (controller.signal.aborted) await aborted2;
|
|
10411
10420
|
if (!token) throw new RemoteMemoryError("Authentication required", 401);
|
|
10421
|
+
const pathname = path.split("?")[0];
|
|
10422
|
+
const route = `${init.method ?? "GET"} ${pathname}`;
|
|
10423
|
+
const budgets = ["*", route];
|
|
10424
|
+
if (apiPath === "/api/private-memories")
|
|
10425
|
+
budgets.push("private-memory-ip", memoryBudget(pathname, init.method ?? "GET"));
|
|
10426
|
+
for (const bucket of budgets) {
|
|
10427
|
+
const cooldown = cooldowns.get(bucket);
|
|
10428
|
+
if (!cooldown) continue;
|
|
10429
|
+
const remaining = cooldown.until - Date.now();
|
|
10430
|
+
if (remaining > 0)
|
|
10431
|
+
throw new RemoteMemoryError(
|
|
10432
|
+
cooldown.error.message,
|
|
10433
|
+
429,
|
|
10434
|
+
cooldown.error.code,
|
|
10435
|
+
remaining,
|
|
10436
|
+
cooldown.error.rateLimitBucket
|
|
10437
|
+
);
|
|
10438
|
+
cooldowns.delete(bucket);
|
|
10439
|
+
}
|
|
10412
10440
|
const response = await fetcher(root + path, {
|
|
10413
10441
|
...init,
|
|
10414
10442
|
headers: {
|
|
@@ -10421,12 +10449,18 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
|
|
|
10421
10449
|
if (!response.ok) {
|
|
10422
10450
|
const body = await response.json().catch(() => null);
|
|
10423
10451
|
const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
|
|
10424
|
-
|
|
10452
|
+
const error = new RemoteMemoryError(
|
|
10425
10453
|
record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
|
|
10426
10454
|
response.status,
|
|
10427
10455
|
record(body) && typeof body.code === "string" ? body.code : void 0,
|
|
10428
|
-
retryAfter ?? void 0
|
|
10456
|
+
retryAfter ?? void 0,
|
|
10457
|
+
record(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
|
|
10429
10458
|
);
|
|
10459
|
+
if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
|
|
10460
|
+
const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
|
|
10461
|
+
cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
|
|
10462
|
+
}
|
|
10463
|
+
throw error;
|
|
10430
10464
|
}
|
|
10431
10465
|
return await response.json();
|
|
10432
10466
|
} catch (error) {
|
|
@@ -10666,6 +10700,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
10666
10700
|
return {
|
|
10667
10701
|
...createRemoteTopicPersistence(request),
|
|
10668
10702
|
...createRemoteWorkPersistence(request),
|
|
10703
|
+
supportsRealtimeChanges: account.realtime_changes === true,
|
|
10669
10704
|
counts: async () => {
|
|
10670
10705
|
const result = await request("/counts", {});
|
|
10671
10706
|
if (!record(result) || ["live", "archived", "quarantined"].some(
|
|
@@ -23450,6 +23485,9 @@ var RemoteMemoryPartialCreateError = class extends Error {
|
|
|
23450
23485
|
function rejectsInput(error) {
|
|
23451
23486
|
return error instanceof EmbeddingHttpError && error.status !== void 0 && error.status >= 400 && error.status < 500 && error.status !== 429 && !isFatalEmbeddingError(error);
|
|
23452
23487
|
}
|
|
23488
|
+
function rejectsMemoryWrite(error) {
|
|
23489
|
+
return error instanceof RemoteMemoryError && (error.status === 400 || error.status === 422) && (error.code === void 0 || error.code === "unknown_field");
|
|
23490
|
+
}
|
|
23453
23491
|
function warnFailed(failed) {
|
|
23454
23492
|
if (failed.length)
|
|
23455
23493
|
getLogger().warn(
|
|
@@ -23537,16 +23575,47 @@ function createRemoteMemoryStore(options) {
|
|
|
23537
23575
|
const { persistence, embeddingOptions } = options;
|
|
23538
23576
|
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
23539
23577
|
const pollIntervalMs = options.pollIntervalMs ?? 6e4;
|
|
23578
|
+
const activity = options.activity ?? {
|
|
23579
|
+
isActive: () => (typeof document === "undefined" || document.visibilityState !== "hidden") && (typeof navigator === "undefined" || navigator.onLine !== false),
|
|
23580
|
+
subscribe: (onChange) => {
|
|
23581
|
+
if (typeof window === "undefined" || typeof document === "undefined") return () => {
|
|
23582
|
+
};
|
|
23583
|
+
document.addEventListener("visibilitychange", onChange);
|
|
23584
|
+
window.addEventListener("online", onChange);
|
|
23585
|
+
window.addEventListener("offline", onChange);
|
|
23586
|
+
return () => {
|
|
23587
|
+
document.removeEventListener("visibilitychange", onChange);
|
|
23588
|
+
window.removeEventListener("online", onChange);
|
|
23589
|
+
window.removeEventListener("offline", onChange);
|
|
23590
|
+
};
|
|
23591
|
+
}
|
|
23592
|
+
};
|
|
23540
23593
|
const pipeline = createRemoteMemoryPipeline({
|
|
23541
23594
|
...options,
|
|
23542
23595
|
graphRanking: options.graphRanking ?? ((query, _traverse, recallOptions) => topicGraphRanking(query, recallOptions)),
|
|
23543
23596
|
temporalRanking: options.temporalRanking ?? ((query, now) => eventTimeRanking(query, now))
|
|
23544
23597
|
});
|
|
23545
23598
|
const subscribers = /* @__PURE__ */ new Set();
|
|
23599
|
+
const retainTopics = () => pollIntervalMs > 0 && [...subscribers].some((subscriber) => subscriber.options.topics);
|
|
23546
23600
|
const seen = /* @__PURE__ */ new Map();
|
|
23601
|
+
const reads = /* @__PURE__ */ new Map();
|
|
23602
|
+
const metadataReads = /* @__PURE__ */ new Map();
|
|
23603
|
+
let topicSnapshot;
|
|
23604
|
+
let topicCatalog;
|
|
23605
|
+
const invalidateReads = () => {
|
|
23606
|
+
reads.clear();
|
|
23607
|
+
metadataReads.clear();
|
|
23608
|
+
topicSnapshot = void 0;
|
|
23609
|
+
topicCatalog = void 0;
|
|
23610
|
+
};
|
|
23547
23611
|
let timer;
|
|
23612
|
+
let scheduledAt;
|
|
23613
|
+
let stopActivity;
|
|
23614
|
+
let stopChanges;
|
|
23615
|
+
let changesConnected = false;
|
|
23548
23616
|
const notify = (change, records = []) => {
|
|
23549
|
-
|
|
23617
|
+
invalidateReads();
|
|
23618
|
+
if (subscribers.size)
|
|
23550
23619
|
for (const record2 of records) {
|
|
23551
23620
|
const previous = seen.get(record2.memory.memory_id);
|
|
23552
23621
|
if ((previous?.version ?? 0) + 1 === record2.version)
|
|
@@ -23570,8 +23639,37 @@ function createRemoteMemoryStore(options) {
|
|
|
23570
23639
|
} while (cursor2 && records.length < max);
|
|
23571
23640
|
return records.slice(0, max);
|
|
23572
23641
|
};
|
|
23573
|
-
const
|
|
23574
|
-
|
|
23642
|
+
const shareRead = (inflight, options2, read) => {
|
|
23643
|
+
if (options2.signal) return read();
|
|
23644
|
+
const key = JSON.stringify(Object.entries(options2).sort(([a], [b]) => a.localeCompare(b)));
|
|
23645
|
+
const active = inflight.get(key);
|
|
23646
|
+
if (active) return active;
|
|
23647
|
+
const pending2 = read();
|
|
23648
|
+
inflight.set(key, pending2);
|
|
23649
|
+
const clear = () => {
|
|
23650
|
+
if (inflight.get(key) === pending2) inflight.delete(key);
|
|
23651
|
+
};
|
|
23652
|
+
void pending2.then(clear, clear);
|
|
23653
|
+
return pending2;
|
|
23654
|
+
};
|
|
23655
|
+
const decrypted = (options2) => shareRead(reads, options2, () => persistence.query(options2));
|
|
23656
|
+
const metadata3 = (options2) => shareRead(
|
|
23657
|
+
metadataReads,
|
|
23658
|
+
options2,
|
|
23659
|
+
() => persistence.queryMetadata(options2)
|
|
23660
|
+
);
|
|
23661
|
+
const readTopics = () => {
|
|
23662
|
+
if (topicCatalog) return topicCatalog;
|
|
23663
|
+
const pending2 = persistence.topics();
|
|
23664
|
+
topicCatalog = pending2;
|
|
23665
|
+
const clear = () => {
|
|
23666
|
+
if (topicCatalog === pending2) topicCatalog = void 0;
|
|
23667
|
+
};
|
|
23668
|
+
void pending2.then(() => {
|
|
23669
|
+
if (!retainTopics()) clear();
|
|
23670
|
+
}, clear);
|
|
23671
|
+
return pending2;
|
|
23672
|
+
};
|
|
23575
23673
|
const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
|
|
23576
23674
|
const memoriesByTopics = async (names) => {
|
|
23577
23675
|
const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
|
|
@@ -24025,11 +24123,11 @@ function createRemoteMemoryStore(options) {
|
|
|
24025
24123
|
};
|
|
24026
24124
|
const changesSince = async (cursor2, pending2) => {
|
|
24027
24125
|
const records = [];
|
|
24028
|
-
const failed = /* @__PURE__ */ new
|
|
24126
|
+
const failed = /* @__PURE__ */ new Map();
|
|
24029
24127
|
const collect = (page) => {
|
|
24030
24128
|
warnFailed(page.failed);
|
|
24031
24129
|
records.push(...page.items);
|
|
24032
|
-
for (const failure of page.failed) failed.
|
|
24130
|
+
for (const failure of page.failed) failed.set(failure.memory_id, failure.version);
|
|
24033
24131
|
};
|
|
24034
24132
|
let resume = cursor2;
|
|
24035
24133
|
let next;
|
|
@@ -24063,25 +24161,72 @@ function createRemoteMemoryStore(options) {
|
|
|
24063
24161
|
let ready = false;
|
|
24064
24162
|
let cursor;
|
|
24065
24163
|
let pending = /* @__PURE__ */ new Set();
|
|
24164
|
+
let failedVersions = /* @__PURE__ */ new Map();
|
|
24066
24165
|
let topicFingerprint;
|
|
24067
24166
|
let polling = false;
|
|
24167
|
+
let pollRequested = false;
|
|
24168
|
+
let failures = 0;
|
|
24169
|
+
let retryAt = 0;
|
|
24170
|
+
const backoff = (error) => {
|
|
24171
|
+
failures++;
|
|
24172
|
+
retryAt = Date.now() + Math.max(
|
|
24173
|
+
error instanceof RemoteMemoryError ? error.retryAfterMs ?? 0 : 0,
|
|
24174
|
+
Math.min(pollIntervalMs * 2 ** Math.min(failures - 1, 10), 15 * 6e4)
|
|
24175
|
+
);
|
|
24176
|
+
};
|
|
24177
|
+
const schedulePoll = (delay, keepEarlier = false) => {
|
|
24178
|
+
const at = Math.max(Date.now() + delay, retryAt);
|
|
24179
|
+
if (keepEarlier && timer && scheduledAt !== void 0 && scheduledAt <= at) return;
|
|
24180
|
+
if (timer) clearTimeout(timer);
|
|
24181
|
+
timer = void 0;
|
|
24182
|
+
scheduledAt = void 0;
|
|
24183
|
+
if (!subscribers.size || pollIntervalMs <= 0 || !activity.isActive()) return;
|
|
24184
|
+
scheduledAt = at;
|
|
24185
|
+
timer = setTimeout(poll, Math.max(0, at - Date.now()));
|
|
24186
|
+
};
|
|
24068
24187
|
const poll = () => {
|
|
24069
|
-
if (
|
|
24188
|
+
if (timer) clearTimeout(timer);
|
|
24189
|
+
timer = void 0;
|
|
24190
|
+
scheduledAt = void 0;
|
|
24191
|
+
if (!subscribers.size || pollIntervalMs <= 0 || !activity.isActive()) return;
|
|
24192
|
+
if (Date.now() < retryAt) {
|
|
24193
|
+
schedulePoll(0);
|
|
24194
|
+
return;
|
|
24195
|
+
}
|
|
24196
|
+
if (polling) {
|
|
24197
|
+
pollRequested = true;
|
|
24198
|
+
return;
|
|
24199
|
+
}
|
|
24070
24200
|
polling = true;
|
|
24201
|
+
pollRequested = false;
|
|
24071
24202
|
const current = generation;
|
|
24072
24203
|
changesSince(cursor, pending).then(async ({ records, resume, failed }) => {
|
|
24073
24204
|
let topicState;
|
|
24205
|
+
let topicFailed = false;
|
|
24074
24206
|
if ([...subscribers].some((s) => s.options.topics))
|
|
24075
24207
|
try {
|
|
24076
|
-
|
|
24077
|
-
|
|
24078
|
-
);
|
|
24208
|
+
topicCatalog = void 0;
|
|
24209
|
+
topicState = JSON.stringify((await readTopics()).map((t) => [t.name, t.version]));
|
|
24079
24210
|
} catch (error) {
|
|
24211
|
+
topicFailed = true;
|
|
24212
|
+
if (current === generation) backoff(error);
|
|
24080
24213
|
getLogger().warn("[memory/remote-store] Topic subscription poll failed:", error);
|
|
24081
24214
|
}
|
|
24082
24215
|
if (current !== generation) return;
|
|
24216
|
+
if (!topicFailed) {
|
|
24217
|
+
failures = 0;
|
|
24218
|
+
retryAt = 0;
|
|
24219
|
+
}
|
|
24220
|
+
const failedChanged = [...failed].some(
|
|
24221
|
+
([id2, version]) => failedVersions.get(id2) !== version
|
|
24222
|
+
);
|
|
24223
|
+
if (records.length || failedChanged || topicState !== void 0 && topicState !== topicFingerprint) {
|
|
24224
|
+
reads.clear();
|
|
24225
|
+
metadataReads.clear();
|
|
24226
|
+
topicSnapshot = void 0;
|
|
24227
|
+
}
|
|
24083
24228
|
const changed = /* @__PURE__ */ new Set();
|
|
24084
|
-
if (topicState !== void 0 && topicFingerprint !== void 0 && topicState !== topicFingerprint) {
|
|
24229
|
+
if (ready && failedChanged || topicState !== void 0 && topicFingerprint !== void 0 && topicState !== topicFingerprint) {
|
|
24085
24230
|
for (const subscriber of subscribers)
|
|
24086
24231
|
if (subscriber.options.topics) changed.add(subscriber);
|
|
24087
24232
|
}
|
|
@@ -24098,15 +24243,40 @@ function createRemoteMemoryStore(options) {
|
|
|
24098
24243
|
}
|
|
24099
24244
|
ready = true;
|
|
24100
24245
|
cursor = resume;
|
|
24101
|
-
pending = failed;
|
|
24246
|
+
pending = new Set(failed.keys());
|
|
24247
|
+
failedVersions = failed;
|
|
24102
24248
|
for (const subscriber of changed)
|
|
24103
24249
|
if (subscribers.has(subscriber)) safely(subscriber.onChange);
|
|
24104
24250
|
}).catch((error) => {
|
|
24251
|
+
if (current === generation) backoff(error);
|
|
24105
24252
|
getLogger().warn("[memory/remote-store] Subscription poll failed:", error);
|
|
24106
24253
|
}).finally(() => {
|
|
24107
24254
|
polling = false;
|
|
24255
|
+
schedulePoll(
|
|
24256
|
+
current !== generation ? 0 : pollRequested ? 200 : changesConnected ? Math.max(pollIntervalMs, 5 * 6e4) : pollIntervalMs
|
|
24257
|
+
);
|
|
24108
24258
|
});
|
|
24109
24259
|
};
|
|
24260
|
+
const refreshActivity = () => {
|
|
24261
|
+
if (timer) clearTimeout(timer);
|
|
24262
|
+
timer = void 0;
|
|
24263
|
+
if (!activity.isActive()) {
|
|
24264
|
+
stopChanges?.();
|
|
24265
|
+
stopChanges = void 0;
|
|
24266
|
+
changesConnected = false;
|
|
24267
|
+
return;
|
|
24268
|
+
}
|
|
24269
|
+
if (!stopChanges && persistence.supportsRealtimeChanges && options.subscribeChanges)
|
|
24270
|
+
stopChanges = options.subscribeChanges((connected) => {
|
|
24271
|
+
changesConnected = connected;
|
|
24272
|
+
if (polling) {
|
|
24273
|
+
pollRequested = true;
|
|
24274
|
+
return;
|
|
24275
|
+
}
|
|
24276
|
+
schedulePoll(connected ? 200 : 0, true);
|
|
24277
|
+
});
|
|
24278
|
+
poll();
|
|
24279
|
+
};
|
|
24110
24280
|
const unrepairable = /* @__PURE__ */ new Set();
|
|
24111
24281
|
let repairCursor;
|
|
24112
24282
|
const repairEmbeddingsUnlocked = async ({
|
|
@@ -24162,40 +24332,78 @@ function createRemoteMemoryStore(options) {
|
|
|
24162
24332
|
result.failed += targets.length;
|
|
24163
24333
|
return finish();
|
|
24164
24334
|
}
|
|
24165
|
-
|
|
24335
|
+
const writes = targets.flatMap((record2, i) => {
|
|
24166
24336
|
const vector = vectors[i];
|
|
24167
24337
|
if (!vector) {
|
|
24168
24338
|
result.failed++;
|
|
24169
|
-
|
|
24339
|
+
return [];
|
|
24170
24340
|
}
|
|
24171
|
-
|
|
24172
|
-
|
|
24173
|
-
|
|
24174
|
-
|
|
24175
|
-
|
|
24176
|
-
|
|
24177
|
-
|
|
24178
|
-
|
|
24179
|
-
|
|
24180
|
-
|
|
24181
|
-
|
|
24182
|
-
|
|
24183
|
-
|
|
24184
|
-
|
|
24185
|
-
|
|
24186
|
-
|
|
24187
|
-
|
|
24188
|
-
|
|
24189
|
-
|
|
24190
|
-
|
|
24191
|
-
} catch (error) {
|
|
24341
|
+
try {
|
|
24342
|
+
return [
|
|
24343
|
+
{
|
|
24344
|
+
memory: {
|
|
24345
|
+
...record2.memory,
|
|
24346
|
+
embedding: storedVector(vector),
|
|
24347
|
+
embedding_model: model
|
|
24348
|
+
},
|
|
24349
|
+
expectedVersion: record2
|
|
24350
|
+
}
|
|
24351
|
+
];
|
|
24352
|
+
} catch {
|
|
24353
|
+
result.failed++;
|
|
24354
|
+
return [];
|
|
24355
|
+
}
|
|
24356
|
+
});
|
|
24357
|
+
for (const batch of chunks2(writes, MAX_BATCH)) {
|
|
24358
|
+
const continueRepair = await serializedAll(
|
|
24359
|
+
batch.map(({ memory }) => memory.memory_id),
|
|
24360
|
+
async () => {
|
|
24192
24361
|
signal?.throwIfAborted();
|
|
24193
|
-
|
|
24194
|
-
|
|
24195
|
-
|
|
24196
|
-
|
|
24362
|
+
const commit = async (slice) => {
|
|
24363
|
+
const saved = await persistence.putMany(slice, signal, leaseToken);
|
|
24364
|
+
for (const record2 of saved) repaired.add(record2.memory.memory_id);
|
|
24365
|
+
result.reembedded += saved.length;
|
|
24366
|
+
notify("embedding", saved);
|
|
24367
|
+
};
|
|
24368
|
+
try {
|
|
24369
|
+
await commit(batch);
|
|
24370
|
+
} catch (error) {
|
|
24371
|
+
signal?.throwIfAborted();
|
|
24372
|
+
if (isRemoteWorkLeaseExpired(error)) throw error;
|
|
24373
|
+
if (!(error instanceof RemoteMemoryError && error.code === "version_conflict") && !rejectsMemoryWrite(error)) {
|
|
24374
|
+
result.failed += batch.length;
|
|
24375
|
+
return false;
|
|
24376
|
+
}
|
|
24377
|
+
if (batch.length === 1) {
|
|
24378
|
+
if (rejectsMemoryWrite(error)) {
|
|
24379
|
+
unrepairable.add(batch[0].memory.memory_id);
|
|
24380
|
+
result.failed++;
|
|
24381
|
+
} else result.skippedConflict++;
|
|
24382
|
+
return true;
|
|
24383
|
+
}
|
|
24384
|
+
for (const [index, write] of batch.entries()) {
|
|
24385
|
+
signal?.throwIfAborted();
|
|
24386
|
+
try {
|
|
24387
|
+
await commit([write]);
|
|
24388
|
+
} catch (error2) {
|
|
24389
|
+
signal?.throwIfAborted();
|
|
24390
|
+
if (isRemoteWorkLeaseExpired(error2)) throw error2;
|
|
24391
|
+
if (error2 instanceof RemoteMemoryError && error2.code === "version_conflict")
|
|
24392
|
+
result.skippedConflict++;
|
|
24393
|
+
else if (rejectsMemoryWrite(error2)) {
|
|
24394
|
+
unrepairable.add(write.memory.memory_id);
|
|
24395
|
+
result.failed++;
|
|
24396
|
+
} else {
|
|
24397
|
+
result.failed += batch.length - index;
|
|
24398
|
+
return false;
|
|
24399
|
+
}
|
|
24400
|
+
}
|
|
24401
|
+
}
|
|
24402
|
+
}
|
|
24403
|
+
return true;
|
|
24197
24404
|
}
|
|
24198
|
-
|
|
24405
|
+
);
|
|
24406
|
+
if (!continueRepair) break;
|
|
24199
24407
|
}
|
|
24200
24408
|
return finish();
|
|
24201
24409
|
};
|
|
@@ -24235,7 +24443,7 @@ function createRemoteMemoryStore(options) {
|
|
|
24235
24443
|
},
|
|
24236
24444
|
importTopics: async (topics) => {
|
|
24237
24445
|
if (!topics.length) return;
|
|
24238
|
-
const existing = new Set((await
|
|
24446
|
+
const existing = new Set((await readTopics()).map((topic2) => topic2.name));
|
|
24239
24447
|
const missing = topics.flatMap((topic2) => {
|
|
24240
24448
|
const name = normalizeEntityName(topic2.name);
|
|
24241
24449
|
if (existing.has(name)) return [];
|
|
@@ -24244,6 +24452,7 @@ function createRemoteMemoryStore(options) {
|
|
|
24244
24452
|
});
|
|
24245
24453
|
if (!missing.length) return;
|
|
24246
24454
|
await persistence.importTopics(missing);
|
|
24455
|
+
invalidateReads();
|
|
24247
24456
|
for (const subscriber of [...subscribers])
|
|
24248
24457
|
if (subscriber.options.topics) safely(subscriber.onChange);
|
|
24249
24458
|
},
|
|
@@ -24257,40 +24466,51 @@ function createRemoteMemoryStore(options) {
|
|
|
24257
24466
|
listProjections: async (listOptions = {}) => (await listRows(metadata3, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
|
|
24258
24467
|
projection
|
|
24259
24468
|
),
|
|
24260
|
-
listTopics:
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
name
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
|
|
24278
|
-
|
|
24279
|
-
|
|
24280
|
-
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
const
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
|
|
24287
|
-
|
|
24288
|
-
|
|
24289
|
-
|
|
24290
|
-
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
24469
|
+
listTopics: () => {
|
|
24470
|
+
if (topicSnapshot) return topicSnapshot.then((topics) => structuredClone(topics));
|
|
24471
|
+
const snapshot = (async () => {
|
|
24472
|
+
const topics = /* @__PURE__ */ new Map();
|
|
24473
|
+
for (const { memory } of await pages(metadata3, {
|
|
24474
|
+
include_archived: true,
|
|
24475
|
+
include_quarantined: true,
|
|
24476
|
+
include_superseded: true
|
|
24477
|
+
})) {
|
|
24478
|
+
for (const topic2 of parseTopics(memory.topics) ?? []) {
|
|
24479
|
+
const name = normalizeEntityName(topic2.name);
|
|
24480
|
+
if (!name) continue;
|
|
24481
|
+
const entry = topics.get(name) ?? {
|
|
24482
|
+
name,
|
|
24483
|
+
kind: null,
|
|
24484
|
+
memoryCount: 0,
|
|
24485
|
+
members: /* @__PURE__ */ new Set()
|
|
24486
|
+
};
|
|
24487
|
+
entry.kind ?? (entry.kind = topic2.kind ?? null);
|
|
24488
|
+
entry.members.add(memory.memory_id);
|
|
24489
|
+
topics.set(name, entry);
|
|
24490
|
+
}
|
|
24491
|
+
}
|
|
24492
|
+
for (const topic2 of await readTopics()) {
|
|
24493
|
+
if (topic2.is_deleted) continue;
|
|
24494
|
+
const current = topics.get(topic2.name);
|
|
24495
|
+
if (current) current.kind ?? (current.kind = topic2.kind ?? null);
|
|
24496
|
+
else
|
|
24497
|
+
topics.set(topic2.name, {
|
|
24498
|
+
name: topic2.name,
|
|
24499
|
+
kind: topic2.kind ?? null,
|
|
24500
|
+
memoryCount: 0,
|
|
24501
|
+
members: /* @__PURE__ */ new Set()
|
|
24502
|
+
});
|
|
24503
|
+
}
|
|
24504
|
+
return [...topics.values()].map(({ members, ...topic2 }) => ({ ...topic2, memoryCount: members.size })).sort((a, b) => a.name.localeCompare(b.name));
|
|
24505
|
+
})();
|
|
24506
|
+
topicSnapshot = snapshot;
|
|
24507
|
+
const clear = () => {
|
|
24508
|
+
if (topicSnapshot === snapshot) topicSnapshot = void 0;
|
|
24509
|
+
};
|
|
24510
|
+
void snapshot.then(() => {
|
|
24511
|
+
if (!retainTopics()) clear();
|
|
24512
|
+
}, clear);
|
|
24513
|
+
return snapshot.then((topics) => structuredClone(topics));
|
|
24294
24514
|
},
|
|
24295
24515
|
get: async (id2) => asStored(await live(id2)),
|
|
24296
24516
|
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
@@ -24471,20 +24691,23 @@ function createRemoteMemoryStore(options) {
|
|
|
24471
24691
|
subscribe: (onChange, subscribeOptions = {}) => {
|
|
24472
24692
|
const subscriber = { onChange, options: subscribeOptions };
|
|
24473
24693
|
subscribers.add(subscriber);
|
|
24474
|
-
if (pollIntervalMs > 0 &&
|
|
24475
|
-
|
|
24476
|
-
|
|
24694
|
+
if (pollIntervalMs > 0 && subscribers.size === 1) {
|
|
24695
|
+
stopActivity = activity.subscribe(refreshActivity);
|
|
24696
|
+
refreshActivity();
|
|
24477
24697
|
}
|
|
24478
24698
|
return () => {
|
|
24479
24699
|
subscribers.delete(subscriber);
|
|
24480
|
-
if (
|
|
24481
|
-
|
|
24700
|
+
if (!retainTopics()) invalidateReads();
|
|
24701
|
+
if (subscribers.size) return;
|
|
24702
|
+
if (timer) clearTimeout(timer);
|
|
24482
24703
|
timer = void 0;
|
|
24704
|
+
stopActivity?.();
|
|
24705
|
+
stopActivity = void 0;
|
|
24706
|
+
stopChanges?.();
|
|
24707
|
+
stopChanges = void 0;
|
|
24708
|
+
changesConnected = false;
|
|
24483
24709
|
generation++;
|
|
24484
|
-
|
|
24485
|
-
ready = false;
|
|
24486
|
-
cursor = void 0;
|
|
24487
|
-
pending = /* @__PURE__ */ new Set();
|
|
24710
|
+
invalidateReads();
|
|
24488
24711
|
};
|
|
24489
24712
|
}
|
|
24490
24713
|
};
|