@remnic/core 10.0.83 → 10.0.84
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/access-cli.js +4 -4
- package/dist/access-operations.d.ts +1 -1
- package/dist/{chunk-SVCHO337.js → chunk-3JPTUCD7.js} +2 -2
- package/dist/{chunk-S57QBPTA.js → chunk-DPPLNZ3A.js} +4 -6
- package/dist/chunk-DPPLNZ3A.js.map +1 -0
- package/dist/{chunk-AYTDCMEL.js → chunk-HLKUZW42.js} +2 -2
- package/dist/{chunk-DD6OIFDG.js → chunk-K3B72DKJ.js} +2 -2
- package/dist/entity-mention-index-cache.d.ts.map +1 -1
- package/dist/entity-mention-index-cache.js +2 -1
- package/dist/entity-retrieval.js +3 -2
- package/dist/index.js +15 -15
- package/dist/orchestration/backlog-scheduler.js +5 -5
- package/dist/orchestration/buffer-drain-runner.js +5 -5
- package/dist/orchestrator.js +4 -4
- package/package.json +2 -2
- package/src/access-mcp-correction-tools.test.ts +45 -0
- package/src/compounding/weekly-evidence.test.ts +237 -0
- package/src/entity-mention-index-cache.ts +1 -6
- package/src/maintenance/rebuild-memory-projection-runner.test.ts +90 -0
- package/src/orchestration/full-corpus-heap-guard.test.ts +52 -0
- package/src/projection-rebuild-config.test.ts +79 -0
- package/src/storage/entity-store-symlink.test.ts +44 -0
- package/src/utils/malformed-entity-record.test.ts +69 -0
- package/dist/chunk-S57QBPTA.js.map +0 -1
- /package/dist/{chunk-SVCHO337.js.map → chunk-3JPTUCD7.js.map} +0 -0
- /package/dist/{chunk-AYTDCMEL.js.map → chunk-HLKUZW42.js.map} +0 -0
- /package/dist/{chunk-DD6OIFDG.js.map → chunk-K3B72DKJ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExtractionDrain,
|
|
3
3
|
TurnIngestionCoordinator
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HLKUZW42.js";
|
|
5
5
|
import {
|
|
6
6
|
headerConnector,
|
|
7
7
|
renderExtractionConversation,
|
|
@@ -440,4 +440,4 @@ export {
|
|
|
440
440
|
ClaimBufferStorage,
|
|
441
441
|
BufferDrainRunner
|
|
442
442
|
};
|
|
443
|
-
//# sourceMappingURL=chunk-
|
|
443
|
+
//# sourceMappingURL=chunk-3JPTUCD7.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compareStrings
|
|
3
|
+
} from "./chunk-ULM7JCDH.js";
|
|
1
4
|
import {
|
|
2
5
|
entityMentionEpoch
|
|
3
6
|
} from "./chunk-7CT3AI52.js";
|
|
@@ -88,11 +91,6 @@ function throwIfMentionAborted(signal) {
|
|
|
88
91
|
const reason = signal.reason;
|
|
89
92
|
throw reason instanceof Error ? reason : new Error("entity mention rebuild aborted");
|
|
90
93
|
}
|
|
91
|
-
function compareStrings(left, right) {
|
|
92
|
-
if (left < right) return -1;
|
|
93
|
-
if (left > right) return 1;
|
|
94
|
-
return 0;
|
|
95
|
-
}
|
|
96
94
|
function deduped(values) {
|
|
97
95
|
const seen = /* @__PURE__ */ new Set();
|
|
98
96
|
const out = [];
|
|
@@ -327,4 +325,4 @@ export {
|
|
|
327
325
|
settleEntityMentionIndex,
|
|
328
326
|
resolveEntityMentionIndex
|
|
329
327
|
};
|
|
330
|
-
//# sourceMappingURL=chunk-
|
|
328
|
+
//# sourceMappingURL=chunk-DPPLNZ3A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/entity-mention-index-cache.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { raceAbort } from \"./abort-error.js\";\nimport { entityMentionEpoch } from \"./entity-mention-epoch.js\";\nimport { log } from \"./logger.js\";\nimport { compareStrings } from \"./eval-trajectory-contracts.js\";\n\n/**\n * In-memory entity mention index.\n *\n * Scope (namespaces, dirs, secure-store key, alias map, native revision) is\n * the cache key. Mention epoch and entity-file mutation are identity inside\n * the slot, not part of the key:\n *\n * - metadata-only corpus bumps do not move the epoch, so the next recall hits\n * - entity-file changes rebuild from entity files before the recall returns,\n * reusing memory snippets (no fact scan). A new entity is visible on that\n * recall; its memory snippets arrive with the next full reconcile. A new\n * canonical id schedules that reconcile. Callers share one scan. One\n * caller's abort stops that caller waiting and leaves the scan running\n * for the others\n * - memory create/edit/delete moves the epoch. The recall serves the last\n * index immediately and one background reconcile runs, plus at most one\n * follow-up if that scan overlaps a later write. A recall during either\n * scan does not grant another follow-up. Further rescans wait for the\n * next recall. After writes quiesce and `settleEntityMentionIndex`\n * finishes, the index matches a full rebuild\n * - secure-store key, alias map, and native revision stay in the key, so a\n * change is a miss and awaits a full rebuild. A locked store never reads\n * another key's plaintext. Evicting that older scope also stops its scan\n * from publishing the persisted index\n * - a persisted index is readable per storage root. A process-wide cache\n * clear blocks every root until that root's own post-clear build publishes.\n * One root publishing does not reopen another root's file\n */\n\nconst MAX_SLOTS = 32;\nconst SETTLE_ROUNDS = 8;\n\nexport type EntityMentionIdentity = {\n mentionEpoch: string;\n entityMutation: string;\n};\n\ntype ScopedStorage = {\n dir: string;\n hotCacheKeyId?(): string;\n entityAliases?: Readonly<Record<string, string>> | null;\n getEntityMutationVersion?(): number;\n};\n\ntype Slot = {\n scopeKey: string;\n index: unknown;\n identity: EntityMentionIdentity;\n token: number;\n rebuild: Promise<void> | null;\n entityJob: Promise<void> | null;\n again: boolean;\n followUps: number;\n currentIdentity: () => EntityMentionIdentity;\n buildFull: (abortSignal?: AbortSignal) => Promise<unknown>;\n};\n\nconst slots = new Map<string, Slot>();\nconst rebuildsByScope = new Map<string, number>();\nconst GENERATION_STRIDE = 1_000_000_000;\nlet clearEpoch = 0;\nconst localGenerationByDir = new Map<string, number>();\nconst publishedGenerationByDir = new Map<string, number>();\nconst persistTailByDir = new Map<string, Promise<void>>();\n\nfunction resolveMentionDir(dir: string): string {\n return path.resolve(dir);\n}\n\nexport function entityMentionCacheGeneration(dir: string): number {\n const resolved = resolveMentionDir(dir);\n return clearEpoch * GENERATION_STRIDE + (localGenerationByDir.get(resolved) ?? 0);\n}\n\nexport function entityMentionPersistedIndexReadable(dir: string): boolean {\n const resolved = resolveMentionDir(dir);\n const local = localGenerationByDir.get(resolved) ?? 0;\n if (clearEpoch === 0 && local === 0) return true;\n return publishedGenerationByDir.get(resolved) === entityMentionCacheGeneration(resolved);\n}\n\nfunction dirsInScope(scopeKey: string): string[] {\n const nsEnd = scopeKey.indexOf(\"\\u001e\");\n const storageEnd = nsEnd === -1 ? -1 : scopeKey.indexOf(\"\\u001e\", nsEnd + 1);\n if (nsEnd === -1 || storageEnd === -1) return [];\n return scopeKey\n .slice(nsEnd + 1, storageEnd)\n .split(\"\\u001f\")\n .map((part) => part.split(\"\\u001d\")[0] ?? \"\")\n .filter((dir) => dir.length > 0)\n .map((dir) => resolveMentionDir(dir));\n}\n\nfunction persistedMentionIndexFiles(scopeKey: string): string[] {\n return dirsInScope(scopeKey).map((dir) => path.join(dir, \"state\", \"entity-mention-index.json\"));\n}\n\nfunction bumpScopeDirs(scopeKey: string): void {\n for (const dir of dirsInScope(scopeKey)) {\n localGenerationByDir.set(dir, (localGenerationByDir.get(dir) ?? 0) + 1);\n }\n}\n\nfunction captureDirGenerations(scopeKey: string): Map<string, number> {\n const captured = new Map<string, number>();\n for (const dir of dirsInScope(scopeKey)) captured.set(dir, entityMentionCacheGeneration(dir));\n return captured;\n}\n\nfunction generationsCurrent(captured: Map<string, number>): boolean {\n for (const [dir, generation] of captured) {\n if (entityMentionCacheGeneration(dir) !== generation) return false;\n }\n return true;\n}\n\nfunction publishDirGenerations(captured: Map<string, number>): void {\n for (const [dir, generation] of captured) {\n if (entityMentionCacheGeneration(dir) === generation) publishedGenerationByDir.set(dir, generation);\n }\n}\n\nexport async function writePersistedEntityMentionIndex(\n dir: string,\n generation: number,\n content: string,\n): Promise<void> {\n const resolved = resolveMentionDir(dir);\n const previous = persistTailByDir.get(resolved) ?? Promise.resolve();\n const run = previous.catch(() => undefined).then(async () => {\n if (entityMentionCacheGeneration(resolved) !== generation) return;\n const file = path.join(resolved, \"state\", \"entity-mention-index.json\");\n await mkdir(path.dirname(file), { recursive: true });\n const current = await readFile(file, \"utf-8\").catch(() => \"\");\n if (current === content) return;\n if (entityMentionCacheGeneration(resolved) !== generation) return;\n await writeFile(file, content, \"utf-8\");\n });\n persistTailByDir.set(resolved, run.then(() => undefined, () => undefined));\n await run;\n}\n\nfunction discardPersistedMentionIndex(scopeKey: string): void {\n for (const file of persistedMentionIndexFiles(scopeKey)) {\n void rm(file, { force: true }).catch(() => undefined);\n }\n}\n\nfunction throwIfMentionAborted(signal?: AbortSignal): void {\n if (!signal?.aborted) return;\n const reason = signal.reason;\n throw reason instanceof Error ? reason : new Error(\"entity mention rebuild aborted\");\n}\n\nfunction deduped(values: readonly string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values) {\n const trimmed = value.trim();\n if (trimmed.length === 0 || seen.has(trimmed)) continue;\n seen.add(trimmed);\n out.push(trimmed);\n }\n return out;\n}\n\nfunction sameIdentity(left: EntityMentionIdentity, right: EntityMentionIdentity): boolean {\n return left.mentionEpoch === right.mentionEpoch && left.entityMutation === right.entityMutation;\n}\n\nfunction noteRebuild(scopeKey: string): void {\n rebuildsByScope.set(scopeKey, (rebuildsByScope.get(scopeKey) ?? 0) + 1);\n}\n\nfunction scopeFamily(scopeKey: string): string {\n const nsEnd = scopeKey.indexOf(\"\\u001e\");\n const storageEnd = nsEnd === -1 ? -1 : scopeKey.indexOf(\"\\u001e\", nsEnd + 1);\n const namespaceKey = nsEnd === -1 ? scopeKey : scopeKey.slice(0, nsEnd);\n const storageKey = nsEnd === -1 || storageEnd === -1 ? \"\" : scopeKey.slice(nsEnd + 1, storageEnd);\n const dirs = storageKey\n .split(\"\\u001f\")\n .map((part) => part.split(\"\\u001d\")[0] ?? \"\")\n .join(\"\\u001f\");\n return `${namespaceKey}\\u001e${dirs}`;\n}\n\nfunction forgetScope(scopeKey: string, bumpPersisted = false): void {\n const slot = slots.get(scopeKey);\n if (slot) {\n slot.token += 1;\n slot.again = false;\n }\n if (bumpPersisted) bumpScopeDirs(scopeKey);\n slots.delete(scopeKey);\n rebuildsByScope.delete(scopeKey);\n}\n\nfunction evictOldest(scopeKey: string): void {\n if (slots.size < MAX_SLOTS || slots.has(scopeKey)) return;\n const oldest = slots.keys().next().value;\n if (typeof oldest === \"string\") forgetScope(oldest);\n}\n\nfunction evictSameFamily(scopeKey: string): void {\n const family = scopeFamily(scopeKey);\n for (const key of [...slots.keys()]) {\n if (key !== scopeKey && scopeFamily(key) === family) forgetScope(key, true);\n }\n}\n\nfunction wantsSnippetReconcile(index: unknown): boolean {\n return (\n !!index &&\n typeof index === \"object\" &&\n (index as { pendingSnippetReconcile?: boolean }).pendingSnippetReconcile === true\n );\n}\n\nfunction armRebuild(slot: Slot): void {\n // A recall that arrives while a scan is already running must not grant\n // another follow-up. The chain stops after the one already armed.\n if (!slot.rebuild) slot.followUps = 1;\n startRebuild(slot);\n}\n\nfunction startRebuild(slot: Slot): void {\n // A recall that arrives during a scan is not a write. The follow-up is\n // armed only when the scan's end identity differs from the identity it\n // started with. Setting `again` here made every concurrent recall pay a\n // second full corpus scan after a stable rebuild.\n if (slot.rebuild) return;\n const token = slot.token;\n const captured = captureDirGenerations(slot.scopeKey);\n noteRebuild(slot.scopeKey);\n const started = slot.currentIdentity();\n slot.again = false;\n const handle: { pending: Promise<void> | null } = { pending: null };\n handle.pending = slot\n .buildFull(undefined)\n .then((index) => {\n if (slot.token !== token || !generationsCurrent(captured)) return;\n publishDirGenerations(captured);\n const ended = slot.currentIdentity();\n slot.index = index;\n if (sameIdentity(started, ended)) {\n slot.identity = ended;\n return;\n }\n // Scan overlapped later writes. Keep the start identity so the next\n // recall stays stale and exactly one follow-up reconcile runs.\n slot.identity = started;\n slot.again = true;\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n log.warn(`entity mention index rebuild failed: ${message}`);\n })\n .finally(() => {\n if (slot.rebuild === handle.pending) slot.rebuild = null;\n // One automatic follow-up per caller-started rebuild. A store that keeps\n // changing during every scan waits for the next recall (or settle) instead\n // of chaining full scans with nobody waiting.\n if (!slot.again || slot.followUps <= 0) return;\n slot.again = false;\n slot.followUps -= 1;\n startRebuild(slot);\n });\n slot.rebuild = handle.pending;\n}\n\nexport function entityMentionScopeKey(\n namespaces: readonly string[] | undefined,\n storages: readonly ScopedStorage[],\n nativeRevision: string,\n): string {\n const namespaceKey = deduped(namespaces ?? []).join(\"\\u001f\");\n const storageKey = storages\n .map((storage) => {\n const aliases = Object.entries(storage.entityAliases ?? {}).sort(([left], [right]) =>\n compareStrings(left, right),\n );\n return `${path.resolve(storage.dir)}\\u001d${storage.hotCacheKeyId?.() ?? \"\"}\\u001d${JSON.stringify(aliases)}`;\n })\n .join(\"\\u001f\");\n return `${namespaceKey}\\u001e${storageKey}\\u001e${nativeRevision}`;\n}\n\nexport function entityMentionIdentity(storages: readonly ScopedStorage[]): EntityMentionIdentity {\n return {\n mentionEpoch: storages.map((storage) => String(entityMentionEpoch.current(storage.dir))).join(\"\\u001f\"),\n entityMutation: storages.map((storage) => String(storage.getEntityMutationVersion?.() ?? 0)).join(\"\\u001f\"),\n };\n}\n\nexport function entityMentionFullRebuildsStarted(scopeKey: string): number {\n return rebuildsByScope.get(scopeKey) ?? 0;\n}\n\nexport function entityMentionIndexScopeKeys(): string[] {\n return [...slots.keys()];\n}\n\nexport function dropEntityMentionIndexCache(scopeKey?: string): void {\n if (scopeKey === undefined) {\n clearEpoch += 1;\n for (const key of [...slots.keys()]) {\n discardPersistedMentionIndex(key);\n forgetScope(key);\n }\n return;\n }\n discardPersistedMentionIndex(scopeKey);\n forgetScope(scopeKey, true);\n}\n\nexport async function settleEntityMentionIndex(scopeKey?: string): Promise<void> {\n const matches = (slot: Slot) => scopeKey === undefined || slot.scopeKey === scopeKey;\n for (let round = 0; round < SETTLE_ROUNDS; round += 1) {\n for (const slot of slots.values()) {\n if (!matches(slot)) continue;\n if (!slot.rebuild && slot.again) {\n slot.again = false;\n startRebuild(slot);\n }\n }\n const pending = [...slots.values()].filter((slot) => matches(slot) && slot.rebuild).map((slot) => slot.rebuild!);\n if (pending.length === 0) return;\n await Promise.all(pending);\n }\n}\n\nexport async function resolveEntityMentionIndex<T>(options: {\n scopeKey: string;\n currentIdentity: () => EntityMentionIdentity;\n buildFull: (abortSignal?: AbortSignal) => Promise<T>;\n rebuildEntities: (previous: T, abortSignal?: AbortSignal) => Promise<T>;\n abortSignal?: AbortSignal;\n}): Promise<T> {\n const live = options.currentIdentity();\n const existing = slots.get(options.scopeKey);\n if (!existing) {\n evictSameFamily(options.scopeKey);\n evictOldest(options.scopeKey);\n noteRebuild(options.scopeKey);\n const captured = captureDirGenerations(options.scopeKey);\n const started = options.currentIdentity();\n const index = await options.buildFull(options.abortSignal);\n // A clear or family eviction during this first scan must not publish it.\n if (!generationsCurrent(captured)) return index;\n publishDirGenerations(captured);\n const ended = options.currentIdentity();\n evictSameFamily(options.scopeKey);\n evictOldest(options.scopeKey);\n const slot: Slot = {\n scopeKey: options.scopeKey,\n index,\n identity: sameIdentity(started, ended) ? ended : started,\n token: 0,\n rebuild: null,\n entityJob: null,\n again: false,\n followUps: 0,\n currentIdentity: options.currentIdentity,\n buildFull: options.buildFull,\n };\n slots.set(options.scopeKey, slot);\n if (!sameIdentity(started, ended)) armRebuild(slot);\n return index;\n }\n existing.currentIdentity = options.currentIdentity;\n existing.buildFull = options.buildFull;\n while (existing.identity.entityMutation !== options.currentIdentity().entityMutation) {\n throwIfMentionAborted(options.abortSignal);\n const pending = existing.entityJob;\n if (pending) {\n await raceAbort(pending, options.abortSignal, \"entity mention rebuild aborted\");\n continue;\n }\n const liveNow = options.currentIdentity();\n const epochBefore = existing.identity.mentionEpoch;\n const mutationBefore = liveNow.entityMutation;\n let release = (): void => {};\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n existing.entityJob = gate;\n existing.token += 1;\n existing.again = false;\n const token = existing.token;\n const captured = captureDirGenerations(existing.scopeKey);\n // Shared scan. This caller's abort stops its wait and leaves the scan\n // running. Publish when the scan settles, even if this caller has left.\n // A family eviction bumps the token and the root generation; this scan\n // must not install its result or start a follow-up that would republish.\n const scan = options.rebuildEntities(existing.index as T, undefined);\n void scan\n .then(\n (rebuilt) => {\n if (existing.token !== token || !generationsCurrent(captured)) return;\n const now = options.currentIdentity();\n existing.index = rebuilt;\n const epochStable = epochBefore === liveNow.mentionEpoch && epochBefore === now.mentionEpoch;\n const mutationStable = mutationBefore === now.entityMutation;\n existing.identity = {\n entityMutation: mutationStable ? now.entityMutation : mutationBefore,\n mentionEpoch: epochStable ? now.mentionEpoch : epochBefore,\n };\n if (existing.identity.mentionEpoch !== now.mentionEpoch || wantsSnippetReconcile(rebuilt)) {\n armRebuild(existing);\n }\n },\n () => {},\n )\n .finally(() => {\n if (existing.entityJob === gate) existing.entityJob = null;\n release();\n });\n const rebuilt = await raceAbort(scan, options.abortSignal, \"entity mention rebuild aborted\");\n throwIfMentionAborted(options.abortSignal);\n return rebuilt;\n }\n if (existing.identity.mentionEpoch !== live.mentionEpoch) {\n armRebuild(existing);\n return existing.index as T;\n }\n return existing.index as T;\n}\n\nentityMentionEpoch.registerReset(() => {\n dropEntityMentionIndexCache();\n});\n"],"mappings":";;;;;;;;;;;;;;AAAA,OAAO,UAAU;AACjB,SAAS,OAAO,UAAU,IAAI,iBAAiB;AAmC/C,IAAM,YAAY;AAClB,IAAM,gBAAgB;AA2BtB,IAAM,QAAQ,oBAAI,IAAkB;AACpC,IAAM,kBAAkB,oBAAI,IAAoB;AAChD,IAAM,oBAAoB;AAC1B,IAAI,aAAa;AACjB,IAAM,uBAAuB,oBAAI,IAAoB;AACrD,IAAM,2BAA2B,oBAAI,IAAoB;AACzD,IAAM,mBAAmB,oBAAI,IAA2B;AAExD,SAAS,kBAAkB,KAAqB;AAC9C,SAAO,KAAK,QAAQ,GAAG;AACzB;AAEO,SAAS,6BAA6B,KAAqB;AAChE,QAAM,WAAW,kBAAkB,GAAG;AACtC,SAAO,aAAa,qBAAqB,qBAAqB,IAAI,QAAQ,KAAK;AACjF;AAEO,SAAS,oCAAoC,KAAsB;AACxE,QAAM,WAAW,kBAAkB,GAAG;AACtC,QAAM,QAAQ,qBAAqB,IAAI,QAAQ,KAAK;AACpD,MAAI,eAAe,KAAK,UAAU,EAAG,QAAO;AAC5C,SAAO,yBAAyB,IAAI,QAAQ,MAAM,6BAA6B,QAAQ;AACzF;AAEA,SAAS,YAAY,UAA4B;AAC/C,QAAM,QAAQ,SAAS,QAAQ,GAAQ;AACvC,QAAM,aAAa,UAAU,KAAK,KAAK,SAAS,QAAQ,KAAU,QAAQ,CAAC;AAC3E,MAAI,UAAU,MAAM,eAAe,GAAI,QAAO,CAAC;AAC/C,SAAO,SACJ,MAAM,QAAQ,GAAG,UAAU,EAC3B,MAAM,GAAQ,EACd,IAAI,CAAC,SAAS,KAAK,MAAM,GAAQ,EAAE,CAAC,KAAK,EAAE,EAC3C,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC,EAC9B,IAAI,CAAC,QAAQ,kBAAkB,GAAG,CAAC;AACxC;AAEA,SAAS,2BAA2B,UAA4B;AAC9D,SAAO,YAAY,QAAQ,EAAE,IAAI,CAAC,QAAQ,KAAK,KAAK,KAAK,SAAS,2BAA2B,CAAC;AAChG;AAEA,SAAS,cAAc,UAAwB;AAC7C,aAAW,OAAO,YAAY,QAAQ,GAAG;AACvC,yBAAqB,IAAI,MAAM,qBAAqB,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,EACxE;AACF;AAEA,SAAS,sBAAsB,UAAuC;AACpE,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,OAAO,YAAY,QAAQ,EAAG,UAAS,IAAI,KAAK,6BAA6B,GAAG,CAAC;AAC5F,SAAO;AACT;AAEA,SAAS,mBAAmB,UAAwC;AAClE,aAAW,CAAC,KAAK,UAAU,KAAK,UAAU;AACxC,QAAI,6BAA6B,GAAG,MAAM,WAAY,QAAO;AAAA,EAC/D;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,UAAqC;AAClE,aAAW,CAAC,KAAK,UAAU,KAAK,UAAU;AACxC,QAAI,6BAA6B,GAAG,MAAM,WAAY,0BAAyB,IAAI,KAAK,UAAU;AAAA,EACpG;AACF;AAEA,eAAsB,iCACpB,KACA,YACA,SACe;AACf,QAAM,WAAW,kBAAkB,GAAG;AACtC,QAAM,WAAW,iBAAiB,IAAI,QAAQ,KAAK,QAAQ,QAAQ;AACnE,QAAM,MAAM,SAAS,MAAM,MAAM,MAAS,EAAE,KAAK,YAAY;AAC3D,QAAI,6BAA6B,QAAQ,MAAM,WAAY;AAC3D,UAAM,OAAO,KAAK,KAAK,UAAU,SAAS,2BAA2B;AACrE,UAAM,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,UAAM,UAAU,MAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE;AAC5D,QAAI,YAAY,QAAS;AACzB,QAAI,6BAA6B,QAAQ,MAAM,WAAY;AAC3D,UAAM,UAAU,MAAM,SAAS,OAAO;AAAA,EACxC,CAAC;AACD,mBAAiB,IAAI,UAAU,IAAI,KAAK,MAAM,QAAW,MAAM,MAAS,CAAC;AACzE,QAAM;AACR;AAEA,SAAS,6BAA6B,UAAwB;AAC5D,aAAW,QAAQ,2BAA2B,QAAQ,GAAG;AACvD,SAAK,GAAG,MAAM,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EACtD;AACF;AAEA,SAAS,sBAAsB,QAA4B;AACzD,MAAI,CAAC,QAAQ,QAAS;AACtB,QAAM,SAAS,OAAO;AACtB,QAAM,kBAAkB,QAAQ,SAAS,IAAI,MAAM,gCAAgC;AACrF;AAEA,SAAS,QAAQ,QAAqC;AACpD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,QAAQ;AAC1B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,WAAW,KAAK,KAAK,IAAI,OAAO,EAAG;AAC/C,SAAK,IAAI,OAAO;AAChB,QAAI,KAAK,OAAO;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAA6B,OAAuC;AACxF,SAAO,KAAK,iBAAiB,MAAM,gBAAgB,KAAK,mBAAmB,MAAM;AACnF;AAEA,SAAS,YAAY,UAAwB;AAC3C,kBAAgB,IAAI,WAAW,gBAAgB,IAAI,QAAQ,KAAK,KAAK,CAAC;AACxE;AAEA,SAAS,YAAY,UAA0B;AAC7C,QAAM,QAAQ,SAAS,QAAQ,GAAQ;AACvC,QAAM,aAAa,UAAU,KAAK,KAAK,SAAS,QAAQ,KAAU,QAAQ,CAAC;AAC3E,QAAM,eAAe,UAAU,KAAK,WAAW,SAAS,MAAM,GAAG,KAAK;AACtE,QAAM,aAAa,UAAU,MAAM,eAAe,KAAK,KAAK,SAAS,MAAM,QAAQ,GAAG,UAAU;AAChG,QAAM,OAAO,WACV,MAAM,GAAQ,EACd,IAAI,CAAC,SAAS,KAAK,MAAM,GAAQ,EAAE,CAAC,KAAK,EAAE,EAC3C,KAAK,GAAQ;AAChB,SAAO,GAAG,YAAY,IAAS,IAAI;AACrC;AAEA,SAAS,YAAY,UAAkB,gBAAgB,OAAa;AAClE,QAAM,OAAO,MAAM,IAAI,QAAQ;AAC/B,MAAI,MAAM;AACR,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AACA,MAAI,cAAe,eAAc,QAAQ;AACzC,QAAM,OAAO,QAAQ;AACrB,kBAAgB,OAAO,QAAQ;AACjC;AAEA,SAAS,YAAY,UAAwB;AAC3C,MAAI,MAAM,OAAO,aAAa,MAAM,IAAI,QAAQ,EAAG;AACnD,QAAM,SAAS,MAAM,KAAK,EAAE,KAAK,EAAE;AACnC,MAAI,OAAO,WAAW,SAAU,aAAY,MAAM;AACpD;AAEA,SAAS,gBAAgB,UAAwB;AAC/C,QAAM,SAAS,YAAY,QAAQ;AACnC,aAAW,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG;AACnC,QAAI,QAAQ,YAAY,YAAY,GAAG,MAAM,OAAQ,aAAY,KAAK,IAAI;AAAA,EAC5E;AACF;AAEA,SAAS,sBAAsB,OAAyB;AACtD,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YAChB,MAAgD,4BAA4B;AAEjF;AAEA,SAAS,WAAW,MAAkB;AAGpC,MAAI,CAAC,KAAK,QAAS,MAAK,YAAY;AACpC,eAAa,IAAI;AACnB;AAEA,SAAS,aAAa,MAAkB;AAKtC,MAAI,KAAK,QAAS;AAClB,QAAM,QAAQ,KAAK;AACnB,QAAM,WAAW,sBAAsB,KAAK,QAAQ;AACpD,cAAY,KAAK,QAAQ;AACzB,QAAM,UAAU,KAAK,gBAAgB;AACrC,OAAK,QAAQ;AACb,QAAM,SAA4C,EAAE,SAAS,KAAK;AAClE,SAAO,UAAU,KACd,UAAU,MAAS,EACnB,KAAK,CAAC,UAAU;AACf,QAAI,KAAK,UAAU,SAAS,CAAC,mBAAmB,QAAQ,EAAG;AAC3D,0BAAsB,QAAQ;AAC9B,UAAM,QAAQ,KAAK,gBAAgB;AACnC,SAAK,QAAQ;AACb,QAAI,aAAa,SAAS,KAAK,GAAG;AAChC,WAAK,WAAW;AAChB;AAAA,IACF;AAGA,SAAK,WAAW;AAChB,SAAK,QAAQ;AAAA,EACf,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,QAAI,KAAK,wCAAwC,OAAO,EAAE;AAAA,EAC5D,CAAC,EACA,QAAQ,MAAM;AACb,QAAI,KAAK,YAAY,OAAO,QAAS,MAAK,UAAU;AAIpD,QAAI,CAAC,KAAK,SAAS,KAAK,aAAa,EAAG;AACxC,SAAK,QAAQ;AACb,SAAK,aAAa;AAClB,iBAAa,IAAI;AAAA,EACnB,CAAC;AACH,OAAK,UAAU,OAAO;AACxB;AAEO,SAAS,sBACd,YACA,UACA,gBACQ;AACR,QAAM,eAAe,QAAQ,cAAc,CAAC,CAAC,EAAE,KAAK,GAAQ;AAC5D,QAAM,aAAa,SAChB,IAAI,CAAC,YAAY;AAChB,UAAM,UAAU,OAAO,QAAQ,QAAQ,iBAAiB,CAAC,CAAC,EAAE;AAAA,MAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAC9E,eAAe,MAAM,KAAK;AAAA,IAC5B;AACA,WAAO,GAAG,KAAK,QAAQ,QAAQ,GAAG,CAAC,IAAS,QAAQ,gBAAgB,KAAK,EAAE,IAAS,KAAK,UAAU,OAAO,CAAC;AAAA,EAC7G,CAAC,EACA,KAAK,GAAQ;AAChB,SAAO,GAAG,YAAY,IAAS,UAAU,IAAS,cAAc;AAClE;AAEO,SAAS,sBAAsB,UAA2D;AAC/F,SAAO;AAAA,IACL,cAAc,SAAS,IAAI,CAAC,YAAY,OAAO,mBAAmB,QAAQ,QAAQ,GAAG,CAAC,CAAC,EAAE,KAAK,GAAQ;AAAA,IACtG,gBAAgB,SAAS,IAAI,CAAC,YAAY,OAAO,QAAQ,2BAA2B,KAAK,CAAC,CAAC,EAAE,KAAK,GAAQ;AAAA,EAC5G;AACF;AAEO,SAAS,iCAAiC,UAA0B;AACzE,SAAO,gBAAgB,IAAI,QAAQ,KAAK;AAC1C;AAEO,SAAS,8BAAwC;AACtD,SAAO,CAAC,GAAG,MAAM,KAAK,CAAC;AACzB;AAEO,SAAS,4BAA4B,UAAyB;AACnE,MAAI,aAAa,QAAW;AAC1B,kBAAc;AACd,eAAW,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG;AACnC,mCAA6B,GAAG;AAChC,kBAAY,GAAG;AAAA,IACjB;AACA;AAAA,EACF;AACA,+BAA6B,QAAQ;AACrC,cAAY,UAAU,IAAI;AAC5B;AAEA,eAAsB,yBAAyB,UAAkC;AAC/E,QAAM,UAAU,CAAC,SAAe,aAAa,UAAa,KAAK,aAAa;AAC5E,WAAS,QAAQ,GAAG,QAAQ,eAAe,SAAS,GAAG;AACrD,eAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,UAAI,CAAC,QAAQ,IAAI,EAAG;AACpB,UAAI,CAAC,KAAK,WAAW,KAAK,OAAO;AAC/B,aAAK,QAAQ;AACb,qBAAa,IAAI;AAAA,MACnB;AAAA,IACF;AACA,UAAM,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,IAAI,CAAC,SAAS,KAAK,OAAQ;AAC/G,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B;AACF;AAEA,eAAsB,0BAA6B,SAMpC;AACb,QAAM,OAAO,QAAQ,gBAAgB;AACrC,QAAM,WAAW,MAAM,IAAI,QAAQ,QAAQ;AAC3C,MAAI,CAAC,UAAU;AACb,oBAAgB,QAAQ,QAAQ;AAChC,gBAAY,QAAQ,QAAQ;AAC5B,gBAAY,QAAQ,QAAQ;AAC5B,UAAM,WAAW,sBAAsB,QAAQ,QAAQ;AACvD,UAAM,UAAU,QAAQ,gBAAgB;AACxC,UAAM,QAAQ,MAAM,QAAQ,UAAU,QAAQ,WAAW;AAEzD,QAAI,CAAC,mBAAmB,QAAQ,EAAG,QAAO;AAC1C,0BAAsB,QAAQ;AAC9B,UAAM,QAAQ,QAAQ,gBAAgB;AACtC,oBAAgB,QAAQ,QAAQ;AAChC,gBAAY,QAAQ,QAAQ;AAC5B,UAAM,OAAa;AAAA,MACjB,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,UAAU,aAAa,SAAS,KAAK,IAAI,QAAQ;AAAA,MACjD,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,iBAAiB,QAAQ;AAAA,MACzB,WAAW,QAAQ;AAAA,IACrB;AACA,UAAM,IAAI,QAAQ,UAAU,IAAI;AAChC,QAAI,CAAC,aAAa,SAAS,KAAK,EAAG,YAAW,IAAI;AAClD,WAAO;AAAA,EACT;AACA,WAAS,kBAAkB,QAAQ;AACnC,WAAS,YAAY,QAAQ;AAC7B,SAAO,SAAS,SAAS,mBAAmB,QAAQ,gBAAgB,EAAE,gBAAgB;AACpF,0BAAsB,QAAQ,WAAW;AACzC,UAAM,UAAU,SAAS;AACzB,QAAI,SAAS;AACX,YAAM,UAAU,SAAS,QAAQ,aAAa,gCAAgC;AAC9E;AAAA,IACF;AACA,UAAM,UAAU,QAAQ,gBAAgB;AACxC,UAAM,cAAc,SAAS,SAAS;AACtC,UAAM,iBAAiB,QAAQ;AAC/B,QAAI,UAAU,MAAY;AAAA,IAAC;AAC3B,UAAM,OAAO,IAAI,QAAc,CAAC,YAAY;AAC1C,gBAAU;AAAA,IACZ,CAAC;AACD,aAAS,YAAY;AACrB,aAAS,SAAS;AAClB,aAAS,QAAQ;AACjB,UAAM,QAAQ,SAAS;AACvB,UAAM,WAAW,sBAAsB,SAAS,QAAQ;AAKxD,UAAM,OAAO,QAAQ,gBAAgB,SAAS,OAAY,MAAS;AACnE,SAAK,KACF;AAAA,MACC,CAACA,aAAY;AACX,YAAI,SAAS,UAAU,SAAS,CAAC,mBAAmB,QAAQ,EAAG;AAC/D,cAAM,MAAM,QAAQ,gBAAgB;AACpC,iBAAS,QAAQA;AACjB,cAAM,cAAc,gBAAgB,QAAQ,gBAAgB,gBAAgB,IAAI;AAChF,cAAM,iBAAiB,mBAAmB,IAAI;AAC9C,iBAAS,WAAW;AAAA,UAClB,gBAAgB,iBAAiB,IAAI,iBAAiB;AAAA,UACtD,cAAc,cAAc,IAAI,eAAe;AAAA,QACjD;AACA,YAAI,SAAS,SAAS,iBAAiB,IAAI,gBAAgB,sBAAsBA,QAAO,GAAG;AACzF,qBAAW,QAAQ;AAAA,QACrB;AAAA,MACF;AAAA,MACA,MAAM;AAAA,MAAC;AAAA,IACT,EACC,QAAQ,MAAM;AACb,UAAI,SAAS,cAAc,KAAM,UAAS,YAAY;AACtD,cAAQ;AAAA,IACV,CAAC;AACH,UAAM,UAAU,MAAM,UAAU,MAAM,QAAQ,aAAa,gCAAgC;AAC3F,0BAAsB,QAAQ,WAAW;AACzC,WAAO;AAAA,EACT;AACA,MAAI,SAAS,SAAS,iBAAiB,KAAK,cAAc;AACxD,eAAW,QAAQ;AACnB,WAAO,SAAS;AAAA,EAClB;AACA,SAAO,SAAS;AAClB;AAEA,mBAAmB,cAAc,MAAM;AACrC,8BAA4B;AAC9B,CAAC;","names":["rebuilt"]}
|
|
@@ -210,7 +210,7 @@ import {
|
|
|
210
210
|
buildEntityRecallSection,
|
|
211
211
|
entityRecentTranscriptLookbackHours,
|
|
212
212
|
readRecentEntityTranscriptEntries
|
|
213
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-K3B72DKJ.js";
|
|
214
214
|
import {
|
|
215
215
|
planEpisodeWindowsWithFallback
|
|
216
216
|
} from "./chunk-T3GIETKV.js";
|
|
@@ -32226,4 +32226,4 @@ export {
|
|
|
32226
32226
|
qmdStartupCollectionChecksWithTimeout,
|
|
32227
32227
|
Orchestrator
|
|
32228
32228
|
};
|
|
32229
|
-
//# sourceMappingURL=chunk-
|
|
32229
|
+
//# sourceMappingURL=chunk-HLKUZW42.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
entityMentionScopeKey,
|
|
6
6
|
resolveEntityMentionIndex,
|
|
7
7
|
writePersistedEntityMentionIndex
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DPPLNZ3A.js";
|
|
9
9
|
import {
|
|
10
10
|
buildOriginStructuredSections,
|
|
11
11
|
sanitizeOriginatedFacts
|
|
@@ -927,4 +927,4 @@ export {
|
|
|
927
927
|
entityIndexVersion,
|
|
928
928
|
entityRecentTranscriptLookbackHours
|
|
929
929
|
};
|
|
930
|
-
//# sourceMappingURL=chunk-
|
|
930
|
+
//# sourceMappingURL=chunk-K3B72DKJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-mention-index-cache.d.ts","sourceRoot":"","sources":["../src/entity-mention-index-cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entity-mention-index-cache.d.ts","sourceRoot":"","sources":["../src/entity-mention-index-cache.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,IAAI,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,wBAAwB,CAAC,IAAI,MAAM,CAAC;CACrC,CAAC;AA2BF,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKxE;AA2CD,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAkID,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,MAAM,GACrB,MAAM,CAWR;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,qBAAqB,CAK/F;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAWnE;AAED,wBAAsB,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/E;AAED,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,qBAAqB,CAAC;IAC7C,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACrD,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,CAAC,CAAC,CAyFb"}
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
resolveEntityMentionIndex,
|
|
10
10
|
settleEntityMentionIndex,
|
|
11
11
|
writePersistedEntityMentionIndex
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DPPLNZ3A.js";
|
|
13
|
+
import "./chunk-ULM7JCDH.js";
|
|
13
14
|
import "./chunk-7CT3AI52.js";
|
|
14
15
|
import "./chunk-R2MBW2S4.js";
|
|
15
16
|
import "./chunk-3WCASNQZ.js";
|
package/dist/entity-retrieval.js
CHANGED
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
entityIndexVersion,
|
|
4
4
|
entityRecentTranscriptLookbackHours,
|
|
5
5
|
readRecentEntityTranscriptEntries
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-K3B72DKJ.js";
|
|
7
|
+
import "./chunk-DPPLNZ3A.js";
|
|
8
|
+
import "./chunk-ULM7JCDH.js";
|
|
8
9
|
import "./chunk-GKUA4MGB.js";
|
|
9
10
|
import "./chunk-WJ6S54ES.js";
|
|
10
11
|
import "./chunk-SVH57F5Z.js";
|
package/dist/index.js
CHANGED
|
@@ -181,7 +181,7 @@ import {
|
|
|
181
181
|
writeManifest,
|
|
182
182
|
writeMeetingEpisodeMemory,
|
|
183
183
|
writeTimelineState
|
|
184
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-HLKUZW42.js";
|
|
185
185
|
import {
|
|
186
186
|
WEARABLE_SOURCE_PREFIX,
|
|
187
187
|
buildExtractionTurns,
|
|
@@ -473,18 +473,6 @@ import {
|
|
|
473
473
|
validateEvalTrajectoryReport,
|
|
474
474
|
writeEvalTrajectoryReport
|
|
475
475
|
} from "./chunk-PIITB2YZ.js";
|
|
476
|
-
import {
|
|
477
|
-
DEFAULT_EVAL_TRAJECTORY_MAX_FUTURE_SKEW_MS,
|
|
478
|
-
DEFAULT_EVAL_TRAJECTORY_MAX_ROWS,
|
|
479
|
-
DEFAULT_EVAL_TRAJECTORY_OUTCOME_WINDOW_MS,
|
|
480
|
-
DEFAULT_EVAL_TRAJECTORY_REPORT_MAX_AGE_MS,
|
|
481
|
-
DEFAULT_EVAL_TRAJECTORY_WEIGHTS,
|
|
482
|
-
EVAL_TRAJECTORY_PROMOTION_THRESHOLDS,
|
|
483
|
-
EVAL_TRAJECTORY_REPORT_SCHEMA_VERSION,
|
|
484
|
-
MAX_EVAL_TRAJECTORY_ROWS_LIMIT,
|
|
485
|
-
resolveEvalTrajectoryRunConfig,
|
|
486
|
-
serializeEvalTrajectoryReport
|
|
487
|
-
} from "./chunk-ULM7JCDH.js";
|
|
488
476
|
import {
|
|
489
477
|
buildEventOrderRecallSection
|
|
490
478
|
} from "./chunk-H7BZBSP6.js";
|
|
@@ -498,8 +486,20 @@ import {
|
|
|
498
486
|
} from "./chunk-DGFU5MSX.js";
|
|
499
487
|
import {
|
|
500
488
|
buildEntityRecallSection
|
|
501
|
-
} from "./chunk-
|
|
502
|
-
import "./chunk-
|
|
489
|
+
} from "./chunk-K3B72DKJ.js";
|
|
490
|
+
import "./chunk-DPPLNZ3A.js";
|
|
491
|
+
import {
|
|
492
|
+
DEFAULT_EVAL_TRAJECTORY_MAX_FUTURE_SKEW_MS,
|
|
493
|
+
DEFAULT_EVAL_TRAJECTORY_MAX_ROWS,
|
|
494
|
+
DEFAULT_EVAL_TRAJECTORY_OUTCOME_WINDOW_MS,
|
|
495
|
+
DEFAULT_EVAL_TRAJECTORY_REPORT_MAX_AGE_MS,
|
|
496
|
+
DEFAULT_EVAL_TRAJECTORY_WEIGHTS,
|
|
497
|
+
EVAL_TRAJECTORY_PROMOTION_THRESHOLDS,
|
|
498
|
+
EVAL_TRAJECTORY_REPORT_SCHEMA_VERSION,
|
|
499
|
+
MAX_EVAL_TRAJECTORY_ROWS_LIMIT,
|
|
500
|
+
resolveEvalTrajectoryRunConfig,
|
|
501
|
+
serializeEvalTrajectoryReport
|
|
502
|
+
} from "./chunk-ULM7JCDH.js";
|
|
503
503
|
import "./chunk-GKUA4MGB.js";
|
|
504
504
|
import "./chunk-WJ6S54ES.js";
|
|
505
505
|
import "./chunk-SVH57F5Z.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BufferDrainRunner
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-3JPTUCD7.js";
|
|
4
|
+
import "../chunk-HLKUZW42.js";
|
|
5
5
|
import "../chunk-KFLD7ZZG.js";
|
|
6
6
|
import "../chunk-QZSIDSB2.js";
|
|
7
7
|
import "../chunk-5PHOU5QI.js";
|
|
@@ -95,14 +95,14 @@ import "../chunk-YVVQUAOO.js";
|
|
|
95
95
|
import "../chunk-VL35ZFSZ.js";
|
|
96
96
|
import "../chunk-W2UOAATB.js";
|
|
97
97
|
import "../chunk-PIITB2YZ.js";
|
|
98
|
-
import "../chunk-ULM7JCDH.js";
|
|
99
98
|
import "../chunk-H7BZBSP6.js";
|
|
100
99
|
import "../chunk-LUPVCGYK.js";
|
|
101
100
|
import "../chunk-BUYVPUEM.js";
|
|
102
101
|
import "../chunk-IAIPNEHD.js";
|
|
103
102
|
import "../chunk-DGFU5MSX.js";
|
|
104
|
-
import "../chunk-
|
|
105
|
-
import "../chunk-
|
|
103
|
+
import "../chunk-K3B72DKJ.js";
|
|
104
|
+
import "../chunk-DPPLNZ3A.js";
|
|
105
|
+
import "../chunk-ULM7JCDH.js";
|
|
106
106
|
import "../chunk-GKUA4MGB.js";
|
|
107
107
|
import "../chunk-WJ6S54ES.js";
|
|
108
108
|
import "../chunk-SVH57F5Z.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BufferDrainRunner,
|
|
3
3
|
ClaimBufferStorage
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-3JPTUCD7.js";
|
|
5
|
+
import "../chunk-HLKUZW42.js";
|
|
6
6
|
import "../chunk-KFLD7ZZG.js";
|
|
7
7
|
import "../chunk-QZSIDSB2.js";
|
|
8
8
|
import "../chunk-5PHOU5QI.js";
|
|
@@ -96,14 +96,14 @@ import "../chunk-YVVQUAOO.js";
|
|
|
96
96
|
import "../chunk-VL35ZFSZ.js";
|
|
97
97
|
import "../chunk-W2UOAATB.js";
|
|
98
98
|
import "../chunk-PIITB2YZ.js";
|
|
99
|
-
import "../chunk-ULM7JCDH.js";
|
|
100
99
|
import "../chunk-H7BZBSP6.js";
|
|
101
100
|
import "../chunk-LUPVCGYK.js";
|
|
102
101
|
import "../chunk-BUYVPUEM.js";
|
|
103
102
|
import "../chunk-IAIPNEHD.js";
|
|
104
103
|
import "../chunk-DGFU5MSX.js";
|
|
105
|
-
import "../chunk-
|
|
106
|
-
import "../chunk-
|
|
104
|
+
import "../chunk-K3B72DKJ.js";
|
|
105
|
+
import "../chunk-DPPLNZ3A.js";
|
|
106
|
+
import "../chunk-ULM7JCDH.js";
|
|
107
107
|
import "../chunk-GKUA4MGB.js";
|
|
108
108
|
import "../chunk-WJ6S54ES.js";
|
|
109
109
|
import "../chunk-SVH57F5Z.js";
|
package/dist/orchestrator.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
graphPathRelativeToStorage,
|
|
5
5
|
mergeGraphExpandedResults,
|
|
6
6
|
qmdStartupCollectionChecksWithTimeout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HLKUZW42.js";
|
|
8
8
|
import "./chunk-KFLD7ZZG.js";
|
|
9
9
|
import "./chunk-QZSIDSB2.js";
|
|
10
10
|
import {
|
|
@@ -100,14 +100,14 @@ import "./chunk-YVVQUAOO.js";
|
|
|
100
100
|
import "./chunk-VL35ZFSZ.js";
|
|
101
101
|
import "./chunk-W2UOAATB.js";
|
|
102
102
|
import "./chunk-PIITB2YZ.js";
|
|
103
|
-
import "./chunk-ULM7JCDH.js";
|
|
104
103
|
import "./chunk-H7BZBSP6.js";
|
|
105
104
|
import "./chunk-LUPVCGYK.js";
|
|
106
105
|
import "./chunk-BUYVPUEM.js";
|
|
107
106
|
import "./chunk-IAIPNEHD.js";
|
|
108
107
|
import "./chunk-DGFU5MSX.js";
|
|
109
|
-
import "./chunk-
|
|
110
|
-
import "./chunk-
|
|
108
|
+
import "./chunk-K3B72DKJ.js";
|
|
109
|
+
import "./chunk-DPPLNZ3A.js";
|
|
110
|
+
import "./chunk-ULM7JCDH.js";
|
|
111
111
|
import "./chunk-GKUA4MGB.js";
|
|
112
112
|
import "./chunk-WJ6S54ES.js";
|
|
113
113
|
import "./chunk-SVH57F5Z.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.84",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3386,7 +3386,7 @@
|
|
|
3386
3386
|
"core"
|
|
3387
3387
|
],
|
|
3388
3388
|
"peerDependencies": {
|
|
3389
|
-
"@remnic/coding-graph": "^10.0.
|
|
3389
|
+
"@remnic/coding-graph": "^10.0.84"
|
|
3390
3390
|
},
|
|
3391
3391
|
"peerDependenciesMeta": {
|
|
3392
3392
|
"@remnic/coding-graph": {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import { correctionMcpTools } from "./access-mcp-correction-tools.js";
|
|
5
|
+
|
|
6
|
+
test("correctionMcpTools exposes plan and apply with closed schemas", () => {
|
|
7
|
+
assert.equal(correctionMcpTools.length, 2);
|
|
8
|
+
const names = correctionMcpTools.map((tool) => tool.name);
|
|
9
|
+
assert.deepEqual(names, ["engram.memory_correct_plan", "engram.memory_correct_apply"]);
|
|
10
|
+
|
|
11
|
+
for (const tool of correctionMcpTools) {
|
|
12
|
+
assert.equal(tool.inputSchema.type, "object");
|
|
13
|
+
assert.equal(tool.inputSchema.additionalProperties, false);
|
|
14
|
+
assert.ok(tool.description && tool.description.length > 20);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("memory_correct_plan requires text and advertises duplicateOf", () => {
|
|
19
|
+
const plan = correctionMcpTools.find((tool) => tool.name === "engram.memory_correct_plan");
|
|
20
|
+
assert.ok(plan);
|
|
21
|
+
assert.deepEqual(plan.inputSchema.required, ["text"]);
|
|
22
|
+
// SAFETY: the memory_correct_plan schema declares these properties; the assertions below read only them.
|
|
23
|
+
const props = plan.inputSchema.properties as Record<string, { type?: string; items?: { type?: string } }>;
|
|
24
|
+
assert.equal(props.text?.type, "string");
|
|
25
|
+
assert.equal(props.duplicateOf?.type, "string");
|
|
26
|
+
assert.equal(props.targetIds?.type, "array");
|
|
27
|
+
assert.equal(props.targetIds?.items?.type, "string");
|
|
28
|
+
assert.equal(props.sessionKey?.type, "string");
|
|
29
|
+
assert.equal(props.namespace?.type, "string");
|
|
30
|
+
assert.match(plan.description, /duplicateOf/);
|
|
31
|
+
assert.match(plan.description, /memory_correct_apply/);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("memory_correct_apply requires planId and advertises confirm", () => {
|
|
35
|
+
const apply = correctionMcpTools.find((tool) => tool.name === "engram.memory_correct_apply");
|
|
36
|
+
assert.ok(apply);
|
|
37
|
+
assert.deepEqual(apply.inputSchema.required, ["planId"]);
|
|
38
|
+
// SAFETY: the memory_correct_apply schema declares these properties; the assertions below read only them.
|
|
39
|
+
const props = apply.inputSchema.properties as Record<string, { type?: string }>;
|
|
40
|
+
assert.equal(props.planId?.type, "string");
|
|
41
|
+
assert.equal(props.confirm?.type, "boolean");
|
|
42
|
+
assert.equal(props.sessionKey?.type, "string");
|
|
43
|
+
assert.equal(props.namespace?.type, "string");
|
|
44
|
+
assert.match(apply.description, /confirm:\s*true/i);
|
|
45
|
+
});
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
|
|
7
|
+
import type { MemoryFile } from "../types.js";
|
|
8
|
+
import { rememberRawFrontmatter } from "../storage/memory-frontmatter-metadata.js";
|
|
9
|
+
import {
|
|
10
|
+
CORRECTION_FILE_BYTE_LIMIT,
|
|
11
|
+
WEEKLY_CORRECTION_READ_LIMIT,
|
|
12
|
+
WEEKLY_CORRECTION_SCAN_LIMIT,
|
|
13
|
+
buildActionFailurePatterns,
|
|
14
|
+
capWeeklyPatternDetails,
|
|
15
|
+
isoWeekStartMs,
|
|
16
|
+
provenanceVisibleInStoreRecall,
|
|
17
|
+
readFeedbackEntriesForWeekFile,
|
|
18
|
+
readWeeklyCorrections,
|
|
19
|
+
type WeeklyActionEvent,
|
|
20
|
+
type WeeklyEvidenceStorage,
|
|
21
|
+
} from "./weekly-evidence.js";
|
|
22
|
+
import { isoWeekId } from "./iso-week.js";
|
|
23
|
+
|
|
24
|
+
test("isoWeekStartMs returns Monday UTC for valid ids and null otherwise", () => {
|
|
25
|
+
const start = isoWeekStartMs("2026-W01");
|
|
26
|
+
assert.ok(start !== null);
|
|
27
|
+
assert.equal(new Date(start).toISOString(), "2025-12-29T00:00:00.000Z");
|
|
28
|
+
assert.equal(isoWeekId(new Date(start)), "2026-W01");
|
|
29
|
+
|
|
30
|
+
const w02 = isoWeekStartMs("2026-W02");
|
|
31
|
+
assert.ok(w02 !== null);
|
|
32
|
+
assert.equal(w02 - start!, 7 * 86_400_000);
|
|
33
|
+
|
|
34
|
+
assert.equal(isoWeekStartMs("2026-W1"), null);
|
|
35
|
+
assert.equal(isoWeekStartMs("2026-W00"), null);
|
|
36
|
+
assert.equal(isoWeekStartMs("not-a-week"), null);
|
|
37
|
+
assert.equal(isoWeekStartMs("2026-W54"), null);
|
|
38
|
+
// 2026 has 53 weeks only if the calendar emits it; W53 that does not land is null.
|
|
39
|
+
const w53 = isoWeekStartMs("2015-W53");
|
|
40
|
+
assert.ok(w53 !== null);
|
|
41
|
+
assert.equal(isoWeekId(new Date(w53)), "2015-W53");
|
|
42
|
+
assert.equal(isoWeekStartMs("2016-W53"), null);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("readFeedbackEntriesForWeekFile filters by ISO week and skips bad lines", async () => {
|
|
46
|
+
const root = await mkdtemp(path.join(os.tmpdir(), "remnic-weekly-feedback-"));
|
|
47
|
+
try {
|
|
48
|
+
const inbox = path.join(root, "feedback.jsonl");
|
|
49
|
+
const inWeek = "2026-01-02T12:00:00.000Z"; // 2026-W01
|
|
50
|
+
const otherWeek = "2026-01-08T12:00:00.000Z"; // 2026-W02
|
|
51
|
+
await writeFile(
|
|
52
|
+
inbox,
|
|
53
|
+
[
|
|
54
|
+
JSON.stringify({
|
|
55
|
+
agent: "alpha",
|
|
56
|
+
decision: "approved",
|
|
57
|
+
reason: "looks good",
|
|
58
|
+
date: inWeek,
|
|
59
|
+
}),
|
|
60
|
+
"not-json",
|
|
61
|
+
JSON.stringify({ agent: "", decision: "approved", reason: "x", date: inWeek }),
|
|
62
|
+
JSON.stringify({
|
|
63
|
+
agent: "beta",
|
|
64
|
+
decision: "rejected",
|
|
65
|
+
reason: "no",
|
|
66
|
+
date: otherWeek,
|
|
67
|
+
}),
|
|
68
|
+
JSON.stringify({
|
|
69
|
+
agent: "gamma",
|
|
70
|
+
decision: "approved_with_feedback",
|
|
71
|
+
reason: "tweak",
|
|
72
|
+
date: "2025-12-30T08:00:00.000Z",
|
|
73
|
+
}),
|
|
74
|
+
"",
|
|
75
|
+
].join("\n"),
|
|
76
|
+
"utf8",
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const entries = await readFeedbackEntriesForWeekFile(inbox, "2026-W01");
|
|
80
|
+
assert.equal(entries.length, 2);
|
|
81
|
+
assert.deepEqual(
|
|
82
|
+
entries.map((row) => row.entry.agent).sort(),
|
|
83
|
+
["alpha", "gamma"],
|
|
84
|
+
);
|
|
85
|
+
assert.equal(entries.find((row) => row.entry.agent === "alpha")?.sourceLine, 1);
|
|
86
|
+
assert.equal(entries.find((row) => row.entry.agent === "gamma")?.sourceLine, 5);
|
|
87
|
+
|
|
88
|
+
assert.deepEqual(await readFeedbackEntriesForWeekFile(path.join(root, "missing.jsonl"), "2026-W01"), []);
|
|
89
|
+
} finally {
|
|
90
|
+
await rm(root, { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("buildActionFailurePatterns keeps failures, skips, and policy decisions", () => {
|
|
95
|
+
const events: WeeklyActionEvent[] = [
|
|
96
|
+
{
|
|
97
|
+
line: 1,
|
|
98
|
+
action: "forget",
|
|
99
|
+
outcome: "failed",
|
|
100
|
+
policyDecision: null,
|
|
101
|
+
namespace: "default",
|
|
102
|
+
reason: "locked",
|
|
103
|
+
ledgerLabel: "memory-actions.jsonl",
|
|
104
|
+
actionId: "a1",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
line: 2,
|
|
108
|
+
action: "promote",
|
|
109
|
+
outcome: "applied",
|
|
110
|
+
policyDecision: null,
|
|
111
|
+
namespace: "default",
|
|
112
|
+
reason: null,
|
|
113
|
+
ledgerLabel: "memory-actions.jsonl",
|
|
114
|
+
actionId: "a2",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
line: 3,
|
|
118
|
+
action: "edit",
|
|
119
|
+
outcome: "applied",
|
|
120
|
+
policyDecision: "deny",
|
|
121
|
+
namespace: "ns1",
|
|
122
|
+
reason: " blocked by policy ",
|
|
123
|
+
ledgerLabel: "namespaces/ns1/state/memory-actions.jsonl",
|
|
124
|
+
actionId: "a3",
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
line: 4,
|
|
128
|
+
action: "merge",
|
|
129
|
+
outcome: "skipped",
|
|
130
|
+
policyDecision: null,
|
|
131
|
+
namespace: "default",
|
|
132
|
+
reason: null,
|
|
133
|
+
ledgerLabel: "memory-actions.jsonl",
|
|
134
|
+
actionId: "a4",
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
const patterns = buildActionFailurePatterns(events);
|
|
139
|
+
assert.equal(patterns.length, 3);
|
|
140
|
+
assert.match(patterns[0]!.pattern, /memory-action\/default: forget failed - locked/);
|
|
141
|
+
assert.equal(patterns[0]!.provenance, "memory-actions.jsonl:*");
|
|
142
|
+
assert.match(patterns[1]!.pattern, /memory-action\/ns1: edit applied\/deny - blocked by policy/);
|
|
143
|
+
assert.match(patterns[2]!.pattern, /memory-action\/default: merge skipped$/);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("readWeeklyCorrections skips files over the byte cap and keeps in-week active ones", async () => {
|
|
147
|
+
const root = await mkdtemp(path.join(os.tmpdir(), "remnic-weekly-corr-"));
|
|
148
|
+
try {
|
|
149
|
+
const correctionsDir = path.join(root, "corrections");
|
|
150
|
+
await mkdir(correctionsDir, { recursive: true });
|
|
151
|
+
|
|
152
|
+
const inWeekMs = Date.parse("2026-01-02T15:00:00.000Z");
|
|
153
|
+
const smallName = `correction-${inWeekMs}.md`;
|
|
154
|
+
const largeName = `correction-${inWeekMs + 1000}.md`;
|
|
155
|
+
const smallBody = `---
|
|
156
|
+
id: corr-small
|
|
157
|
+
category: correction
|
|
158
|
+
status: active
|
|
159
|
+
created: 2026-01-02T15:00:00.000Z
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
Fix the pricing table.
|
|
163
|
+
`;
|
|
164
|
+
await writeFile(path.join(correctionsDir, smallName), smallBody, "utf8");
|
|
165
|
+
await writeFile(
|
|
166
|
+
path.join(correctionsDir, largeName),
|
|
167
|
+
`${"x".repeat(CORRECTION_FILE_BYTE_LIMIT + 1)}`,
|
|
168
|
+
"utf8",
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// SAFETY: rememberRawFrontmatter reads only path, content and frontmatter; this literal sets all three.
|
|
172
|
+
const smallMemory = rememberRawFrontmatter(
|
|
173
|
+
{
|
|
174
|
+
path: path.join(correctionsDir, smallName),
|
|
175
|
+
content: "Fix the pricing table.",
|
|
176
|
+
frontmatter: {
|
|
177
|
+
id: "corr-small",
|
|
178
|
+
category: "correction",
|
|
179
|
+
status: "active",
|
|
180
|
+
created: "2026-01-02T15:00:00.000Z",
|
|
181
|
+
},
|
|
182
|
+
} as MemoryFile,
|
|
183
|
+
smallBody,
|
|
184
|
+
);
|
|
185
|
+
const byPath = new Map<string, MemoryFile>([[path.join(correctionsDir, smallName), smallMemory]]);
|
|
186
|
+
|
|
187
|
+
const storage: WeeklyEvidenceStorage = {
|
|
188
|
+
async readMemoryByPath(filePath) {
|
|
189
|
+
return byPath.get(filePath) ?? null;
|
|
190
|
+
},
|
|
191
|
+
async readMemoryActionEventRows() {
|
|
192
|
+
return [];
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const evidence = await readWeeklyCorrections({
|
|
197
|
+
storage,
|
|
198
|
+
memoryDir: root,
|
|
199
|
+
weekId: "2026-W01",
|
|
200
|
+
});
|
|
201
|
+
assert.equal(evidence.length, 1);
|
|
202
|
+
assert.equal(evidence[0]!.id, "corr-small");
|
|
203
|
+
assert.equal(evidence[0]!.note, "Fix the pricing table.");
|
|
204
|
+
assert.equal(evidence[0]!.provenance, `corrections/${smallName}`);
|
|
205
|
+
|
|
206
|
+
assert.ok(CORRECTION_FILE_BYTE_LIMIT === 256 * 1024);
|
|
207
|
+
assert.ok(WEEKLY_CORRECTION_READ_LIMIT === 500);
|
|
208
|
+
assert.ok(WEEKLY_CORRECTION_SCAN_LIMIT === 2000);
|
|
209
|
+
} finally {
|
|
210
|
+
await rm(root, { recursive: true, force: true });
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("provenanceVisibleInStoreRecall and capWeeklyPatternDetails prefer visible actions", () => {
|
|
215
|
+
assert.equal(provenanceVisibleInStoreRecall(["facts/a.md"]), true);
|
|
216
|
+
assert.equal(provenanceVisibleInStoreRecall(["namespaces/other/x.md"]), false);
|
|
217
|
+
assert.equal(provenanceVisibleInStoreRecall(["namespaces/home/x.md"], "namespaces/home/"), true);
|
|
218
|
+
assert.equal(provenanceVisibleInStoreRecall([]), true);
|
|
219
|
+
|
|
220
|
+
const details = [
|
|
221
|
+
{ pattern: "foreign", provenance: ["namespaces/other/a.md"] as const },
|
|
222
|
+
{ pattern: "action-a", provenance: ["memory-actions.jsonl:*"] as const },
|
|
223
|
+
{ pattern: "corr", provenance: ["corrections/c.md"] as const },
|
|
224
|
+
{ pattern: "action-b", provenance: ["memory-actions.jsonl:*"] as const },
|
|
225
|
+
{ pattern: "overflow", provenance: ["facts/x.md"] as const },
|
|
226
|
+
];
|
|
227
|
+
const capped = capWeeklyPatternDetails(
|
|
228
|
+
details,
|
|
229
|
+
(pattern) => (pattern.startsWith("action") ? "action" : "correction"),
|
|
230
|
+
null,
|
|
231
|
+
3,
|
|
232
|
+
);
|
|
233
|
+
assert.deepEqual(
|
|
234
|
+
capped.map((row) => row.pattern),
|
|
235
|
+
["action-a", "action-b", "corr"],
|
|
236
|
+
);
|
|
237
|
+
});
|
|
@@ -3,6 +3,7 @@ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { raceAbort } from "./abort-error.js";
|
|
4
4
|
import { entityMentionEpoch } from "./entity-mention-epoch.js";
|
|
5
5
|
import { log } from "./logger.js";
|
|
6
|
+
import { compareStrings } from "./eval-trajectory-contracts.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* In-memory entity mention index.
|
|
@@ -158,12 +159,6 @@ function throwIfMentionAborted(signal?: AbortSignal): void {
|
|
|
158
159
|
throw reason instanceof Error ? reason : new Error("entity mention rebuild aborted");
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
function compareStrings(left: string, right: string): number {
|
|
162
|
-
if (left < right) return -1;
|
|
163
|
-
if (left > right) return 1;
|
|
164
|
-
return 0;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
162
|
function deduped(values: readonly string[]): string[] {
|
|
168
163
|
const seen = new Set<string>();
|
|
169
164
|
const out: string[] = [];
|