@remnic/core 9.3.742 → 9.3.744
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-boundary.d.ts +6 -6
- package/dist/access-boundary.js +10 -10
- package/dist/access-cli.js +29 -29
- package/dist/access-http.d.ts +6 -6
- package/dist/access-http.js +15 -15
- package/dist/access-mcp.d.ts +6 -6
- package/dist/access-mcp.js +14 -14
- package/dist/access-operations-batch.js +12 -12
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +13 -13
- package/dist/{access-service-K8n12dXu.d.ts → access-service-OT3Gk79W.d.ts} +3 -3
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +9 -9
- package/dist/access-surface-catalog.d.ts +6 -6
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +2 -2
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +10 -5
- package/dist/capabilities.js +1 -1
- package/dist/{catalog-_Bap6vfD.d.ts → catalog-CX0CjOaf.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-X5PMDVY4.js → chunk-3EA5LIFJ.js} +4 -4
- package/dist/{chunk-YNHRWFAP.js → chunk-4DLFJJOQ.js} +2 -2
- package/dist/{chunk-WIMKOTNY.js → chunk-5QANTTY2.js} +2 -2
- package/dist/{chunk-AM7YKD7V.js → chunk-5UNSGRCR.js} +5 -5
- package/dist/{chunk-Y6PNYJVO.js → chunk-A2KKLCOS.js} +2 -2
- package/dist/{chunk-O4IWVWSW.js → chunk-AVBT5WEW.js} +3 -3
- package/dist/{chunk-QUNH5UZH.js → chunk-BYLC4DKI.js} +2 -2
- package/dist/{chunk-UOVDO6TC.js → chunk-CHELXDTO.js} +3 -3
- package/dist/{chunk-TQQN64J2.js → chunk-DBSMLRTO.js} +2 -2
- package/dist/{chunk-EZZUNKMJ.js → chunk-DYK27X7V.js} +3 -3
- package/dist/{chunk-K2N6WIZM.js → chunk-E7RGJQWP.js} +2 -2
- package/dist/{chunk-M4WI23X3.js → chunk-EEKDRAWX.js} +2 -2
- package/dist/{chunk-GFJ5ABKS.js → chunk-G5FP7VSQ.js} +11 -11
- package/dist/{chunk-BE6NEQLF.js → chunk-HAZVVOYT.js} +3 -3
- package/dist/{chunk-OT5K26NG.js → chunk-HM6UJPPO.js} +2 -2
- package/dist/{chunk-PI4JHLDD.js → chunk-IP5SANO2.js} +2 -2
- package/dist/{chunk-WHEF76BQ.js → chunk-JRZV3767.js} +2 -2
- package/dist/{chunk-OS5RKJOH.js → chunk-JZ7P26GF.js} +2 -2
- package/dist/{chunk-Y62QPRKV.js → chunk-K5LLP4CY.js} +2 -2
- package/dist/{chunk-C3Z5YJSM.js → chunk-LOPZ2DWR.js} +2 -2
- package/dist/{chunk-BJPL5WAL.js → chunk-MXDG6SRH.js} +3 -3
- package/dist/{chunk-UYYSOMS2.js → chunk-NBP3YHHS.js} +4 -4
- package/dist/{chunk-USHVHI6J.js → chunk-NNL4LJAD.js} +3 -3
- package/dist/{chunk-GPX5E36D.js → chunk-OSMBC3JU.js} +2 -2
- package/dist/{chunk-OUSOMUFV.js → chunk-PE6XR4GG.js} +2 -2
- package/dist/{chunk-CMPXLMC3.js → chunk-PI23H7FV.js} +3 -3
- package/dist/{chunk-WGDE2TJP.js → chunk-QOGXUNWL.js} +4 -4
- package/dist/{chunk-ELL5VYXC.js → chunk-RNWWAS5V.js} +3 -3
- package/dist/{chunk-7HUGLMSW.js → chunk-SODQQCAZ.js} +1013 -821
- package/dist/chunk-SODQQCAZ.js.map +1 -0
- package/dist/{chunk-JMMSVRF4.js → chunk-TQPSOTC7.js} +7 -7
- package/dist/{chunk-AX4TRSRE.js → chunk-U5WVRMCA.js} +2 -2
- package/dist/{chunk-7ADHJ6SU.js → chunk-VE54E6RP.js} +4 -4
- package/dist/{chunk-G7Q4D2G3.js → chunk-VSF7AAGE.js} +1 -3
- package/dist/chunk-VSF7AAGE.js.map +1 -0
- package/dist/{chunk-OVYBENIJ.js → chunk-W3M34XT4.js} +3 -3
- package/dist/{chunk-NHJYUIII.js → chunk-WPLRJ4XM.js} +7 -7
- package/dist/{chunk-UEIF7RWQ.js → chunk-XEADGIAA.js} +6 -6
- package/dist/{cli-BEOLy1xo.d.ts → cli-BQiTZ7Zs.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +21 -21
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +2 -2
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-UERKJESC.js → contradiction-scan-3FJYWS3G.js} +3 -3
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +2 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +5 -4
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +4 -4
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-GQ3UQNIL.js → first-start-migration-4I3VDSYS.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +36 -36
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +6 -6
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +2 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -6
- package/dist/{orchestrator-Dr-1v5EL.d.ts → orchestrator-BPQGHpJz.d.ts} +263 -31
- package/dist/orchestrator.d.ts +5 -4
- package/dist/orchestrator.js +24 -24
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-DsIEiCka.d.ts → semantic-consolidation-ByzGwC9c.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-CSKL7BDG.js → tier-stats-5XF4UBRQ.js} +2 -2
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CglNn2V-.d.ts → types-5Jik3r4G.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/package.json +2 -2
- package/src/capabilities.test.ts +0 -2
- package/src/capabilities.ts +7 -6
- package/src/orchestration/contradiction-linking-coordinator.ts +336 -0
- package/src/orchestration/graph-recall-coordinator.ts +471 -0
- package/src/orchestration/recall-section-coordinator.ts +349 -0
- package/src/orchestrator.ts +97 -741
- package/dist/chunk-7HUGLMSW.js.map +0 -1
- package/dist/chunk-G7Q4D2G3.js.map +0 -1
- /package/dist/{chunk-X5PMDVY4.js.map → chunk-3EA5LIFJ.js.map} +0 -0
- /package/dist/{chunk-YNHRWFAP.js.map → chunk-4DLFJJOQ.js.map} +0 -0
- /package/dist/{chunk-WIMKOTNY.js.map → chunk-5QANTTY2.js.map} +0 -0
- /package/dist/{chunk-AM7YKD7V.js.map → chunk-5UNSGRCR.js.map} +0 -0
- /package/dist/{chunk-Y6PNYJVO.js.map → chunk-A2KKLCOS.js.map} +0 -0
- /package/dist/{chunk-O4IWVWSW.js.map → chunk-AVBT5WEW.js.map} +0 -0
- /package/dist/{chunk-QUNH5UZH.js.map → chunk-BYLC4DKI.js.map} +0 -0
- /package/dist/{chunk-UOVDO6TC.js.map → chunk-CHELXDTO.js.map} +0 -0
- /package/dist/{chunk-TQQN64J2.js.map → chunk-DBSMLRTO.js.map} +0 -0
- /package/dist/{chunk-EZZUNKMJ.js.map → chunk-DYK27X7V.js.map} +0 -0
- /package/dist/{chunk-K2N6WIZM.js.map → chunk-E7RGJQWP.js.map} +0 -0
- /package/dist/{chunk-M4WI23X3.js.map → chunk-EEKDRAWX.js.map} +0 -0
- /package/dist/{chunk-GFJ5ABKS.js.map → chunk-G5FP7VSQ.js.map} +0 -0
- /package/dist/{chunk-BE6NEQLF.js.map → chunk-HAZVVOYT.js.map} +0 -0
- /package/dist/{chunk-OT5K26NG.js.map → chunk-HM6UJPPO.js.map} +0 -0
- /package/dist/{chunk-PI4JHLDD.js.map → chunk-IP5SANO2.js.map} +0 -0
- /package/dist/{chunk-WHEF76BQ.js.map → chunk-JRZV3767.js.map} +0 -0
- /package/dist/{chunk-OS5RKJOH.js.map → chunk-JZ7P26GF.js.map} +0 -0
- /package/dist/{chunk-Y62QPRKV.js.map → chunk-K5LLP4CY.js.map} +0 -0
- /package/dist/{chunk-C3Z5YJSM.js.map → chunk-LOPZ2DWR.js.map} +0 -0
- /package/dist/{chunk-BJPL5WAL.js.map → chunk-MXDG6SRH.js.map} +0 -0
- /package/dist/{chunk-UYYSOMS2.js.map → chunk-NBP3YHHS.js.map} +0 -0
- /package/dist/{chunk-USHVHI6J.js.map → chunk-NNL4LJAD.js.map} +0 -0
- /package/dist/{chunk-GPX5E36D.js.map → chunk-OSMBC3JU.js.map} +0 -0
- /package/dist/{chunk-OUSOMUFV.js.map → chunk-PE6XR4GG.js.map} +0 -0
- /package/dist/{chunk-CMPXLMC3.js.map → chunk-PI23H7FV.js.map} +0 -0
- /package/dist/{chunk-WGDE2TJP.js.map → chunk-QOGXUNWL.js.map} +0 -0
- /package/dist/{chunk-ELL5VYXC.js.map → chunk-RNWWAS5V.js.map} +0 -0
- /package/dist/{chunk-JMMSVRF4.js.map → chunk-TQPSOTC7.js.map} +0 -0
- /package/dist/{chunk-AX4TRSRE.js.map → chunk-U5WVRMCA.js.map} +0 -0
- /package/dist/{chunk-7ADHJ6SU.js.map → chunk-VE54E6RP.js.map} +0 -0
- /package/dist/{chunk-OVYBENIJ.js.map → chunk-W3M34XT4.js.map} +0 -0
- /package/dist/{chunk-NHJYUIII.js.map → chunk-WPLRJ4XM.js.map} +0 -0
- /package/dist/{chunk-UEIF7RWQ.js.map → chunk-XEADGIAA.js.map} +0 -0
- /package/dist/{contradiction-scan-UERKJESC.js.map → contradiction-scan-3FJYWS3G.js.map} +0 -0
- /package/dist/{first-start-migration-GQ3UQNIL.js.map → first-start-migration-4I3VDSYS.js.map} +0 -0
- /package/dist/{tier-stats-CSKL7BDG.js.map → tier-stats-5XF4UBRQ.js.map} +0 -0
package/src/orchestrator.ts
CHANGED
|
@@ -104,8 +104,20 @@ import { EntitySynthesisCoordinator } from "./orchestration/entity-synthesis-coo
|
|
|
104
104
|
import { RecallResultFormatter } from "./orchestration/recall-result-formatter.js";
|
|
105
105
|
import { ConversationIndexCoordinator } from "./orchestration/conversation-index-coordinator.js";
|
|
106
106
|
import { RecallRerankCoordinator } from "./orchestration/recall-rerank-coordinator.js";
|
|
107
|
+
import { RecallSectionCoordinator } from "./orchestration/recall-section-coordinator.js";
|
|
107
108
|
import { QmdResultResolver, qmdCollectionPathParts, qmdResultPathCandidates } from "./orchestration/qmd-result-resolver.js";
|
|
109
|
+
import { ContradictionLinkingCoordinator } from "./orchestration/contradiction-linking-coordinator.js";
|
|
108
110
|
export { hasIdentityRecoveryIntent, resolveEffectiveIdentityInjectionMode } from "./orchestration/recall-result-formatter.js";
|
|
111
|
+
import {
|
|
112
|
+
GraphRecallCoordinator,
|
|
113
|
+
mergeGraphExpandedResults,
|
|
114
|
+
graphPathRelativeToStorage,
|
|
115
|
+
blendGraphExpandedRecallScore,
|
|
116
|
+
type GraphRecallRankedResult,
|
|
117
|
+
type GraphRecallShadowComparison,
|
|
118
|
+
} from "./orchestration/graph-recall-coordinator.js";
|
|
119
|
+
export { mergeGraphExpandedResults, graphPathRelativeToStorage, blendGraphExpandedRecallScore } from "./orchestration/graph-recall-coordinator.js";
|
|
120
|
+
export type { GraphRecallRankedResult, GraphRecallShadowComparison } from "./orchestration/graph-recall-coordinator.js";
|
|
109
121
|
import {
|
|
110
122
|
runLiveConnectorsOnce,
|
|
111
123
|
type LiveConnectorsRunSummary,
|
|
@@ -504,21 +516,6 @@ export interface GraphRecallSnapshot {
|
|
|
504
516
|
shadowComparison?: GraphRecallShadowComparison;
|
|
505
517
|
}
|
|
506
518
|
|
|
507
|
-
export interface GraphRecallRankedResult {
|
|
508
|
-
path: string;
|
|
509
|
-
score: number;
|
|
510
|
-
docid?: string;
|
|
511
|
-
sourceLabels: string[];
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
export interface GraphRecallShadowComparison {
|
|
515
|
-
baselineCount: number;
|
|
516
|
-
graphCount: number;
|
|
517
|
-
overlapCount: number;
|
|
518
|
-
overlapRatio: number;
|
|
519
|
-
averageOverlapDelta: number;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
519
|
export interface IntentDebugSnapshot {
|
|
523
520
|
recordedAt: string;
|
|
524
521
|
promptHash: string;
|
|
@@ -1341,63 +1338,6 @@ export function computeQmdHybridFetchLimit(
|
|
|
1341
1338
|
const artifactHeadroom = Math.max(20, Math.max(0, maxArtifactRecall) * 8);
|
|
1342
1339
|
return Math.min(400, cappedRecallLimit + artifactHeadroom);
|
|
1343
1340
|
}
|
|
1344
|
-
|
|
1345
|
-
export function mergeGraphExpandedResults(
|
|
1346
|
-
primary: QmdSearchResult[],
|
|
1347
|
-
expanded: QmdSearchResult[],
|
|
1348
|
-
): QmdSearchResult[] {
|
|
1349
|
-
const mergedByPath = new Map<string, QmdSearchResult>();
|
|
1350
|
-
for (const item of [...primary, ...expanded]) {
|
|
1351
|
-
const prev = mergedByPath.get(item.path);
|
|
1352
|
-
if (!prev) {
|
|
1353
|
-
mergedByPath.set(item.path, item);
|
|
1354
|
-
continue;
|
|
1355
|
-
}
|
|
1356
|
-
const better = item.score > prev.score ? item : prev;
|
|
1357
|
-
const snippet = prev.snippet || item.snippet;
|
|
1358
|
-
mergedByPath.set(item.path, { ...better, snippet });
|
|
1359
|
-
}
|
|
1360
|
-
return Array.from(mergedByPath.values());
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
export function graphPathRelativeToStorage(
|
|
1364
|
-
storageDir: string,
|
|
1365
|
-
candidatePath: string,
|
|
1366
|
-
): string | null {
|
|
1367
|
-
const absolutePath = path.isAbsolute(candidatePath)
|
|
1368
|
-
? candidatePath
|
|
1369
|
-
: path.resolve(storageDir, candidatePath);
|
|
1370
|
-
const rel = path.relative(storageDir, absolutePath);
|
|
1371
|
-
if (!rel || rel === ".") return null;
|
|
1372
|
-
if (rel.startsWith("..")) return null;
|
|
1373
|
-
return rel.split(path.sep).join("/");
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
function normalizeGraphActivationScore(score: number): number {
|
|
1377
|
-
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
1378
|
-
return bounded / (1 + bounded);
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
export function blendGraphExpandedRecallScore(options: {
|
|
1382
|
-
graphActivationScore: number;
|
|
1383
|
-
seedRecallScore: number;
|
|
1384
|
-
activationWeight: number;
|
|
1385
|
-
blendMin: number;
|
|
1386
|
-
blendMax: number;
|
|
1387
|
-
}): number {
|
|
1388
|
-
const graphNorm = normalizeGraphActivationScore(options.graphActivationScore);
|
|
1389
|
-
const seedScore = Number.isFinite(options.seedRecallScore)
|
|
1390
|
-
? Math.min(1, Math.max(0, options.seedRecallScore))
|
|
1391
|
-
: 0;
|
|
1392
|
-
const weight = Math.min(1, Math.max(0, options.activationWeight));
|
|
1393
|
-
const rawMin = Math.min(1, Math.max(0, options.blendMin));
|
|
1394
|
-
const rawMax = Math.min(1, Math.max(0, options.blendMax));
|
|
1395
|
-
const minBound = Math.min(rawMin, rawMax);
|
|
1396
|
-
const maxBound = Math.max(rawMin, rawMax);
|
|
1397
|
-
const blended = graphNorm * weight + seedScore * (1 - weight);
|
|
1398
|
-
return Math.max(minBound, Math.min(maxBound, blended));
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
1341
|
export function summarizeGraphShadowComparison(
|
|
1402
1342
|
baseline: QmdSearchResult[],
|
|
1403
1343
|
merged: QmdSearchResult[],
|
|
@@ -1840,7 +1780,10 @@ export class Orchestrator {
|
|
|
1840
1780
|
*/
|
|
1841
1781
|
readonly conversationIndexCoordinator: ConversationIndexCoordinator;
|
|
1842
1782
|
readonly recallRerankCoordinator: RecallRerankCoordinator;
|
|
1783
|
+
readonly recallSectionCoordinator: RecallSectionCoordinator;
|
|
1843
1784
|
readonly qmdResultResolver: QmdResultResolver;
|
|
1785
|
+
readonly contradictionLinkingCoordinator: ContradictionLinkingCoordinator;
|
|
1786
|
+
readonly graphRecallCoordinator: GraphRecallCoordinator;
|
|
1844
1787
|
private heartbeatObserverChains = new Map<string, Promise<void>>();
|
|
1845
1788
|
private recentExtractionFingerprints = new Map<string, number>();
|
|
1846
1789
|
private readonly consolidationObservers = new Set<
|
|
@@ -2841,7 +2784,33 @@ export class Orchestrator {
|
|
|
2841
2784
|
readQmdResultMemory: (resultPath, fallbackStorage, recallNamespaces) =>
|
|
2842
2785
|
this.readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces),
|
|
2843
2786
|
});
|
|
2787
|
+
this.recallSectionCoordinator = new RecallSectionCoordinator({
|
|
2788
|
+
getConfig: () => this.config,
|
|
2789
|
+
resolveSectionEnabled: (id, def) => this.isRecallSectionEnabled(id, def),
|
|
2790
|
+
});
|
|
2791
|
+
this.contradictionLinkingCoordinator = new ContradictionLinkingCoordinator({
|
|
2792
|
+
getConfig: () => this.config,
|
|
2793
|
+
isSearchAvailable: () => this.isSearchAvailableForNamespaceRouting(),
|
|
2794
|
+
searchAcrossNamespaces: (options) => this.searchAcrossNamespaces(options),
|
|
2795
|
+
extractMemoryIdsFromResults: (results) => this.extractMemoryIdsFromResults(results),
|
|
2796
|
+
namespaceFromPath: (p) => this.namespaceFromPath(p),
|
|
2797
|
+
storageForNamespace: (namespace) => this.storageRouter.storageFor(namespace),
|
|
2798
|
+
getExtraction: () => this.extraction,
|
|
2799
|
+
});
|
|
2844
2800
|
this.modelRegistry = new ModelRegistry(config.memoryDir);
|
|
2801
|
+
this.graphRecallCoordinator = new GraphRecallCoordinator({
|
|
2802
|
+
getConfig: () => this.config,
|
|
2803
|
+
getStorage: () => this.storage,
|
|
2804
|
+
storageFor: (namespace) => this.storageRouter.storageFor(namespace),
|
|
2805
|
+
graphIndexFor: (storage) => this.graphIndexFor(storage),
|
|
2806
|
+
namespaceFromPath: (p) => this.namespaceFromPath(p),
|
|
2807
|
+
resolveColdQmdResultForRecall: (result, fallbackStorage, recallNamespaces) =>
|
|
2808
|
+
this.resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces),
|
|
2809
|
+
storageForAbsoluteQmdResultPath: (resultPath, fallbackStorage, recallNamespaces) =>
|
|
2810
|
+
this.storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces),
|
|
2811
|
+
readQmdResultMemory: (resultPath, fallbackStorage, recallNamespaces) =>
|
|
2812
|
+
this.readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces),
|
|
2813
|
+
});
|
|
2845
2814
|
this.relevance = new RelevanceStore(config.memoryDir);
|
|
2846
2815
|
this.negatives = new NegativeExampleStore(config.memoryDir);
|
|
2847
2816
|
this.lastRecall = new LastRecallStore(config.memoryDir);
|
|
@@ -6018,12 +5987,14 @@ export class Orchestrator {
|
|
|
6018
5987
|
return capped;
|
|
6019
5988
|
}
|
|
6020
5989
|
|
|
5990
|
+
// Issue #1526 (seam 14): graph-recall expansion moved to
|
|
5991
|
+
// GraphRecallCoordinator. Thin delegation keeps the private API stable
|
|
5992
|
+
// for callers (recallInternal, cold-fallback pipeline) + tests.
|
|
6021
5993
|
private async expandResultsViaGraph(options: {
|
|
6022
5994
|
memoryResults: QmdSearchResult[];
|
|
6023
5995
|
recallNamespaces: string[];
|
|
6024
5996
|
recallResultLimit: number;
|
|
6025
5997
|
deadlineAtMs?: number | null;
|
|
6026
|
-
/** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */
|
|
6027
5998
|
includeLowConfidence?: boolean;
|
|
6028
5999
|
}): Promise<{
|
|
6029
6000
|
merged: QmdSearchResult[];
|
|
@@ -6031,198 +6002,10 @@ export class Orchestrator {
|
|
|
6031
6002
|
expandedPaths: GraphRecallExpandedEntry[];
|
|
6032
6003
|
seedResults: QmdSearchResult[];
|
|
6033
6004
|
}> {
|
|
6034
|
-
|
|
6035
|
-
typeof options.deadlineAtMs === "number" &&
|
|
6036
|
-
Date.now() >= options.deadlineAtMs;
|
|
6037
|
-
const byNamespace = new Map<string, QmdSearchResult[]>();
|
|
6038
|
-
const addResultForNamespace = (
|
|
6039
|
-
namespace: string,
|
|
6040
|
-
result: QmdSearchResult,
|
|
6041
|
-
): void => {
|
|
6042
|
-
const existing = byNamespace.get(namespace);
|
|
6043
|
-
if (existing) {
|
|
6044
|
-
existing.push(result);
|
|
6045
|
-
} else {
|
|
6046
|
-
byNamespace.set(namespace, [result]);
|
|
6047
|
-
}
|
|
6048
|
-
};
|
|
6049
|
-
const resolvedAmbiguousSeeds = new Map<
|
|
6050
|
-
string,
|
|
6051
|
-
{ namespace: string; result: QmdSearchResult } | null
|
|
6052
|
-
>();
|
|
6053
|
-
const resolveAmbiguousSeedOwner = async (
|
|
6054
|
-
result: QmdSearchResult,
|
|
6055
|
-
parts: { collection: string; relativePath: string } | null,
|
|
6056
|
-
): Promise<{ namespace: string; result: QmdSearchResult } | null> => {
|
|
6057
|
-
const cached = resolvedAmbiguousSeeds.get(result.path);
|
|
6058
|
-
if (cached !== undefined) return cached;
|
|
6059
|
-
if (deadlineExpired()) {
|
|
6060
|
-
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6061
|
-
return null;
|
|
6062
|
-
}
|
|
6063
|
-
|
|
6064
|
-
let resolvedPath = result.path;
|
|
6065
|
-
let resolvedResult = result;
|
|
6066
|
-
if (parts) {
|
|
6067
|
-
const resolvedCold = await this.resolveColdQmdResultForRecall(
|
|
6068
|
-
result,
|
|
6069
|
-
this.storage,
|
|
6070
|
-
options.recallNamespaces,
|
|
6071
|
-
);
|
|
6072
|
-
if (!resolvedCold || deadlineExpired()) {
|
|
6073
|
-
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6074
|
-
return null;
|
|
6075
|
-
}
|
|
6076
|
-
resolvedPath = resolvedCold.result.path;
|
|
6077
|
-
resolvedResult = resolvedCold.result;
|
|
6078
|
-
}
|
|
6079
|
-
|
|
6080
|
-
if (!path.isAbsolute(resolvedPath)) {
|
|
6081
|
-
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6082
|
-
return null;
|
|
6083
|
-
}
|
|
6084
|
-
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
6085
|
-
resolvedPath,
|
|
6086
|
-
this.storage,
|
|
6087
|
-
options.recallNamespaces,
|
|
6088
|
-
);
|
|
6089
|
-
const ownerNamespace = ownerStorage?.namespace ?? null;
|
|
6090
|
-
const resolved =
|
|
6091
|
-
ownerNamespace && options.recallNamespaces.includes(ownerNamespace)
|
|
6092
|
-
? { namespace: ownerNamespace, result: resolvedResult }
|
|
6093
|
-
: null;
|
|
6094
|
-
resolvedAmbiguousSeeds.set(result.path, resolved);
|
|
6095
|
-
return resolved;
|
|
6096
|
-
};
|
|
6097
|
-
const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
6098
|
-
for (const result of options.memoryResults) {
|
|
6099
|
-
if (deadlineExpired()) break;
|
|
6100
|
-
const parts = qmdCollectionPathParts(result.path);
|
|
6101
|
-
if (parts?.collection === coldCollection) {
|
|
6102
|
-
const resolved = await resolveAmbiguousSeedOwner(result, parts);
|
|
6103
|
-
if (resolved) {
|
|
6104
|
-
addResultForNamespace(resolved.namespace, resolved.result);
|
|
6105
|
-
}
|
|
6106
|
-
continue;
|
|
6107
|
-
}
|
|
6108
|
-
if (path.isAbsolute(result.path)) {
|
|
6109
|
-
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
6110
|
-
if (resolved) {
|
|
6111
|
-
addResultForNamespace(resolved.namespace, resolved.result);
|
|
6112
|
-
}
|
|
6113
|
-
continue;
|
|
6114
|
-
}
|
|
6115
|
-
const ns = this.namespaceFromPath(result.path);
|
|
6116
|
-
if (!options.recallNamespaces.includes(ns)) continue;
|
|
6117
|
-
addResultForNamespace(ns, result);
|
|
6118
|
-
}
|
|
6119
|
-
|
|
6120
|
-
const perNamespaceSeedCap = Math.max(3, options.recallResultLimit);
|
|
6121
|
-
const perNamespaceExpandedCap = Math.max(8, options.recallResultLimit * 2);
|
|
6122
|
-
const seedPaths: string[] = [];
|
|
6123
|
-
const seedResults: QmdSearchResult[] = [];
|
|
6124
|
-
const expandedPaths: GraphRecallExpandedEntry[] = [];
|
|
6125
|
-
const expandedResults: QmdSearchResult[] = [];
|
|
6126
|
-
|
|
6127
|
-
for (const [namespace, nsResults] of byNamespace.entries()) {
|
|
6128
|
-
if (deadlineExpired()) break;
|
|
6129
|
-
const storage = await this.storageRouter.storageFor(namespace);
|
|
6130
|
-
const seedCandidates = nsResults.slice(0, perNamespaceSeedCap);
|
|
6131
|
-
seedResults.push(...seedCandidates);
|
|
6132
|
-
const seedRelativePaths =
|
|
6133
|
-
typeof options.deadlineAtMs === "number"
|
|
6134
|
-
? await this.graphSeedPathsWithinDeadline(
|
|
6135
|
-
storage,
|
|
6136
|
-
seedCandidates,
|
|
6137
|
-
options.deadlineAtMs,
|
|
6138
|
-
[namespace],
|
|
6139
|
-
)
|
|
6140
|
-
: (
|
|
6141
|
-
await Promise.all(
|
|
6142
|
-
seedCandidates.map((result) =>
|
|
6143
|
-
this.graphSeedPathRelativeToStorage(storage, result, [
|
|
6144
|
-
namespace,
|
|
6145
|
-
]),
|
|
6146
|
-
),
|
|
6147
|
-
)
|
|
6148
|
-
).filter(
|
|
6149
|
-
(value): value is string =>
|
|
6150
|
-
typeof value === "string" && value.length > 0,
|
|
6151
|
-
);
|
|
6152
|
-
if (deadlineExpired()) break;
|
|
6153
|
-
if (seedRelativePaths.length === 0) continue;
|
|
6154
|
-
|
|
6155
|
-
const seedRecallScore = seedCandidates.reduce(
|
|
6156
|
-
(max, item) => Math.max(max, item.score),
|
|
6157
|
-
0,
|
|
6158
|
-
);
|
|
6159
|
-
seedPaths.push(
|
|
6160
|
-
...seedRelativePaths.map((rel) => path.join(storage.dir, rel)),
|
|
6161
|
-
);
|
|
6162
|
-
const seedSet = new Set(seedRelativePaths);
|
|
6163
|
-
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
6164
|
-
seedRelativePaths,
|
|
6165
|
-
this.config.maxGraphTraversalSteps,
|
|
6166
|
-
{
|
|
6167
|
-
...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),
|
|
6168
|
-
...(typeof options.deadlineAtMs === "number"
|
|
6169
|
-
? { deadlineAtMs: options.deadlineAtMs }
|
|
6170
|
-
: {}),
|
|
6171
|
-
},
|
|
6172
|
-
);
|
|
6173
|
-
if (expanded.length === 0) continue;
|
|
6174
|
-
if (deadlineExpired()) break;
|
|
6175
|
-
|
|
6176
|
-
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
6177
|
-
if (deadlineExpired()) break;
|
|
6178
|
-
if (seedSet.has(candidate.path)) continue;
|
|
6179
|
-
const memoryPath = path.resolve(storage.dir, candidate.path);
|
|
6180
|
-
const memory = await storage.readMemoryByPath(memoryPath);
|
|
6181
|
-
if (deadlineExpired()) break;
|
|
6182
|
-
if (!memory) continue;
|
|
6183
|
-
if (isArtifactMemoryPath(memory.path)) continue;
|
|
6184
|
-
if (memory.frontmatter.status && memory.frontmatter.status !== "active")
|
|
6185
|
-
continue;
|
|
6186
|
-
|
|
6187
|
-
const snippet = memory.content.slice(0, 400);
|
|
6188
|
-
const score = blendGraphExpandedRecallScore({
|
|
6189
|
-
graphActivationScore: candidate.score,
|
|
6190
|
-
seedRecallScore,
|
|
6191
|
-
activationWeight: this.config.graphExpansionActivationWeight,
|
|
6192
|
-
blendMin: this.config.graphExpansionBlendMin,
|
|
6193
|
-
blendMax: this.config.graphExpansionBlendMax,
|
|
6194
|
-
});
|
|
6195
|
-
expandedResults.push({
|
|
6196
|
-
docid: memory.frontmatter.id,
|
|
6197
|
-
path: memory.path,
|
|
6198
|
-
snippet,
|
|
6199
|
-
score,
|
|
6200
|
-
});
|
|
6201
|
-
expandedPaths.push({
|
|
6202
|
-
path: memory.path,
|
|
6203
|
-
score,
|
|
6204
|
-
namespace,
|
|
6205
|
-
seed: path.resolve(storage.dir, candidate.seed),
|
|
6206
|
-
hopDepth: candidate.hopDepth,
|
|
6207
|
-
decayedWeight: candidate.decayedWeight,
|
|
6208
|
-
graphType: candidate.graphType,
|
|
6209
|
-
// Issue #681 PR 3/3 — surface the per-edge confidence used for
|
|
6210
|
-
// PageRank weighting / floor pruning so downstream observability
|
|
6211
|
-
// (recall_xray, memory_graph_explain) can attribute ranking and
|
|
6212
|
-
// pruning decisions to specific edges.
|
|
6213
|
-
edgeConfidence: candidate.edgeConfidence,
|
|
6214
|
-
});
|
|
6215
|
-
}
|
|
6216
|
-
}
|
|
6217
|
-
|
|
6218
|
-
return {
|
|
6219
|
-
merged: mergeGraphExpandedResults(options.memoryResults, expandedResults),
|
|
6220
|
-
seedPaths,
|
|
6221
|
-
expandedPaths,
|
|
6222
|
-
seedResults,
|
|
6223
|
-
};
|
|
6005
|
+
return this.graphRecallCoordinator.expandResultsViaGraph(options);
|
|
6224
6006
|
}
|
|
6225
|
-
|
|
6007
|
+
// Issue #1526 (seam 14): graph-recall snapshot moved to
|
|
6008
|
+
// GraphRecallCoordinator. Thin delegation keeps the private API stable.
|
|
6226
6009
|
private async recordLastGraphRecallSnapshot(options: {
|
|
6227
6010
|
storage: StorageManager;
|
|
6228
6011
|
prompt: string;
|
|
@@ -6238,45 +6021,8 @@ export class Orchestrator {
|
|
|
6238
6021
|
finalResults?: GraphRecallRankedResult[];
|
|
6239
6022
|
shadowComparison?: GraphRecallShadowComparison;
|
|
6240
6023
|
}): Promise<void> {
|
|
6241
|
-
|
|
6242
|
-
const snapshotPath = path.join(
|
|
6243
|
-
options.storage.dir,
|
|
6244
|
-
"state",
|
|
6245
|
-
"last_graph_recall.json",
|
|
6246
|
-
);
|
|
6247
|
-
await mkdir(path.dirname(snapshotPath), { recursive: true });
|
|
6248
|
-
const now = new Date().toISOString();
|
|
6249
|
-
const totalSeedCount = options.seedPaths.length;
|
|
6250
|
-
const totalExpandedCount = options.expandedPaths.length;
|
|
6251
|
-
const seeds = options.seedPaths.slice(0, 64);
|
|
6252
|
-
const expanded = clampGraphRecallExpandedEntries(
|
|
6253
|
-
options.expandedPaths,
|
|
6254
|
-
64,
|
|
6255
|
-
);
|
|
6256
|
-
const payload = {
|
|
6257
|
-
recordedAt: now,
|
|
6258
|
-
mode: options.recallMode,
|
|
6259
|
-
queryHash: createHash("sha256").update(options.prompt).digest("hex"),
|
|
6260
|
-
queryLength: options.prompt.length,
|
|
6261
|
-
namespaces: options.recallNamespaces,
|
|
6262
|
-
seedCount: totalSeedCount,
|
|
6263
|
-
expandedCount: totalExpandedCount,
|
|
6264
|
-
seeds,
|
|
6265
|
-
expanded,
|
|
6266
|
-
status: options.status,
|
|
6267
|
-
reason: options.reason,
|
|
6268
|
-
shadowMode: options.shadowMode === true,
|
|
6269
|
-
queryIntent: options.queryIntent,
|
|
6270
|
-
seedResults: (options.seedResults ?? []).slice(0, 64),
|
|
6271
|
-
finalResults: (options.finalResults ?? []).slice(0, 64),
|
|
6272
|
-
shadowComparison: options.shadowComparison,
|
|
6273
|
-
};
|
|
6274
|
-
await writeFile(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
6275
|
-
} catch (err) {
|
|
6276
|
-
log.debug(`last graph recall write failed: ${err}`);
|
|
6277
|
-
}
|
|
6024
|
+
return this.graphRecallCoordinator.recordLastGraphRecallSnapshot(options);
|
|
6278
6025
|
}
|
|
6279
|
-
|
|
6280
6026
|
private async recordLastIntentSnapshot(options: {
|
|
6281
6027
|
storage: StorageManager;
|
|
6282
6028
|
snapshot: IntentDebugSnapshot;
|
|
@@ -6377,52 +6123,46 @@ export class Orchestrator {
|
|
|
6377
6123
|
}));
|
|
6378
6124
|
}
|
|
6379
6125
|
|
|
6126
|
+
// Issue #1526 (seam 13): recall section budgeting/assembly moved to
|
|
6127
|
+
// RecallSectionCoordinator. Thin delegation keeps the orchestrator's
|
|
6128
|
+
// recallInternal call sites stable.
|
|
6380
6129
|
private getRecallSectionEntry(
|
|
6381
6130
|
sectionId: string,
|
|
6382
6131
|
): RecallSectionConfig | undefined {
|
|
6383
|
-
|
|
6384
|
-
? this.config.recallPipeline
|
|
6385
|
-
: [];
|
|
6386
|
-
return pipeline.find((entry) => entry.id === sectionId);
|
|
6132
|
+
return this.recallSectionCoordinator.getRecallSectionEntry(sectionId);
|
|
6387
6133
|
}
|
|
6388
6134
|
|
|
6389
6135
|
private isRecallSectionEnabled(
|
|
6390
6136
|
sectionId: string,
|
|
6391
6137
|
defaultEnabled: boolean = true,
|
|
6392
6138
|
): boolean {
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6139
|
+
return this.recallSectionCoordinator.isRecallSectionEnabled(
|
|
6140
|
+
sectionId,
|
|
6141
|
+
defaultEnabled,
|
|
6142
|
+
);
|
|
6396
6143
|
}
|
|
6397
6144
|
|
|
6398
6145
|
private isSpecializedRecallSectionEnabled(
|
|
6399
6146
|
sectionId: string,
|
|
6400
6147
|
topLevelEnabled: boolean,
|
|
6401
6148
|
): boolean {
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6149
|
+
return this.recallSectionCoordinator.isSpecializedRecallSectionEnabled(
|
|
6150
|
+
sectionId,
|
|
6151
|
+
topLevelEnabled,
|
|
6152
|
+
);
|
|
6405
6153
|
}
|
|
6406
6154
|
|
|
6407
6155
|
private getRecallSectionMaxChars(
|
|
6408
6156
|
sectionId: string,
|
|
6409
6157
|
): number | null | undefined {
|
|
6410
|
-
|
|
6411
|
-
if (!entry) return undefined;
|
|
6412
|
-
if (entry.maxChars === null) return null;
|
|
6413
|
-
if (typeof entry.maxChars !== "number") return undefined;
|
|
6414
|
-
return Math.max(0, Math.floor(entry.maxChars));
|
|
6158
|
+
return this.recallSectionCoordinator.getRecallSectionMaxChars(sectionId);
|
|
6415
6159
|
}
|
|
6416
6160
|
|
|
6417
6161
|
private getRecallSectionNumber(
|
|
6418
6162
|
sectionId: string,
|
|
6419
6163
|
key: keyof RecallSectionConfig,
|
|
6420
6164
|
): number | undefined {
|
|
6421
|
-
|
|
6422
|
-
if (!entry) return undefined;
|
|
6423
|
-
const value = entry[key];
|
|
6424
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
|
|
6425
|
-
return Math.max(0, Math.floor(value));
|
|
6165
|
+
return this.recallSectionCoordinator.getRecallSectionNumber(sectionId, key);
|
|
6426
6166
|
}
|
|
6427
6167
|
|
|
6428
6168
|
private appendRecallSection(
|
|
@@ -6430,104 +6170,25 @@ export class Orchestrator {
|
|
|
6430
6170
|
sectionId: string,
|
|
6431
6171
|
content: string,
|
|
6432
6172
|
): boolean {
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
if (!this.isRecallSectionEnabled(sectionId)) return false;
|
|
6439
|
-
const trimmed = content.trim();
|
|
6440
|
-
if (trimmed.length === 0) return false;
|
|
6441
|
-
|
|
6442
|
-
const maxChars = this.getRecallSectionMaxChars(sectionId);
|
|
6443
|
-
let finalContent = trimmed;
|
|
6444
|
-
if (maxChars === 0) return false;
|
|
6445
|
-
if (typeof maxChars === "number" && finalContent.length > maxChars) {
|
|
6446
|
-
finalContent = `${finalContent.slice(0, maxChars)}\n\n...(trimmed)\n`;
|
|
6447
|
-
}
|
|
6448
|
-
|
|
6449
|
-
const existing = sectionBuckets.get(sectionId) ?? [];
|
|
6450
|
-
existing.push(finalContent);
|
|
6451
|
-
sectionBuckets.set(sectionId, existing);
|
|
6452
|
-
return true;
|
|
6173
|
+
return this.recallSectionCoordinator.appendRecallSection(
|
|
6174
|
+
sectionBuckets,
|
|
6175
|
+
sectionId,
|
|
6176
|
+
content,
|
|
6177
|
+
);
|
|
6453
6178
|
}
|
|
6454
6179
|
|
|
6455
6180
|
private truncateRecallSectionToBudget(
|
|
6456
6181
|
content: string,
|
|
6457
6182
|
maxChars: number,
|
|
6458
6183
|
): string {
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
return content.slice(0, maxChars);
|
|
6464
|
-
}
|
|
6465
|
-
return `${content.slice(0, maxChars - suffix.length)}${suffix}`;
|
|
6466
|
-
}
|
|
6467
|
-
|
|
6468
|
-
private protectedRecallSectionIds(
|
|
6469
|
-
sectionBuckets: Map<string, string[]>,
|
|
6470
|
-
): Set<string> {
|
|
6471
|
-
const protectedIds = new Set<string>();
|
|
6472
|
-
if ((sectionBuckets.get("memories")?.length ?? 0) > 0) {
|
|
6473
|
-
protectedIds.add("memories");
|
|
6474
|
-
}
|
|
6475
|
-
return protectedIds;
|
|
6476
|
-
}
|
|
6477
|
-
|
|
6478
|
-
private protectedRecallReservationChars(content: string): number {
|
|
6479
|
-
const headingBoundary = content.indexOf("\n\n");
|
|
6480
|
-
const headingChars =
|
|
6481
|
-
headingBoundary >= 0 ? headingBoundary + 2 : Math.min(content.length, 24);
|
|
6482
|
-
return Math.min(content.length, Math.max(headingChars, 24));
|
|
6483
|
-
}
|
|
6484
|
-
|
|
6485
|
-
private estimateReservedRecallBudget(
|
|
6486
|
-
entries: Array<{ id: string; content: string }>,
|
|
6487
|
-
startIndex: number,
|
|
6488
|
-
protectedIds: Set<string>,
|
|
6489
|
-
alreadyIncludedCount: number,
|
|
6490
|
-
): number {
|
|
6491
|
-
const separatorLength = "\n\n---\n\n".length;
|
|
6492
|
-
let reserved = 0;
|
|
6493
|
-
let simulatedIncluded = alreadyIncludedCount;
|
|
6494
|
-
for (let i = startIndex; i < entries.length; i += 1) {
|
|
6495
|
-
const entry = entries[i];
|
|
6496
|
-
if (!entry || !protectedIds.has(entry.id)) continue;
|
|
6497
|
-
if (simulatedIncluded > 0) {
|
|
6498
|
-
reserved += separatorLength;
|
|
6499
|
-
}
|
|
6500
|
-
reserved += this.protectedRecallReservationChars(entry.content);
|
|
6501
|
-
simulatedIncluded += 1;
|
|
6502
|
-
}
|
|
6503
|
-
return reserved;
|
|
6184
|
+
return this.recallSectionCoordinator.truncateRecallSectionToBudget(
|
|
6185
|
+
content,
|
|
6186
|
+
maxChars,
|
|
6187
|
+
);
|
|
6504
6188
|
}
|
|
6505
6189
|
|
|
6506
6190
|
private getRecallBudgetChars(override?: number): number {
|
|
6507
|
-
|
|
6508
|
-
typeof override === "number" &&
|
|
6509
|
-
Number.isFinite(override) &&
|
|
6510
|
-
override >= 0
|
|
6511
|
-
) {
|
|
6512
|
-
return Math.floor(override);
|
|
6513
|
-
}
|
|
6514
|
-
const configuredBudget = this.config.recallBudgetChars;
|
|
6515
|
-
if (
|
|
6516
|
-
typeof configuredBudget === "number" &&
|
|
6517
|
-
Number.isFinite(configuredBudget) &&
|
|
6518
|
-
configuredBudget >= 0
|
|
6519
|
-
) {
|
|
6520
|
-
return Math.floor(configuredBudget);
|
|
6521
|
-
}
|
|
6522
|
-
const tokenBudget = this.config.maxMemoryTokens;
|
|
6523
|
-
if (
|
|
6524
|
-
typeof tokenBudget === "number" &&
|
|
6525
|
-
Number.isFinite(tokenBudget) &&
|
|
6526
|
-
tokenBudget >= 0
|
|
6527
|
-
) {
|
|
6528
|
-
return Math.floor(tokenBudget * 4);
|
|
6529
|
-
}
|
|
6530
|
-
return 0;
|
|
6191
|
+
return this.recallSectionCoordinator.getRecallBudgetChars(override);
|
|
6531
6192
|
}
|
|
6532
6193
|
|
|
6533
6194
|
private assembleRecallSections(
|
|
@@ -6540,89 +6201,13 @@ export class Orchestrator {
|
|
|
6540
6201
|
truncated: boolean;
|
|
6541
6202
|
finalChars: number;
|
|
6542
6203
|
} {
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
.filter((entry) => entry.enabled !== false)
|
|
6549
|
-
.map((entry) => entry.id);
|
|
6550
|
-
const seen = new Set<string>();
|
|
6551
|
-
|
|
6552
|
-
for (const id of orderedIds) {
|
|
6553
|
-
const chunks = sectionBuckets.get(id);
|
|
6554
|
-
if (!chunks || chunks.length === 0) continue;
|
|
6555
|
-
orderedEntries.push({ id, content: chunks.join("\n\n") });
|
|
6556
|
-
seen.add(id);
|
|
6557
|
-
}
|
|
6558
|
-
|
|
6559
|
-
for (const [id, chunks] of sectionBuckets.entries()) {
|
|
6560
|
-
if (seen.has(id)) continue;
|
|
6561
|
-
if (chunks.length === 0) continue;
|
|
6562
|
-
orderedEntries.push({ id, content: chunks.join("\n\n") });
|
|
6563
|
-
}
|
|
6564
|
-
|
|
6565
|
-
const budget = this.getRecallBudgetChars(budgetOverride);
|
|
6566
|
-
if (budget === 0) {
|
|
6567
|
-
return {
|
|
6568
|
-
sections: [],
|
|
6569
|
-
includedIds: [],
|
|
6570
|
-
omittedIds: orderedEntries.map((entry) => entry.id),
|
|
6571
|
-
truncated: orderedEntries.length > 0,
|
|
6572
|
-
finalChars: 0,
|
|
6573
|
-
};
|
|
6574
|
-
}
|
|
6575
|
-
|
|
6576
|
-
const separator = "\n\n---\n\n";
|
|
6577
|
-
const protectedIds = this.protectedRecallSectionIds(sectionBuckets);
|
|
6578
|
-
const sections: string[] = [];
|
|
6579
|
-
const includedIds: string[] = [];
|
|
6580
|
-
const omittedIds: string[] = [];
|
|
6581
|
-
let usedChars = 0;
|
|
6582
|
-
let truncated = false;
|
|
6204
|
+
return this.recallSectionCoordinator.assembleRecallSections(
|
|
6205
|
+
sectionBuckets,
|
|
6206
|
+
budgetOverride,
|
|
6207
|
+
);
|
|
6208
|
+
}
|
|
6583
6209
|
|
|
6584
|
-
for (let index = 0; index < orderedEntries.length; index += 1) {
|
|
6585
|
-
const entry = orderedEntries[index]!;
|
|
6586
|
-
const separatorChars = sections.length > 0 ? separator.length : 0;
|
|
6587
|
-
const reserve = protectedIds.has(entry.id)
|
|
6588
|
-
? 0
|
|
6589
|
-
: this.estimateReservedRecallBudget(
|
|
6590
|
-
orderedEntries,
|
|
6591
|
-
index + 1,
|
|
6592
|
-
protectedIds,
|
|
6593
|
-
sections.length + 1,
|
|
6594
|
-
);
|
|
6595
|
-
const availableForEntry = budget - usedChars - separatorChars - reserve;
|
|
6596
|
-
if (availableForEntry <= 0) {
|
|
6597
|
-
omittedIds.push(entry.id);
|
|
6598
|
-
truncated = true;
|
|
6599
|
-
continue;
|
|
6600
|
-
}
|
|
6601
|
-
const finalContent = this.truncateRecallSectionToBudget(
|
|
6602
|
-
entry.content,
|
|
6603
|
-
availableForEntry,
|
|
6604
|
-
);
|
|
6605
|
-
if (!finalContent) {
|
|
6606
|
-
omittedIds.push(entry.id);
|
|
6607
|
-
truncated = true;
|
|
6608
|
-
continue;
|
|
6609
|
-
}
|
|
6610
|
-
if (finalContent.length < entry.content.length) {
|
|
6611
|
-
truncated = true;
|
|
6612
|
-
}
|
|
6613
|
-
sections.push(finalContent);
|
|
6614
|
-
includedIds.push(entry.id);
|
|
6615
|
-
usedChars += separatorChars + finalContent.length;
|
|
6616
|
-
}
|
|
6617
6210
|
|
|
6618
|
-
return {
|
|
6619
|
-
sections,
|
|
6620
|
-
includedIds,
|
|
6621
|
-
omittedIds,
|
|
6622
|
-
truncated,
|
|
6623
|
-
finalChars: usedChars,
|
|
6624
|
-
};
|
|
6625
|
-
}
|
|
6626
6211
|
|
|
6627
6212
|
/**
|
|
6628
6213
|
* Clock source for the shared post-retrieval assembly/enrichment budget. The
|
|
@@ -16946,18 +16531,7 @@ export class Orchestrator {
|
|
|
16946
16531
|
includedSections?: string[];
|
|
16947
16532
|
omittedSections?: string[];
|
|
16948
16533
|
}): LastRecallBudgetSummary {
|
|
16949
|
-
return
|
|
16950
|
-
requestedTopK: options.requestedTopK,
|
|
16951
|
-
appliedTopK: options.recallResultLimit,
|
|
16952
|
-
recallBudgetChars: this.getRecallBudgetChars(),
|
|
16953
|
-
maxMemoryTokens: this.config.maxMemoryTokens,
|
|
16954
|
-
qmdFetchLimit: options.qmdFetchLimit,
|
|
16955
|
-
qmdHybridFetchLimit: options.qmdHybridFetchLimit,
|
|
16956
|
-
finalContextChars: options.finalContextChars,
|
|
16957
|
-
truncated: options.truncated,
|
|
16958
|
-
includedSections: [...(options.includedSections ?? [])],
|
|
16959
|
-
omittedSections: [...(options.omittedSections ?? [])],
|
|
16960
|
-
};
|
|
16534
|
+
return this.recallSectionCoordinator.buildLastRecallBudgetSummary(options);
|
|
16961
16535
|
}
|
|
16962
16536
|
|
|
16963
16537
|
private collectLastRecallSources(
|
|
@@ -16969,16 +16543,10 @@ export class Orchestrator {
|
|
|
16969
16543
|
| "cold_fallback"
|
|
16970
16544
|
| "recent_scan",
|
|
16971
16545
|
): string[] {
|
|
16972
|
-
|
|
16973
|
-
|
|
16974
|
-
|
|
16975
|
-
|
|
16976
|
-
for (const [sectionId, chunks] of sectionBuckets.entries()) {
|
|
16977
|
-
if (chunks.length > 0) {
|
|
16978
|
-
used.add(sectionId);
|
|
16979
|
-
}
|
|
16980
|
-
}
|
|
16981
|
-
return [...used];
|
|
16546
|
+
return this.recallSectionCoordinator.collectLastRecallSources(
|
|
16547
|
+
sectionBuckets,
|
|
16548
|
+
recallSource,
|
|
16549
|
+
);
|
|
16982
16550
|
}
|
|
16983
16551
|
|
|
16984
16552
|
/**
|
|
@@ -18338,99 +17906,11 @@ export class Orchestrator {
|
|
|
18338
17906
|
supersededCreated: string;
|
|
18339
17907
|
supersededTags: string[];
|
|
18340
17908
|
} | null> {
|
|
18341
|
-
|
|
18342
|
-
|
|
18343
|
-
|
|
18344
|
-
|
|
18345
|
-
|
|
18346
|
-
namespaces: [namespaceScope],
|
|
18347
|
-
maxResults: 5,
|
|
18348
|
-
mode: "search",
|
|
18349
|
-
});
|
|
18350
|
-
|
|
18351
|
-
for (const result of results) {
|
|
18352
|
-
// Check similarity threshold
|
|
18353
|
-
if (result.score < this.config.contradictionSimilarityThreshold) {
|
|
18354
|
-
continue;
|
|
18355
|
-
}
|
|
18356
|
-
|
|
18357
|
-
// Get the existing memory
|
|
18358
|
-
const memoryId = this.extractMemoryIdsFromResults([result])[0];
|
|
18359
|
-
if (!memoryId) continue;
|
|
18360
|
-
|
|
18361
|
-
const resultNamespace = this.namespaceFromPath(result.path);
|
|
18362
|
-
if (resultNamespace !== namespaceScope) continue;
|
|
18363
|
-
const resultStorage =
|
|
18364
|
-
await this.storageRouter.storageFor(resultNamespace);
|
|
18365
|
-
const existingMemory = await resultStorage.getMemoryById(memoryId);
|
|
18366
|
-
if (!existingMemory) continue;
|
|
18367
|
-
|
|
18368
|
-
// Skip memories already resolved or explicitly forgotten. Other
|
|
18369
|
-
// non-active statuses remain valid contradiction candidates.
|
|
18370
|
-
if (
|
|
18371
|
-
existingMemory.frontmatter.status === "superseded" ||
|
|
18372
|
-
existingMemory.frontmatter.status === "forgotten"
|
|
18373
|
-
) {
|
|
18374
|
-
continue;
|
|
18375
|
-
}
|
|
18376
|
-
|
|
18377
|
-
// Verify contradiction with LLM
|
|
18378
|
-
const verification = await this.extraction.verifyContradiction(
|
|
18379
|
-
{ content, category },
|
|
18380
|
-
{
|
|
18381
|
-
id: existingMemory.frontmatter.id,
|
|
18382
|
-
content: existingMemory.content,
|
|
18383
|
-
category: existingMemory.frontmatter.category,
|
|
18384
|
-
created: existingMemory.frontmatter.created,
|
|
18385
|
-
},
|
|
18386
|
-
);
|
|
18387
|
-
|
|
18388
|
-
if (!verification) continue;
|
|
18389
|
-
|
|
18390
|
-
// Check if it's a real contradiction with high confidence
|
|
18391
|
-
if (
|
|
18392
|
-
verification.isContradiction &&
|
|
18393
|
-
verification.confidence >= this.config.contradictionMinConfidence
|
|
18394
|
-
) {
|
|
18395
|
-
// When the LLM says the existing memory is newer (whichIsNewer ===
|
|
18396
|
-
// "first") the incoming fact is the stale one in both resolve modes —
|
|
18397
|
-
// log and continue so the caller never marks contradictionDetected and
|
|
18398
|
-
// the semantic-skip gate can discard the outdated write normally.
|
|
18399
|
-
if (verification.whichIsNewer === "first") {
|
|
18400
|
-
log.info(
|
|
18401
|
-
`detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory — existing is newer, incoming fact is stale`,
|
|
18402
|
-
);
|
|
18403
|
-
continue;
|
|
18404
|
-
}
|
|
18405
|
-
|
|
18406
|
-
// The new fact is newer than the existing one. When auto-resolve is
|
|
18407
|
-
// enabled, the caller retires the old memory AFTER the new write lands
|
|
18408
|
-
// and its tombstone status is known (#1645: defer auto-resolve until
|
|
18409
|
-
// tombstone status is known — a tombstone-blocked new write must not
|
|
18410
|
-
// retire the only active copy, leaving neither memory active). When
|
|
18411
|
-
// disabled, the old memory stays active for manual review. The
|
|
18412
|
-
// contradiction info is returned in both cases so the caller can apply
|
|
18413
|
-
// the deferred retire post-write.
|
|
18414
|
-
|
|
18415
|
-
// Return the contradiction info regardless of auto-resolve setting.
|
|
18416
|
-
// The caller uses this to set `contradictionDetected=true` which
|
|
18417
|
-
// prevents the semantic-skip guard from silently dropping a
|
|
18418
|
-
// legitimately contradictory update (the regression this fixes).
|
|
18419
|
-
log.info(
|
|
18420
|
-
`detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory${this.config.contradictionAutoResolve ? " (auto-resolved)" : " (queued for manual review)"}`,
|
|
18421
|
-
);
|
|
18422
|
-
return {
|
|
18423
|
-
supersededId: existingMemory.frontmatter.id,
|
|
18424
|
-
confidence: verification.confidence,
|
|
18425
|
-
reason: verification.reasoning,
|
|
18426
|
-
supersededPath: existingMemory.path,
|
|
18427
|
-
supersededCreated: existingMemory.frontmatter.created,
|
|
18428
|
-
supersededTags: existingMemory.frontmatter.tags ?? [],
|
|
18429
|
-
};
|
|
18430
|
-
}
|
|
18431
|
-
}
|
|
18432
|
-
|
|
18433
|
-
return null;
|
|
17909
|
+
return this.contradictionLinkingCoordinator.checkForContradiction(
|
|
17910
|
+
content,
|
|
17911
|
+
category,
|
|
17912
|
+
namespaceScope,
|
|
17913
|
+
);
|
|
18434
17914
|
}
|
|
18435
17915
|
|
|
18436
17916
|
/**
|
|
@@ -18453,49 +17933,12 @@ export class Orchestrator {
|
|
|
18453
17933
|
newMemoryId: string,
|
|
18454
17934
|
postWriteGuard: boolean,
|
|
18455
17935
|
): Promise<void> {
|
|
18456
|
-
|
|
18457
|
-
|
|
18458
|
-
|
|
18459
|
-
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
await storage.writeMemoryFrontmatter(blockedRow, { supersedes: undefined });
|
|
18463
|
-
}
|
|
18464
|
-
} catch (err) {
|
|
18465
|
-
log.warn(
|
|
18466
|
-
`contradiction auto-resolve supersedes clear failed for blocked ${newMemoryId}: ${err}`,
|
|
18467
|
-
);
|
|
18468
|
-
}
|
|
18469
|
-
}
|
|
18470
|
-
if (
|
|
18471
|
-
!contradiction ||
|
|
18472
|
-
!this.config.contradictionAutoResolve ||
|
|
18473
|
-
postWriteGuard
|
|
18474
|
-
) {
|
|
18475
|
-
return;
|
|
18476
|
-
}
|
|
18477
|
-
try {
|
|
18478
|
-
await storage.supersedeMemory(
|
|
18479
|
-
contradiction.supersededId,
|
|
18480
|
-
newMemoryId,
|
|
18481
|
-
contradiction.reason,
|
|
18482
|
-
);
|
|
18483
|
-
if (
|
|
18484
|
-
resolveIndexingCapabilities(this.config).queryAwareIndexing &&
|
|
18485
|
-
contradiction.supersededPath
|
|
18486
|
-
) {
|
|
18487
|
-
deindexMemory(
|
|
18488
|
-
this.config.memoryDir,
|
|
18489
|
-
contradiction.supersededPath,
|
|
18490
|
-
contradiction.supersededCreated,
|
|
18491
|
-
contradiction.supersededTags,
|
|
18492
|
-
);
|
|
18493
|
-
}
|
|
18494
|
-
} catch (err) {
|
|
18495
|
-
log.warn(
|
|
18496
|
-
`contradiction auto-resolve supersede failed for ${contradiction.supersededId}: ${err}`,
|
|
18497
|
-
);
|
|
18498
|
-
}
|
|
17936
|
+
return this.contradictionLinkingCoordinator.applyDeferredContradictionResolve(
|
|
17937
|
+
contradiction,
|
|
17938
|
+
storage,
|
|
17939
|
+
newMemoryId,
|
|
17940
|
+
postWriteGuard,
|
|
17941
|
+
);
|
|
18499
17942
|
}
|
|
18500
17943
|
|
|
18501
17944
|
// ---------------------------------------------------------------------------
|
|
@@ -18510,98 +17953,11 @@ export class Orchestrator {
|
|
|
18510
17953
|
category: string,
|
|
18511
17954
|
namespaceScope: string,
|
|
18512
17955
|
): Promise<MemoryLink[]> {
|
|
18513
|
-
|
|
18514
|
-
|
|
18515
|
-
|
|
18516
|
-
|
|
18517
|
-
query: content,
|
|
18518
|
-
namespaces: [namespaceScope],
|
|
18519
|
-
maxResults: 5,
|
|
18520
|
-
mode: "search",
|
|
18521
|
-
});
|
|
18522
|
-
if (results.length === 0) return [];
|
|
18523
|
-
|
|
18524
|
-
// Get full memory details for candidates
|
|
18525
|
-
const candidates: Array<{ id: string; content: string; category: string }> =
|
|
18526
|
-
[];
|
|
18527
|
-
for (const result of results) {
|
|
18528
|
-
const memoryId = this.extractMemoryIdsFromResults([result])[0];
|
|
18529
|
-
if (!memoryId) continue;
|
|
18530
|
-
|
|
18531
|
-
const resultNamespace = this.namespaceFromPath(result.path);
|
|
18532
|
-
if (resultNamespace !== namespaceScope) continue;
|
|
18533
|
-
const resultStorage =
|
|
18534
|
-
await this.storageRouter.storageFor(resultNamespace);
|
|
18535
|
-
const memory = await resultStorage.getMemoryById(memoryId);
|
|
18536
|
-
if (
|
|
18537
|
-
memory &&
|
|
18538
|
-
memory.frontmatter.status !== "superseded" &&
|
|
18539
|
-
memory.frontmatter.status !== "forgotten"
|
|
18540
|
-
) {
|
|
18541
|
-
candidates.push({
|
|
18542
|
-
id: memory.frontmatter.id,
|
|
18543
|
-
content: memory.content,
|
|
18544
|
-
category: memory.frontmatter.category,
|
|
18545
|
-
});
|
|
18546
|
-
}
|
|
18547
|
-
}
|
|
18548
|
-
|
|
18549
|
-
if (candidates.length === 0) return [];
|
|
18550
|
-
|
|
18551
|
-
// Ask LLM for link suggestions
|
|
18552
|
-
const suggestions = await this.extraction.suggestLinks(
|
|
18553
|
-
{ content, category },
|
|
18554
|
-
candidates,
|
|
17956
|
+
return this.contradictionLinkingCoordinator.suggestLinksForMemory(
|
|
17957
|
+
content,
|
|
17958
|
+
category,
|
|
17959
|
+
namespaceScope,
|
|
18555
17960
|
);
|
|
18556
|
-
|
|
18557
|
-
if (!suggestions || suggestions.links.length === 0) return [];
|
|
18558
|
-
|
|
18559
|
-
// Convert to MemoryLink format
|
|
18560
|
-
return suggestions.links.map((link) => ({
|
|
18561
|
-
targetId: link.targetId,
|
|
18562
|
-
linkType: link.linkType,
|
|
18563
|
-
strength: link.strength,
|
|
18564
|
-
reason: link.reason || undefined,
|
|
18565
|
-
}));
|
|
18566
|
-
}
|
|
18567
|
-
|
|
18568
|
-
private async graphSeedPathRelativeToStorage(
|
|
18569
|
-
storage: StorageManager,
|
|
18570
|
-
result: QmdSearchResult,
|
|
18571
|
-
recallNamespaces: readonly string[] = [],
|
|
18572
|
-
): Promise<string | null> {
|
|
18573
|
-
const parts = qmdCollectionPathParts(result.path);
|
|
18574
|
-
if (parts) {
|
|
18575
|
-
const memory = await this.readQmdResultMemory(
|
|
18576
|
-
result.path,
|
|
18577
|
-
storage,
|
|
18578
|
-
recallNamespaces,
|
|
18579
|
-
);
|
|
18580
|
-
return memory
|
|
18581
|
-
? graphPathRelativeToStorage(storage.dir, memory.path)
|
|
18582
|
-
: null;
|
|
18583
|
-
}
|
|
18584
|
-
return graphPathRelativeToStorage(storage.dir, result.path);
|
|
18585
|
-
}
|
|
18586
|
-
|
|
18587
|
-
private async graphSeedPathsWithinDeadline(
|
|
18588
|
-
storage: StorageManager,
|
|
18589
|
-
results: QmdSearchResult[],
|
|
18590
|
-
deadlineAtMs: number,
|
|
18591
|
-
recallNamespaces: readonly string[] = [],
|
|
18592
|
-
): Promise<string[]> {
|
|
18593
|
-
const resolved: string[] = [];
|
|
18594
|
-
for (const result of results) {
|
|
18595
|
-
if (Date.now() >= deadlineAtMs) break;
|
|
18596
|
-
const seedPath = await this.graphSeedPathRelativeToStorage(
|
|
18597
|
-
storage,
|
|
18598
|
-
result,
|
|
18599
|
-
recallNamespaces,
|
|
18600
|
-
);
|
|
18601
|
-
if (Date.now() >= deadlineAtMs) break;
|
|
18602
|
-
if (seedPath) resolved.push(seedPath);
|
|
18603
|
-
}
|
|
18604
|
-
return resolved;
|
|
18605
17961
|
}
|
|
18606
17962
|
|
|
18607
17963
|
private namespaceFromPath(p: string): string {
|