@remnic/core 9.3.665 → 9.3.667
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-audit.js +2 -2
- package/dist/access-cli.js +41 -40
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +3 -2
- package/dist/access-http.js +25 -25
- package/dist/access-mcp.d.ts +3 -2
- package/dist/access-mcp.js +22 -22
- package/dist/access-schema.d.ts +36 -36
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-D0SLB4MH.d.ts → access-service-BCuaiNHa.d.ts} +1 -1
- package/dist/access-service.d.ts +3 -2
- package/dist/access-service.js +21 -21
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/bootstrap.d.ts +2 -1
- package/dist/briefing.js +4 -3
- package/dist/capabilities.d.ts +73 -0
- package/dist/capabilities.js +8 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +7 -6
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-ROHLEUTH.js → chunk-23EBQ27U.js} +5 -5
- package/dist/{chunk-YW52BQSU.js → chunk-2TCHDANJ.js} +2 -2
- package/dist/{chunk-IROWLAWG.js → chunk-46WUVFOD.js} +4 -4
- package/dist/{chunk-WH4SKYPX.js → chunk-4FJKKC2N.js} +107 -77
- package/dist/chunk-4FJKKC2N.js.map +1 -0
- package/dist/{chunk-7C4MPEPE.js → chunk-4T7P2HLJ.js} +3 -3
- package/dist/{chunk-7XH7VJN4.js → chunk-6T4LTI2F.js} +4 -4
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-BZG2CWOQ.js → chunk-A5TEHAR4.js} +3 -3
- package/dist/{chunk-C7AF236A.js → chunk-AARDBQTA.js} +2 -2
- package/dist/{chunk-IHG6CC7T.js → chunk-BQJUPECT.js} +2 -2
- package/dist/{chunk-7OGJQP7T.js → chunk-CRO4LCQ6.js} +5 -5
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-UXA5L2DZ.js → chunk-HQCGRSRU.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-XW3W4PV4.js → chunk-JTPXSXHC.js} +2 -2
- package/dist/{chunk-OHJFJ4HI.js → chunk-KOXGLQS7.js} +2 -2
- package/dist/{chunk-2OPARZ4B.js → chunk-MPXYHC35.js} +26 -26
- package/dist/{chunk-6JBKHTQD.js → chunk-MR4PJ277.js} +2 -2
- package/dist/{chunk-EXXBA5OM.js → chunk-OI4BXFSB.js} +4 -4
- package/dist/{chunk-SQZ42MKH.js → chunk-OQH5XUH3.js} +6 -3
- package/dist/chunk-OQH5XUH3.js.map +1 -0
- package/dist/{chunk-2HEZXPYU.js → chunk-Q2LQZYQ7.js} +3 -3
- package/dist/{chunk-XRSIGVTS.js → chunk-QHWJG5C5.js} +8 -8
- package/dist/{chunk-T2AN3BSP.js → chunk-QZ7ODIVL.js} +2 -2
- package/dist/chunk-RI5XBIZ6.js +23 -0
- package/dist/chunk-RI5XBIZ6.js.map +1 -0
- package/dist/{chunk-D7IXTY5E.js → chunk-TJ7HH5LB.js} +2 -2
- package/dist/{chunk-V25ZAOSB.js → chunk-UOBLE67F.js} +4 -4
- package/dist/{chunk-JIX3ZL2J.js → chunk-UVUTV7CM.js} +15 -15
- package/dist/{chunk-VH6EIKVS.js → chunk-WKMCC4NQ.js} +35 -16
- package/dist/chunk-WKMCC4NQ.js.map +1 -0
- package/dist/{chunk-SSOMTUCA.js → chunk-WXGTC424.js} +1 -1
- package/dist/{chunk-KHGE6PMF.js → chunk-WXXLSZHA.js} +2 -2
- package/dist/{chunk-DSLUOQDY.js → chunk-XMWF6AU3.js} +2 -2
- package/dist/{chunk-DQY7NJ5L.js → chunk-XS2CWEHZ.js} +2 -2
- package/dist/{cli-BQRqR9N-.d.ts → cli-C98xlwYA.d.ts} +2 -2
- package/dist/cli.d.ts +4 -3
- package/dist/cli.js +42 -42
- package/dist/compounding/engine.js +4 -3
- package/dist/connectors/codex-materialize-runner.js +4 -3
- package/dist/connectors/index.js +4 -3
- package/dist/consolidation-provenance-check.js +2 -2
- package/dist/conversation-index/backend.js +2 -2
- package/dist/dashboard-runtime.js +2 -2
- package/dist/direct-answer-wiring.d.ts +13 -3
- package/dist/direct-answer-wiring.js +1 -1
- package/dist/entity-retrieval.js +4 -3
- package/dist/explicit-capture.d.ts +2 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +66 -65
- package/dist/index.js.map +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.js +4 -4
- package/dist/maintenance/memory-governance.js +4 -4
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -3
- package/dist/maintenance/rebuild-memory-projection.js +5 -5
- package/dist/mcp-memory-inspector-app.d.ts +3 -2
- package/dist/namespaces/migrate.js +11 -11
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.js +4 -3
- package/dist/operator-toolkit.js +15 -15
- package/dist/{orchestrator-Cg1UkvmO.d.ts → orchestrator-DyP9QYsh.d.ts} +16 -0
- package/dist/orchestrator.d.ts +2 -1
- package/dist/orchestrator.js +32 -31
- package/dist/recall-planner-llm.d.ts +2 -1
- package/dist/recall-planner-llm.js +3 -2
- package/dist/recall-planner-llm.js.map +1 -1
- package/dist/schemas.d.ts +64 -64
- package/dist/search/factory.js +6 -6
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.js +1 -1
- package/dist/search/orama-backend.js +1 -1
- package/dist/semantic-consolidation.js +5 -4
- package/dist/semantic-rule-promotion.js +4 -3
- package/dist/semantic-rule-verifier.js +4 -3
- package/dist/shared-context/manager.d.ts +2 -2
- package/dist/storage.js +3 -2
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/verified-recall.js +4 -3
- package/package.json +1 -1
- package/src/capabilities.test.ts +97 -0
- package/src/capabilities.ts +86 -0
- package/src/direct-answer-wiring.test.ts +53 -2
- package/src/direct-answer-wiring.ts +18 -5
- package/src/orchestrator.ts +83 -22
- package/src/recall-planner-llm.test.ts +12 -11
- package/src/recall-planner-llm.ts +7 -1
- package/src/storage-fallback-category-dirs.test.ts +150 -1
- package/src/storage.ts +51 -14
- package/dist/chunk-SQZ42MKH.js.map +0 -1
- package/dist/chunk-VH6EIKVS.js.map +0 -1
- package/dist/chunk-WH4SKYPX.js.map +0 -1
- /package/dist/{chunk-ROHLEUTH.js.map → chunk-23EBQ27U.js.map} +0 -0
- /package/dist/{chunk-YW52BQSU.js.map → chunk-2TCHDANJ.js.map} +0 -0
- /package/dist/{chunk-IROWLAWG.js.map → chunk-46WUVFOD.js.map} +0 -0
- /package/dist/{chunk-7C4MPEPE.js.map → chunk-4T7P2HLJ.js.map} +0 -0
- /package/dist/{chunk-7XH7VJN4.js.map → chunk-6T4LTI2F.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-BZG2CWOQ.js.map → chunk-A5TEHAR4.js.map} +0 -0
- /package/dist/{chunk-C7AF236A.js.map → chunk-AARDBQTA.js.map} +0 -0
- /package/dist/{chunk-IHG6CC7T.js.map → chunk-BQJUPECT.js.map} +0 -0
- /package/dist/{chunk-7OGJQP7T.js.map → chunk-CRO4LCQ6.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-UXA5L2DZ.js.map → chunk-HQCGRSRU.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-XW3W4PV4.js.map → chunk-JTPXSXHC.js.map} +0 -0
- /package/dist/{chunk-OHJFJ4HI.js.map → chunk-KOXGLQS7.js.map} +0 -0
- /package/dist/{chunk-2OPARZ4B.js.map → chunk-MPXYHC35.js.map} +0 -0
- /package/dist/{chunk-6JBKHTQD.js.map → chunk-MR4PJ277.js.map} +0 -0
- /package/dist/{chunk-EXXBA5OM.js.map → chunk-OI4BXFSB.js.map} +0 -0
- /package/dist/{chunk-2HEZXPYU.js.map → chunk-Q2LQZYQ7.js.map} +0 -0
- /package/dist/{chunk-XRSIGVTS.js.map → chunk-QHWJG5C5.js.map} +0 -0
- /package/dist/{chunk-T2AN3BSP.js.map → chunk-QZ7ODIVL.js.map} +0 -0
- /package/dist/{chunk-D7IXTY5E.js.map → chunk-TJ7HH5LB.js.map} +0 -0
- /package/dist/{chunk-V25ZAOSB.js.map → chunk-UOBLE67F.js.map} +0 -0
- /package/dist/{chunk-JIX3ZL2J.js.map → chunk-UVUTV7CM.js.map} +0 -0
- /package/dist/{chunk-SSOMTUCA.js.map → chunk-WXGTC424.js.map} +0 -0
- /package/dist/{chunk-KHGE6PMF.js.map → chunk-WXXLSZHA.js.map} +0 -0
- /package/dist/{chunk-DSLUOQDY.js.map → chunk-XMWF6AU3.js.map} +0 -0
- /package/dist/{chunk-DQY7NJ5L.js.map → chunk-XS2CWEHZ.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type DirectAnswerWiringInput,
|
|
8
8
|
} from "./direct-answer-wiring.js";
|
|
9
9
|
import { DEFAULT_TAXONOMY } from "./taxonomy/default-taxonomy.js";
|
|
10
|
-
import type { MemoryFile
|
|
10
|
+
import type { MemoryFile } from "./types.js";
|
|
11
11
|
import type { TrustZoneName } from "./trust-zones.js";
|
|
12
12
|
|
|
13
13
|
type WiringConfig = DirectAnswerWiringInput["config"];
|
|
@@ -94,7 +94,8 @@ test("tryDirectAnswer disabled-path does not call any source accessor", async ()
|
|
|
94
94
|
const result = await tryDirectAnswer({
|
|
95
95
|
query: "does not matter",
|
|
96
96
|
namespace: "default",
|
|
97
|
-
config:
|
|
97
|
+
config: BASE_CONFIG,
|
|
98
|
+
enabled: false,
|
|
98
99
|
sources,
|
|
99
100
|
});
|
|
100
101
|
assert.equal(result.eligible, false);
|
|
@@ -104,6 +105,42 @@ test("tryDirectAnswer disabled-path does not call any source accessor", async ()
|
|
|
104
105
|
assert.deepEqual(sources.calls.importance, []);
|
|
105
106
|
});
|
|
106
107
|
|
|
108
|
+
// ── Backward-compat (#1523): omit top-level `enabled`, fall back to config ──
|
|
109
|
+
|
|
110
|
+
test("tryDirectAnswer falls back to config.recallDirectAnswerEnabled when `enabled` is omitted (disabled)", async () => {
|
|
111
|
+
// Old input shape: config carries recallDirectAnswerEnabled: false and no
|
|
112
|
+
// top-level `enabled`. Must short-circuit as "disabled" (identical to the
|
|
113
|
+
// pre-#1523 behavior) rather than treating undefined as enabled.
|
|
114
|
+
const sources = makeMockSources({ memories: [makeMemory()] });
|
|
115
|
+
const result = await tryDirectAnswer({
|
|
116
|
+
query: "does not matter",
|
|
117
|
+
namespace: "default",
|
|
118
|
+
config: { ...BASE_CONFIG, recallDirectAnswerEnabled: false },
|
|
119
|
+
sources,
|
|
120
|
+
});
|
|
121
|
+
assert.equal(result.eligible, false);
|
|
122
|
+
assert.equal(result.reason, "disabled");
|
|
123
|
+
assert.equal(sources.calls.listCandidates, 0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("tryDirectAnswer falls back to config.recallDirectAnswerEnabled when `enabled` is omitted (enabled)", async () => {
|
|
127
|
+
// Old input shape with recallDirectAnswerEnabled: true and no `enabled` must
|
|
128
|
+
// NOT short-circuit — it proceeds to materialize candidates.
|
|
129
|
+
const sources = makeMockSources({
|
|
130
|
+
memories: [makeMemory({ tags: ["pnpm"], content: "remnic uses pnpm" })],
|
|
131
|
+
trustZones: { m1: "trusted" },
|
|
132
|
+
importance: { m1: 0.9 },
|
|
133
|
+
});
|
|
134
|
+
const result = await tryDirectAnswer({
|
|
135
|
+
query: "package manager remnic",
|
|
136
|
+
namespace: "default",
|
|
137
|
+
config: BASE_CONFIG, // recallDirectAnswerEnabled: true
|
|
138
|
+
sources,
|
|
139
|
+
});
|
|
140
|
+
assert.notEqual(result.reason, "disabled");
|
|
141
|
+
assert.equal(sources.calls.listCandidates, 1);
|
|
142
|
+
});
|
|
143
|
+
|
|
107
144
|
// ── Empty-query short-circuit: no I/O ───────────────────────────────────────
|
|
108
145
|
|
|
109
146
|
test("tryDirectAnswer skips all I/O when query normalizes to zero searchable tokens", async () => {
|
|
@@ -119,6 +156,7 @@ test("tryDirectAnswer skips all I/O when query normalizes to zero searchable tok
|
|
|
119
156
|
query: "? !!! ",
|
|
120
157
|
namespace: "default",
|
|
121
158
|
config: BASE_CONFIG,
|
|
159
|
+
enabled: true,
|
|
122
160
|
sources,
|
|
123
161
|
});
|
|
124
162
|
assert.equal(result.reason, "empty-query");
|
|
@@ -135,6 +173,7 @@ test("tryDirectAnswer with empty memory list returns no-candidates", async () =>
|
|
|
135
173
|
query: "package manager remnic",
|
|
136
174
|
namespace: "default",
|
|
137
175
|
config: BASE_CONFIG,
|
|
176
|
+
enabled: true,
|
|
138
177
|
sources,
|
|
139
178
|
});
|
|
140
179
|
assert.equal(result.reason, "no-candidates");
|
|
@@ -158,6 +197,7 @@ test("tryDirectAnswer skips importance resolution for non-trusted memories", asy
|
|
|
158
197
|
query: "package manager remnic",
|
|
159
198
|
namespace: "default",
|
|
160
199
|
config: BASE_CONFIG,
|
|
200
|
+
enabled: true,
|
|
161
201
|
sources,
|
|
162
202
|
});
|
|
163
203
|
assert.equal(result.eligible, false);
|
|
@@ -182,6 +222,7 @@ test("tryDirectAnswer skips importance for quarantine-zone memories", async () =
|
|
|
182
222
|
query: "package manager remnic",
|
|
183
223
|
namespace: "default",
|
|
184
224
|
config: BASE_CONFIG,
|
|
225
|
+
enabled: true,
|
|
185
226
|
sources,
|
|
186
227
|
});
|
|
187
228
|
assert.equal(result.eligible, false);
|
|
@@ -203,6 +244,7 @@ test("tryDirectAnswer skips importance when trust zone is missing (null)", async
|
|
|
203
244
|
query: "package manager remnic",
|
|
204
245
|
namespace: "default",
|
|
205
246
|
config: BASE_CONFIG,
|
|
247
|
+
enabled: true,
|
|
206
248
|
sources,
|
|
207
249
|
});
|
|
208
250
|
assert.equal(result.eligible, false);
|
|
@@ -229,6 +271,7 @@ test("tryDirectAnswer skips importance when taxonomy bucket is not eligible", as
|
|
|
229
271
|
query: "package manager remnic",
|
|
230
272
|
namespace: "default",
|
|
231
273
|
config: BASE_CONFIG,
|
|
274
|
+
enabled: true,
|
|
232
275
|
sources,
|
|
233
276
|
});
|
|
234
277
|
assert.equal(result.eligible, false);
|
|
@@ -254,6 +297,7 @@ test("tryDirectAnswer returns eligible for a single trusted user-confirmed decis
|
|
|
254
297
|
query: "package manager remnic",
|
|
255
298
|
namespace: "default",
|
|
256
299
|
config: BASE_CONFIG,
|
|
300
|
+
enabled: true,
|
|
257
301
|
sources,
|
|
258
302
|
});
|
|
259
303
|
assert.equal(result.eligible, true);
|
|
@@ -284,6 +328,7 @@ test("tryDirectAnswer defers to hybrid when two trusted candidates are within am
|
|
|
284
328
|
query: "package manager remnic",
|
|
285
329
|
namespace: "default",
|
|
286
330
|
config: BASE_CONFIG,
|
|
331
|
+
enabled: true,
|
|
287
332
|
sources,
|
|
288
333
|
});
|
|
289
334
|
assert.equal(result.eligible, false);
|
|
@@ -327,6 +372,7 @@ test("tryDirectAnswer throws AbortError when signal aborts mid-loop", async () =
|
|
|
327
372
|
query: "package manager remnic",
|
|
328
373
|
namespace: "default",
|
|
329
374
|
config: BASE_CONFIG,
|
|
375
|
+
enabled: true,
|
|
330
376
|
sources,
|
|
331
377
|
abortSignal: controller.signal,
|
|
332
378
|
}),
|
|
@@ -363,6 +409,7 @@ test("tryDirectAnswer throws when abort lands during trustZoneFor on the only me
|
|
|
363
409
|
query: "package manager remnic",
|
|
364
410
|
namespace: "default",
|
|
365
411
|
config: BASE_CONFIG,
|
|
412
|
+
enabled: true,
|
|
366
413
|
sources,
|
|
367
414
|
abortSignal: controller.signal,
|
|
368
415
|
}),
|
|
@@ -391,6 +438,7 @@ test("tryDirectAnswer throws when abort lands during trustZoneFor on the last of
|
|
|
391
438
|
query: "package manager remnic",
|
|
392
439
|
namespace: "default",
|
|
393
440
|
config: BASE_CONFIG,
|
|
441
|
+
enabled: true,
|
|
394
442
|
sources,
|
|
395
443
|
abortSignal: controller.signal,
|
|
396
444
|
}),
|
|
@@ -408,6 +456,7 @@ test("tryDirectAnswer throws when signal is already aborted before I/O", async (
|
|
|
408
456
|
query: "anything",
|
|
409
457
|
namespace: "default",
|
|
410
458
|
config: BASE_CONFIG,
|
|
459
|
+
enabled: true,
|
|
411
460
|
sources,
|
|
412
461
|
abortSignal: controller.signal,
|
|
413
462
|
}),
|
|
@@ -434,6 +483,7 @@ test("tryDirectAnswer passes the requested namespace to listCandidateMemories",
|
|
|
434
483
|
query: "anything",
|
|
435
484
|
namespace: "project-x",
|
|
436
485
|
config: BASE_CONFIG,
|
|
486
|
+
enabled: true,
|
|
437
487
|
sources,
|
|
438
488
|
});
|
|
439
489
|
assert.equal(observedNamespace, "project-x");
|
|
@@ -465,6 +515,7 @@ test("tryDirectAnswer forwards queryEntityRefs to the eligibility gate", async (
|
|
|
465
515
|
query: "package manager remnic",
|
|
466
516
|
namespace: "default",
|
|
467
517
|
config: BASE_CONFIG,
|
|
518
|
+
enabled: true,
|
|
468
519
|
sources,
|
|
469
520
|
queryEntityRefs: ["remnic"],
|
|
470
521
|
});
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
*
|
|
15
15
|
* Short-circuit contract:
|
|
16
16
|
*
|
|
17
|
-
* - When `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* - When the resolved gate (`input.enabled` if supplied, else
|
|
18
|
+
* `config.recallDirectAnswerEnabled`) is `false`, the function returns the
|
|
19
|
+
* eligibility verdict with reason `"disabled"` without touching any source
|
|
20
|
+
* accessor. This is the documented default.
|
|
20
21
|
* - When enabled, the wiring cheaply drops non-trusted-zone memories
|
|
21
22
|
* and ineligible taxonomy buckets before computing importance, so
|
|
22
23
|
* the eligibility module sees a pre-filtered candidate set. The
|
|
@@ -79,6 +80,15 @@ export interface DirectAnswerWiringInput {
|
|
|
79
80
|
| "recallDirectAnswerAmbiguityMargin"
|
|
80
81
|
| "recallDirectAnswerEligibleTaxonomyBuckets"
|
|
81
82
|
>;
|
|
83
|
+
/**
|
|
84
|
+
* Direct-answer capability gate, resolved once at the recall-operation entry
|
|
85
|
+
* (issue #1523: `caps.recallDirectAnswer`). OPTIONAL and additive: when the
|
|
86
|
+
* caller supplies it, this module and the orchestrator agree on a single
|
|
87
|
+
* resolved gate value for the whole operation. When omitted, we fall back to
|
|
88
|
+
* `config.recallDirectAnswerEnabled` so existing callers on the old input
|
|
89
|
+
* shape keep identical behavior.
|
|
90
|
+
*/
|
|
91
|
+
enabled?: boolean;
|
|
82
92
|
sources: DirectAnswerSources;
|
|
83
93
|
queryEntityRefs?: string[];
|
|
84
94
|
abortSignal?: AbortSignal;
|
|
@@ -92,10 +102,13 @@ export interface DirectAnswerWiringInput {
|
|
|
92
102
|
export async function tryDirectAnswer(
|
|
93
103
|
input: DirectAnswerWiringInput,
|
|
94
104
|
): Promise<DirectAnswerResult> {
|
|
95
|
-
const { query, namespace, config, sources, queryEntityRefs, abortSignal } = input;
|
|
105
|
+
const { query, namespace, config, enabled, sources, queryEntityRefs, abortSignal } = input;
|
|
96
106
|
|
|
97
107
|
const eligibilityConfig: DirectAnswerConfig = {
|
|
98
|
-
|
|
108
|
+
// Prefer the resolved capability when supplied; fall back to the config
|
|
109
|
+
// flag so callers on the old input shape (config-only, no `enabled`) get
|
|
110
|
+
// identical gating (issue #1523 backward-compat).
|
|
111
|
+
enabled: enabled ?? config.recallDirectAnswerEnabled,
|
|
99
112
|
tokenOverlapFloor: config.recallDirectAnswerTokenOverlapFloor,
|
|
100
113
|
importanceFloor: config.recallDirectAnswerImportanceFloor,
|
|
101
114
|
ambiguityMargin: config.recallDirectAnswerAmbiguityMargin,
|
package/src/orchestrator.ts
CHANGED
|
@@ -245,6 +245,7 @@ import {
|
|
|
245
245
|
type TrustZoneSearchResult,
|
|
246
246
|
} from "./trust-zones.js";
|
|
247
247
|
import { tryDirectAnswer, type DirectAnswerSources } from "./direct-answer-wiring.js";
|
|
248
|
+
import { resolveCapabilities, type CapabilitySet } from "./capabilities.js";
|
|
248
249
|
import { DEFAULT_TAXONOMY } from "./taxonomy/index.js";
|
|
249
250
|
import {
|
|
250
251
|
searchHarmonicRetrieval,
|
|
@@ -1376,6 +1377,13 @@ export function resolveRecallModeDecision(options: RecallModeGraphOptions): Reca
|
|
|
1376
1377
|
export async function resolveRecallModeDecisionAsync(
|
|
1377
1378
|
options: RecallModeGraphOptions & {
|
|
1378
1379
|
config: PluginConfig;
|
|
1380
|
+
/**
|
|
1381
|
+
* Recall-operation capability gates (issue #1523). OPTIONAL and additive:
|
|
1382
|
+
* the recall orchestrator passes a resolved set, but existing callers that
|
|
1383
|
+
* only pass `config` + planner flags stay backward-compatible — the LLM
|
|
1384
|
+
* planner gate falls back to `config.recallPlannerLlmEnabled` when omitted.
|
|
1385
|
+
*/
|
|
1386
|
+
caps?: CapabilitySet;
|
|
1379
1387
|
hints?: string[];
|
|
1380
1388
|
llm?: FallbackLlmClient;
|
|
1381
1389
|
signal?: AbortSignal;
|
|
@@ -1384,7 +1392,11 @@ export async function resolveRecallModeDecisionAsync(
|
|
|
1384
1392
|
const heuristicDecision = resolveRecallModeDecision(options);
|
|
1385
1393
|
|
|
1386
1394
|
// Planner globally off, or LLM planning not opted into → heuristic only.
|
|
1387
|
-
|
|
1395
|
+
// Prefer the resolved capability when supplied; otherwise fall back to the
|
|
1396
|
+
// config flag so callers on the old option shape get identical gating.
|
|
1397
|
+
const plannerLlmEnabled =
|
|
1398
|
+
options.caps?.recallPlannerLlm ?? options.config.recallPlannerLlmEnabled;
|
|
1399
|
+
if (!options.plannerEnabled || !plannerLlmEnabled) {
|
|
1388
1400
|
return heuristicDecision;
|
|
1389
1401
|
}
|
|
1390
1402
|
|
|
@@ -1395,6 +1407,7 @@ export async function resolveRecallModeDecisionAsync(
|
|
|
1395
1407
|
options.config,
|
|
1396
1408
|
options.llm,
|
|
1397
1409
|
options.signal,
|
|
1410
|
+
options.caps,
|
|
1398
1411
|
);
|
|
1399
1412
|
|
|
1400
1413
|
// Shadow mode: record what the LLM would have chosen but keep the heuristic
|
|
@@ -5738,6 +5751,10 @@ export class Orchestrator {
|
|
|
5738
5751
|
sessionKey?: string,
|
|
5739
5752
|
options: RecallInvocationOptions = {},
|
|
5740
5753
|
): Promise<string> {
|
|
5754
|
+
// Resolve the recall-operation capability gates ONCE, at the operation
|
|
5755
|
+
// entry, and thread the frozen set down (issue #1523). Never re-read the
|
|
5756
|
+
// migrated flags off `this.config` mid-operation.
|
|
5757
|
+
const caps = resolveCapabilities(this.config);
|
|
5741
5758
|
const abortController = new AbortController();
|
|
5742
5759
|
const onAbort = () => {
|
|
5743
5760
|
abortController.abort();
|
|
@@ -5813,7 +5830,7 @@ export class Orchestrator {
|
|
|
5813
5830
|
const recallPromise = this.recallInternal(prompt, sessionKey, {
|
|
5814
5831
|
...options,
|
|
5815
5832
|
abortSignal: abortController.signal,
|
|
5816
|
-
});
|
|
5833
|
+
}, caps);
|
|
5817
5834
|
const RECALL_TIMEOUT_MS = this.config.recallOuterTimeoutMs ?? 75_000;
|
|
5818
5835
|
if (RECALL_TIMEOUT_MS <= 0) {
|
|
5819
5836
|
return await recallPromise;
|
|
@@ -5837,13 +5854,14 @@ export class Orchestrator {
|
|
|
5837
5854
|
// Observation-mode direct-answer tier (issue #518 slice 3c).
|
|
5838
5855
|
// Runs after the user's recall already succeeded, fire-and-forget,
|
|
5839
5856
|
// so annotation latency can never delay the caller's response.
|
|
5840
|
-
if (
|
|
5857
|
+
if (caps.recallDirectAnswer && sessionKey) {
|
|
5841
5858
|
try {
|
|
5842
5859
|
this.enqueueDirectAnswerObservation(
|
|
5843
5860
|
prompt,
|
|
5844
5861
|
sessionKey,
|
|
5845
5862
|
options.namespace?.trim() || undefined,
|
|
5846
5863
|
options.principalOverride,
|
|
5864
|
+
caps,
|
|
5847
5865
|
);
|
|
5848
5866
|
} catch (err) {
|
|
5849
5867
|
log.debug(`direct-answer observation setup failed: ${err}`);
|
|
@@ -5912,6 +5930,7 @@ export class Orchestrator {
|
|
|
5912
5930
|
sessionKey: string,
|
|
5913
5931
|
namespaceOverride: string | undefined,
|
|
5914
5932
|
principalOverride: string | undefined,
|
|
5933
|
+
caps: CapabilitySet,
|
|
5915
5934
|
): void {
|
|
5916
5935
|
const expectedSnapshot = this.lastRecall.get(sessionKey);
|
|
5917
5936
|
if (expectedSnapshot === null) return;
|
|
@@ -5992,6 +6011,7 @@ export class Orchestrator {
|
|
|
5992
6011
|
sessionKey,
|
|
5993
6012
|
observationNamespaces,
|
|
5994
6013
|
expectedIdentity,
|
|
6014
|
+
caps,
|
|
5995
6015
|
undefined,
|
|
5996
6016
|
);
|
|
5997
6017
|
} catch (err) {
|
|
@@ -6007,6 +6027,7 @@ export class Orchestrator {
|
|
|
6007
6027
|
expectedIdentity:
|
|
6008
6028
|
| { writeNonce?: string; traceId?: string; recordedAt?: string }
|
|
6009
6029
|
| undefined,
|
|
6030
|
+
caps: CapabilitySet,
|
|
6010
6031
|
_parentAbortSignal?: AbortSignal,
|
|
6011
6032
|
): Promise<void> {
|
|
6012
6033
|
const tierStart = Date.now();
|
|
@@ -6091,6 +6112,7 @@ export class Orchestrator {
|
|
|
6091
6112
|
query: prompt,
|
|
6092
6113
|
namespace: ns,
|
|
6093
6114
|
config: this.config,
|
|
6115
|
+
enabled: caps.recallDirectAnswer,
|
|
6094
6116
|
sources,
|
|
6095
6117
|
});
|
|
6096
6118
|
if (r.eligible && r.winner) {
|
|
@@ -7273,10 +7295,22 @@ export class Orchestrator {
|
|
|
7273
7295
|
};
|
|
7274
7296
|
}
|
|
7275
7297
|
|
|
7298
|
+
/**
|
|
7299
|
+
* Clock source for the shared post-retrieval assembly/enrichment budget. The
|
|
7300
|
+
* deadline is set from this value and every expiry check reads it back, so a
|
|
7301
|
+
* test can drive the budget deterministically instead of racing the few-ms
|
|
7302
|
+
* wall-clock window that made the "skips … after budget expires" tests flaky.
|
|
7303
|
+
* Production behavior is unchanged — it returns the wall clock.
|
|
7304
|
+
*/
|
|
7305
|
+
protected recallAssemblyClockMs(): number {
|
|
7306
|
+
return Date.now();
|
|
7307
|
+
}
|
|
7308
|
+
|
|
7276
7309
|
private async recallInternal(
|
|
7277
7310
|
prompt: string,
|
|
7278
7311
|
sessionKey?: string,
|
|
7279
7312
|
options: RecallInvocationOptions = {},
|
|
7313
|
+
caps: CapabilitySet = resolveCapabilities(this.config),
|
|
7280
7314
|
): Promise<string> {
|
|
7281
7315
|
const recallStart = Date.now();
|
|
7282
7316
|
// Backend degradations observed by this recall's QMD searches (#1536):
|
|
@@ -7436,11 +7470,10 @@ export class Orchestrator {
|
|
|
7436
7470
|
let identityInjectionTruncated = false;
|
|
7437
7471
|
timings.queryPolicy = `${queryPolicy.promptShape}/${queryPolicy.retrievalBudgetMode}${queryPolicy.skipConversationRecall ? "/skip-conv" : ""}`;
|
|
7438
7472
|
const recallModeDecisionOptions = {
|
|
7439
|
-
plannerEnabled:
|
|
7440
|
-
graphRecallEnabled:
|
|
7473
|
+
plannerEnabled: caps.recallPlanner,
|
|
7474
|
+
graphRecallEnabled: caps.graphRecall,
|
|
7441
7475
|
multiGraphMemoryEnabled: this.config.multiGraphMemoryEnabled,
|
|
7442
|
-
graphExpandedIntentEnabled:
|
|
7443
|
-
this.config.graphExpandedIntentEnabled === true,
|
|
7476
|
+
graphExpandedIntentEnabled: caps.graphExpandedIntent,
|
|
7444
7477
|
prompt,
|
|
7445
7478
|
};
|
|
7446
7479
|
const requestedMode = options.mode;
|
|
@@ -7454,6 +7487,7 @@ export class Orchestrator {
|
|
|
7454
7487
|
: await resolveRecallModeDecisionAsync({
|
|
7455
7488
|
...recallModeDecisionOptions,
|
|
7456
7489
|
config: this.config,
|
|
7490
|
+
caps,
|
|
7457
7491
|
signal: options.abortSignal,
|
|
7458
7492
|
});
|
|
7459
7493
|
if (
|
|
@@ -7779,7 +7813,7 @@ export class Orchestrator {
|
|
|
7779
7813
|
promptLength: prompt.length,
|
|
7780
7814
|
retrievalQueryHash,
|
|
7781
7815
|
retrievalQueryLength: retrievalQuery.length,
|
|
7782
|
-
plannerEnabled:
|
|
7816
|
+
plannerEnabled: caps.recallPlanner,
|
|
7783
7817
|
plannedMode: requestedMode ?? recallDecision.plannedMode,
|
|
7784
7818
|
effectiveMode: recallMode,
|
|
7785
7819
|
recallResultLimit,
|
|
@@ -7790,7 +7824,7 @@ export class Orchestrator {
|
|
|
7790
7824
|
reason: graphDecisionReason,
|
|
7791
7825
|
shadowMode: graphDecisionShadowMode,
|
|
7792
7826
|
qmdAvailable,
|
|
7793
|
-
graphRecallEnabled:
|
|
7827
|
+
graphRecallEnabled: caps.graphRecall,
|
|
7794
7828
|
multiGraphMemoryEnabled: this.config.multiGraphMemoryEnabled,
|
|
7795
7829
|
},
|
|
7796
7830
|
});
|
|
@@ -10238,7 +10272,7 @@ export class Orchestrator {
|
|
|
10238
10272
|
|
|
10239
10273
|
const enrichmentAssemblyDeadlineAtMs =
|
|
10240
10274
|
enrichmentSectionDeadlineMs > 0
|
|
10241
|
-
?
|
|
10275
|
+
? this.recallAssemblyClockMs() + enrichmentSectionDeadlineMs
|
|
10242
10276
|
: null;
|
|
10243
10277
|
|
|
10244
10278
|
const awaitEnrichmentSection = async <T>(
|
|
@@ -10280,7 +10314,7 @@ export class Orchestrator {
|
|
|
10280
10314
|
const timeoutMs =
|
|
10281
10315
|
enrichmentAssemblyDeadlineAtMs === null
|
|
10282
10316
|
? null
|
|
10283
|
-
: Math.max(0, enrichmentAssemblyDeadlineAtMs -
|
|
10317
|
+
: Math.max(0, enrichmentAssemblyDeadlineAtMs - this.recallAssemblyClockMs());
|
|
10284
10318
|
if (timeoutMs === 0) {
|
|
10285
10319
|
const settledOutcome = promise.getSettledOutcome();
|
|
10286
10320
|
if (settledOutcome) {
|
|
@@ -10326,7 +10360,7 @@ export class Orchestrator {
|
|
|
10326
10360
|
const remainingEnrichmentAssemblyMs = (): number | null =>
|
|
10327
10361
|
enrichmentAssemblyDeadlineAtMs === null
|
|
10328
10362
|
? null
|
|
10329
|
-
: Math.max(0, enrichmentAssemblyDeadlineAtMs -
|
|
10363
|
+
: Math.max(0, enrichmentAssemblyDeadlineAtMs - this.recallAssemblyClockMs());
|
|
10330
10364
|
|
|
10331
10365
|
const awaitAssemblyStep = async <T>(
|
|
10332
10366
|
name: string,
|
|
@@ -11012,7 +11046,7 @@ export class Orchestrator {
|
|
|
11012
11046
|
|
|
11013
11047
|
const isFullModeGraphAssist =
|
|
11014
11048
|
this.config.multiGraphMemoryEnabled &&
|
|
11015
|
-
|
|
11049
|
+
caps.graphAssistInFullMode &&
|
|
11016
11050
|
recallMode === "full" &&
|
|
11017
11051
|
memoryResults.length >=
|
|
11018
11052
|
Math.max(1, this.config.graphAssistMinSeedResults ?? 3);
|
|
@@ -11192,7 +11226,7 @@ export class Orchestrator {
|
|
|
11192
11226
|
timeoutMs: this.config.rerankTimeoutMs,
|
|
11193
11227
|
maxCandidates: this.config.rerankMaxCandidates,
|
|
11194
11228
|
cache: this.rerankCache,
|
|
11195
|
-
cacheEnabled:
|
|
11229
|
+
cacheEnabled: caps.rerankCache,
|
|
11196
11230
|
cacheTtlMs: this.config.rerankCacheTtlMs,
|
|
11197
11231
|
});
|
|
11198
11232
|
if (ranked && ranked.length > 0) {
|
|
@@ -11222,7 +11256,7 @@ export class Orchestrator {
|
|
|
11222
11256
|
// flips the default once bench shows tie-or-win. Fail-open: any
|
|
11223
11257
|
// lookup error leaves the original scores untouched rather than
|
|
11224
11258
|
// breaking recall for the whole namespace.
|
|
11225
|
-
if (
|
|
11259
|
+
if (caps.recallMemoryWorthFilter && memoryResults.length > 0) {
|
|
11226
11260
|
try {
|
|
11227
11261
|
memoryResults = await this.applyMemoryWorthRerank(memoryResults, recallNamespaces);
|
|
11228
11262
|
} catch (err) {
|
|
@@ -11260,7 +11294,7 @@ export class Orchestrator {
|
|
|
11260
11294
|
memoryResults.length,
|
|
11261
11295
|
);
|
|
11262
11296
|
let confidenceGateRejected = false;
|
|
11263
|
-
if (
|
|
11297
|
+
if (caps.recallConfidenceGate && effectiveGateScore > 0) {
|
|
11264
11298
|
if (effectiveGateScore < this.config.recallConfidenceGateThreshold) {
|
|
11265
11299
|
log.debug(
|
|
11266
11300
|
`recall: confidence gate rejected ${memoryResults.length} results (effective score ${effectiveGateScore.toFixed(3)} below ${this.config.recallConfidenceGateThreshold})`,
|
|
@@ -11278,6 +11312,7 @@ export class Orchestrator {
|
|
|
11278
11312
|
memoryResults,
|
|
11279
11313
|
recallResultLimit,
|
|
11280
11314
|
retrievalQuery,
|
|
11315
|
+
caps,
|
|
11281
11316
|
);
|
|
11282
11317
|
|
|
11283
11318
|
// E-Mem-inspired memory reconstruction: fill gaps for referenced entities
|
|
@@ -11394,6 +11429,7 @@ export class Orchestrator {
|
|
|
11394
11429
|
boostedScoped,
|
|
11395
11430
|
recallResultLimit,
|
|
11396
11431
|
retrievalQuery,
|
|
11432
|
+
caps,
|
|
11397
11433
|
);
|
|
11398
11434
|
},
|
|
11399
11435
|
[] as QmdSearchResult[],
|
|
@@ -11431,6 +11467,7 @@ export class Orchestrator {
|
|
|
11431
11467
|
recallNamespaces,
|
|
11432
11468
|
recallResultLimit,
|
|
11433
11469
|
recallMode,
|
|
11470
|
+
caps,
|
|
11434
11471
|
queryAwarePrefilter,
|
|
11435
11472
|
abortSignal: options.abortSignal,
|
|
11436
11473
|
onDegradation: (degradation) => {
|
|
@@ -11551,6 +11588,7 @@ export class Orchestrator {
|
|
|
11551
11588
|
boostedScoped,
|
|
11552
11589
|
recallResultLimit,
|
|
11553
11590
|
retrievalQuery,
|
|
11591
|
+
caps,
|
|
11554
11592
|
);
|
|
11555
11593
|
},
|
|
11556
11594
|
[] as QmdSearchResult[],
|
|
@@ -11656,6 +11694,7 @@ export class Orchestrator {
|
|
|
11656
11694
|
recallNamespaces,
|
|
11657
11695
|
recallResultLimit,
|
|
11658
11696
|
recallMode,
|
|
11697
|
+
caps,
|
|
11659
11698
|
queryAwarePrefilter,
|
|
11660
11699
|
abortSignal: options.abortSignal,
|
|
11661
11700
|
onDegradation: (degradation) => {
|
|
@@ -11730,6 +11769,7 @@ export class Orchestrator {
|
|
|
11730
11769
|
boostedRecent,
|
|
11731
11770
|
recallResultLimit,
|
|
11732
11771
|
retrievalQuery,
|
|
11772
|
+
caps,
|
|
11733
11773
|
);
|
|
11734
11774
|
},
|
|
11735
11775
|
[] as QmdSearchResult[],
|
|
@@ -11768,6 +11808,7 @@ export class Orchestrator {
|
|
|
11768
11808
|
recallNamespaces,
|
|
11769
11809
|
recallResultLimit,
|
|
11770
11810
|
recallMode,
|
|
11811
|
+
caps,
|
|
11771
11812
|
queryAwarePrefilter,
|
|
11772
11813
|
abortSignal: options.abortSignal,
|
|
11773
11814
|
onDegradation: (degradation) => {
|
|
@@ -11815,6 +11856,7 @@ export class Orchestrator {
|
|
|
11815
11856
|
recallNamespaces,
|
|
11816
11857
|
recallResultLimit,
|
|
11817
11858
|
recallMode,
|
|
11859
|
+
caps,
|
|
11818
11860
|
queryAwarePrefilter,
|
|
11819
11861
|
abortSignal: options.abortSignal,
|
|
11820
11862
|
onDegradation: (degradation) => {
|
|
@@ -18361,6 +18403,11 @@ export class Orchestrator {
|
|
|
18361
18403
|
results: QmdSearchResult[],
|
|
18362
18404
|
limit: number,
|
|
18363
18405
|
retrievalQuery?: string,
|
|
18406
|
+
// `caps` is additive AND last (issue #1523) so the positional call shape
|
|
18407
|
+
// stays backward-compatible: the recall pipeline threads a resolved set,
|
|
18408
|
+
// but callers that omit it (e.g. direct unit-test invocations) get an
|
|
18409
|
+
// equivalent set derived from the same config — behavior-preserving.
|
|
18410
|
+
caps: CapabilitySet = resolveCapabilities(this.config),
|
|
18364
18411
|
): QmdSearchResult[] {
|
|
18365
18412
|
const safeLimit =
|
|
18366
18413
|
typeof limit === "number" && Number.isFinite(limit)
|
|
@@ -18377,13 +18424,13 @@ export class Orchestrator {
|
|
|
18377
18424
|
// facts/decisions before MMR picks the final section. No-op when the
|
|
18378
18425
|
// flag is off or the query is not a problem-solving ask.
|
|
18379
18426
|
const boosted =
|
|
18380
|
-
|
|
18427
|
+
caps.recallReasoningTraceBoost && typeof retrievalQuery === "string"
|
|
18381
18428
|
? applyReasoningTraceBoost(results, {
|
|
18382
18429
|
enabled: true,
|
|
18383
18430
|
query: retrievalQuery,
|
|
18384
18431
|
})
|
|
18385
18432
|
: results;
|
|
18386
|
-
const diversified = this.applyMmrToQmdResults(sectionId, boosted);
|
|
18433
|
+
const diversified = this.applyMmrToQmdResults(sectionId, boosted, caps);
|
|
18387
18434
|
return diversified.slice(0, safeLimit);
|
|
18388
18435
|
}
|
|
18389
18436
|
|
|
@@ -18398,8 +18445,11 @@ export class Orchestrator {
|
|
|
18398
18445
|
private applyMmrToQmdResults(
|
|
18399
18446
|
sectionId: string,
|
|
18400
18447
|
results: QmdSearchResult[],
|
|
18448
|
+
// Additive `caps` (issue #1523); defaults to a config-derived set so direct
|
|
18449
|
+
// callers that omit it behave identically to the threaded recall path.
|
|
18450
|
+
caps: CapabilitySet = resolveCapabilities(this.config),
|
|
18401
18451
|
): QmdSearchResult[] {
|
|
18402
|
-
if (
|
|
18452
|
+
if (!caps.recallMmr) return results;
|
|
18403
18453
|
if (!Array.isArray(results) || results.length < 2) return results;
|
|
18404
18454
|
|
|
18405
18455
|
// Config is runtime API (see AGENTS.md §4): preserve `0` as a true zero
|
|
@@ -18698,6 +18748,13 @@ export class Orchestrator {
|
|
|
18698
18748
|
recallNamespaces: string[];
|
|
18699
18749
|
recallResultLimit: number;
|
|
18700
18750
|
recallMode: RecallPlanMode;
|
|
18751
|
+
/**
|
|
18752
|
+
* Recall-operation capability gates resolved once at recall entry (#1523).
|
|
18753
|
+
* OPTIONAL and additive: the recall pipeline threads a resolved set, but
|
|
18754
|
+
* callers that omit it (e.g. direct unit-test invocations) get an
|
|
18755
|
+
* equivalent config-derived set — behavior-preserving.
|
|
18756
|
+
*/
|
|
18757
|
+
caps?: CapabilitySet;
|
|
18701
18758
|
queryAwarePrefilter?: QueryAwarePrefilter;
|
|
18702
18759
|
abortSignal?: AbortSignal;
|
|
18703
18760
|
/** Backend degradation observer — cold-tier QMD must report like hot (#1536). */
|
|
@@ -18717,6 +18774,9 @@ export class Orchestrator {
|
|
|
18717
18774
|
/** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */
|
|
18718
18775
|
includeLowConfidence?: boolean;
|
|
18719
18776
|
}): Promise<QmdSearchResult[]> {
|
|
18777
|
+
// Prefer the threaded set; fall back to a config-derived set so direct
|
|
18778
|
+
// callers (unit tests) behave identically to the recall pipeline (#1523).
|
|
18779
|
+
const caps = options.caps ?? resolveCapabilities(this.config);
|
|
18720
18780
|
if (options.queryAwarePrefilter?.candidatePaths?.size === 0) {
|
|
18721
18781
|
if (options.xrayPoolSizeSink) options.xrayPoolSizeSink.size = 0;
|
|
18722
18782
|
return [];
|
|
@@ -18932,7 +18992,7 @@ export class Orchestrator {
|
|
|
18932
18992
|
const isFullModeGraphAssist =
|
|
18933
18993
|
this.config.qmdTierParityGraphEnabled &&
|
|
18934
18994
|
this.config.multiGraphMemoryEnabled &&
|
|
18935
|
-
|
|
18995
|
+
caps.graphAssistInFullMode &&
|
|
18936
18996
|
options.recallMode === "full" &&
|
|
18937
18997
|
results.length >= Math.max(1, this.config.graphAssistMinSeedResults ?? 3);
|
|
18938
18998
|
const shouldRunGraphExpansion =
|
|
@@ -19028,7 +19088,7 @@ export class Orchestrator {
|
|
|
19028
19088
|
timeoutMs: this.config.rerankTimeoutMs,
|
|
19029
19089
|
maxCandidates: this.config.rerankMaxCandidates,
|
|
19030
19090
|
cache: this.rerankCache,
|
|
19031
|
-
cacheEnabled:
|
|
19091
|
+
cacheEnabled: caps.rerankCache,
|
|
19032
19092
|
cacheTtlMs: this.config.rerankCacheTtlMs,
|
|
19033
19093
|
});
|
|
19034
19094
|
if (ranked && ranked.length > 0) {
|
|
@@ -19054,7 +19114,7 @@ export class Orchestrator {
|
|
|
19054
19114
|
// Memory Worth filter — must fire on the cold fallback path too, or the
|
|
19055
19115
|
// feature flag produces divergent behavior by retrieval path (CLAUDE.md
|
|
19056
19116
|
// rule 39). Fail-open on lookup errors.
|
|
19057
|
-
if (
|
|
19117
|
+
if (caps.recallMemoryWorthFilter && results.length > 0) {
|
|
19058
19118
|
try {
|
|
19059
19119
|
results = await this.applyMemoryWorthRerank(results, options.recallNamespaces);
|
|
19060
19120
|
} catch (err) {
|
|
@@ -19079,6 +19139,7 @@ export class Orchestrator {
|
|
|
19079
19139
|
results,
|
|
19080
19140
|
options.recallResultLimit,
|
|
19081
19141
|
options.prompt,
|
|
19142
|
+
caps,
|
|
19082
19143
|
);
|
|
19083
19144
|
}
|
|
19084
19145
|
|