@remnic/core 9.3.700 → 9.3.702
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 +7 -7
- package/dist/access-boundary.js +17 -14
- package/dist/access-cli.js +40 -37
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +7 -7
- package/dist/access-http.js +20 -17
- package/dist/access-mcp.d.ts +7 -7
- package/dist/access-mcp.js +19 -16
- package/dist/access-operations.d.ts +7 -7
- package/dist/access-operations.js +18 -15
- package/dist/{access-service-Cte3ol0W.d.ts → access-service-COCzhgEL.d.ts} +397 -19
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +16 -13
- package/dist/access-surface-catalog.d.ts +7 -7
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +7 -6
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -5
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +8 -7
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-DN1PzThs.d.ts → catalog-DxCzhjE6.d.ts} +28 -54
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +9 -8
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-XJNBEDFE.js → chunk-3FAMU5TX.js} +31 -74
- package/dist/chunk-3FAMU5TX.js.map +1 -0
- package/dist/{chunk-PCZR32VL.js → chunk-3JJWNZTT.js} +2 -2
- package/dist/{chunk-YXLT4EMM.js → chunk-4463LUIE.js} +12 -2
- package/dist/chunk-4463LUIE.js.map +1 -0
- package/dist/{chunk-R5DB26G6.js → chunk-4SBW47WK.js} +9 -23
- package/dist/chunk-4SBW47WK.js.map +1 -0
- package/dist/{chunk-CCOXIDRM.js → chunk-5VXVXJH6.js} +149 -6
- package/dist/{chunk-CCOXIDRM.js.map → chunk-5VXVXJH6.js.map} +1 -1
- package/dist/{chunk-PQG4T5V3.js → chunk-64XXOQRW.js} +49 -45
- package/dist/chunk-64XXOQRW.js.map +1 -0
- package/dist/{chunk-YXIFA36P.js → chunk-6TAETM63.js} +2 -2
- package/dist/{chunk-6JDGADXK.js → chunk-6VVP6NK7.js} +2 -2
- package/dist/{chunk-FN2SM5SN.js → chunk-ABCGDW3A.js} +75 -12
- package/dist/chunk-ABCGDW3A.js.map +1 -0
- package/dist/{chunk-CHM274U6.js → chunk-AMNLZ6SF.js} +2 -2
- package/dist/{chunk-JX3YZVII.js → chunk-CZJ6QSKG.js} +3 -3
- package/dist/{chunk-GYVVQYA3.js → chunk-EOOVJK2U.js} +3 -3
- package/dist/{chunk-JKW5XSWC.js → chunk-EYJD6KIO.js} +2 -2
- package/dist/{chunk-XY4WJTEX.js → chunk-EZR35XHX.js} +2 -2
- package/dist/{chunk-UU6MVCJ6.js → chunk-FIOYURII.js} +32 -25
- package/dist/chunk-FIOYURII.js.map +1 -0
- package/dist/{chunk-2NWHLAXX.js → chunk-FVI5B7DE.js} +2 -2
- package/dist/{chunk-X74FJSW7.js → chunk-GFIARMA7.js} +16 -8
- package/dist/chunk-GFIARMA7.js.map +1 -0
- package/dist/{chunk-PONNZ54D.js → chunk-GY3SKOS4.js} +4 -4
- package/dist/{chunk-U33LWTQQ.js → chunk-HV57RHMD.js} +4 -4
- package/dist/{chunk-RC3CNIPK.js → chunk-IO5NQEGZ.js} +2 -2
- package/dist/{chunk-IKNQAGBV.js → chunk-IX3UQT4H.js} +1 -1
- package/dist/{chunk-IKNQAGBV.js.map → chunk-IX3UQT4H.js.map} +1 -1
- package/dist/{chunk-HDLC75NX.js → chunk-IX72AAMZ.js} +2 -2
- package/dist/{chunk-DR2JTSLZ.js → chunk-JMA4RYRN.js} +62 -163
- package/dist/chunk-JMA4RYRN.js.map +1 -0
- package/dist/{chunk-G5PKTQ5J.js → chunk-JTKFZMZ7.js} +2 -2
- package/dist/{chunk-YMTGXDN6.js → chunk-KC6TCAWV.js} +5 -5
- package/dist/{chunk-ROZJACKP.js → chunk-KKK7YTYN.js} +4 -1
- package/dist/chunk-KKK7YTYN.js.map +1 -0
- package/dist/{chunk-EC2AYKRX.js → chunk-L6W77GWW.js} +10 -24
- package/dist/chunk-L6W77GWW.js.map +1 -0
- package/dist/{chunk-ED35D32I.js → chunk-LQ4J7ELC.js} +2 -2
- package/dist/{chunk-YPR7DOPD.js → chunk-LTJAMRGI.js} +4 -4
- package/dist/{chunk-YPR7DOPD.js.map → chunk-LTJAMRGI.js.map} +1 -1
- package/dist/chunk-LUPVCGYK.js +63 -0
- package/dist/chunk-LUPVCGYK.js.map +1 -0
- package/dist/{chunk-RJ2THZ4H.js → chunk-MBUM2Y3L.js} +2 -2
- package/dist/{chunk-T5QAZIBO.js → chunk-MOXFPLD6.js} +3 -3
- package/dist/{chunk-O54DY26V.js → chunk-MXEWQKM7.js} +2 -2
- package/dist/{chunk-33L6XHU2.js → chunk-NUIJEGVD.js} +6 -6
- package/dist/{chunk-3E5WRQNQ.js → chunk-OXEAMU42.js} +529 -9
- package/dist/chunk-OXEAMU42.js.map +1 -0
- package/dist/{chunk-EOBJRBLC.js → chunk-QGJAGC2J.js} +2 -2
- package/dist/{chunk-SMIVW7XC.js → chunk-QIMFOCSH.js} +2 -2
- package/dist/{chunk-IJEZMWKA.js → chunk-SFOAQQDJ.js} +3 -3
- package/dist/{chunk-HRUULBBV.js → chunk-SHRRWOVY.js} +81 -4
- package/dist/chunk-SHRRWOVY.js.map +1 -0
- package/dist/{chunk-NINRTFSV.js → chunk-SINGJCUR.js} +5 -5
- package/dist/{chunk-ZPQVJEVQ.js → chunk-SK2CR6MW.js} +146 -2
- package/dist/chunk-SK2CR6MW.js.map +1 -0
- package/dist/{chunk-SEWF2O74.js → chunk-TGAHHCB6.js} +2 -2
- package/dist/{chunk-D75JXBV4.js → chunk-WN4GHSDH.js} +2 -2
- package/dist/{chunk-K4DWSPMW.js → chunk-WRGPE6AW.js} +2 -2
- package/dist/{chunk-GA5A6MJH.js → chunk-XGMCUY5P.js} +62 -116
- package/dist/chunk-XGMCUY5P.js.map +1 -0
- package/dist/{chunk-SDPDU2PM.js → chunk-YTMDF6S7.js} +2 -2
- package/dist/{chunk-ZDK2IW5F.js → chunk-Z7XEIAV4.js} +2 -2
- package/dist/{chunk-NHBEO3F3.js → chunk-ZCEI242W.js} +24 -24
- package/dist/{cli--yVN9yEV.d.ts → cli-BM4xQPp4.d.ts} +3 -3
- package/dist/cli.d.ts +7 -7
- package/dist/cli.js +35 -34
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +8 -7
- 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/config.js +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +8 -7
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -8
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +2 -2
- 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/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/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +8 -7
- package/dist/entity-schema.d.ts +1 -1
- package/dist/event-order-recall.js +2 -1
- package/dist/explicit-capture.d.ts +5 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/explicit-cue-recall.js +2 -1
- 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 +14 -1
- package/dist/extraction.js +5 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-BEXG5PQC.js → forget-6SOIPUMQ.js} +3 -3
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +123 -123
- package/dist/index.js +57 -56
- package/dist/index.js.map +1 -1
- 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/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +8 -7
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -7
- package/dist/maintenance/rebuild-memory-projection.js +9 -8
- package/dist/mcp-memory-inspector-app.d.ts +7 -7
- 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 +9 -8
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +14 -3
- package/dist/namespaces/storage.js +8 -7
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +14 -13
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +10 -9
- package/dist/{orchestrator-CJI4xdqV.d.ts → orchestrator-C9CDWAm6.d.ts} +4 -4
- package/dist/orchestrator.d.ts +5 -5
- package/dist/orchestrator.js +33 -31
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +36 -2
- package/dist/provenance.js +5 -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-explain-renderer.js +3 -3
- package/dist/recall-pipeline-stages.d.ts +15 -0
- package/dist/recall-pipeline-stages.js +3 -56
- package/dist/recall-pipeline-stages.js.map +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-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/response-guidance-recall.js +2 -1
- package/dist/resume-bundles.js +7 -5
- 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/schemas.d.ts +19 -0
- package/dist/schemas.js +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- 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-DJR8_DMQ.d.ts → semantic-SLAa_prH.d.ts} +1 -1
- package/dist/{semantic-consolidation-BtUfv-AL.d.ts → semantic-consolidation-DgFXyALl.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +9 -8
- package/dist/semantic-rule-promotion.js +8 -7
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +8 -7
- 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/signal.d.ts +1 -1
- package/dist/storage.d.ts +13 -1
- package/dist/storage.js +7 -6
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/summary-snapshot.js +2 -1
- package/dist/targeted-fact-recall.js +2 -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/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transcript.js +2 -2
- package/dist/{types-PuiPZ9iE.d.ts → types-MWKPZnM0.d.ts} +25 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/utils/serialize-mutations.js +1 -1
- package/dist/verified-recall.js +8 -7
- package/package.json +2 -2
- package/src/access-http.ts +162 -0
- package/src/access-service.ts +215 -0
- package/src/admin/admin-surfaces.test.ts +458 -0
- package/src/admin/admin-surfaces.ts +819 -0
- package/src/event-order-recall.test.ts +53 -0
- package/src/event-order-recall.ts +61 -37
- package/src/explicit-cue-recall.ts +21 -1
- package/src/extraction.ts +91 -6
- package/src/namespaces/catalog.test.ts +222 -14
- package/src/namespaces/catalog.ts +54 -187
- package/src/namespaces/storage.ts +87 -80
- package/src/orchestrator.ts +46 -5
- package/src/provenance-extraction.test.ts +838 -0
- package/src/provenance.ts +413 -0
- package/src/recall-pipeline-parity.test.ts +288 -0
- package/src/recall-pipeline-stages.test.ts +43 -0
- package/src/recall-pipeline-stages.ts +22 -0
- package/src/response-guidance-recall.ts +32 -36
- package/src/schemas.ts +7 -0
- package/src/storage.ts +23 -0
- package/src/summary-snapshot.test.ts +63 -1
- package/src/summary-snapshot.ts +61 -80
- package/src/targeted-fact-recall.ts +25 -32
- package/src/types.ts +24 -0
- package/src/utils/serialize-mutations.ts +10 -6
- package/dist/chunk-3E5WRQNQ.js.map +0 -1
- package/dist/chunk-DR2JTSLZ.js.map +0 -1
- package/dist/chunk-EC2AYKRX.js.map +0 -1
- package/dist/chunk-FN2SM5SN.js.map +0 -1
- package/dist/chunk-GA5A6MJH.js.map +0 -1
- package/dist/chunk-HRUULBBV.js.map +0 -1
- package/dist/chunk-PQG4T5V3.js.map +0 -1
- package/dist/chunk-R5DB26G6.js.map +0 -1
- package/dist/chunk-ROZJACKP.js.map +0 -1
- package/dist/chunk-UU6MVCJ6.js.map +0 -1
- package/dist/chunk-X74FJSW7.js.map +0 -1
- package/dist/chunk-XJNBEDFE.js.map +0 -1
- package/dist/chunk-YXLT4EMM.js.map +0 -1
- package/dist/chunk-ZPQVJEVQ.js.map +0 -1
- /package/dist/{chunk-PCZR32VL.js.map → chunk-3JJWNZTT.js.map} +0 -0
- /package/dist/{chunk-YXIFA36P.js.map → chunk-6TAETM63.js.map} +0 -0
- /package/dist/{chunk-6JDGADXK.js.map → chunk-6VVP6NK7.js.map} +0 -0
- /package/dist/{chunk-CHM274U6.js.map → chunk-AMNLZ6SF.js.map} +0 -0
- /package/dist/{chunk-JX3YZVII.js.map → chunk-CZJ6QSKG.js.map} +0 -0
- /package/dist/{chunk-GYVVQYA3.js.map → chunk-EOOVJK2U.js.map} +0 -0
- /package/dist/{chunk-JKW5XSWC.js.map → chunk-EYJD6KIO.js.map} +0 -0
- /package/dist/{chunk-XY4WJTEX.js.map → chunk-EZR35XHX.js.map} +0 -0
- /package/dist/{chunk-2NWHLAXX.js.map → chunk-FVI5B7DE.js.map} +0 -0
- /package/dist/{chunk-PONNZ54D.js.map → chunk-GY3SKOS4.js.map} +0 -0
- /package/dist/{chunk-U33LWTQQ.js.map → chunk-HV57RHMD.js.map} +0 -0
- /package/dist/{chunk-RC3CNIPK.js.map → chunk-IO5NQEGZ.js.map} +0 -0
- /package/dist/{chunk-HDLC75NX.js.map → chunk-IX72AAMZ.js.map} +0 -0
- /package/dist/{chunk-G5PKTQ5J.js.map → chunk-JTKFZMZ7.js.map} +0 -0
- /package/dist/{chunk-YMTGXDN6.js.map → chunk-KC6TCAWV.js.map} +0 -0
- /package/dist/{chunk-ED35D32I.js.map → chunk-LQ4J7ELC.js.map} +0 -0
- /package/dist/{chunk-RJ2THZ4H.js.map → chunk-MBUM2Y3L.js.map} +0 -0
- /package/dist/{chunk-T5QAZIBO.js.map → chunk-MOXFPLD6.js.map} +0 -0
- /package/dist/{chunk-O54DY26V.js.map → chunk-MXEWQKM7.js.map} +0 -0
- /package/dist/{chunk-33L6XHU2.js.map → chunk-NUIJEGVD.js.map} +0 -0
- /package/dist/{chunk-EOBJRBLC.js.map → chunk-QGJAGC2J.js.map} +0 -0
- /package/dist/{chunk-SMIVW7XC.js.map → chunk-QIMFOCSH.js.map} +0 -0
- /package/dist/{chunk-IJEZMWKA.js.map → chunk-SFOAQQDJ.js.map} +0 -0
- /package/dist/{chunk-NINRTFSV.js.map → chunk-SINGJCUR.js.map} +0 -0
- /package/dist/{chunk-SEWF2O74.js.map → chunk-TGAHHCB6.js.map} +0 -0
- /package/dist/{chunk-D75JXBV4.js.map → chunk-WN4GHSDH.js.map} +0 -0
- /package/dist/{chunk-K4DWSPMW.js.map → chunk-WRGPE6AW.js.map} +0 -0
- /package/dist/{chunk-SDPDU2PM.js.map → chunk-YTMDF6S7.js.map} +0 -0
- /package/dist/{chunk-ZDK2IW5F.js.map → chunk-Z7XEIAV4.js.map} +0 -0
- /package/dist/{chunk-NHBEO3F3.js.map → chunk-ZCEI242W.js.map} +0 -0
- /package/dist/{forget-BEXG5PQC.js.map → forget-6SOIPUMQ.js.map} +0 -0
|
@@ -216,6 +216,59 @@ test("event order recall keeps summary within the section budget", async () => {
|
|
|
216
216
|
assert.match(recalled, /^## Chronological event evidence/);
|
|
217
217
|
});
|
|
218
218
|
|
|
219
|
+
test("event order recall budgets the outline BEFORE evidence so the total never exceeds maxChars (#1539 fix)", async () => {
|
|
220
|
+
// Issue #1539 step 4 (the ONE declared behavior change): pre-fix, event-order
|
|
221
|
+
// built the evidence pack at the FULL budget, then appended the chronology
|
|
222
|
+
// outline + summary, then clipped — which could silently exceed maxChars
|
|
223
|
+
// (the outline consumed space the evidence pack had already filled). Post-fix,
|
|
224
|
+
// the summary (incl. outline) is computed FIRST and its length subtracted from
|
|
225
|
+
// the evidence budget, so evidence + summary = budget exactly.
|
|
226
|
+
//
|
|
227
|
+
// This test uses a fixture rich enough to produce a non-empty chronology
|
|
228
|
+
// outline, then asserts the total fits the budget with the outline present.
|
|
229
|
+
const sessionId = "event-order-outline-budget-fix";
|
|
230
|
+
const engine = new FakeEventOrderEngine(sessionId, [
|
|
231
|
+
{
|
|
232
|
+
turn_index: 10,
|
|
233
|
+
role: "user",
|
|
234
|
+
content:
|
|
235
|
+
"I first brought up passive voice reduction and checklist in my writing process.",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
turn_index: 30,
|
|
239
|
+
role: "user",
|
|
240
|
+
content:
|
|
241
|
+
"Later I discussed webinar planning and promotion for the workshop series.",
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
turn_index: 50,
|
|
245
|
+
role: "user",
|
|
246
|
+
content:
|
|
247
|
+
"After that I focused on engagement and incentives discussion with the team.",
|
|
248
|
+
},
|
|
249
|
+
]);
|
|
250
|
+
|
|
251
|
+
const maxChars = 600;
|
|
252
|
+
const recalled = await buildEventOrderRecallSection({
|
|
253
|
+
engine,
|
|
254
|
+
sessionId,
|
|
255
|
+
query:
|
|
256
|
+
"Can you walk me through the order in which I brought up different aspects of my personal and professional progress throughout our conversations, in order? Mention ONLY and ONLY three items.",
|
|
257
|
+
maxChars,
|
|
258
|
+
maxScanWindowTurns: 4,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
assert.ok(recalled.length > 0);
|
|
262
|
+
// The fix guarantees the total (evidence + summary + outline) fits the budget.
|
|
263
|
+
assert.ok(
|
|
264
|
+
recalled.length <= maxChars,
|
|
265
|
+
`expected recalled section length ${recalled.length} to fit ${maxChars}`,
|
|
266
|
+
);
|
|
267
|
+
// The outline must be present — the fix guarantees it is budgeted for, not
|
|
268
|
+
// clipped away by evidence that consumed the full budget.
|
|
269
|
+
assert.match(recalled, /Chronology outline:/);
|
|
270
|
+
});
|
|
271
|
+
|
|
219
272
|
test("event order recall returns relevant user turns in chronological order", async () => {
|
|
220
273
|
const sessionId = "event-order-core";
|
|
221
274
|
const engine = new FakeEventOrderEngine(sessionId, [
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { buildEvidencePack, type EvidencePackItem } from "./evidence-pack.js";
|
|
2
2
|
import type { ExplicitCueRecallEngine } from "./explicit-cue-recall.js";
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
unifiedDedupeAndRank,
|
|
6
|
+
type RankedEvidenceItem,
|
|
7
|
+
} from "./recall-pipeline-stages.js";
|
|
8
|
+
|
|
4
9
|
export interface EventOrderRecallOptions {
|
|
5
10
|
engine: ExplicitCueRecallEngine | null | undefined;
|
|
6
11
|
// event-order reads a SINGLE LCM session key. Unlike the relevance-ranked
|
|
@@ -18,10 +23,6 @@ export interface EventOrderRecallOptions {
|
|
|
18
23
|
title?: string;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
interface RankedEventItem extends EvidencePackItem {
|
|
22
|
-
rank: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
26
|
const DEFAULT_SCAN_WINDOW_TURNS = 12;
|
|
26
27
|
const DEFAULT_SCAN_WINDOW_TOKENS = 24_000;
|
|
27
28
|
const DEFAULT_MAX_ITEMS = 24;
|
|
@@ -67,15 +68,14 @@ export async function buildEventOrderRecallSection(
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
const title = options.title ?? "Chronological event evidence";
|
|
70
|
-
const evidence = buildEvidencePack(ranked, {
|
|
71
|
-
title,
|
|
72
|
-
maxChars: budget,
|
|
73
|
-
maxItemChars: options.maxItemChars,
|
|
74
|
-
});
|
|
75
|
-
if (!evidence) {
|
|
76
|
-
return "";
|
|
77
|
-
}
|
|
78
71
|
|
|
72
|
+
// Issue #1539 step 4 (the ONE declared behavior change): budget the outline
|
|
73
|
+
// BEFORE building evidence, matching guidance/targeted-fact. Previously
|
|
74
|
+
// event-order built the evidence pack at the FULL budget, then appended the
|
|
75
|
+
// chronology outline, then clipped the total — which could silently exceed
|
|
76
|
+
// maxChars (the outline consumed space the evidence pack had already filled).
|
|
77
|
+
// Now the summary (incl. outline) is computed first and its length subtracted
|
|
78
|
+
// from the evidence budget, so evidence + summary = budget exactly.
|
|
79
79
|
const requested = parseRequestedItemCount(options.query);
|
|
80
80
|
const outlineSource = requested
|
|
81
81
|
? rankEventOrderItemsForOutline(items, options.query).slice(0, maxItems)
|
|
@@ -87,8 +87,20 @@ export async function buildEventOrderRecallSection(
|
|
|
87
87
|
outline,
|
|
88
88
|
"Use these turns to preserve the order in which the user raised the topics.",
|
|
89
89
|
].filter(Boolean).join(" ");
|
|
90
|
+
const summaryInsert = `\n\n${summary}`;
|
|
91
|
+
const evidenceBudget = Math.max(0, budget - summaryInsert.length);
|
|
92
|
+
const evidence = buildEvidencePack(ranked, {
|
|
93
|
+
title,
|
|
94
|
+
maxChars: evidenceBudget,
|
|
95
|
+
maxItemChars: options.maxItemChars,
|
|
96
|
+
});
|
|
97
|
+
if (!evidence) {
|
|
98
|
+
// If no evidence fit the residual budget, still emit the summary clipped to
|
|
99
|
+
// budget (matches targeted-fact's empty-evidence-with-summary fallback).
|
|
100
|
+
return clipSectionToBudget(`## ${title}${summaryInsert}`, budget);
|
|
101
|
+
}
|
|
90
102
|
return clipSectionToBudget(
|
|
91
|
-
evidence.replace(`## ${title}`, `## ${title}
|
|
103
|
+
evidence.replace(`## ${title}`, `## ${title}${summaryInsert}`),
|
|
92
104
|
budget,
|
|
93
105
|
);
|
|
94
106
|
}
|
|
@@ -148,23 +160,28 @@ function rankAndSelectEventOrderItems(
|
|
|
148
160
|
items: EvidencePackItem[],
|
|
149
161
|
options: EventOrderRecallOptions,
|
|
150
162
|
maxItems: number,
|
|
151
|
-
):
|
|
163
|
+
): RankedEvidenceItem[] {
|
|
152
164
|
const requested = parseRequestedItemCount(options.query);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
// Issue #1539 PR6: rank + threshold-filter + sort now route through the
|
|
166
|
+
// unified spine. Event-order's three declared divergences are named config
|
|
167
|
+
// fields: rankThreshold:6 (was an undocumented inline .filter), ASC sort
|
|
168
|
+
// direction (was a byte-identical comparator copy with flipped direction),
|
|
169
|
+
// and dedupByContent:false (event-order keeps distinct turns — turn_index is
|
|
170
|
+
// local to each session_id, so chronology must not collapse same-body turns).
|
|
171
|
+
// The spine's id-dedup is a no-op here: event-order reads a single session
|
|
172
|
+
// with unique per-turn ids (no cross-key merge, per the #1505 opt-out).
|
|
173
|
+
// Content is already cue-appended during collection; the spine scores on the
|
|
174
|
+
// (already-transformed) item.content, matching the prior inline behavior.
|
|
175
|
+
const rankedByScore = unifiedDedupeAndRank(items, {
|
|
176
|
+
query: options.query,
|
|
177
|
+
intents: [],
|
|
178
|
+
scoreEvidence: (item, q) => scoreEventOrderItem(item, q),
|
|
179
|
+
rankThreshold: 6,
|
|
180
|
+
dedupByContent: false,
|
|
181
|
+
turnIndexSortDirection: "asc",
|
|
182
|
+
});
|
|
166
183
|
|
|
167
|
-
const selectedById = new Map<string,
|
|
184
|
+
const selectedById = new Map<string, RankedEvidenceItem>();
|
|
168
185
|
if (requested) {
|
|
169
186
|
const queryTerms = extractEventOrderTerms(options.query);
|
|
170
187
|
const tailReserve = Math.min(
|
|
@@ -254,13 +271,20 @@ function rankAndSelectEventOrderItems(
|
|
|
254
271
|
function rankEventOrderItemsForOutline(
|
|
255
272
|
items: readonly EvidencePackItem[],
|
|
256
273
|
query: string,
|
|
257
|
-
):
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
274
|
+
): RankedEvidenceItem[] {
|
|
275
|
+
// Issue #1539 PR6: the outline source uses the same declared config as the
|
|
276
|
+
// main rank pass (rankThreshold:6, dedupByContent:false) but preserves
|
|
277
|
+
// collection order via preserveInsertionOrder — the outline renders turns in
|
|
278
|
+
// the order they were collected (chronological by session scan), not in
|
|
279
|
+
// rank-sorted order.
|
|
280
|
+
return unifiedDedupeAndRank(items, {
|
|
281
|
+
query,
|
|
282
|
+
intents: [],
|
|
283
|
+
scoreEvidence: (item, q) => scoreEventOrderItem(item, q),
|
|
284
|
+
rankThreshold: 6,
|
|
285
|
+
dedupByContent: false,
|
|
286
|
+
preserveInsertionOrder: true,
|
|
287
|
+
});
|
|
264
288
|
}
|
|
265
289
|
|
|
266
290
|
function eventItemSelectionKey(item: EvidencePackItem): string {
|
|
@@ -527,7 +551,7 @@ function appendChronologicalCues(content: string, query: string): string {
|
|
|
527
551
|
}
|
|
528
552
|
|
|
529
553
|
function buildChronologyOutline(
|
|
530
|
-
items: readonly
|
|
554
|
+
items: readonly RankedEvidenceItem[],
|
|
531
555
|
query: string,
|
|
532
556
|
requested?: number,
|
|
533
557
|
): string {
|
|
@@ -584,7 +608,7 @@ function buildChronologyOutline(
|
|
|
584
608
|
}
|
|
585
609
|
|
|
586
610
|
function collectChronologyOutlineCandidates(
|
|
587
|
-
items: readonly
|
|
611
|
+
items: readonly RankedEvidenceItem[],
|
|
588
612
|
query: string,
|
|
589
613
|
): Array<{ turn: number; label: string; priority: number }> {
|
|
590
614
|
const terms = extractEventOrderTerms(query);
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
gatherAcrossReadSessions,
|
|
4
4
|
resolveLcmReadSessionIds,
|
|
5
5
|
} from "./lcm-fallback-read.js";
|
|
6
|
+
import { unifiedDedupeAndRank } from "./recall-pipeline-stages.js";
|
|
6
7
|
|
|
7
8
|
export interface ExplicitCueRecallEngine {
|
|
8
9
|
expandContext(
|
|
@@ -410,7 +411,26 @@ export async function buildExplicitCueRecallSection(
|
|
|
410
411
|
includeContentLexicalCues: options.includeContentLexicalCues,
|
|
411
412
|
includeStructuredPlanCues: options.includeStructuredPlanCues,
|
|
412
413
|
});
|
|
413
|
-
|
|
414
|
+
// Issue #1539 PR5: route through the unified spine to declare explicit-cue's
|
|
415
|
+
// policy explicitly. The call is behavior-idempotent — items are already
|
|
416
|
+
// deduped by `seenTurns` during collection (so the spine's id-dedup matches
|
|
417
|
+
// exactly), the constant scorer assigns rank=0 which `buildEvidencePack`
|
|
418
|
+
// ignores, and `preserveInsertionOrder` skips the sort so the deliberate
|
|
419
|
+
// value ordering (turn references -> content cues -> lexical cues, by evidence
|
|
420
|
+
// type then read-key priority) is preserved byte-for-byte.
|
|
421
|
+
//
|
|
422
|
+
// The value is the DECLARED config: a fifth recall pipeline would be a config
|
|
423
|
+
// file, and this config documents explicit-cue's opt-outs (no scoring, id-only
|
|
424
|
+
// dedup, insertion-order preservation) as named fields instead of embedded
|
|
425
|
+
// code. See recall-pipeline-stages.ts for the spine contract.
|
|
426
|
+
const rankedEvidenceItems = unifiedDedupeAndRank(evidenceItems, {
|
|
427
|
+
query: "",
|
|
428
|
+
intents: [],
|
|
429
|
+
scoreEvidence: () => 0,
|
|
430
|
+
dedupByContent: false,
|
|
431
|
+
preserveInsertionOrder: true,
|
|
432
|
+
});
|
|
433
|
+
return buildEvidencePack(rankedEvidenceItems, {
|
|
414
434
|
title: "Explicit Cue Evidence",
|
|
415
435
|
query: evidenceFocusQuery,
|
|
416
436
|
maxChars,
|
package/src/extraction.ts
CHANGED
|
@@ -37,6 +37,7 @@ import { ProfilingCollector } from "./profiling.js";
|
|
|
37
37
|
import { normalizeProcedureSteps } from "./procedural/procedure-types.js";
|
|
38
38
|
import { normalizeReasoningTrace } from "./reasoning-trace-types.js";
|
|
39
39
|
import { looksLikeMechanicalTelemetryTranscript } from "./telemetry-transcript.js";
|
|
40
|
+
import { buildFactProvenance, type ProvenanceTurnInput } from "./provenance.js";
|
|
40
41
|
|
|
41
42
|
type ExtractionQuestion = ExtractionResult["questions"][number];
|
|
42
43
|
type ExtractedFactResult = ExtractionResult["facts"][number];
|
|
@@ -269,6 +270,15 @@ export class ExtractionEngine {
|
|
|
269
270
|
: null;
|
|
270
271
|
return candidate ? normalizeReasoningTrace(candidate) ?? undefined : undefined;
|
|
271
272
|
})(),
|
|
273
|
+
// Issue #1575 PR 2: the LLM provides a verbatim supporting quote
|
|
274
|
+
// per fact. Optional/nullable per repo gotcha 6 (OpenAI Responses
|
|
275
|
+
// API emits null for absent optional fields). The post-parse
|
|
276
|
+
// validator (buildFactProvenance) locates this quote in the
|
|
277
|
+
// buffered turns and builds verified ProvenanceSource[] entries.
|
|
278
|
+
quote:
|
|
279
|
+
typeof f?.quote === "string" && f.quote.trim().length > 0
|
|
280
|
+
? f.quote
|
|
281
|
+
: undefined,
|
|
272
282
|
}))
|
|
273
283
|
.filter((f: any) => f.content.length > 0)
|
|
274
284
|
: [];
|
|
@@ -736,7 +746,10 @@ export class ExtractionEngine {
|
|
|
736
746
|
`Return at most ${maxAdditional} additional high-confidence memory candidates that were omitted from the base extraction.`,
|
|
737
747
|
"Only include information directly supported by the conversation. Do not speculate. Do not repeat the base extraction.",
|
|
738
748
|
"Return only valid JSON with this shape:",
|
|
739
|
-
'{"facts":[{"category":"fact","content":"...","confidence":0.0,"tags":["..."],"entityRef":"optional","promptedByQuestion":"optional"}],"profileUpdates":["..."],"entities":[{"name":"...","type":"person","facts":["..."],"structuredSections":[{"key":"beliefs","title":"Beliefs","facts":["..."]}],"promptedByQuestion":"optional"}],"relationships":[{"source":"...","target":"...","label":"...","promptedByQuestion":"optional"}]}',
|
|
749
|
+
'{"facts":[{"category":"fact","content":"...","confidence":0.0,"tags":["..."],"entityRef":"optional","promptedByQuestion":"optional","quote":"optional verbatim span from a single turn"}],"profileUpdates":["..."],"entities":[{"name":"...","type":"person","facts":["..."],"structuredSections":[{"key":"beliefs","title":"Beliefs","facts":["..."]}],"promptedByQuestion":"optional"}],"relationships":[{"source":"...","target":"...","label":"...","promptedByQuestion":"optional"}]}',
|
|
750
|
+
this.config.provenance?.enabled
|
|
751
|
+
? '- Source quotes: For each fact, include a "quote" field with the EXACT verbatim words from the conversation that support the fact (a contiguous span from a single turn, not a paraphrase). Cap at ~300 chars.'
|
|
752
|
+
: "",
|
|
740
753
|
"",
|
|
741
754
|
"Base extracted facts (do not repeat):",
|
|
742
755
|
factsPreview || "(none)",
|
|
@@ -963,6 +976,73 @@ export class ExtractionEngine {
|
|
|
963
976
|
return null;
|
|
964
977
|
}
|
|
965
978
|
|
|
979
|
+
/**
|
|
980
|
+
* Attach claim-level provenance spans to each fact in the extraction result
|
|
981
|
+
* (issue #1575 PR 2). Runs once at write time, after sanitize + proactive
|
|
982
|
+
* pass so ALL facts (base + proactive additions) get verified spans before
|
|
983
|
+
* the result is returned for persistence.
|
|
984
|
+
*
|
|
985
|
+
* The validator locates each fact's LLM-provided `quote` in the buffered
|
|
986
|
+
* turns and builds a `ProvenanceSource[]` with verified offsets. Never
|
|
987
|
+
* throws, never drops a fact — an unverifiable span is a tagged state, not
|
|
988
|
+
* a silent failure (rule 34 spirit). When `provenance.enabled` is false,
|
|
989
|
+
* this is a no-op (byte-identical to pre-feature behavior, rule 39).
|
|
990
|
+
*/
|
|
991
|
+
private attachProvenanceToResult(
|
|
992
|
+
result: ExtractionResult,
|
|
993
|
+
turns: ReadonlyArray<{
|
|
994
|
+
content: string;
|
|
995
|
+
sessionKey?: string;
|
|
996
|
+
logicalSessionKey?: string;
|
|
997
|
+
timestamp: string;
|
|
998
|
+
turnFingerprint?: string;
|
|
999
|
+
}>,
|
|
1000
|
+
): ExtractionResult {
|
|
1001
|
+
// Even when provenance is disabled, strip the transient LLM-provided
|
|
1002
|
+
// `quote` field so it does not leak through the persist pipeline (the
|
|
1003
|
+
// enabled path strips it after validation; the disabled path must match).
|
|
1004
|
+
// quote is never persisted to frontmatter, but carrying it risks it
|
|
1005
|
+
// surfacing in content-hash dedup or downstream in-memory consumers
|
|
1006
|
+
// (cursor thread dHiY).
|
|
1007
|
+
if (!this.config.provenance?.enabled) {
|
|
1008
|
+
if (result.facts.length === 0) return result;
|
|
1009
|
+
return {
|
|
1010
|
+
...result,
|
|
1011
|
+
facts: result.facts.map((fact) => {
|
|
1012
|
+
if (fact.quote === undefined) return fact;
|
|
1013
|
+
const { quote: _stripped, ...rest } = fact;
|
|
1014
|
+
return rest;
|
|
1015
|
+
}),
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
if (result.facts.length === 0) return result;
|
|
1019
|
+
const provenanceTurns: ProvenanceTurnInput[] = turns.map((t) => ({
|
|
1020
|
+
content: t.content,
|
|
1021
|
+
sessionKey: t.sessionKey,
|
|
1022
|
+
logicalSessionKey: t.logicalSessionKey,
|
|
1023
|
+
timestamp: t.timestamp,
|
|
1024
|
+
turnId: t.turnFingerprint,
|
|
1025
|
+
}));
|
|
1026
|
+
const facts = result.facts.map((fact) => {
|
|
1027
|
+
const built = buildFactProvenance(
|
|
1028
|
+
fact.quote,
|
|
1029
|
+
provenanceTurns,
|
|
1030
|
+
this.config.provenance,
|
|
1031
|
+
);
|
|
1032
|
+
// Strip the transient `quote` field — it has served its purpose (the
|
|
1033
|
+
// validator consumed it) and must NOT leak into the persisted ExtractedFact
|
|
1034
|
+
// shape or the content-hash dedup key (rule 23 / checklist §13).
|
|
1035
|
+
const { quote: _stripped, ...factWithoutQuote } = fact;
|
|
1036
|
+
return {
|
|
1037
|
+
...factWithoutQuote,
|
|
1038
|
+
...(built.sources && built.sources.length > 0 ? { sources: built.sources } : {}),
|
|
1039
|
+
...(built.provenance !== "none" ? { provenance: built.provenance } : {}),
|
|
1040
|
+
...(built.requireSpansPending ? { requireSpansPending: true } : {}),
|
|
1041
|
+
};
|
|
1042
|
+
});
|
|
1043
|
+
return { ...result, facts };
|
|
1044
|
+
}
|
|
1045
|
+
|
|
966
1046
|
async extract(turns: BufferTurn[], existingEntities?: string[]): Promise<ExtractionResult> {
|
|
967
1047
|
|
|
968
1048
|
// Guard: skip if buffer is empty or all turns are whitespace-only
|
|
@@ -1037,7 +1117,8 @@ export class ExtractionEngine {
|
|
|
1037
1117
|
this.emit({ kind: "llm_end", traceId, model: this.config.localLlmModel, operation: "extraction", durationMs });
|
|
1038
1118
|
log.debug(`extraction: used local LLM — ${localResult.facts.length} facts, ${localResult.entities.length} entities`);
|
|
1039
1119
|
const sanitized = this.sanitizeExtractionResult(localResult, messageTimestamp);
|
|
1040
|
-
|
|
1120
|
+
const finalResult = await this.applyProactiveQuestionPass(conversation, sanitized);
|
|
1121
|
+
return this.attachProvenanceToResult(finalResult, boundedTurns);
|
|
1041
1122
|
}
|
|
1042
1123
|
// Local failed, fall back if allowed
|
|
1043
1124
|
if (!this.config.localLlmFallback) {
|
|
@@ -1080,7 +1161,8 @@ export class ExtractionEngine {
|
|
|
1080
1161
|
this.emit({ kind: "llm_end", traceId, model: this.config.model, operation: "extraction", durationMs });
|
|
1081
1162
|
log.debug(`extraction: used direct client (${this.config.model}) — ${directResult.facts.length} facts, ${directResult.entities.length} entities`);
|
|
1082
1163
|
const sanitized = this.sanitizeExtractionResult(directResult, messageTimestamp);
|
|
1083
|
-
|
|
1164
|
+
const finalResult = await this.applyProactiveQuestionPass(conversation, sanitized);
|
|
1165
|
+
return this.attachProvenanceToResult(finalResult, boundedTurns);
|
|
1084
1166
|
}
|
|
1085
1167
|
// Emit error event so Opik sees the direct client failure before fallback.
|
|
1086
1168
|
// Wrapped in try/catch so a subscriber error doesn't break the fallback path.
|
|
@@ -1180,7 +1262,8 @@ export class ExtractionEngine {
|
|
|
1180
1262
|
questions: result.questions ?? [],
|
|
1181
1263
|
identityReflection: result.identityReflection ?? undefined,
|
|
1182
1264
|
} as ExtractionResult, messageTimestamp);
|
|
1183
|
-
|
|
1265
|
+
const finalResult = await this.applyProactiveQuestionPass(conversation, sanitized);
|
|
1266
|
+
return this.attachProvenanceToResult(finalResult, boundedTurns);
|
|
1184
1267
|
}
|
|
1185
1268
|
|
|
1186
1269
|
this.emit({
|
|
@@ -1291,7 +1374,8 @@ These are durable insights - capture them:
|
|
|
1291
1374
|
=== Rules ===
|
|
1292
1375
|
- Extract only NEW information worth remembering across sessions
|
|
1293
1376
|
- Skip transient details (file paths, current errors, temporary states, agent actions)
|
|
1294
|
-
- Confidence: Explicit (0.95-1.0), Implied (0.70-0.94), Inferred (0.40-0.69), Speculative (0.00-0.39)
|
|
1377
|
+
- Confidence: Explicit (0.95-1.0), Implied (0.70-0.94), Inferred (0.40-0.69), Speculative (0.00-0.39)${this.config.provenance?.enabled ? `
|
|
1378
|
+
- Source quotes: For each fact, include a "quote" field with the EXACT verbatim words from the conversation that support the fact (copy a contiguous span from a single turn, not a paraphrase). Cap at ~300 chars.` : ""}
|
|
1295
1379
|
- Corrections get highest confidence (0.95+)
|
|
1296
1380
|
- Each fact should be standalone and self-contained
|
|
1297
1381
|
- Lines labelled [context user] or [context assistant] are reference context only. Use them to resolve pronouns and adjacent question/answer pairs, but do not extract a memory stated only in context lines unless a normal [user] or [assistant] line confirms or completes it.
|
|
@@ -1549,7 +1633,8 @@ Rules:
|
|
|
1549
1633
|
* Explicit (0.95-1.0): Direct user statements — "I prefer X", "my name is Y"
|
|
1550
1634
|
* Implied (0.70-0.94): Strong contextual inference — user consistently does X, clear from conversation flow
|
|
1551
1635
|
* Inferred (0.40-0.69): Pattern recognition — reasonable guess from limited evidence
|
|
1552
|
-
* Speculative (0.00-0.39): Tentative hypothesis — weak signal, needs future confirmation. Speculative memories auto-expire after 30 days if not confirmed.
|
|
1636
|
+
* Speculative (0.00-0.39): Tentative hypothesis — weak signal, needs future confirmation. Speculative memories auto-expire after 30 days if not confirmed.${this.config.provenance?.enabled ? `
|
|
1637
|
+
- Source quotes: For each fact, include a "quote" field containing the EXACT verbatim words from the conversation that support the fact. Copy a contiguous span from a single speaker turn (not a paraphrase, not a summary). Cap at ~300 characters. This grounds every memory in the literal utterance that created it.` : ""}
|
|
1553
1638
|
- For commitments: include any deadline or timeframe mentioned${this.config.extractionScopeClassificationEnabled ? `
|
|
1554
1639
|
|
|
1555
1640
|
Scope classification:
|