@remnic/core 9.69.16 → 9.69.18
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-admin-ops-surface.d.ts +11 -11
- package/dist/access-admin-ops-surface.js +49 -45
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +50 -46
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +49 -45
- package/dist/access-cli.js +111 -110
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +11 -11
- package/dist/access-extraction-force-flush.js +49 -45
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +11 -11
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +51 -47
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +69 -65
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +49 -45
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +49 -45
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +60 -56
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-Rzuo1nGR.d.ts → access-namespace-preflight-BMHhxoL9.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +49 -45
- package/dist/access-observe-transcript.d.ts +147 -0
- package/dist/access-observe-transcript.js +16 -0
- package/dist/access-observe-write-surface.d.ts +12 -11
- package/dist/access-observe-write-surface.js +49 -45
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +6 -6
- package/dist/access-operations-batch.js +52 -48
- package/dist/access-operations.d.ts +13 -13
- package/dist/access-operations.js +57 -53
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +49 -45
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +49 -45
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +49 -45
- package/dist/access-schema.d.ts +4 -4
- package/dist/access-schema.js +5 -5
- package/dist/{access-service-tcC_jK6C.d.ts → access-service-CYdqPfpS.d.ts} +22 -13
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +49 -45
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +51 -47
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- 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 +7 -7
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-Q6Q2FVSC.js → auto-sync-GRUJFD2F.js} +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +14 -14
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-DjTLVOYp.d.ts → catalog-C1qHsGew.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +16 -16
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-RJ57OOCD.js → chunk-2J4TIFBK.js} +3 -3
- package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
- package/dist/{chunk-P6GKRT2H.js → chunk-2Z3DG5CQ.js} +1 -1
- package/dist/{chunk-BO4PWIJY.js → chunk-3LADWWMA.js} +3 -3
- package/dist/{chunk-P7LVYPIX.js → chunk-3LJPSRAN.js} +3 -3
- package/dist/{chunk-ZKZCJRRO.js → chunk-43HMVVOL.js} +2 -2
- package/dist/{chunk-3TSU662L.js → chunk-46QMN7I7.js} +5 -5
- package/dist/{chunk-HODFGQGT.js → chunk-4HYNMLT6.js} +2 -2
- package/dist/{chunk-HTOWFFAI.js → chunk-5CF2R4NS.js} +2 -2
- package/dist/{chunk-QVI63XSO.js → chunk-5MF4EGL5.js} +50 -50
- package/dist/{chunk-KLSPKMIO.js → chunk-5SGOARQJ.js} +2 -2
- package/dist/{chunk-JGXMA6HL.js → chunk-6FUMA6AA.js} +2 -2
- package/dist/chunk-6MINUTGJ.js +64 -0
- package/dist/chunk-6MINUTGJ.js.map +1 -0
- package/dist/{chunk-K2IJH4D3.js → chunk-7RRUHJPG.js} +7 -7
- package/dist/{chunk-I4QAH4SY.js → chunk-7TUB6JWA.js} +3 -3
- package/dist/{chunk-NNBZS3DY.js → chunk-AG46P24C.js} +4 -4
- package/dist/{chunk-B64IVEOH.js → chunk-AWF4CNYJ.js} +2 -2
- package/dist/{chunk-C25N5HWX.js → chunk-B2AGUKSS.js} +2 -2
- package/dist/{chunk-7ZMU4XQT.js → chunk-BR3OOQZQ.js} +2 -2
- package/dist/{chunk-TRLCMLX7.js → chunk-BZTJEILZ.js} +2 -2
- package/dist/{chunk-OLBZ2WGG.js → chunk-C2JCVZWX.js} +2 -2
- package/dist/{chunk-YWN3GYI2.js → chunk-CASWJ2HM.js} +2 -2
- package/dist/{chunk-S35IIP5P.js → chunk-CFKCFY4B.js} +2 -2
- package/dist/{chunk-S5G2LAL7.js → chunk-CHWUICVY.js} +4 -4
- package/dist/{chunk-7JV4JST3.js → chunk-CVJMGVEW.js} +47 -47
- package/dist/{chunk-BE4Y6GK6.js → chunk-D35XLYQ7.js} +11 -11
- package/dist/{chunk-DA4ZMCBU.js → chunk-D5ZNOKR7.js} +3 -3
- package/dist/{chunk-BEXFNGQ3.js → chunk-DK6GMO6D.js} +3 -3
- package/dist/{chunk-I6DUKBUI.js → chunk-DP4EBV7C.js} +2 -2
- package/dist/{chunk-W6GEMUZM.js → chunk-EFCBJDYE.js} +13 -13
- package/dist/{chunk-XMIAU4CO.js → chunk-EJ5RKUXW.js} +2 -2
- package/dist/{chunk-LF6SHWVV.js → chunk-F5UWQ4LX.js} +2 -2
- package/dist/{chunk-XQGFIAG7.js → chunk-FB7LAJQM.js} +2 -2
- package/dist/{chunk-OAKATRAN.js → chunk-G6N654ND.js} +10 -10
- package/dist/{chunk-2EHDPHMD.js → chunk-GGYDJJBO.js} +2 -2
- package/dist/{chunk-VAMZYOOV.js → chunk-HOUST5UX.js} +2 -2
- package/dist/{chunk-NHLEFBE2.js → chunk-I4Y6TBD7.js} +3 -3
- package/dist/{chunk-W272SWN7.js → chunk-I7FY43VC.js} +7 -7
- package/dist/{chunk-MSDIETFC.js → chunk-IZZ7Q2RJ.js} +56 -47
- package/dist/chunk-IZZ7Q2RJ.js.map +1 -0
- package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
- package/dist/{chunk-XJJYSX6F.js → chunk-JCUG7AXZ.js} +4 -4
- package/dist/{chunk-ZRUEP4IK.js → chunk-JIM4BIOC.js} +30 -49
- package/dist/chunk-JIM4BIOC.js.map +1 -0
- package/dist/{chunk-BX6GW4KC.js → chunk-JMAG7WZ7.js} +2 -2
- package/dist/{chunk-NF3NMAG7.js → chunk-JOYC4RYC.js} +2 -2
- package/dist/{chunk-5JQV4T5Q.js → chunk-JZ6EYAVP.js} +2 -2
- package/dist/{chunk-QRDSXR3V.js → chunk-KA2HZCMG.js} +2 -2
- package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-ETZ7KKOS.js → chunk-KTVSPFCQ.js} +2 -2
- package/dist/{chunk-PAWIY5OQ.js → chunk-L74A6NTI.js} +6 -6
- package/dist/{chunk-2XJDAEAM.js → chunk-LFK623SF.js} +5 -5
- package/dist/chunk-LVE64P5Y.js +80 -0
- package/dist/chunk-LVE64P5Y.js.map +1 -0
- package/dist/{chunk-IEZ6CGTW.js → chunk-N3SS45OW.js} +115 -55
- package/dist/chunk-N3SS45OW.js.map +1 -0
- package/dist/{chunk-QUVWFZOU.js → chunk-N7JK2RKG.js} +2 -2
- package/dist/{chunk-BFDOBESV.js → chunk-NYRB7BKY.js} +2 -2
- package/dist/{chunk-LDOQE34V.js → chunk-NZGO2GKL.js} +2 -2
- package/dist/{chunk-VYD63IFH.js → chunk-OGTKQ5MJ.js} +3 -3
- package/dist/{chunk-BIJAWZYW.js → chunk-OLT3YTDH.js} +4 -4
- package/dist/{chunk-F2ERDKY2.js → chunk-PC7WNIRL.js} +17 -17
- package/dist/{chunk-3BS2OGDT.js → chunk-PPOT6SPR.js} +5 -5
- package/dist/{chunk-G7VEQEMG.js → chunk-QVSRE355.js} +65 -39
- package/dist/chunk-QVSRE355.js.map +1 -0
- package/dist/{chunk-LUDXSSTW.js → chunk-R7LY4YKF.js} +2 -2
- package/dist/{chunk-N37X5RU7.js → chunk-RACZB5HT.js} +4 -4
- package/dist/{chunk-LJAP4KSW.js → chunk-RO2X2EYM.js} +2 -2
- package/dist/{chunk-5YQ7RFSO.js → chunk-S37NN23M.js} +2 -2
- package/dist/{chunk-DDX6KIXF.js → chunk-SB4OBB7P.js} +2 -2
- package/dist/{chunk-JHTF22NQ.js → chunk-TA7UZZMW.js} +2 -2
- package/dist/{chunk-4UVDLNHQ.js → chunk-UMEOXLIZ.js} +2 -2
- package/dist/{chunk-63I7LMLG.js → chunk-WL5PR5YC.js} +2 -2
- package/dist/{chunk-H5IIBGDM.js → chunk-X33MJFD2.js} +2 -2
- package/dist/{chunk-SXHBZXHK.js → chunk-XJJLWTLW.js} +5 -5
- package/dist/{chunk-OYV6RKPM.js → chunk-XOQGUGJL.js} +2 -6
- package/dist/chunk-XOQGUGJL.js.map +1 -0
- package/dist/{chunk-GIC6BASP.js → chunk-XZBXINXZ.js} +4 -4
- package/dist/{chunk-APZXA4WI.js → chunk-YVLENSNS.js} +2 -2
- package/dist/{chunk-OUKBMQ2O.js → chunk-Z3SQEEB6.js} +2 -2
- package/dist/{chunk-NN5CQTAJ.js → chunk-ZEBRENA6.js} +2 -2
- package/dist/{chunk-5H2G5X4R.js → chunk-ZJWDWPX6.js} +3 -3
- package/dist/{chunk-M7DGN6JZ.js → chunk-ZL3XX5LW.js} +2 -2
- package/dist/{chunk-4WIKMOE3.js → chunk-ZZM476NV.js} +1 -1
- package/dist/{cli-BI9YYpKx.d.ts → cli-DN9LpWf0.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +92 -88
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +13 -13
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +13 -13
- 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 +7 -7
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +13 -13
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +13 -13
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +3 -3
- package/dist/converge-config.d.ts +16 -2
- package/dist/converge-config.js +9 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +15 -15
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- 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/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +15 -15
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/deep-recall-http-glue.d.ts +11 -11
- package/dist/deep-recall-http-glue.js +6 -6
- package/dist/deep-recall-mcp-tools.d.ts +11 -11
- package/dist/deep-recall-policy-llm.d.ts +1 -1
- package/dist/deep-recall-seeds.d.ts +1 -1
- package/dist/deep-recall.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-37JdQv_3.d.ts → dependency-propagation-delivery-DjpUlhLi.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-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +13 -13
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +50 -46
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +11 -11
- package/dist/extraction-error-classification.d.ts +1 -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-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +16 -16
- package/dist/fallback-llm.d.ts +1 -1
- 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-decay-FXGELBFA.js → graph-edge-decay-DGTBFALQ.js} +4 -4
- package/dist/graph-edge-decay-DGTBFALQ.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.d.ts +1 -1
- package/dist/graph.js +2 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-DquhYqsc.d.ts → index-CsUrdMyL.d.ts} +2 -2
- package/dist/index.d.ts +26 -26
- package/dist/index.js +138 -127
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +3 -3
- package/dist/location/index.js +15 -15
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +13 -13
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -13
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +14 -14
- package/dist/{maintenance-CizZOycr.d.ts → maintenance-D1GRGLTE.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-controller.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-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +11 -11
- package/dist/memory-subject.d.ts +11 -11
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +14 -14
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +13 -13
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync.js +2 -2
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +16 -16
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +30 -30
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +21 -21
- package/dist/{orchestrator-DqLcuNMP.d.ts → orchestrator-DeqaPGT5.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +111 -110
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-DbJpmcRu.d.ts → pipeline-umUzU0D1.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-Bocro5ZU.d.ts → public-http-C1ht4oDJ.d.ts} +1 -1
- package/dist/{qmd-DA_7fbSz.d.ts → qmd-BasT78PP.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.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-memory-map.d.ts +1 -1
- package/dist/recall-navigate-access.d.ts +1 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +1 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +1 -1
- package/dist/recall-navigate.js +2 -2
- 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-timings.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/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/cursor.js +2 -2
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.d.ts +16 -1
- package/dist/reconcile/plan.js +2 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +8 -8
- package/dist/retrieval-agents.d.ts +2 -2
- 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/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +42 -42
- package/dist/{scope-profiles-BpiWKZzx.d.ts → scope-profiles-DXYzyOXW.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +13 -13
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-NJpaZpkY.d.ts → semantic-consolidation-CqDeaY0U.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +14 -14
- package/dist/semantic-rule-promotion.js +13 -13
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +13 -13
- package/dist/{service-DdlZjX1D.d.ts → service-BKD-DVYZ.d.ts} +2 -2
- 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/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +13 -13
- package/dist/standup/build.js +13 -13
- package/dist/{storage-C7BWrpU9.d.ts → storage-BcFd1lN_.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +12 -12
- package/dist/subject-config.d.ts +1 -1
- package/dist/summarizer.d.ts +30 -4
- package/dist/summarizer.js +6 -4
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +52 -48
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.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 +2 -2
- 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/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +14 -14
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-Cy1l6fzp.d.ts → types-BRg3tMyp.d.ts} +2 -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 +13 -13
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +14 -14
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +13 -13
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-mcp-output-schemas.ts +60 -34
- package/src/access-observe-transcript-persistence.test.ts +252 -0
- package/src/access-observe-transcript.ts +153 -0
- package/src/access-observe-write-surface.ts +234 -224
- package/src/access-service.ts +33 -28
- package/src/converge-config.ts +40 -3
- package/src/index.ts +1 -1
- package/src/reconcile/plan.test.ts +118 -88
- package/src/reconcile/plan.ts +98 -84
- package/src/summarizer.ts +217 -111
- package/src/summary-snapshot.test.ts +8 -6
- package/src/types.ts +47 -44
- package/dist/chunk-G7VEQEMG.js.map +0 -1
- package/dist/chunk-HBVPYRDW.js +0 -39
- package/dist/chunk-HBVPYRDW.js.map +0 -1
- package/dist/chunk-IEZ6CGTW.js.map +0 -1
- package/dist/chunk-MSDIETFC.js.map +0 -1
- package/dist/chunk-OYV6RKPM.js.map +0 -1
- package/dist/chunk-ZRUEP4IK.js.map +0 -1
- /package/dist/{graph-edge-decay-FXGELBFA.js.map → access-observe-transcript.js.map} +0 -0
- /package/dist/{auto-sync-Q6Q2FVSC.js.map → auto-sync-GRUJFD2F.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-RJ57OOCD.js.map → chunk-2J4TIFBK.js.map} +0 -0
- /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-P6GKRT2H.js.map → chunk-2Z3DG5CQ.js.map} +0 -0
- /package/dist/{chunk-BO4PWIJY.js.map → chunk-3LADWWMA.js.map} +0 -0
- /package/dist/{chunk-P7LVYPIX.js.map → chunk-3LJPSRAN.js.map} +0 -0
- /package/dist/{chunk-ZKZCJRRO.js.map → chunk-43HMVVOL.js.map} +0 -0
- /package/dist/{chunk-3TSU662L.js.map → chunk-46QMN7I7.js.map} +0 -0
- /package/dist/{chunk-HODFGQGT.js.map → chunk-4HYNMLT6.js.map} +0 -0
- /package/dist/{chunk-HTOWFFAI.js.map → chunk-5CF2R4NS.js.map} +0 -0
- /package/dist/{chunk-QVI63XSO.js.map → chunk-5MF4EGL5.js.map} +0 -0
- /package/dist/{chunk-KLSPKMIO.js.map → chunk-5SGOARQJ.js.map} +0 -0
- /package/dist/{chunk-JGXMA6HL.js.map → chunk-6FUMA6AA.js.map} +0 -0
- /package/dist/{chunk-K2IJH4D3.js.map → chunk-7RRUHJPG.js.map} +0 -0
- /package/dist/{chunk-I4QAH4SY.js.map → chunk-7TUB6JWA.js.map} +0 -0
- /package/dist/{chunk-NNBZS3DY.js.map → chunk-AG46P24C.js.map} +0 -0
- /package/dist/{chunk-B64IVEOH.js.map → chunk-AWF4CNYJ.js.map} +0 -0
- /package/dist/{chunk-C25N5HWX.js.map → chunk-B2AGUKSS.js.map} +0 -0
- /package/dist/{chunk-7ZMU4XQT.js.map → chunk-BR3OOQZQ.js.map} +0 -0
- /package/dist/{chunk-TRLCMLX7.js.map → chunk-BZTJEILZ.js.map} +0 -0
- /package/dist/{chunk-OLBZ2WGG.js.map → chunk-C2JCVZWX.js.map} +0 -0
- /package/dist/{chunk-YWN3GYI2.js.map → chunk-CASWJ2HM.js.map} +0 -0
- /package/dist/{chunk-S35IIP5P.js.map → chunk-CFKCFY4B.js.map} +0 -0
- /package/dist/{chunk-S5G2LAL7.js.map → chunk-CHWUICVY.js.map} +0 -0
- /package/dist/{chunk-7JV4JST3.js.map → chunk-CVJMGVEW.js.map} +0 -0
- /package/dist/{chunk-BE4Y6GK6.js.map → chunk-D35XLYQ7.js.map} +0 -0
- /package/dist/{chunk-DA4ZMCBU.js.map → chunk-D5ZNOKR7.js.map} +0 -0
- /package/dist/{chunk-BEXFNGQ3.js.map → chunk-DK6GMO6D.js.map} +0 -0
- /package/dist/{chunk-I6DUKBUI.js.map → chunk-DP4EBV7C.js.map} +0 -0
- /package/dist/{chunk-W6GEMUZM.js.map → chunk-EFCBJDYE.js.map} +0 -0
- /package/dist/{chunk-XMIAU4CO.js.map → chunk-EJ5RKUXW.js.map} +0 -0
- /package/dist/{chunk-LF6SHWVV.js.map → chunk-F5UWQ4LX.js.map} +0 -0
- /package/dist/{chunk-XQGFIAG7.js.map → chunk-FB7LAJQM.js.map} +0 -0
- /package/dist/{chunk-OAKATRAN.js.map → chunk-G6N654ND.js.map} +0 -0
- /package/dist/{chunk-2EHDPHMD.js.map → chunk-GGYDJJBO.js.map} +0 -0
- /package/dist/{chunk-VAMZYOOV.js.map → chunk-HOUST5UX.js.map} +0 -0
- /package/dist/{chunk-NHLEFBE2.js.map → chunk-I4Y6TBD7.js.map} +0 -0
- /package/dist/{chunk-W272SWN7.js.map → chunk-I7FY43VC.js.map} +0 -0
- /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
- /package/dist/{chunk-XJJYSX6F.js.map → chunk-JCUG7AXZ.js.map} +0 -0
- /package/dist/{chunk-BX6GW4KC.js.map → chunk-JMAG7WZ7.js.map} +0 -0
- /package/dist/{chunk-NF3NMAG7.js.map → chunk-JOYC4RYC.js.map} +0 -0
- /package/dist/{chunk-5JQV4T5Q.js.map → chunk-JZ6EYAVP.js.map} +0 -0
- /package/dist/{chunk-QRDSXR3V.js.map → chunk-KA2HZCMG.js.map} +0 -0
- /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-ETZ7KKOS.js.map → chunk-KTVSPFCQ.js.map} +0 -0
- /package/dist/{chunk-PAWIY5OQ.js.map → chunk-L74A6NTI.js.map} +0 -0
- /package/dist/{chunk-2XJDAEAM.js.map → chunk-LFK623SF.js.map} +0 -0
- /package/dist/{chunk-QUVWFZOU.js.map → chunk-N7JK2RKG.js.map} +0 -0
- /package/dist/{chunk-BFDOBESV.js.map → chunk-NYRB7BKY.js.map} +0 -0
- /package/dist/{chunk-LDOQE34V.js.map → chunk-NZGO2GKL.js.map} +0 -0
- /package/dist/{chunk-VYD63IFH.js.map → chunk-OGTKQ5MJ.js.map} +0 -0
- /package/dist/{chunk-BIJAWZYW.js.map → chunk-OLT3YTDH.js.map} +0 -0
- /package/dist/{chunk-F2ERDKY2.js.map → chunk-PC7WNIRL.js.map} +0 -0
- /package/dist/{chunk-3BS2OGDT.js.map → chunk-PPOT6SPR.js.map} +0 -0
- /package/dist/{chunk-LUDXSSTW.js.map → chunk-R7LY4YKF.js.map} +0 -0
- /package/dist/{chunk-N37X5RU7.js.map → chunk-RACZB5HT.js.map} +0 -0
- /package/dist/{chunk-LJAP4KSW.js.map → chunk-RO2X2EYM.js.map} +0 -0
- /package/dist/{chunk-5YQ7RFSO.js.map → chunk-S37NN23M.js.map} +0 -0
- /package/dist/{chunk-DDX6KIXF.js.map → chunk-SB4OBB7P.js.map} +0 -0
- /package/dist/{chunk-JHTF22NQ.js.map → chunk-TA7UZZMW.js.map} +0 -0
- /package/dist/{chunk-4UVDLNHQ.js.map → chunk-UMEOXLIZ.js.map} +0 -0
- /package/dist/{chunk-63I7LMLG.js.map → chunk-WL5PR5YC.js.map} +0 -0
- /package/dist/{chunk-H5IIBGDM.js.map → chunk-X33MJFD2.js.map} +0 -0
- /package/dist/{chunk-SXHBZXHK.js.map → chunk-XJJLWTLW.js.map} +0 -0
- /package/dist/{chunk-GIC6BASP.js.map → chunk-XZBXINXZ.js.map} +0 -0
- /package/dist/{chunk-APZXA4WI.js.map → chunk-YVLENSNS.js.map} +0 -0
- /package/dist/{chunk-OUKBMQ2O.js.map → chunk-Z3SQEEB6.js.map} +0 -0
- /package/dist/{chunk-NN5CQTAJ.js.map → chunk-ZEBRENA6.js.map} +0 -0
- /package/dist/{chunk-5H2G5X4R.js.map → chunk-ZJWDWPX6.js.map} +0 -0
- /package/dist/{chunk-M7DGN6JZ.js.map → chunk-ZL3XX5LW.js.map} +0 -0
- /package/dist/{chunk-4WIKMOE3.js.map → chunk-ZZM476NV.js.map} +0 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #2783: the daemon's observe path must persist observe-derived turns
|
|
3
|
+
* into the transcript store, and `memory_summarize_hourly` must report an
|
|
4
|
+
* empty/stale transcript store distinctly instead of a bare unconditional
|
|
5
|
+
* ok. Delegate-mode gateways (and any observe-only client) starve the
|
|
6
|
+
* hourly summarizer otherwise — 11 days of silent empty runs in the field.
|
|
7
|
+
*/
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
import { mkdtemp, readdir, readFile, rm } from "node:fs/promises";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import test from "node:test";
|
|
13
|
+
|
|
14
|
+
import { EngramAccessService } from "./access-service.js";
|
|
15
|
+
import { HourlySummarizer } from "./summarizer.js";
|
|
16
|
+
import { Orchestrator } from "./orchestrator.js";
|
|
17
|
+
import { TranscriptManager } from "./transcript.js";
|
|
18
|
+
import type { CodingContext, PluginConfig } from "./types.js";
|
|
19
|
+
|
|
20
|
+
interface StubOrchestrator {
|
|
21
|
+
config: PluginConfig;
|
|
22
|
+
transcript: TranscriptManager;
|
|
23
|
+
summarizer: HourlySummarizer;
|
|
24
|
+
lcmEngine?: undefined;
|
|
25
|
+
ingestReplayBatch: () => Promise<unknown[]>;
|
|
26
|
+
_codingContextBySession: Map<string, CodingContext>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeService(
|
|
30
|
+
memoryDir: string,
|
|
31
|
+
transcriptEnabled: boolean,
|
|
32
|
+
transcriptSkipChannelTypes: string[] = []
|
|
33
|
+
): { service: EngramAccessService; orchestrator: StubOrchestrator } {
|
|
34
|
+
const config = {
|
|
35
|
+
memoryDir,
|
|
36
|
+
transcriptEnabled,
|
|
37
|
+
transcriptSkipChannelTypes,
|
|
38
|
+
namespacesEnabled: false,
|
|
39
|
+
defaultNamespace: "default",
|
|
40
|
+
} as unknown as PluginConfig;
|
|
41
|
+
const orch = Object.create(Orchestrator.prototype) as Orchestrator;
|
|
42
|
+
const stub: StubOrchestrator = {
|
|
43
|
+
config,
|
|
44
|
+
transcript: new TranscriptManager(config),
|
|
45
|
+
summarizer: new HourlySummarizer(config),
|
|
46
|
+
lcmEngine: undefined,
|
|
47
|
+
ingestReplayBatch: async () => [],
|
|
48
|
+
_codingContextBySession: new Map<string, CodingContext>(),
|
|
49
|
+
};
|
|
50
|
+
Object.assign(orch as unknown as Record<string, unknown>, stub);
|
|
51
|
+
return { service: new EngramAccessService(orch), orchestrator: stub };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function withTempDir(fn: (dir: string) => Promise<void>): Promise<void> {
|
|
55
|
+
const dir = await mkdtemp(path.join(tmpdir(), "remnic-2783-"));
|
|
56
|
+
try {
|
|
57
|
+
await fn(dir);
|
|
58
|
+
} finally {
|
|
59
|
+
await rm(dir, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function readAllTranscriptLines(dir: string): Promise<Array<Record<string, unknown>>> {
|
|
64
|
+
const root = path.join(dir, "transcripts");
|
|
65
|
+
const entries: Array<Record<string, unknown>> = [];
|
|
66
|
+
const typeDirs = await readdir(root, { withFileTypes: true }).catch(() => []);
|
|
67
|
+
for (const typeEnt of typeDirs) {
|
|
68
|
+
if (!typeEnt.isDirectory()) continue;
|
|
69
|
+
const idDirs = await readdir(path.join(root, typeEnt.name), { withFileTypes: true });
|
|
70
|
+
for (const idEnt of idDirs) {
|
|
71
|
+
if (!idEnt.isDirectory()) continue;
|
|
72
|
+
const files = await readdir(path.join(root, typeEnt.name, idEnt.name));
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
if (!file.endsWith(".jsonl")) continue;
|
|
75
|
+
const raw = await readFile(path.join(root, typeEnt.name, idEnt.name, file), "utf-8");
|
|
76
|
+
for (const line of raw.split("\n")) {
|
|
77
|
+
if (line.trim().length === 0) continue;
|
|
78
|
+
entries.push(JSON.parse(line) as Record<string, unknown>);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return entries;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const USER_TURN = "please summarize the replication topology for the fleet";
|
|
87
|
+
const ASSISTANT_TURN = "the fleet uses one primary daemon with a replicated failover copy";
|
|
88
|
+
|
|
89
|
+
test("observe persists user and assistant turns into the transcript store (#2783)", async () => {
|
|
90
|
+
await withTempDir(async (dir) => {
|
|
91
|
+
const { service } = makeService(dir, true);
|
|
92
|
+
const response = await service.observe({
|
|
93
|
+
sessionKey: "agent:delegate-test:session-1",
|
|
94
|
+
messages: [
|
|
95
|
+
{ role: "user", content: USER_TURN },
|
|
96
|
+
{ role: "assistant", content: ASSISTANT_TURN },
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
assert.equal(response.transcriptPersisted, true);
|
|
100
|
+
const entries = await readAllTranscriptLines(dir);
|
|
101
|
+
assert.equal(entries.length, 2);
|
|
102
|
+
assert.equal(entries[0]?.role, "user");
|
|
103
|
+
assert.equal(entries[0]?.content, USER_TURN);
|
|
104
|
+
assert.equal(entries[0]?.sessionKey, "agent:delegate-test:session-1");
|
|
105
|
+
assert.equal(entries[1]?.role, "assistant");
|
|
106
|
+
assert.equal(entries[1]?.content, ASSISTANT_TURN);
|
|
107
|
+
assert.equal(typeof entries[0]?.turnId, "string");
|
|
108
|
+
assert.equal(typeof entries[0]?.timestamp, "string");
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("observe filters short messages below the embedded parity noise floor (#2783)", async () => {
|
|
113
|
+
await withTempDir(async (dir) => {
|
|
114
|
+
const { service } = makeService(dir, true);
|
|
115
|
+
const response = await service.observe({
|
|
116
|
+
sessionKey: "agent:delegate-test:session-2",
|
|
117
|
+
messages: [
|
|
118
|
+
{ role: "user", content: "ok" },
|
|
119
|
+
{ role: "assistant", content: ASSISTANT_TURN },
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
assert.equal(response.transcriptPersisted, true);
|
|
123
|
+
const entries = await readAllTranscriptLines(dir);
|
|
124
|
+
assert.equal(entries.length, 1);
|
|
125
|
+
assert.equal(entries[0]?.role, "assistant");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("a re-POST of the same user turn is deduped; new turns still append (#2783)", async () => {
|
|
130
|
+
await withTempDir(async (dir) => {
|
|
131
|
+
const { service } = makeService(dir, true);
|
|
132
|
+
await service.observe({
|
|
133
|
+
sessionKey: "agent:delegate-test:session-3",
|
|
134
|
+
messages: [
|
|
135
|
+
{ role: "user", content: USER_TURN },
|
|
136
|
+
{ role: "assistant", content: ASSISTANT_TURN },
|
|
137
|
+
],
|
|
138
|
+
});
|
|
139
|
+
// Un-keyed client retry of the SAME turn (no idempotencyKey).
|
|
140
|
+
await service.observe({
|
|
141
|
+
sessionKey: "agent:delegate-test:session-3",
|
|
142
|
+
messages: [
|
|
143
|
+
{ role: "user", content: USER_TURN },
|
|
144
|
+
{ role: "assistant", content: ASSISTANT_TURN },
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
const afterRetry = await readAllTranscriptLines(dir);
|
|
148
|
+
assert.equal(afterRetry.length, 2);
|
|
149
|
+
|
|
150
|
+
// A genuinely new turn still appends.
|
|
151
|
+
await service.observe({
|
|
152
|
+
sessionKey: "agent:delegate-test:session-3",
|
|
153
|
+
messages: [{ role: "user", content: "now check the failover read path end to end please" }],
|
|
154
|
+
});
|
|
155
|
+
const afterNew = await readAllTranscriptLines(dir);
|
|
156
|
+
assert.equal(afterNew.length, 3);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("transcript persistence is gated on the transcriptEnabled capability (#2783)", async () => {
|
|
161
|
+
await withTempDir(async (dir) => {
|
|
162
|
+
const { service } = makeService(dir, false);
|
|
163
|
+
const response = await service.observe({
|
|
164
|
+
sessionKey: "agent:delegate-test:session-4",
|
|
165
|
+
messages: [{ role: "user", content: USER_TURN }],
|
|
166
|
+
});
|
|
167
|
+
assert.equal(response.transcriptPersisted, false);
|
|
168
|
+
const entries = await readAllTranscriptLines(dir);
|
|
169
|
+
assert.equal(entries.length, 0);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("memory_summarize_hourly warns distinctly when the transcript store is empty (#2783)", async () => {
|
|
174
|
+
await withTempDir(async (dir) => {
|
|
175
|
+
const { service } = makeService(dir, true);
|
|
176
|
+
const result = await service.memorySummarizeHourly();
|
|
177
|
+
assert.equal(result.ok, true);
|
|
178
|
+
assert.equal(result.sessionsConsidered, 0);
|
|
179
|
+
assert.equal(result.warning, "transcript store is empty");
|
|
180
|
+
assert.match(result.message, /transcript store is empty/);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("memory_summarize_hourly warns distinctly when the store is stale and the hour was idle (#2783)", async () => {
|
|
185
|
+
await withTempDir(async (dir) => {
|
|
186
|
+
const { service, orchestrator } = makeService(dir, true);
|
|
187
|
+
// Seed one transcript entry far in the past: the store is non-empty but
|
|
188
|
+
// stale, and the target hour has no entries.
|
|
189
|
+
await orchestrator.transcript.append({
|
|
190
|
+
timestamp: new Date(Date.now() - 6 * 60 * 60 * 1000).toISOString(),
|
|
191
|
+
role: "user",
|
|
192
|
+
content: "an old turn from a much earlier hour",
|
|
193
|
+
sessionKey: "agent:delegate-test:session-5",
|
|
194
|
+
turnId: "seed-turn",
|
|
195
|
+
});
|
|
196
|
+
const result = await service.memorySummarizeHourly();
|
|
197
|
+
assert.equal(result.ok, true);
|
|
198
|
+
assert.ok(result.sessionsConsidered > 0);
|
|
199
|
+
assert.equal(result.sessionsWithEntries, 0);
|
|
200
|
+
assert.equal(result.staleStore, true);
|
|
201
|
+
assert.equal(result.warning, "no transcript entries for the target hour and no new entries recently");
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("observeTranscriptSessionKey scopes transcripts to the effective write namespace (#2783 review)", async () => {
|
|
206
|
+
const { observeTranscriptSessionKey } = await import("./access-observe-transcript.js");
|
|
207
|
+
const config = { defaultNamespace: "generalist" } as { defaultNamespace: string };
|
|
208
|
+
// Same client-controlled sessionKey from two principals in different
|
|
209
|
+
// namespaces must not share one transcript identity.
|
|
210
|
+
const a = observeTranscriptSessionKey("agent:shared-key:s1", "project-origin-aaa", config);
|
|
211
|
+
const b = observeTranscriptSessionKey("agent:shared-key:s1", "project-origin-bbb", config);
|
|
212
|
+
assert.notEqual(a, b);
|
|
213
|
+
assert.ok(a.includes("project-origin-aaa"));
|
|
214
|
+
assert.ok(b.includes("project-origin-bbb"));
|
|
215
|
+
// A default-store write keeps the raw key (single-store deployments
|
|
216
|
+
// unchanged, mirroring the LCM archive key rules).
|
|
217
|
+
assert.equal(observeTranscriptSessionKey("agent:shared-key:s1", "generalist", config), "agent:shared-key:s1");
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("skip-listed channel types report transcriptPersisted=false, not a silent success (#2783 review)", async () => {
|
|
221
|
+
await withTempDir(async (dir) => {
|
|
222
|
+
// cron is in the default skip list; a session whose channel type
|
|
223
|
+
// resolves to it must not report persisted=true for a no-op append.
|
|
224
|
+
const { service } = makeService(dir, true, ["cron"]);
|
|
225
|
+
const response = await service.observe({
|
|
226
|
+
sessionKey: "agent:nightly:cron:job-1",
|
|
227
|
+
messages: [{ role: "user", content: "this nightly cron turn must not claim transcript persistence" }],
|
|
228
|
+
});
|
|
229
|
+
assert.equal(response.transcriptPersisted, false);
|
|
230
|
+
const entries = await readAllTranscriptLines(dir);
|
|
231
|
+
assert.equal(entries.length, 0);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("overlapping identical observes do not double-append the same turn (#2783 review)", async () => {
|
|
236
|
+
await withTempDir(async (dir) => {
|
|
237
|
+
const { service } = makeService(dir, true);
|
|
238
|
+
const [a, b] = await Promise.all([
|
|
239
|
+
service.observe({
|
|
240
|
+
sessionKey: "agent:overlap:s1",
|
|
241
|
+
messages: [{ role: "user", content: "the same turn submitted concurrently by a retrying client" }],
|
|
242
|
+
}),
|
|
243
|
+
service.observe({
|
|
244
|
+
sessionKey: "agent:overlap:s1",
|
|
245
|
+
messages: [{ role: "user", content: "the same turn submitted concurrently by a retrying client" }],
|
|
246
|
+
}),
|
|
247
|
+
]);
|
|
248
|
+
const entries = await readAllTranscriptLines(dir);
|
|
249
|
+
assert.equal(entries.length, 1);
|
|
250
|
+
assert.equal(a.transcriptPersisted !== b.transcriptPersisted, true);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observe-derived transcript persistence (issue #2783).
|
|
3
|
+
*
|
|
4
|
+
* Delegate-mode gateways POST every turn to `/observe`; without a transcript
|
|
5
|
+
* append in the daemon's observe path the transcript store never grows and
|
|
6
|
+
* the hourly summarizer starves silently while every run reports ok. This
|
|
7
|
+
* module is that append: it mirrors the embedded runtime's `agent_end`
|
|
8
|
+
* handler (src/index.ts) — same `TranscriptManager`, same entry shape, same
|
|
9
|
+
* `transcriptEnabled` presentation gate, same 10-char noise floor.
|
|
10
|
+
*
|
|
11
|
+
* Turns are deduped against a bounded process-lifetime (session, role,
|
|
12
|
+
* content) fingerprint — the daemon-side equivalent of the embedded
|
|
13
|
+
* runtime's `observedInboundContentFingerprints`, extended to both roles
|
|
14
|
+
* because an un-keyed client re-POST always carries the whole turn — so a
|
|
15
|
+
* retry cannot double-write it.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
19
|
+
import { lcmSessionKeyForNamespace } from "./coding/coding-namespace.js";
|
|
20
|
+
import type { PluginConfig } from "./types.js";
|
|
21
|
+
import { log } from "./logger.js";
|
|
22
|
+
import type { Orchestrator } from "./orchestrator.js";
|
|
23
|
+
import type { TranscriptEntry } from "./types.js";
|
|
24
|
+
|
|
25
|
+
const OBSERVE_TRANSCRIPT_DEDUPE_MAX_ENTRIES = 8192;
|
|
26
|
+
const OBSERVE_TRANSCRIPT_MIN_CONTENT_CHARS = 10;
|
|
27
|
+
/**
|
|
28
|
+
* A fingerprint only suppresses re-POSTs inside this window. A client retry
|
|
29
|
+
* lands seconds later; a session LEGITIMATELY repeating the same >10-char
|
|
30
|
+
* turn usually does so minutes or hours later, and that repeat is a real
|
|
31
|
+
* conversation event the transcripts must keep (review: preserve legitimate
|
|
32
|
+
* repeated turns).
|
|
33
|
+
*/
|
|
34
|
+
const OBSERVE_TRANSCRIPT_DEDUPE_TTL_MS = 10 * 60 * 1000;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The transcript-side session identity for an observe payload (issue #2783
|
|
38
|
+
* review: namespace scoping). Two authenticated principals can submit the
|
|
39
|
+
* same client-controlled sessionKey while resolving to different effective
|
|
40
|
+
* write namespaces; persisting through the raw key would let one
|
|
41
|
+
* principal's transcript-derived summaries surface under the other's
|
|
42
|
+
* session. Mirror the LCM archive's answer (rule 42 parity): prefix the
|
|
43
|
+
* key with the effective write namespace whenever it diverges from the
|
|
44
|
+
* default store. The summarizer lists sessions from the store itself, so
|
|
45
|
+
* reads self-consistently follow the same prefixed keys.
|
|
46
|
+
*/
|
|
47
|
+
export function observeTranscriptSessionKey(
|
|
48
|
+
sessionKey: string,
|
|
49
|
+
writeNamespace: string,
|
|
50
|
+
config: Pick<PluginConfig, "defaultNamespace">
|
|
51
|
+
): string {
|
|
52
|
+
return lcmSessionKeyForNamespace(writeNamespace, sessionKey, config.defaultNamespace) ?? sessionKey;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Bounded FIFO of seen fingerprints; insertion order is the eviction order. */
|
|
56
|
+
export class ObserveTranscriptPersister {
|
|
57
|
+
private readonly seenFingerprintsAt = new Map<string, number>();
|
|
58
|
+
/** In-flight appends by fingerprint: an overlapping identical observe waits for the first append instead of double-writing. */
|
|
59
|
+
private readonly inflightAppends = new Map<string, Promise<void>>();
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Append every eligible message of an observe payload to the per-session
|
|
63
|
+
* transcript store. Best-effort: a failing append logs and does not fail
|
|
64
|
+
* the observe. Returns true when at least one turn was appended.
|
|
65
|
+
*/
|
|
66
|
+
async persist(
|
|
67
|
+
orchestrator: Orchestrator,
|
|
68
|
+
sessionKey: string,
|
|
69
|
+
messages: ReadonlyArray<{ role: string; content: string }>,
|
|
70
|
+
rawSessionKey?: string
|
|
71
|
+
): Promise<boolean> {
|
|
72
|
+
let persisted = false;
|
|
73
|
+
// TranscriptManager.append silently no-ops for skip-listed channel types
|
|
74
|
+
// (cron by default) — check BEFORE appending so the response's
|
|
75
|
+
// transcriptPersisted stays truthful (review: report skipped appends).
|
|
76
|
+
// The channel identity must derive from the RAW session key: the legacy
|
|
77
|
+
// parser requires the key to start with "agent:", so a namespace-prefixed
|
|
78
|
+
// transcript identity would always classify as "session" and the skip
|
|
79
|
+
// list would silently not apply to namespaced cron sessions (review r4).
|
|
80
|
+
const { channelType } = orchestrator.transcript.getTranscriptPath(rawSessionKey ?? sessionKey);
|
|
81
|
+
if (orchestrator.config.transcriptSkipChannelTypes.includes(channelType)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
for (const message of messages) {
|
|
85
|
+
if (message.content.length < OBSERVE_TRANSCRIPT_MIN_CONTENT_CHARS) continue;
|
|
86
|
+
// Fixed-size digest, never the raw content: 8192 retained entries of
|
|
87
|
+
// full turn text is an avoidable heap-exhaustion surface on a daemon
|
|
88
|
+
// that accepts arbitrary observe payloads (review round 2).
|
|
89
|
+
const fingerprint = createHash("sha256")
|
|
90
|
+
.update(`${sessionKey}\0${message.role}\0${message.content}`)
|
|
91
|
+
.digest("hex");
|
|
92
|
+
// Two identical observes can overlap before either records its
|
|
93
|
+
// fingerprint; both would then append and the transcript would carry
|
|
94
|
+
// the turn twice. The attempt loop serializes per fingerprint: a caller
|
|
95
|
+
// that finds an in-flight append awaits it and RE-RUNS BOTH checks — on
|
|
96
|
+
// success the completed-set check skips the message; on failure (no
|
|
97
|
+
// fingerprint recorded) exactly ONE waiter proceeds to retry, because
|
|
98
|
+
// the check-then-register sequence has no await between its steps and
|
|
99
|
+
// is therefore atomic on the event loop (review r4).
|
|
100
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
101
|
+
const seenAt = this.seenFingerprintsAt.get(fingerprint);
|
|
102
|
+
if (seenAt !== undefined && Date.now() - seenAt < OBSERVE_TRANSCRIPT_DEDUPE_TTL_MS) {
|
|
103
|
+
break; // duplicate within the retry window — skip the message
|
|
104
|
+
}
|
|
105
|
+
const inflight = this.inflightAppends.get(fingerprint);
|
|
106
|
+
if (inflight) {
|
|
107
|
+
await inflight;
|
|
108
|
+
continue; // re-run both checks with the append's outcome visible
|
|
109
|
+
}
|
|
110
|
+
const entry: TranscriptEntry = {
|
|
111
|
+
timestamp: new Date().toISOString(),
|
|
112
|
+
role: message.role as TranscriptEntry["role"],
|
|
113
|
+
content: message.content,
|
|
114
|
+
sessionKey,
|
|
115
|
+
turnId: randomUUID(),
|
|
116
|
+
};
|
|
117
|
+
const appendPromise = orchestrator.transcript
|
|
118
|
+
.append(entry)
|
|
119
|
+
.then(() => {
|
|
120
|
+
// Remember only after a successful append: a transient failure
|
|
121
|
+
// must not permanently swallow the turn — the client's retry has
|
|
122
|
+
// to be able to re-append it (review round 2).
|
|
123
|
+
this.remember(fingerprint);
|
|
124
|
+
persisted = true;
|
|
125
|
+
})
|
|
126
|
+
.catch((err) => {
|
|
127
|
+
// Same policy as the LCM enqueue in the observe path: transcript
|
|
128
|
+
// persistence must never fail the observe itself.
|
|
129
|
+
log.error(`access-observe transcript append failed: ${err}`);
|
|
130
|
+
})
|
|
131
|
+
.finally(() => {
|
|
132
|
+
this.inflightAppends.delete(fingerprint);
|
|
133
|
+
});
|
|
134
|
+
this.inflightAppends.set(fingerprint, appendPromise);
|
|
135
|
+
await appendPromise;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return persisted;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private remember(fingerprint: string): void {
|
|
143
|
+
// Map.set keeps an existing key at its ORIGINAL insertion position, so a
|
|
144
|
+
// TTL-refreshed fingerprint could still be the FIFO-oldest and get
|
|
145
|
+
// evicted immediately — delete first to move it to the end (review r4).
|
|
146
|
+
this.seenFingerprintsAt.delete(fingerprint);
|
|
147
|
+
this.seenFingerprintsAt.set(fingerprint, Date.now());
|
|
148
|
+
if (this.seenFingerprintsAt.size > OBSERVE_TRANSCRIPT_DEDUPE_MAX_ENTRIES) {
|
|
149
|
+
const oldest = this.seenFingerprintsAt.keys().next().value;
|
|
150
|
+
if (typeof oldest === "string") this.seenFingerprintsAt.delete(oldest);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|