@remnic/core 9.3.726 → 9.3.728
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 +5 -5
- package/dist/access-boundary.js +22 -22
- package/dist/access-cli.js +45 -45
- package/dist/access-http.d.ts +20 -5
- package/dist/access-http.js +27 -27
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +26 -26
- package/dist/access-operations-batch.js +23 -23
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +25 -25
- package/dist/access-schema.d.ts +4 -4
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-B2PlPtxh.d.ts → access-service-Bgpjxo4f.d.ts} +36 -4
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +21 -21
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +7 -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 +44 -2
- package/dist/capabilities.js +5 -3
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-CzUb-GyD.d.ts → catalog-bMczlO2G.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 +8 -8
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-BIA7ELIB.js → chunk-36SEDFAU.js} +3 -3
- package/dist/{chunk-UQSVUEN2.js → chunk-37436GML.js} +2 -2
- package/dist/{chunk-DVRHLN2O.js → chunk-3RCBIOOJ.js} +18 -2
- package/dist/{chunk-DVRHLN2O.js.map → chunk-3RCBIOOJ.js.map} +1 -1
- package/dist/{chunk-RRHHQYJS.js → chunk-3TSTGI6F.js} +2 -2
- package/dist/{chunk-5OOA7SGX.js → chunk-4ESAR77N.js} +2 -2
- package/dist/{chunk-FO3HO52S.js → chunk-4H4F3BFL.js} +2 -2
- package/dist/{chunk-BEUCACTV.js → chunk-4NOI577P.js} +2 -2
- package/dist/{chunk-BBIE7W52.js → chunk-4NR2PDZ5.js} +2 -2
- package/dist/{chunk-WGTWGDR5.js → chunk-76NHR6ZL.js} +5 -5
- package/dist/{chunk-PKMQK2WY.js → chunk-773DPI6T.js} +4 -4
- package/dist/{chunk-MQVKHFIU.js → chunk-7RLCCNHU.js} +8 -8
- package/dist/{chunk-XGTBNVIU.js → chunk-AAD2ZS6P.js} +11 -1
- package/dist/chunk-AAD2ZS6P.js.map +1 -0
- package/dist/{chunk-EZNDNMRH.js → chunk-AQLOP5F4.js} +2 -2
- package/dist/{chunk-UNNDFYUX.js → chunk-ARV3AUOM.js} +5 -5
- package/dist/{chunk-NPL7VDM6.js → chunk-ASKXIAHD.js} +2 -2
- package/dist/{chunk-TQQH2FTX.js → chunk-BQCHEV7O.js} +106 -15
- package/dist/{chunk-TQQH2FTX.js.map → chunk-BQCHEV7O.js.map} +1 -1
- package/dist/{chunk-ZA2S2VLL.js → chunk-C2PG7IEH.js} +5 -2
- package/dist/chunk-C2PG7IEH.js.map +1 -0
- package/dist/{chunk-K4ZNARDO.js → chunk-CBWI22JN.js} +2 -2
- package/dist/{chunk-ZOHMPFOB.js → chunk-CKFLLAIS.js} +3 -3
- package/dist/{chunk-JPUT5NGH.js → chunk-DMQWV6SQ.js} +2 -2
- package/dist/{chunk-F3XZN24Z.js → chunk-DRUDC2UX.js} +2 -2
- package/dist/{chunk-KJR66XOM.js → chunk-EY6MDMHK.js} +2 -2
- package/dist/{chunk-3TUT4PWB.js → chunk-FVZ2ISIX.js} +2 -2
- package/dist/{chunk-C4X4QGIO.js → chunk-G6NKALRN.js} +5 -2
- package/dist/chunk-G6NKALRN.js.map +1 -0
- package/dist/{chunk-6SQQOJ4U.js → chunk-GKRLPHPU.js} +2 -2
- package/dist/{chunk-PLG6JHQS.js → chunk-H5BWGCRZ.js} +43 -42
- package/dist/chunk-H5BWGCRZ.js.map +1 -0
- package/dist/{chunk-2NBP25BG.js → chunk-HGNOCPZX.js} +171 -79
- package/dist/chunk-HGNOCPZX.js.map +1 -0
- package/dist/{chunk-5NWYQUQC.js → chunk-HOHVIVDR.js} +2 -2
- package/dist/{chunk-DCKNMLEQ.js → chunk-I5REUWLH.js} +11 -5
- package/dist/chunk-I5REUWLH.js.map +1 -0
- package/dist/{chunk-6WAJQKBS.js → chunk-JYLFZWUX.js} +2 -2
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-UKTDXTWX.js → chunk-M4AYVEWS.js} +7 -7
- package/dist/{chunk-YTZ3VGC7.js → chunk-M4V2JVSZ.js} +2 -2
- package/dist/{chunk-TA3Y6GEX.js → chunk-MLKWJOAJ.js} +2 -2
- package/dist/{chunk-DQXPJ6HD.js → chunk-O6YH5F47.js} +4 -4
- package/dist/{chunk-7AG54AF3.js → chunk-PUR2CKX2.js} +1 -1
- package/dist/chunk-PUR2CKX2.js.map +1 -0
- package/dist/{chunk-OAHOL3ZC.js → chunk-QNEUZIAH.js} +152 -62
- package/dist/chunk-QNEUZIAH.js.map +1 -0
- package/dist/{chunk-Q6D75LVH.js → chunk-UM5AWJNQ.js} +79 -17
- package/dist/chunk-UM5AWJNQ.js.map +1 -0
- package/dist/{chunk-53EEQYE5.js → chunk-UTHQPSRC.js} +8 -8
- package/dist/{chunk-BB57OZWC.js → chunk-UVPL565C.js} +2 -2
- package/dist/{chunk-6AFVIOVZ.js → chunk-V4GNSDFH.js} +2 -2
- package/dist/{chunk-EHISUJFN.js → chunk-WAS3NV46.js} +6 -3
- package/dist/chunk-WAS3NV46.js.map +1 -0
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-V7CMKMHM.js → chunk-Y4YD5TYW.js} +3 -3
- package/dist/{chunk-7NS7AWMZ.js → chunk-YGIQORJ3.js} +3 -3
- package/dist/{chunk-MDBZTH7N.js → chunk-YKBHOBJK.js} +44 -10
- package/dist/chunk-YKBHOBJK.js.map +1 -0
- package/dist/{chunk-3MS3QVX6.js → chunk-YOLZS7NY.js} +2 -2
- package/dist/{chunk-6OIDDKAA.js → chunk-YTU7WKYN.js} +35 -9
- package/dist/chunk-YTU7WKYN.js.map +1 -0
- package/dist/{cli-IOlDHSBT.d.ts → cli-BLME420h.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +49 -49
- package/dist/compat/codex-cli-fallback.d.ts +1 -0
- package/dist/compat/codex-cli-fallback.js +22 -0
- package/dist/compat/codex-cli-fallback.js.map +1 -0
- package/dist/compat/codex-thread-key.d.ts +1 -0
- package/dist/compat/codex-thread-key.js +18 -0
- package/dist/compat/codex-thread-key.js.map +1 -0
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +7 -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 +3 -3
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +7 -7
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +7 -7
- 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/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/embedding-fallback.js +2 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +7 -7
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-faithfulness.js +2 -2
- 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 +3 -2
- package/dist/faithfulness-config.d.ts +1 -0
- package/dist/faithfulness-config.js +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-PG5HBC3K.js → first-start-migration-22LPFHD5.js} +6 -2
- package/dist/first-start-migration-22LPFHD5.js.map +1 -0
- 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 +9 -9
- package/dist/index.js +64 -64
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +7 -7
- 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-model-endpoint.d.ts +9 -4
- package/dist/local-model-endpoint.js +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +7 -7
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
- package/dist/maintenance/rebuild-memory-projection.js +8 -8
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- 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 +14 -13
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -5
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +7 -7
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +20 -20
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +9 -9
- package/dist/{orchestrator-C_OMSIMZ.d.ts → orchestrator-DqPAz8ot.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +33 -33
- 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/provenance.js +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-explain-renderer.js +3 -3
- 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/resume-bundles.js +4 -4
- 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 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +5 -4
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -8
- 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-B8LiYtvx.d.ts → semantic-consolidation-Cl15ksZy.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +8 -8
- package/dist/semantic-rule-promotion.js +7 -7
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +7 -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 +1 -1
- package/dist/storage.js +6 -6
- package/dist/summarizer.d.ts +1 -1
- 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/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-DmTaqob2.d.ts → types-ChQb9D6s.d.ts} +8 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +7 -7
- package/package.json +26 -2
- package/src/access-http.ts +68 -1
- package/src/access-service.ts +2 -1
- package/src/admin/admin-surfaces.test.ts +289 -0
- package/src/admin/admin-surfaces.ts +138 -7
- package/src/bitemporal-dedup-backfill.test.ts +294 -0
- package/src/capabilities.test.ts +155 -0
- package/src/capabilities.ts +91 -0
- package/src/chat/chat-engine.test.ts +104 -1
- package/src/chat/chat-http.test.ts +119 -1
- package/src/chat/chat-http.ts +252 -97
- package/src/chat/chat-session.ts +166 -7
- package/src/cli.ts +3 -2
- package/src/compat/codex-cli-fallback.ts +23 -0
- package/src/compat/codex-subpath-aliases.test.ts +93 -0
- package/src/compat/codex-thread-key.ts +23 -0
- package/src/embedding-fallback.ts +2 -1
- package/src/extraction-faithfulness.test.ts +240 -0
- package/src/extraction-faithfulness.ts +58 -6
- package/src/extraction.ts +7 -3
- package/src/faithfulness-config.ts +16 -1
- package/src/local-model-endpoint.ts +24 -3
- package/src/maintenance/first-start-migration.ts +3 -1
- package/src/orchestrator.ts +238 -34
- package/src/provenance-extraction.test.ts +266 -0
- package/src/provenance.ts +66 -16
- package/src/search/embed-helper.ts +3 -2
- package/src/types.ts +8 -0
- package/dist/chunk-2NBP25BG.js.map +0 -1
- package/dist/chunk-6OIDDKAA.js.map +0 -1
- package/dist/chunk-7AG54AF3.js.map +0 -1
- package/dist/chunk-C4X4QGIO.js.map +0 -1
- package/dist/chunk-DCKNMLEQ.js.map +0 -1
- package/dist/chunk-EHISUJFN.js.map +0 -1
- package/dist/chunk-MDBZTH7N.js.map +0 -1
- package/dist/chunk-OAHOL3ZC.js.map +0 -1
- package/dist/chunk-PLG6JHQS.js.map +0 -1
- package/dist/chunk-Q6D75LVH.js.map +0 -1
- package/dist/chunk-XGTBNVIU.js.map +0 -1
- package/dist/chunk-ZA2S2VLL.js.map +0 -1
- package/dist/first-start-migration-PG5HBC3K.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-BIA7ELIB.js.map → chunk-36SEDFAU.js.map} +0 -0
- /package/dist/{chunk-UQSVUEN2.js.map → chunk-37436GML.js.map} +0 -0
- /package/dist/{chunk-RRHHQYJS.js.map → chunk-3TSTGI6F.js.map} +0 -0
- /package/dist/{chunk-5OOA7SGX.js.map → chunk-4ESAR77N.js.map} +0 -0
- /package/dist/{chunk-FO3HO52S.js.map → chunk-4H4F3BFL.js.map} +0 -0
- /package/dist/{chunk-BEUCACTV.js.map → chunk-4NOI577P.js.map} +0 -0
- /package/dist/{chunk-BBIE7W52.js.map → chunk-4NR2PDZ5.js.map} +0 -0
- /package/dist/{chunk-WGTWGDR5.js.map → chunk-76NHR6ZL.js.map} +0 -0
- /package/dist/{chunk-PKMQK2WY.js.map → chunk-773DPI6T.js.map} +0 -0
- /package/dist/{chunk-MQVKHFIU.js.map → chunk-7RLCCNHU.js.map} +0 -0
- /package/dist/{chunk-EZNDNMRH.js.map → chunk-AQLOP5F4.js.map} +0 -0
- /package/dist/{chunk-UNNDFYUX.js.map → chunk-ARV3AUOM.js.map} +0 -0
- /package/dist/{chunk-NPL7VDM6.js.map → chunk-ASKXIAHD.js.map} +0 -0
- /package/dist/{chunk-K4ZNARDO.js.map → chunk-CBWI22JN.js.map} +0 -0
- /package/dist/{chunk-ZOHMPFOB.js.map → chunk-CKFLLAIS.js.map} +0 -0
- /package/dist/{chunk-JPUT5NGH.js.map → chunk-DMQWV6SQ.js.map} +0 -0
- /package/dist/{chunk-F3XZN24Z.js.map → chunk-DRUDC2UX.js.map} +0 -0
- /package/dist/{chunk-KJR66XOM.js.map → chunk-EY6MDMHK.js.map} +0 -0
- /package/dist/{chunk-3TUT4PWB.js.map → chunk-FVZ2ISIX.js.map} +0 -0
- /package/dist/{chunk-6SQQOJ4U.js.map → chunk-GKRLPHPU.js.map} +0 -0
- /package/dist/{chunk-5NWYQUQC.js.map → chunk-HOHVIVDR.js.map} +0 -0
- /package/dist/{chunk-6WAJQKBS.js.map → chunk-JYLFZWUX.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-UKTDXTWX.js.map → chunk-M4AYVEWS.js.map} +0 -0
- /package/dist/{chunk-YTZ3VGC7.js.map → chunk-M4V2JVSZ.js.map} +0 -0
- /package/dist/{chunk-TA3Y6GEX.js.map → chunk-MLKWJOAJ.js.map} +0 -0
- /package/dist/{chunk-DQXPJ6HD.js.map → chunk-O6YH5F47.js.map} +0 -0
- /package/dist/{chunk-53EEQYE5.js.map → chunk-UTHQPSRC.js.map} +0 -0
- /package/dist/{chunk-BB57OZWC.js.map → chunk-UVPL565C.js.map} +0 -0
- /package/dist/{chunk-6AFVIOVZ.js.map → chunk-V4GNSDFH.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-V7CMKMHM.js.map → chunk-Y4YD5TYW.js.map} +0 -0
- /package/dist/{chunk-7NS7AWMZ.js.map → chunk-YGIQORJ3.js.map} +0 -0
- /package/dist/{chunk-3MS3QVX6.js.map → chunk-YOLZS7NY.js.map} +0 -0
|
@@ -836,3 +836,269 @@ test("toStrictIsoTimestamp path: valid MM/DD/YYYY still normalizes (thread dH47
|
|
|
836
836
|
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/,
|
|
837
837
|
);
|
|
838
838
|
});
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
// ---------------------------------------------------------------------------
|
|
842
|
+
// Regression: issue #1657 — partial year-led timestamps must not be admitted
|
|
843
|
+
// as fabricated complete dates. Date.parse fills in missing calendar
|
|
844
|
+
// components ("2026-05" -> May 1) and the ymd guard misparses the date/time
|
|
845
|
+
// boundary ("2026-05T10:00" reads the hour as the day). The normalization
|
|
846
|
+
// path must reject any year-led shape with fewer than three complete calendar
|
|
847
|
+
// components rather than persisting a fabricated observedAt.
|
|
848
|
+
// ---------------------------------------------------------------------------
|
|
849
|
+
|
|
850
|
+
test("toStrictIsoTimestamp path: partial YYYY-MM timestamp is rejected, not fabricated (issue #1657)", () => {
|
|
851
|
+
// "2026-05" is Date.parse-able (-> 2026-05-01) and passes the separator
|
|
852
|
+
// guard, so pre-fix the write path persisted a fabricated observedAt of
|
|
853
|
+
// 2026-05-01T00:00:00.000Z. Reject it so the source is dropped.
|
|
854
|
+
const turns = [
|
|
855
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
856
|
+
timestamp: "2026-05" as unknown as string,
|
|
857
|
+
}),
|
|
858
|
+
];
|
|
859
|
+
const result = buildFactProvenance(
|
|
860
|
+
"migrated the production database to pgBouncer",
|
|
861
|
+
turns,
|
|
862
|
+
DEFAULT_CONFIG,
|
|
863
|
+
);
|
|
864
|
+
// No verified source: the only matching turn has a partial timestamp.
|
|
865
|
+
assert.equal(result.provenance, "unverified");
|
|
866
|
+
assert.ok(result.sources);
|
|
867
|
+
assert.notEqual(
|
|
868
|
+
result.sources![0]!.observedAt,
|
|
869
|
+
"2026-05-01T00:00:00.000Z",
|
|
870
|
+
"partial YYYY-MM timestamp must not fabricate May 1",
|
|
871
|
+
);
|
|
872
|
+
assert.equal(
|
|
873
|
+
result.sources![0]!.observedAt,
|
|
874
|
+
new Date(0).toISOString(),
|
|
875
|
+
"rejected partial timestamp falls back to epoch",
|
|
876
|
+
);
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
test("toStrictIsoTimestamp path: partial YYYY-MM T HH:MM is rejected, not misparsed (issue #1657)", () => {
|
|
880
|
+
// "2026-05T10:00" is Date.parse-able; the ymd regex grabs the hour "10" as
|
|
881
|
+
// the day across the date/time boundary, so pre-fix the write path persisted
|
|
882
|
+
// a fabricated observedAt (on May 10, shifted by timezone). Reject it.
|
|
883
|
+
const turns = [
|
|
884
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
885
|
+
timestamp: "2026-05T10:00" as unknown as string,
|
|
886
|
+
}),
|
|
887
|
+
];
|
|
888
|
+
const result = buildFactProvenance(
|
|
889
|
+
"migrated the production database to pgBouncer",
|
|
890
|
+
turns,
|
|
891
|
+
DEFAULT_CONFIG,
|
|
892
|
+
);
|
|
893
|
+
assert.equal(result.provenance, "unverified");
|
|
894
|
+
assert.ok(result.sources);
|
|
895
|
+
assert.equal(
|
|
896
|
+
result.sources![0]!.observedAt,
|
|
897
|
+
new Date(0).toISOString(),
|
|
898
|
+
"partial YYYY-MM T HH:MM timestamp must fall back to epoch, not a fabricated date",
|
|
899
|
+
);
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
test("toStrictIsoTimestamp path: complete YYYY-MM-DD (no time) still normalizes (issue #1657 non-regression)", () => {
|
|
903
|
+
// A complete calendar date with no time component must still round-trip
|
|
904
|
+
// through Date.parse to strict ISO. This is the boundary the partial-date
|
|
905
|
+
// guard must NOT over-reject.
|
|
906
|
+
const turns = [
|
|
907
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
908
|
+
timestamp: "2026-05-03" as unknown as string,
|
|
909
|
+
}),
|
|
910
|
+
];
|
|
911
|
+
const result = buildFactProvenance(
|
|
912
|
+
"migrated the production database to pgBouncer",
|
|
913
|
+
turns,
|
|
914
|
+
DEFAULT_CONFIG,
|
|
915
|
+
);
|
|
916
|
+
assert.equal(result.provenance, "verified");
|
|
917
|
+
assert.ok(result.sources);
|
|
918
|
+
assert.equal(
|
|
919
|
+
result.sources![0]!.observedAt,
|
|
920
|
+
"2026-05-03T00:00:00.000Z",
|
|
921
|
+
"complete date-only timestamp normalizes to UTC midnight",
|
|
922
|
+
);
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
test("toStrictIsoTimestamp path: space-separated partial YYYY-MM HH:MM is rejected (issue #1657, codex r2)", () => {
|
|
926
|
+
// "2026-05 10:00" is Date.parse-able; the date separator must be a real
|
|
927
|
+
// date separator (- or /), not the space that precedes the time component.
|
|
928
|
+
// Pre-fix the guard treated the space as a date separator and captured the
|
|
929
|
+
// hour "10" as the day, persisting a fabricated 2026-05-(10) source.
|
|
930
|
+
const turns = [
|
|
931
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
932
|
+
timestamp: "2026-05 10:00" as unknown as string,
|
|
933
|
+
}),
|
|
934
|
+
];
|
|
935
|
+
const result = buildFactProvenance(
|
|
936
|
+
"migrated the production database to pgBouncer",
|
|
937
|
+
turns,
|
|
938
|
+
DEFAULT_CONFIG,
|
|
939
|
+
);
|
|
940
|
+
assert.equal(result.provenance, "unverified");
|
|
941
|
+
assert.ok(result.sources);
|
|
942
|
+
assert.equal(
|
|
943
|
+
result.sources![0]!.observedAt,
|
|
944
|
+
new Date(0).toISOString(),
|
|
945
|
+
"space-separated partial timestamp must fall back to epoch, not a fabricated date",
|
|
946
|
+
);
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
test("toStrictIsoTimestamp path: leading-whitespace partial timestamp is rejected (issue #1657, codex r3)", () => {
|
|
950
|
+
// Date.parse trims leading whitespace, so " 2026-05" parses as May 1 —
|
|
951
|
+
// but the ^\d{4} guard anchored at the start would not recognize the
|
|
952
|
+
// string as year-led, bypassing the partial-date rejection. Trim first.
|
|
953
|
+
const turns = [
|
|
954
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
955
|
+
timestamp: " 2026-05" as unknown as string,
|
|
956
|
+
}),
|
|
957
|
+
];
|
|
958
|
+
const result = buildFactProvenance(
|
|
959
|
+
"migrated the production database to pgBouncer",
|
|
960
|
+
turns,
|
|
961
|
+
DEFAULT_CONFIG,
|
|
962
|
+
);
|
|
963
|
+
assert.equal(result.provenance, "unverified");
|
|
964
|
+
assert.ok(result.sources);
|
|
965
|
+
assert.equal(
|
|
966
|
+
result.sources![0]!.observedAt,
|
|
967
|
+
new Date(0).toISOString(),
|
|
968
|
+
"leading-whitespace partial timestamp must fall back to epoch, not a fabricated date",
|
|
969
|
+
);
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
test("toStrictIsoTimestamp path: complete year-first textual-month date is preserved (issue #1657, codex r4)", () => {
|
|
973
|
+
// A complete year-first TEXTUAL-month date ("2026-Jan-15") is normalized by
|
|
974
|
+
// Date.parse and must stay verified — the unified guard must not reject a
|
|
975
|
+
// complete textual month. Date.parse parses this non-ISO form in the LOCAL
|
|
976
|
+
// timezone, so assert the source is preserved (verified, not the epoch
|
|
977
|
+
// fallback) and normalized to strict ISO — without assuming the UTC day,
|
|
978
|
+
// which shifts across timezones (codex r7).
|
|
979
|
+
const turns = [
|
|
980
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
981
|
+
timestamp: "2026-Jan-15" as unknown as string,
|
|
982
|
+
}),
|
|
983
|
+
];
|
|
984
|
+
const result = buildFactProvenance(
|
|
985
|
+
"migrated the production database to pgBouncer",
|
|
986
|
+
turns,
|
|
987
|
+
DEFAULT_CONFIG,
|
|
988
|
+
);
|
|
989
|
+
assert.equal(result.provenance, "verified", "complete textual-month date must stay verified");
|
|
990
|
+
assert.ok(result.sources);
|
|
991
|
+
const observedAt = result.sources![0]!.observedAt;
|
|
992
|
+
assert.match(
|
|
993
|
+
observedAt,
|
|
994
|
+
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/,
|
|
995
|
+
"textual-month observedAt must normalize to strict ISO",
|
|
996
|
+
);
|
|
997
|
+
assert.notEqual(
|
|
998
|
+
observedAt,
|
|
999
|
+
new Date(0).toISOString(),
|
|
1000
|
+
"complete textual-month date must not fall back to the epoch (it was accepted, not rejected)",
|
|
1001
|
+
);
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
test("toStrictIsoTimestamp path: partial textual year-month is rejected (issue #1657, codex r5)", () => {
|
|
1005
|
+
// "2026-Jan" is Date.parse-able (-> Jan 1) — a partial year-led TEXTUAL
|
|
1006
|
+
// month that must be rejected just like the numeric "2026-05", not
|
|
1007
|
+
// fabricated. The unified year-led guard covers textual months too.
|
|
1008
|
+
const turns = [
|
|
1009
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
1010
|
+
timestamp: "2026-Jan" as unknown as string,
|
|
1011
|
+
}),
|
|
1012
|
+
];
|
|
1013
|
+
const result = buildFactProvenance(
|
|
1014
|
+
"migrated the production database to pgBouncer",
|
|
1015
|
+
turns,
|
|
1016
|
+
DEFAULT_CONFIG,
|
|
1017
|
+
);
|
|
1018
|
+
assert.equal(result.provenance, "unverified");
|
|
1019
|
+
assert.equal(
|
|
1020
|
+
result.sources![0]!.observedAt,
|
|
1021
|
+
new Date(0).toISOString(),
|
|
1022
|
+
"partial textual year-month must fall back to epoch, not a fabricated Jan 1",
|
|
1023
|
+
);
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
test("toStrictIsoTimestamp path: partial textual year-month with time is rejected (issue #1657, codex r5)", () => {
|
|
1027
|
+
// "2026-Jan 10:00" — the hour must not be captured as the day across the
|
|
1028
|
+
// date/time boundary (textual analogue of "2026-05 10:00").
|
|
1029
|
+
const turns = [
|
|
1030
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
1031
|
+
timestamp: "2026-Jan 10:00" as unknown as string,
|
|
1032
|
+
}),
|
|
1033
|
+
];
|
|
1034
|
+
const result = buildFactProvenance(
|
|
1035
|
+
"migrated the production database to pgBouncer",
|
|
1036
|
+
turns,
|
|
1037
|
+
DEFAULT_CONFIG,
|
|
1038
|
+
);
|
|
1039
|
+
assert.equal(result.provenance, "unverified");
|
|
1040
|
+
assert.equal(
|
|
1041
|
+
result.sources![0]!.observedAt,
|
|
1042
|
+
new Date(0).toISOString(),
|
|
1043
|
+
"partial textual year-month with time must fall back to epoch",
|
|
1044
|
+
);
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
test("toStrictIsoTimestamp path: textual-month calendar overflow is rejected (issue #1657, codex r5)", () => {
|
|
1048
|
+
// "2026-Feb-30" is a COMPLETE textual date but Feb 30 overflows — Date.parse
|
|
1049
|
+
// shifts it to March 2. The unified guard validates the textual month's
|
|
1050
|
+
// calendar day too, so this is rejected rather than fabricated (textual
|
|
1051
|
+
// analogue of the numeric dANc overflow).
|
|
1052
|
+
const turns = [
|
|
1053
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
1054
|
+
timestamp: "2026-Feb-30" as unknown as string,
|
|
1055
|
+
}),
|
|
1056
|
+
];
|
|
1057
|
+
const result = buildFactProvenance(
|
|
1058
|
+
"migrated the production database to pgBouncer",
|
|
1059
|
+
turns,
|
|
1060
|
+
DEFAULT_CONFIG,
|
|
1061
|
+
);
|
|
1062
|
+
assert.equal(result.provenance, "unverified");
|
|
1063
|
+
assert.notEqual(
|
|
1064
|
+
result.sources![0]!.observedAt,
|
|
1065
|
+
"2026-03-02T00:00:00.000Z",
|
|
1066
|
+
"textual-month overflow must not be silently shifted to March 2",
|
|
1067
|
+
);
|
|
1068
|
+
assert.equal(
|
|
1069
|
+
result.sources![0]!.observedAt,
|
|
1070
|
+
new Date(0).toISOString(),
|
|
1071
|
+
"textual-month overflow falls back to epoch",
|
|
1072
|
+
);
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
test("toStrictIsoTimestamp path: full month name is preserved (issue #1657, codex r6)", () => {
|
|
1076
|
+
// Date.parse accepts full month names ("2026-January-15"), so the textual
|
|
1077
|
+
// month map must include both abbreviations and full names — otherwise a
|
|
1078
|
+
// complete, valid full-name date is dropped to an unverified epoch source.
|
|
1079
|
+
// Date.parse parses this non-ISO form in the LOCAL timezone, so assert the
|
|
1080
|
+
// source is preserved (verified, not epoch) without a UTC-day assumption.
|
|
1081
|
+
const turns = [
|
|
1082
|
+
makeTurn("We migrated the production database to pgBouncer.", {
|
|
1083
|
+
timestamp: "2026-January-15" as unknown as string,
|
|
1084
|
+
}),
|
|
1085
|
+
];
|
|
1086
|
+
const result = buildFactProvenance(
|
|
1087
|
+
"migrated the production database to pgBouncer",
|
|
1088
|
+
turns,
|
|
1089
|
+
DEFAULT_CONFIG,
|
|
1090
|
+
);
|
|
1091
|
+
assert.equal(result.provenance, "verified", "full-name textual month must stay verified");
|
|
1092
|
+
assert.ok(result.sources);
|
|
1093
|
+
const observedAt = result.sources![0]!.observedAt;
|
|
1094
|
+
assert.match(
|
|
1095
|
+
observedAt,
|
|
1096
|
+
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/,
|
|
1097
|
+
"full-name textual month observedAt must normalize to strict ISO",
|
|
1098
|
+
);
|
|
1099
|
+
assert.notEqual(
|
|
1100
|
+
observedAt,
|
|
1101
|
+
new Date(0).toISOString(),
|
|
1102
|
+
"full-name textual month must not fall back to the epoch (it was accepted, not rejected)",
|
|
1103
|
+
);
|
|
1104
|
+
});
|
package/src/provenance.ts
CHANGED
|
@@ -188,33 +188,39 @@ function isStrictIsoTimestamp(s: string): boolean {
|
|
|
188
188
|
*/
|
|
189
189
|
function toStrictIsoTimestamp(ts: string | undefined | null): string | undefined {
|
|
190
190
|
if (typeof ts !== "string" || ts.length === 0) return undefined;
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
// Trim surrounding whitespace: Date.parse accepts leading/trailing
|
|
192
|
+
// whitespace, so an imported " 2026-05" would otherwise bypass the
|
|
193
|
+
// year-led partial-date guard below and fabricate May 1
|
|
194
|
+
// (chatgpt-codex-connector review on #1714, issue #1657).
|
|
195
|
+
const value = ts.trim();
|
|
196
|
+
if (value.length === 0) return undefined;
|
|
197
|
+
if (isStrictIsoTimestamp(value)) return value;
|
|
198
|
+
const parsed = Date.parse(value);
|
|
193
199
|
if (Number.isNaN(parsed)) return undefined;
|
|
194
200
|
// Reject bare-year / numeric-only strings that Date.parse accepts (e.g.
|
|
195
201
|
// "123") — isStrictIsoTimestamp already rejected them, and the round-trip
|
|
196
202
|
// below would otherwise resurrect them. Require at least one date/time
|
|
197
203
|
// separator so a plain number never round-trips into a fake epoch.
|
|
198
|
-
if (!/[-:T]/.test(
|
|
199
|
-
// Reject
|
|
200
|
-
// Date.parse silently
|
|
201
|
-
// 2026-
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
// the
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
204
|
+
if (!/[-:T]/.test(value)) return undefined;
|
|
205
|
+
// Reject year-led timestamps that are not a COMPLETE, calendar-valid date
|
|
206
|
+
// (issue #1657). Date.parse silently fills missing components ("2026-05" ->
|
|
207
|
+
// May 1, "2026-Jan" -> Jan 1) and rolls overflow ("2026-02-30" and
|
|
208
|
+
// "2026-Feb-30" -> March 2), fabricating observedAt. `parseYearLedDatePrefix`
|
|
209
|
+
// requires a complete three-component date — numeric OR textual month — with
|
|
210
|
+
// real date separators (not T/:, and not the space that precedes a time
|
|
211
|
+
// component, so the hour is never captured as the day) and a calendar-valid
|
|
212
|
+
// day, in one rule (subsumes the prior partial-numeric and numeric-overflow
|
|
213
|
+
// checks, and extends them to textual months). Non-year-led shapes
|
|
214
|
+
// ("Jan 15 2026", "02/30/2026") fall through to Date.parse / the mdy check.
|
|
215
|
+
if (/^\d{4}\D/.test(value) && parseYearLedDatePrefix(value) === null) {
|
|
216
|
+
return undefined;
|
|
211
217
|
}
|
|
212
218
|
// Also validate M/D/Y or D/M/Y formats (provider/import common shapes:
|
|
213
219
|
// 02/30/2026, 30-02-2026, etc.). Date.parse silently shifts overflow in
|
|
214
220
|
// these too. Try both month-first and day-first interpretations; if
|
|
215
221
|
// neither is a valid calendar date, reject (chatgpt-codex-connector thread
|
|
216
222
|
// dH47 — non-YMD overflow timestamps).
|
|
217
|
-
const mdy = /^(\d{1,2})\D(\d{1,2})\D(\d{4})/.exec(
|
|
223
|
+
const mdy = /^(\d{1,2})\D(\d{1,2})\D(\d{4})/.exec(value);
|
|
218
224
|
if (mdy) {
|
|
219
225
|
const a = Number(mdy[1]), b = Number(mdy[2]), yr = Number(mdy[3]);
|
|
220
226
|
if (!isValidCalendarDate(yr, a, b) && !isValidCalendarDate(yr, b, a)) {
|
|
@@ -238,6 +244,50 @@ function isValidCalendarDate(y: number, mo: number, da: number): boolean {
|
|
|
238
244
|
return da <= daysInMonth[mo - 1]!;
|
|
239
245
|
}
|
|
240
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Recognized month-name → number map for year-led textual-month dates
|
|
249
|
+
* (issue #1657). Both the 3-letter abbreviations and the full names that
|
|
250
|
+
* Date.parse accepts for year-first shapes (e.g. "2026-Jan-15",
|
|
251
|
+
* "2026-January-15", "2026 February 2").
|
|
252
|
+
*/
|
|
253
|
+
const MONTH_NAMES: Record<string, number> = {
|
|
254
|
+
jan: 1, january: 1,
|
|
255
|
+
feb: 2, february: 2,
|
|
256
|
+
mar: 3, march: 3,
|
|
257
|
+
apr: 4, april: 4,
|
|
258
|
+
may: 5,
|
|
259
|
+
jun: 6, june: 6,
|
|
260
|
+
jul: 7, july: 7,
|
|
261
|
+
aug: 8, august: 8,
|
|
262
|
+
sep: 9, september: 9,
|
|
263
|
+
sept: 9,
|
|
264
|
+
oct: 10, october: 10,
|
|
265
|
+
nov: 11, november: 11,
|
|
266
|
+
dec: 12, december: 12,
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Parse a complete, calendar-valid year-led date prefix from `s`
|
|
271
|
+
* (issue #1657): `YYYY <sep> (MM | MonthName) <sep> DD` where the separators
|
|
272
|
+
* are real date separators (non-digit, non-T, non-colon) and the day is a
|
|
273
|
+
* true calendar day — not the hour before a `:` time separator (the
|
|
274
|
+
* `(?![\d:])` lookahead rejects "2026-05 10:00" capturing "10" as the day).
|
|
275
|
+
* Returns the numeric components for a complete, valid date; `null` for an
|
|
276
|
+
* incomplete ("2026-05", "2026-Jan"), overflowed ("2026-02-30",
|
|
277
|
+
* "2026-Feb-30"), or non-year-led prefix. Centralizes the fabricated-date
|
|
278
|
+
* rejection for the toStrictIsoTimestamp normalization path across numeric
|
|
279
|
+
* and textual months in one rule.
|
|
280
|
+
*/
|
|
281
|
+
function parseYearLedDatePrefix(s: string): { y: number; mo: number; da: number } | null {
|
|
282
|
+
const m = /^(\d{4})[^0-9T](\d{1,2}|[A-Za-z]{3,})[^0-9T:](\d{1,2})(?![\d:])/.exec(s);
|
|
283
|
+
if (!m) return null;
|
|
284
|
+
const y = Number(m[1]);
|
|
285
|
+
const da = Number(m[3]);
|
|
286
|
+
const mo = /^\d+$/.test(m[2]) ? Number(m[2]) : (MONTH_NAMES[m[2]!.toLowerCase()] ?? -1);
|
|
287
|
+
if (!isValidCalendarDate(y, mo, da)) return null;
|
|
288
|
+
return { y, mo, da };
|
|
289
|
+
}
|
|
290
|
+
|
|
241
291
|
/**
|
|
242
292
|
* Zod schema for a single `ProvenanceSource` entry (issue #1575). Parsed
|
|
243
293
|
* JSON from frontmatter is external data, so each entry is validated here
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { log } from "../logger.js";
|
|
2
|
+
import { resolveMemoryLifecycleCapabilities } from "../capabilities.js";
|
|
2
3
|
import type { PluginConfig } from "../types.js";
|
|
3
4
|
import { isAbortError } from "../abort-error.js";
|
|
4
5
|
import { withTimeoutSignal } from "./abort.js";
|
|
@@ -209,7 +210,7 @@ export class EmbedHelper {
|
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
private resolveProvider(options: { includeHost?: boolean } = {}): ProviderConfig | null {
|
|
212
|
-
if (!this.config.
|
|
213
|
+
if (!resolveMemoryLifecycleCapabilities(this.config).embeddingFallback) return null;
|
|
213
214
|
|
|
214
215
|
if (
|
|
215
216
|
options.includeHost !== false &&
|
|
@@ -244,7 +245,7 @@ export class EmbedHelper {
|
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
private resolveFallbackProviderForIdentity(identity: EmbedProviderIdentity): ProviderConfig | null {
|
|
247
|
-
if (!this.config.
|
|
248
|
+
if (!resolveMemoryLifecycleCapabilities(this.config).embeddingFallback) return null;
|
|
248
249
|
const separator = identity.indexOf(":");
|
|
249
250
|
if (separator <= 0 || separator === identity.length - 1) return null;
|
|
250
251
|
const type = identity.slice(0, separator);
|
package/src/types.ts
CHANGED
|
@@ -1222,6 +1222,14 @@ export interface PluginConfig {
|
|
|
1222
1222
|
extractionFaithfulnessContextChars: number;
|
|
1223
1223
|
/** Per-batch timeout in ms; timeout → tagged error, never blocks writes. Default 8000. */
|
|
1224
1224
|
extractionFaithfulnessTimeoutMs: number;
|
|
1225
|
+
/**
|
|
1226
|
+
* Resilient-fallback toggle for the local model-lab endpoint (issue #1700
|
|
1227
|
+
* nit #6). When the local endpoint returns 200 with non-verdict JSON, the
|
|
1228
|
+
* default (false) surfaces `malformed_output` so a misconfigured endpoint is
|
|
1229
|
+
* visible to the operator. Set true to instead fall back to the configured
|
|
1230
|
+
* chain on local parse failure (pre-validated via parseFaithfulnessResponse).
|
|
1231
|
+
*/
|
|
1232
|
+
extractionFaithfulnessLocalParseFallback: boolean;
|
|
1225
1233
|
/**
|
|
1226
1234
|
* Correction-intent model-lab pointer (issue #1581 / #1585). When both this
|
|
1227
1235
|
* and `correctionIntentBaseUrl` are set, the detection path can route to a
|