@remnic/core 9.57.6 → 9.58.0
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 +12 -11
- package/dist/access-admin-ops-surface.js +25 -24
- package/dist/access-authorization-probe.d.ts +12 -11
- package/dist/access-authorization-probe.js +26 -25
- package/dist/access-boundary.d.ts +12 -11
- package/dist/access-boundary.js +25 -24
- package/dist/access-cli.js +77 -76
- 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 +12 -11
- package/dist/access-extraction-force-flush.js +25 -24
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +12 -11
- package/dist/access-http-lifecycle-flush.d.ts +12 -11
- package/dist/access-http-offline-stream.d.ts +12 -11
- package/dist/access-http-query.js +25 -24
- package/dist/access-http.d.ts +13 -12
- package/dist/access-http.js +36 -35
- package/dist/access-identity-continuity-surface.d.ts +10 -9
- package/dist/access-identity-continuity-surface.js +25 -24
- package/dist/access-lcm-surface.d.ts +12 -11
- package/dist/access-lcm-surface.js +25 -24
- package/dist/access-mcp.d.ts +12 -11
- package/dist/access-mcp.js +32 -31
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-Bpt-SYP0.d.ts → access-namespace-preflight-TBXz-8s_.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +25 -24
- package/dist/access-observe-write-surface.d.ts +12 -11
- package/dist/access-observe-write-surface.js +25 -24
- package/dist/access-offline-manifest.d.ts +10 -9
- package/dist/access-operations-batch.js +27 -26
- package/dist/access-operations.d.ts +12 -11
- package/dist/access-operations.js +31 -30
- package/dist/access-recall-concurrency.d.ts +12 -11
- package/dist/access-recall-concurrency.js +25 -24
- package/dist/access-recall-response.d.ts +12 -11
- package/dist/access-recall-response.js +25 -24
- package/dist/access-recall-surface.d.ts +12 -11
- package/dist/access-recall-surface.js +25 -24
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-4DO8XMq6.d.ts → access-service-BQkRul4d.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +12 -11
- package/dist/access-service.d.ts +12 -11
- package/dist/access-service.js +25 -24
- package/dist/access-surface-catalog.d.ts +12 -11
- package/dist/access-surface-catalog.js +27 -26
- 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 +1 -1
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +10 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +10 -10
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-surprise.js +4 -3
- 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/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/{catalog-BasnO3Bw.d.ts → catalog-z1UerMbh.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +14 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-P6WBAR27.js → chunk-2GBFKHBZ.js} +9 -9
- package/dist/chunk-2GBFKHBZ.js.map +1 -0
- package/dist/{chunk-YTZA7U6Q.js → chunk-2VHCLHZ5.js} +3 -3
- package/dist/{chunk-NEJQ65NV.js → chunk-4CLE2LXB.js} +2 -2
- package/dist/{chunk-3VFVQDZO.js → chunk-4IIKJOYM.js} +1 -1
- package/dist/{chunk-3VFVQDZO.js.map → chunk-4IIKJOYM.js.map} +1 -1
- package/dist/{chunk-JLNBQWZ2.js → chunk-5JMAGU26.js} +7 -6
- package/dist/{chunk-JLNBQWZ2.js.map → chunk-5JMAGU26.js.map} +1 -1
- package/dist/{chunk-VDX2J7OX.js → chunk-5W7CTZ2E.js} +4 -4
- package/dist/{chunk-CZUHNJHX.js → chunk-6C7Q6NG3.js} +13 -13
- package/dist/{chunk-LMXUWAXW.js → chunk-6TBIWIAG.js} +9 -8
- package/dist/chunk-6TBIWIAG.js.map +1 -0
- package/dist/{chunk-4O6R3GPK.js → chunk-6W2ISYUV.js} +4 -4
- package/dist/{chunk-3AJOJOFP.js → chunk-77DAFTUU.js} +3 -3
- package/dist/{chunk-IKT6ZVO7.js → chunk-7DHFB5SG.js} +3 -3
- package/dist/{chunk-SFR7J2G6.js → chunk-7G34CBKS.js} +2 -2
- package/dist/{chunk-IT57AOMC.js → chunk-AH2NX6S7.js} +3 -3
- package/dist/{chunk-HYQJQGD3.js → chunk-AM4T6CHX.js} +49 -35
- package/dist/chunk-AM4T6CHX.js.map +1 -0
- package/dist/{chunk-Z54EM5YZ.js → chunk-B2QHVLJO.js} +60 -30
- package/dist/chunk-B2QHVLJO.js.map +1 -0
- package/dist/{chunk-FI3PIOOI.js → chunk-B4CSPFYN.js} +8 -8
- package/dist/{chunk-7PJARJS4.js → chunk-BPM6UHUL.js} +2 -2
- package/dist/{chunk-PPUTUOC3.js → chunk-BTHDQOF4.js} +5 -5
- package/dist/{chunk-DUHMYBVE.js → chunk-CZGOLAEW.js} +41 -41
- package/dist/{chunk-5PGYCWA7.js → chunk-DE6YCZEE.js} +2 -2
- package/dist/{chunk-JOA4Q765.js → chunk-EUYWQ7TS.js} +2 -2
- package/dist/{chunk-O5AFC5KM.js → chunk-EWL5DICB.js} +2 -2
- package/dist/{chunk-4YZCIK5E.js → chunk-EZXGJJXM.js} +2 -2
- package/dist/{chunk-GXIY65UH.js → chunk-FI5EAP4N.js} +2 -2
- package/dist/{chunk-YOKSRIFI.js → chunk-FUWS2MNJ.js} +4 -4
- package/dist/{chunk-6RK2X7BR.js → chunk-G3JFFUKR.js} +2 -2
- package/dist/{chunk-VANZKHTN.js → chunk-G5OB4XZX.js} +4 -4
- package/dist/{chunk-TEHPIMXD.js → chunk-HK6KYIF6.js} +2 -2
- package/dist/{chunk-XBGLEOID.js → chunk-I4BLRM7X.js} +9 -9
- package/dist/{chunk-5ZIWRMZM.js → chunk-IVKIODHO.js} +7 -6
- package/dist/chunk-IVKIODHO.js.map +1 -0
- package/dist/{chunk-6SX4MY5Q.js → chunk-J65AKOD6.js} +2 -2
- package/dist/{chunk-BPWZDHFM.js → chunk-J6QIAYNR.js} +2 -2
- package/dist/{chunk-XL3TATMJ.js → chunk-JHMAYABJ.js} +4 -4
- package/dist/{chunk-F7M36OG2.js → chunk-JNWISMYG.js} +10 -10
- package/dist/{chunk-VYIXCMUP.js → chunk-KBIIE57I.js} +3 -3
- package/dist/{chunk-QKPDN325.js → chunk-KF75ANST.js} +6 -3
- package/dist/chunk-KF75ANST.js.map +1 -0
- package/dist/{chunk-24PNX2GF.js → chunk-KXYMU4IN.js} +3 -3
- package/dist/{chunk-FKTD7IVS.js → chunk-L3JVAM5Q.js} +2 -2
- package/dist/{chunk-5QHDXMXP.js → chunk-LLZKOSGM.js} +1 -1
- package/dist/{chunk-5QHDXMXP.js.map → chunk-LLZKOSGM.js.map} +1 -1
- package/dist/{chunk-LIF6DO6U.js → chunk-MG7GI4TT.js} +2 -2
- package/dist/{chunk-RUZM6Z52.js → chunk-MMZK2DWN.js} +1 -1
- package/dist/{chunk-NTJ6TY44.js → chunk-ODAE36PG.js} +3 -3
- package/dist/{chunk-QFN4U7AG.js → chunk-ODZKV2F7.js} +3 -3
- package/dist/{chunk-QFN4U7AG.js.map → chunk-ODZKV2F7.js.map} +1 -1
- package/dist/{chunk-YLHM5BQQ.js → chunk-OLX2HJFW.js} +4 -4
- package/dist/{chunk-DNC4A7RS.js → chunk-OU7RWWW6.js} +2 -2
- package/dist/{chunk-L3LRWDJW.js → chunk-OV36CROW.js} +3 -3
- package/dist/{chunk-BXLOS5AJ.js → chunk-OWHERGF2.js} +2 -2
- package/dist/{chunk-CSV34HIW.js → chunk-P5OYNV7B.js} +2 -2
- package/dist/{chunk-SNW3YRO6.js → chunk-P6GOYLHN.js} +2 -2
- package/dist/{chunk-REVMY7RA.js → chunk-PFPNUFKZ.js} +109 -59
- package/dist/chunk-PFPNUFKZ.js.map +1 -0
- package/dist/{chunk-USGKHF36.js → chunk-QUJC22CT.js} +2 -2
- package/dist/{chunk-BVRREV3N.js → chunk-R7IV3EUJ.js} +2 -2
- package/dist/{chunk-KSXJOC4F.js → chunk-RDFF2NAU.js} +18 -8
- package/dist/chunk-RDFF2NAU.js.map +1 -0
- package/dist/{chunk-D4LVHPOA.js → chunk-RXN7Z2V5.js} +3 -3
- package/dist/{chunk-7VSHDLJQ.js → chunk-T2VJ2EO5.js} +6 -6
- package/dist/chunk-TOTT6S2V.js +20 -0
- package/dist/chunk-TOTT6S2V.js.map +1 -0
- package/dist/{chunk-U7BMN33M.js → chunk-UBSM6TZP.js} +2 -2
- package/dist/{chunk-DQEMWVMT.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/{chunk-U7XLOSG2.js → chunk-VIM6QH4D.js} +2 -2
- package/dist/{chunk-LJJWFV2Q.js → chunk-VJXSAJFW.js} +2 -2
- package/dist/{chunk-HZC3OECF.js → chunk-VOKK4WCG.js} +2 -2
- package/dist/{chunk-LTAVSOZW.js → chunk-WVP2I6C5.js} +5 -4
- package/dist/chunk-WVP2I6C5.js.map +1 -0
- package/dist/{chunk-LRDP2AC2.js → chunk-YBCZTBN2.js} +2 -2
- package/dist/{chunk-USAUBGBC.js → chunk-YKZFX2HQ.js} +2 -2
- package/dist/{chunk-I2GIYTRU.js → chunk-ZOGOOSB3.js} +2 -2
- package/dist/{chunk-PBGWYM3H.js → chunk-ZPUIRTIZ.js} +27 -15
- package/dist/chunk-ZPUIRTIZ.js.map +1 -0
- package/dist/chunking.js +2 -1
- package/dist/{cli-CQdYilcx.d.ts → cli-DsyVvOFP.d.ts} +5 -5
- package/dist/cli.d.ts +14 -13
- package/dist/cli.js +57 -56
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +10 -10
- package/dist/compounding/preference-consolidator.d.ts +2 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +12 -11
- package/dist/connectors/codex-materialize.d.ts +7 -12
- package/dist/connectors/codex-materialize.js +2 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +12 -11
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +4 -4
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +12 -12
- 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/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +12 -12
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +3 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-C_K_AHcv.d.ts → dependency-propagation-delivery-DdwSc1qh.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 +2 -2
- package/dist/entity-retrieval.js +10 -10
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +10 -9
- package/dist/external-wiki-access.d.ts +12 -11
- package/dist/external-wiki-access.js +26 -25
- 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 +12 -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 -15
- 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-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.d.ts +1 -1
- 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.d.ts +22 -21
- package/dist/index.js +81 -80
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/archive.d.ts +3 -2
- package/dist/lcm/archive.js +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +5 -4
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +7 -6
- package/dist/lcm/recall.d.ts +1 -0
- package/dist/lcm/summarizer.d.ts +1 -0
- package/dist/lcm/summarizer.js +3 -2
- package/dist/lcm/tools.d.ts +2 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +2 -3
- package/dist/local-llm.js +2 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +10 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +11 -11
- package/dist/{maintenance-DdP931i9.d.ts → maintenance-DvkiF7fm.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +12 -11
- 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-snapshot.d.ts +1 -1
- 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 +11 -11
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +10 -10
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +13 -13
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +18 -18
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +15 -15
- package/dist/{orchestrator-DxUWX7gs.d.ts → orchestrator-CXPIzs3D.d.ts} +9 -9
- package/dist/orchestrator.d.ts +10 -9
- package/dist/orchestrator.js +77 -76
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-BKUMU1vU.d.ts → pipeline-BuYWU9rt.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-Dw0bJhcC.d.ts → public-http-m9x1Qyzn.d.ts} +1 -1
- package/dist/{qmd-DJP-GLFe.d.ts → qmd-DYnrPw-m.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 +4 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +5 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +4 -3
- package/dist/recall-xray.d.ts +2 -7
- package/dist/recall-xray.js +3 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- 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 +4 -3
- 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/{scope-profiles-CaKcnB-6.d.ts → scope-profiles-C1QG4Cmv.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 +6 -6
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +11 -11
- 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-chunking.js +3 -2
- package/dist/{semantic-consolidation-P0eMWqh-.d.ts → semantic-consolidation-DMeX8XS0.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +14 -13
- package/dist/semantic-rule-promotion.js +10 -10
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +10 -10
- package/dist/{service-D5GQLxq_.d.ts → service-CT3ENiTO.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/session-observer-state.js +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 +12 -11
- package/dist/{storage-DIyil2ll.d.ts → storage-B0L76y7N.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +9 -9
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +15 -14
- package/dist/support-passport/index.js +28 -27
- 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/token-estimate.d.ts +10 -0
- package/dist/token-estimate.js +8 -0
- package/dist/token-estimate.js.map +1 -0
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -6
- package/dist/transcript.js +2 -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-CbXieHKr.d.ts → types-D7pB0QwO.d.ts} +1 -1
- 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 +10 -10
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +12 -2
- package/src/chunking.ts +6 -12
- package/src/config.ts +2 -0
- package/src/connectors/codex-materialize.ts +21 -26
- package/src/lcm/archive.ts +4 -5
- package/src/lcm/engine.ts +55 -34
- package/src/lcm/summarizer.ts +27 -16
- package/src/lcm-engine.test.ts +82 -2
- package/src/local-llm.ts +4 -6
- package/src/memory-extension-host/render-extensions-block.ts +3 -9
- package/src/orchestration/recall-section-coordinator.ts +93 -27
- package/src/recall-token-budget.test.ts +51 -0
- package/src/recall-xray.ts +4 -11
- package/src/semantic-chunking.ts +5 -12
- package/src/session-observer-state.ts +3 -3
- package/src/testing/subjects/recall-budget.test.ts +21 -5
- package/src/token-estimate.test.ts +38 -0
- package/src/token-estimate.ts +22 -0
- package/src/transcript.test.ts +38 -3
- package/src/transcript.ts +58 -59
- package/src/types.ts +1 -1
- package/dist/chunk-5ZIWRMZM.js.map +0 -1
- package/dist/chunk-HYQJQGD3.js.map +0 -1
- package/dist/chunk-KSXJOC4F.js.map +0 -1
- package/dist/chunk-LMXUWAXW.js.map +0 -1
- package/dist/chunk-LTAVSOZW.js.map +0 -1
- package/dist/chunk-P6WBAR27.js.map +0 -1
- package/dist/chunk-PBGWYM3H.js.map +0 -1
- package/dist/chunk-QKPDN325.js.map +0 -1
- package/dist/chunk-REVMY7RA.js.map +0 -1
- package/dist/chunk-Z54EM5YZ.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{chunk-YTZA7U6Q.js.map → chunk-2VHCLHZ5.js.map} +0 -0
- /package/dist/{chunk-NEJQ65NV.js.map → chunk-4CLE2LXB.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-5W7CTZ2E.js.map} +0 -0
- /package/dist/{chunk-CZUHNJHX.js.map → chunk-6C7Q6NG3.js.map} +0 -0
- /package/dist/{chunk-4O6R3GPK.js.map → chunk-6W2ISYUV.js.map} +0 -0
- /package/dist/{chunk-3AJOJOFP.js.map → chunk-77DAFTUU.js.map} +0 -0
- /package/dist/{chunk-IKT6ZVO7.js.map → chunk-7DHFB5SG.js.map} +0 -0
- /package/dist/{chunk-SFR7J2G6.js.map → chunk-7G34CBKS.js.map} +0 -0
- /package/dist/{chunk-IT57AOMC.js.map → chunk-AH2NX6S7.js.map} +0 -0
- /package/dist/{chunk-FI3PIOOI.js.map → chunk-B4CSPFYN.js.map} +0 -0
- /package/dist/{chunk-7PJARJS4.js.map → chunk-BPM6UHUL.js.map} +0 -0
- /package/dist/{chunk-PPUTUOC3.js.map → chunk-BTHDQOF4.js.map} +0 -0
- /package/dist/{chunk-DUHMYBVE.js.map → chunk-CZGOLAEW.js.map} +0 -0
- /package/dist/{chunk-5PGYCWA7.js.map → chunk-DE6YCZEE.js.map} +0 -0
- /package/dist/{chunk-JOA4Q765.js.map → chunk-EUYWQ7TS.js.map} +0 -0
- /package/dist/{chunk-O5AFC5KM.js.map → chunk-EWL5DICB.js.map} +0 -0
- /package/dist/{chunk-4YZCIK5E.js.map → chunk-EZXGJJXM.js.map} +0 -0
- /package/dist/{chunk-GXIY65UH.js.map → chunk-FI5EAP4N.js.map} +0 -0
- /package/dist/{chunk-YOKSRIFI.js.map → chunk-FUWS2MNJ.js.map} +0 -0
- /package/dist/{chunk-6RK2X7BR.js.map → chunk-G3JFFUKR.js.map} +0 -0
- /package/dist/{chunk-VANZKHTN.js.map → chunk-G5OB4XZX.js.map} +0 -0
- /package/dist/{chunk-TEHPIMXD.js.map → chunk-HK6KYIF6.js.map} +0 -0
- /package/dist/{chunk-XBGLEOID.js.map → chunk-I4BLRM7X.js.map} +0 -0
- /package/dist/{chunk-6SX4MY5Q.js.map → chunk-J65AKOD6.js.map} +0 -0
- /package/dist/{chunk-BPWZDHFM.js.map → chunk-J6QIAYNR.js.map} +0 -0
- /package/dist/{chunk-XL3TATMJ.js.map → chunk-JHMAYABJ.js.map} +0 -0
- /package/dist/{chunk-F7M36OG2.js.map → chunk-JNWISMYG.js.map} +0 -0
- /package/dist/{chunk-VYIXCMUP.js.map → chunk-KBIIE57I.js.map} +0 -0
- /package/dist/{chunk-24PNX2GF.js.map → chunk-KXYMU4IN.js.map} +0 -0
- /package/dist/{chunk-FKTD7IVS.js.map → chunk-L3JVAM5Q.js.map} +0 -0
- /package/dist/{chunk-LIF6DO6U.js.map → chunk-MG7GI4TT.js.map} +0 -0
- /package/dist/{chunk-RUZM6Z52.js.map → chunk-MMZK2DWN.js.map} +0 -0
- /package/dist/{chunk-NTJ6TY44.js.map → chunk-ODAE36PG.js.map} +0 -0
- /package/dist/{chunk-YLHM5BQQ.js.map → chunk-OLX2HJFW.js.map} +0 -0
- /package/dist/{chunk-DNC4A7RS.js.map → chunk-OU7RWWW6.js.map} +0 -0
- /package/dist/{chunk-L3LRWDJW.js.map → chunk-OV36CROW.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-CSV34HIW.js.map → chunk-P5OYNV7B.js.map} +0 -0
- /package/dist/{chunk-SNW3YRO6.js.map → chunk-P6GOYLHN.js.map} +0 -0
- /package/dist/{chunk-USGKHF36.js.map → chunk-QUJC22CT.js.map} +0 -0
- /package/dist/{chunk-BVRREV3N.js.map → chunk-R7IV3EUJ.js.map} +0 -0
- /package/dist/{chunk-D4LVHPOA.js.map → chunk-RXN7Z2V5.js.map} +0 -0
- /package/dist/{chunk-7VSHDLJQ.js.map → chunk-T2VJ2EO5.js.map} +0 -0
- /package/dist/{chunk-U7BMN33M.js.map → chunk-UBSM6TZP.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-U7XLOSG2.js.map → chunk-VIM6QH4D.js.map} +0 -0
- /package/dist/{chunk-LJJWFV2Q.js.map → chunk-VJXSAJFW.js.map} +0 -0
- /package/dist/{chunk-HZC3OECF.js.map → chunk-VOKK4WCG.js.map} +0 -0
- /package/dist/{chunk-LRDP2AC2.js.map → chunk-YBCZTBN2.js.map} +0 -0
- /package/dist/{chunk-USAUBGBC.js.map → chunk-YKZFX2HQ.js.map} +0 -0
- /package/dist/{chunk-I2GIYTRU.js.map → chunk-ZOGOOSB3.js.map} +0 -0
package/src/chunking.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* Preserves coherent thoughts by never splitting mid-sentence.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { estimateTokenCount } from "./token-estimate.js";
|
|
9
|
+
|
|
8
10
|
export interface ChunkingConfig {
|
|
9
11
|
/** Target tokens per chunk (default 200) */
|
|
10
12
|
targetTokens: number;
|
|
@@ -37,14 +39,6 @@ export const DEFAULT_CHUNKING_CONFIG: ChunkingConfig = {
|
|
|
37
39
|
overlapSentences: 2,
|
|
38
40
|
};
|
|
39
41
|
|
|
40
|
-
/**
|
|
41
|
-
* Estimate token count for text.
|
|
42
|
-
* Rough approximation: ~4 characters per token for English.
|
|
43
|
-
*/
|
|
44
|
-
function estimateTokens(text: string): number {
|
|
45
|
-
return Math.ceil(text.length / 4);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
42
|
/**
|
|
49
43
|
* Split text into sentences.
|
|
50
44
|
*
|
|
@@ -189,7 +183,7 @@ export function chunkContent(
|
|
|
189
183
|
content: string,
|
|
190
184
|
config: ChunkingConfig = DEFAULT_CHUNKING_CONFIG,
|
|
191
185
|
): ChunkResult {
|
|
192
|
-
const totalTokens =
|
|
186
|
+
const totalTokens = estimateTokenCount(content);
|
|
193
187
|
|
|
194
188
|
// Don't chunk if below minimum threshold
|
|
195
189
|
if (totalTokens < config.minTokens) {
|
|
@@ -224,7 +218,7 @@ export function chunkContent(
|
|
|
224
218
|
|
|
225
219
|
for (let i = 0; i < sentences.length; i++) {
|
|
226
220
|
const sentence = sentences[i];
|
|
227
|
-
const sentenceTokens =
|
|
221
|
+
const sentenceTokens = estimateTokenCount(sentence);
|
|
228
222
|
|
|
229
223
|
// Add sentence to current chunk
|
|
230
224
|
currentChunkSentences.push(sentence);
|
|
@@ -241,7 +235,7 @@ export function chunkContent(
|
|
|
241
235
|
chunks.push({
|
|
242
236
|
content: chunkContent,
|
|
243
237
|
index: chunkIndex,
|
|
244
|
-
tokenCount:
|
|
238
|
+
tokenCount: estimateTokenCount(chunkContent),
|
|
245
239
|
});
|
|
246
240
|
chunkIndex++;
|
|
247
241
|
|
|
@@ -256,7 +250,7 @@ export function chunkContent(
|
|
|
256
250
|
currentTokens = 0;
|
|
257
251
|
} else {
|
|
258
252
|
currentChunkSentences = currentChunkSentences.slice(-overlapCount);
|
|
259
|
-
currentTokens = currentChunkSentences.reduce((sum, s) => sum +
|
|
253
|
+
currentTokens = currentChunkSentences.reduce((sum, s) => sum + estimateTokenCount(s), 0);
|
|
260
254
|
}
|
|
261
255
|
}
|
|
262
256
|
}
|
package/src/config.ts
CHANGED
|
@@ -4508,6 +4508,8 @@ function buildRecallPipelineConfig(cfg: Record<string, unknown>): RecallPipeline
|
|
|
4508
4508
|
? Math.max(0, Math.floor(cfg.maxMemoryTokens))
|
|
4509
4509
|
: 2000;
|
|
4510
4510
|
const recallBudgetCharsRaw = clampNonNegativeNumber(cfg.recallBudgetChars);
|
|
4511
|
+
// Keep four characters per token as Latin-script headroom. Assemblers enforce
|
|
4512
|
+
// maxMemoryTokens with the shared script-aware estimator.
|
|
4511
4513
|
const recallBudgetChars = recallBudgetCharsRaw ?? maxMemoryTokens * 4;
|
|
4512
4514
|
|
|
4513
4515
|
const rawPipeline = cfg.recallPipeline;
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
* - **Idempotent no-ops.** A content hash is written into the sentinel. If
|
|
29
29
|
* the re-rendered hash matches the previous run, we skip writes entirely.
|
|
30
30
|
* - **Token budget.** `memory_summary.md` is truncated to fit under the
|
|
31
|
-
* configured token
|
|
32
|
-
*
|
|
31
|
+
* configured script-aware token estimate, leaving headroom under Codex's
|
|
32
|
+
* 5000-token summary cap.
|
|
33
33
|
*
|
|
34
34
|
* Privacy
|
|
35
35
|
* ───────
|
|
@@ -47,6 +47,7 @@ import path from "node:path";
|
|
|
47
47
|
import { log } from "../logger.js";
|
|
48
48
|
import { readEnvVar, resolveHomeDir } from "../runtime/env.js";
|
|
49
49
|
import type { MemoryFile } from "../types.js";
|
|
50
|
+
import { estimateTokenCount } from "../token-estimate.js";
|
|
50
51
|
import { expandTildePath } from "../utils/path.js";
|
|
51
52
|
|
|
52
53
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
@@ -60,7 +61,7 @@ export interface MaterializeOptions {
|
|
|
60
61
|
memories: MemoryFile[];
|
|
61
62
|
/** Override `<codex_home>`. Defaults to `$CODEX_HOME` or `~/.codex`. */
|
|
62
63
|
codexHome?: string;
|
|
63
|
-
/** Maximum
|
|
64
|
+
/** Maximum estimated token size of memory_summary.md. Default 4500. */
|
|
64
65
|
maxSummaryTokens?: number;
|
|
65
66
|
/** Maximum age of rollout_summaries/*.md in days. Default 30. */
|
|
66
67
|
rolloutRetentionDays?: number;
|
|
@@ -990,35 +991,23 @@ function trimHyphenEdges(value: string): string {
|
|
|
990
991
|
while (end > start && value[end - 1] === "-") end -= 1;
|
|
991
992
|
return value.slice(start, end);
|
|
992
993
|
}
|
|
993
|
-
|
|
994
|
-
/**
|
|
995
|
-
* Whitespace-tokenized approximation used by the budget check. Matches the
|
|
996
|
-
* simple heuristic Codex's usage.rs reporting uses for the "5000 token"
|
|
997
|
-
* memory_summary cap.
|
|
998
|
-
*/
|
|
994
|
+
/** Shared script-aware approximation used by the budget check. */
|
|
999
995
|
export function approximateTokenCount(text: string): number {
|
|
1000
|
-
|
|
1001
|
-
if (trimmed.length === 0) return 0;
|
|
1002
|
-
return trimmed.split(/\s+/u).length;
|
|
996
|
+
return estimateTokenCount(text);
|
|
1003
997
|
}
|
|
1004
998
|
|
|
1005
999
|
/**
|
|
1006
|
-
* Truncate `text` so it fits under `maxTokens
|
|
1007
|
-
*
|
|
1008
|
-
* marker so downstream readers can see that truncation happened.
|
|
1000
|
+
* Truncate `text` so it fits under `maxTokens`. We drop trailing lines until
|
|
1001
|
+
* under budget, then append a marker so readers can see that truncation occurred.
|
|
1009
1002
|
*/
|
|
1010
1003
|
export function truncateToTokenBudget(text: string, maxTokens: number): string {
|
|
1011
1004
|
if (maxTokens <= 0) return "";
|
|
1012
1005
|
if (approximateTokenCount(text) <= maxTokens) return text;
|
|
1013
1006
|
|
|
1014
|
-
// Reserve headroom for the truncation marker so the line-preserving path
|
|
1015
|
-
// can actually fit the marker without flipping to the hard-cut fallback.
|
|
1016
|
-
// Both markers are counted with the same whitespace heuristic the budget
|
|
1017
|
-
// check uses, so the arithmetic stays consistent.
|
|
1018
1007
|
const lineMarker = "_[truncated for summary budget]_";
|
|
1019
1008
|
const tailMarker = "[truncated]";
|
|
1009
|
+
if (approximateTokenCount(tailMarker) > maxTokens) return "";
|
|
1020
1010
|
const lineMarkerTokens = approximateTokenCount(lineMarker);
|
|
1021
|
-
const tailMarkerTokens = approximateTokenCount(tailMarker);
|
|
1022
1011
|
|
|
1023
1012
|
const lines = text.split(/\r?\n/u);
|
|
1024
1013
|
const lineBudget = Math.max(0, maxTokens - lineMarkerTokens);
|
|
@@ -1028,13 +1017,19 @@ export function truncateToTokenBudget(text: string, maxTokens: number): string {
|
|
|
1028
1017
|
lines.push(lineMarker);
|
|
1029
1018
|
let result = lines.join("\n");
|
|
1030
1019
|
|
|
1031
|
-
// If a single huge line still blows the budget, hard-cut tokens. Reserve
|
|
1032
|
-
// space for the tail marker's own token count so the final string stays
|
|
1033
|
-
// within maxTokens rather than sneaking over by a few tokens.
|
|
1034
1020
|
if (approximateTokenCount(result) > maxTokens) {
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
|
|
1021
|
+
const codePoints = [...result];
|
|
1022
|
+
let low = 0;
|
|
1023
|
+
let high = codePoints.length;
|
|
1024
|
+
while (low < high) {
|
|
1025
|
+
const mid = Math.ceil((low + high) / 2);
|
|
1026
|
+
const prefix = codePoints.slice(0, mid).join("");
|
|
1027
|
+
const candidate = prefix.length > 0 ? `${prefix} ${tailMarker}` : tailMarker;
|
|
1028
|
+
if (approximateTokenCount(candidate) <= maxTokens) low = mid;
|
|
1029
|
+
else high = mid - 1;
|
|
1030
|
+
}
|
|
1031
|
+
const prefix = codePoints.slice(0, low).join("");
|
|
1032
|
+
result = prefix.length > 0 ? `${prefix} ${tailMarker}` : tailMarker;
|
|
1038
1033
|
}
|
|
1039
1034
|
return result;
|
|
1040
1035
|
}
|
package/src/lcm/archive.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type Database from "better-sqlite3";
|
|
2
2
|
import { log } from "../logger.js";
|
|
3
3
|
import {
|
|
4
|
-
parseMessageParts,
|
|
5
4
|
type LcmMessagePartInput,
|
|
6
5
|
type MessagePartSourceFormat,
|
|
6
|
+
parseMessageParts,
|
|
7
7
|
} from "../message-parts/index.js";
|
|
8
|
+
import { estimateTokenCount } from "../token-estimate.js";
|
|
8
9
|
|
|
9
10
|
export interface LcmMessage {
|
|
10
11
|
id: number;
|
|
@@ -48,10 +49,8 @@ export interface LcmStructuredRecallMatch {
|
|
|
48
49
|
score: number;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
/**
|
|
52
|
-
export
|
|
53
|
-
return Math.ceil(text.length / 4);
|
|
54
|
-
}
|
|
52
|
+
/** Shared script-aware token estimate used by LCM accounting. */
|
|
53
|
+
export const estimateTokens = estimateTokenCount;
|
|
55
54
|
|
|
56
55
|
const PUBLIC_LCM_SEARCH_LIMIT = 100;
|
|
57
56
|
|
package/src/lcm/engine.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
} from "./recall.js";
|
|
11
11
|
import { LcmWorkQueue, type LcmObserveMessage } from "./queue.js";
|
|
12
12
|
import type { PluginConfig } from "../types.js";
|
|
13
|
+
import { estimateTokenCount } from "../token-estimate.js";
|
|
13
14
|
import { log } from "../logger.js";
|
|
14
|
-
|
|
15
15
|
export interface LcmEngineConfig {
|
|
16
16
|
enabled: boolean;
|
|
17
17
|
leafBatchSize: number;
|
|
@@ -556,12 +556,14 @@ export class LcmEngine {
|
|
|
556
556
|
const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);
|
|
557
557
|
if (messages.length === 0) return [];
|
|
558
558
|
|
|
559
|
-
// Enforce token budget
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
559
|
+
// Enforce the token budget while keeping the existing first/last shape.
|
|
560
|
+
const tokenBudget = Math.max(0, Math.floor(maxTokens));
|
|
561
|
+
if (tokenBudget === 0) return [];
|
|
562
|
+
const totalTokens = messages.reduce(
|
|
563
|
+
(sum, message) => sum + estimateTokenCount(message.content),
|
|
564
|
+
0,
|
|
565
|
+
);
|
|
566
|
+
if (totalTokens <= tokenBudget) {
|
|
565
567
|
return messages.map((m) => ({
|
|
566
568
|
id: m.id,
|
|
567
569
|
session_id: m.session_id,
|
|
@@ -571,45 +573,48 @@ export class LcmEngine {
|
|
|
571
573
|
}));
|
|
572
574
|
}
|
|
573
575
|
|
|
574
|
-
// Keep first and last messages, truncate from middle
|
|
575
576
|
const result: LcmExpandedMessage[] = [];
|
|
576
|
-
let budget = maxChars;
|
|
577
|
-
|
|
578
|
-
// Reserve space for the last message
|
|
579
577
|
const lastMsg = messages[messages.length - 1];
|
|
580
|
-
const
|
|
581
|
-
lastMsg.content
|
|
582
|
-
Math.floor(
|
|
578
|
+
const reservedLastTokens = Math.min(
|
|
579
|
+
estimateTokenCount(lastMsg.content),
|
|
580
|
+
Math.max(1, Math.floor(tokenBudget * 0.3)),
|
|
583
581
|
);
|
|
584
|
-
|
|
582
|
+
let remainingTokens = tokenBudget - reservedLastTokens;
|
|
585
583
|
|
|
586
|
-
// Add messages from the beginning
|
|
587
584
|
for (let i = 0; i < messages.length - 1; i++) {
|
|
588
|
-
if (
|
|
589
|
-
const
|
|
590
|
-
|
|
585
|
+
if (remainingTokens <= 0) break;
|
|
586
|
+
const content = truncateToTokenBudget(
|
|
587
|
+
messages[i].content,
|
|
588
|
+
remainingTokens,
|
|
589
|
+
);
|
|
590
|
+
if (!content) continue;
|
|
591
591
|
result.push({
|
|
592
|
-
id:
|
|
593
|
-
session_id:
|
|
594
|
-
turn_index:
|
|
595
|
-
role:
|
|
596
|
-
content
|
|
592
|
+
id: messages[i].id,
|
|
593
|
+
session_id: messages[i].session_id,
|
|
594
|
+
turn_index: messages[i].turn_index,
|
|
595
|
+
role: messages[i].role,
|
|
596
|
+
content,
|
|
597
597
|
});
|
|
598
|
-
|
|
598
|
+
remainingTokens -= estimateTokenCount(content);
|
|
599
599
|
}
|
|
600
600
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
601
|
+
const lastContent = truncateToTokenBudget(
|
|
602
|
+
lastMsg.content,
|
|
603
|
+
reservedLastTokens + remainingTokens,
|
|
604
|
+
);
|
|
605
|
+
if (lastContent) {
|
|
606
|
+
result.push({
|
|
607
|
+
id: lastMsg.id,
|
|
608
|
+
session_id: lastMsg.session_id,
|
|
609
|
+
turn_index: lastMsg.turn_index,
|
|
610
|
+
role: lastMsg.role,
|
|
611
|
+
content: lastContent,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
610
614
|
return result;
|
|
611
615
|
}
|
|
612
616
|
|
|
617
|
+
|
|
613
618
|
/** Get statistics about the LCM archive. */
|
|
614
619
|
async getStats(sessionId?: string): Promise<{
|
|
615
620
|
totalMessages: number;
|
|
@@ -691,3 +696,19 @@ export class LcmEngine {
|
|
|
691
696
|
this.initPromise = null;
|
|
692
697
|
}
|
|
693
698
|
}
|
|
699
|
+
function truncateToTokenBudget(text: string, maxTokens: number): string {
|
|
700
|
+
if (maxTokens <= 0) return "";
|
|
701
|
+
if (estimateTokenCount(text) <= maxTokens) return text;
|
|
702
|
+
const codePoints = [...text];
|
|
703
|
+
let low = 0;
|
|
704
|
+
let high = codePoints.length;
|
|
705
|
+
while (low < high) {
|
|
706
|
+
const mid = Math.ceil((low + high) / 2);
|
|
707
|
+
if (estimateTokenCount(codePoints.slice(0, mid).join("")) <= maxTokens) {
|
|
708
|
+
low = mid;
|
|
709
|
+
} else {
|
|
710
|
+
high = mid - 1;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return codePoints.slice(0, low).join("");
|
|
714
|
+
}
|
package/src/lcm/summarizer.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { log } from "../logger.js";
|
|
2
|
+
import { looksLikeMechanicalTelemetryTranscript } from "../telemetry-transcript.js";
|
|
3
|
+
import { estimateTokenCount } from "../token-estimate.js";
|
|
2
4
|
import type { LcmArchive, LcmMessage } from "./archive.js";
|
|
3
|
-
import { LcmDag } from "./dag.js";
|
|
4
5
|
import { estimateTokens } from "./archive.js";
|
|
5
|
-
import {
|
|
6
|
+
import type { LcmDag } from "./dag.js";
|
|
6
7
|
|
|
7
8
|
/** Generate a ULID-like ID (timestamp + random). */
|
|
8
9
|
function generateNodeId(): string {
|
|
@@ -199,32 +200,42 @@ export class LcmSummarizer {
|
|
|
199
200
|
|
|
200
201
|
/** Deterministic truncation: first and last sentence, plus middle truncation. */
|
|
201
202
|
function deterministicTruncate(text: string, maxTokens: number): string {
|
|
202
|
-
|
|
203
|
-
if (text.length <= maxChars) return text;
|
|
203
|
+
if (maxTokens <= 0 || estimateTokenCount(text) <= maxTokens) return text;
|
|
204
204
|
|
|
205
205
|
const sentences = text.split(/(?<=[.!?])\s+/).filter((s) => s.length > 0);
|
|
206
|
-
if (sentences.length <= 2)
|
|
207
|
-
return text.slice(0, maxChars);
|
|
208
|
-
}
|
|
206
|
+
if (sentences.length <= 2) return clampToTokenBudget(text, maxTokens);
|
|
209
207
|
|
|
210
208
|
const first = sentences[0];
|
|
211
209
|
const last = sentences[sentences.length - 1];
|
|
212
|
-
const
|
|
210
|
+
const render = (middle: string[], truncated: boolean): string =>
|
|
211
|
+
`${first} ${middle.join(" ")}${truncated ? " [...] " : " "}${last}`;
|
|
213
212
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
const base = render([], false);
|
|
214
|
+
if (estimateTokenCount(base) > maxTokens) return clampToTokenBudget(text, maxTokens);
|
|
215
|
+
if (estimateTokenCount(render([], true)) > maxTokens) return base;
|
|
217
216
|
|
|
218
|
-
// Fill from the beginning until budget runs out
|
|
219
217
|
const middle: string[] = [];
|
|
220
|
-
let used = 0;
|
|
221
218
|
for (let i = 1; i < sentences.length - 1; i++) {
|
|
222
|
-
|
|
219
|
+
const candidate = [...middle, sentences[i]];
|
|
220
|
+
const truncated = i < sentences.length - 2;
|
|
221
|
+
if (estimateTokenCount(render(candidate, truncated)) > maxTokens) break;
|
|
223
222
|
middle.push(sentences[i]);
|
|
224
|
-
used += sentences[i].length;
|
|
225
223
|
}
|
|
226
224
|
|
|
227
|
-
|
|
225
|
+
const truncated = middle.length < sentences.length - 2;
|
|
226
|
+
return clampToTokenBudget(render(middle, truncated), maxTokens);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function clampToTokenBudget(text: string, maxTokens: number): string {
|
|
230
|
+
const codePoints = [...text];
|
|
231
|
+
let low = 0;
|
|
232
|
+
let high = codePoints.length;
|
|
233
|
+
while (low < high) {
|
|
234
|
+
const mid = Math.ceil((low + high) / 2);
|
|
235
|
+
if (estimateTokenCount(codePoints.slice(0, mid).join("")) <= maxTokens) low = mid;
|
|
236
|
+
else high = mid - 1;
|
|
237
|
+
}
|
|
238
|
+
return codePoints.slice(0, low).join("");
|
|
228
239
|
}
|
|
229
240
|
|
|
230
241
|
function chunkArray<T>(arr: T[], size: number): T[][] {
|
package/src/lcm-engine.test.ts
CHANGED
|
@@ -7,6 +7,7 @@ import test from "node:test";
|
|
|
7
7
|
import { LcmArchive } from "./lcm/archive.js";
|
|
8
8
|
import { LcmEngine, extractLcmConfig } from "./lcm/engine.js";
|
|
9
9
|
import { openLcmDatabase } from "./lcm/schema.js";
|
|
10
|
+
import { estimateTokenCount } from "./token-estimate.js";
|
|
10
11
|
import type { PluginConfig } from "./types.js";
|
|
11
12
|
|
|
12
13
|
function createPluginConfig(memoryDir: string): PluginConfig {
|
|
@@ -661,20 +662,99 @@ test("expandContext preserves first, middle, and last row identity when truncate
|
|
|
661
662
|
session_id: "session-truncated",
|
|
662
663
|
turn_index: 2,
|
|
663
664
|
role: "assistant",
|
|
664
|
-
content: "
|
|
665
|
+
content: "BBBBBBBB",
|
|
665
666
|
},
|
|
666
667
|
{
|
|
667
668
|
id: last.id,
|
|
668
669
|
session_id: "session-truncated",
|
|
669
670
|
turn_index: 4,
|
|
670
671
|
role: "assistant",
|
|
671
|
-
content: "
|
|
672
|
+
content: "DDDD",
|
|
672
673
|
},
|
|
673
674
|
]);
|
|
674
675
|
} finally {
|
|
675
676
|
await rm(memoryDir, { recursive: true, force: true });
|
|
676
677
|
}
|
|
677
678
|
});
|
|
679
|
+
test("expandContext applies token budgets to wide-script messages", async () => {
|
|
680
|
+
const memoryDir = await mkdtemp(
|
|
681
|
+
path.join(os.tmpdir(), "engram-lcm-expand-wide-script-"),
|
|
682
|
+
);
|
|
683
|
+
|
|
684
|
+
try {
|
|
685
|
+
const engine = new LcmEngine(
|
|
686
|
+
createPluginConfig(memoryDir),
|
|
687
|
+
async () => "summary",
|
|
688
|
+
);
|
|
689
|
+
await engine.ensureInitialized();
|
|
690
|
+
|
|
691
|
+
const db = openLcmDatabase(memoryDir);
|
|
692
|
+
try {
|
|
693
|
+
const archive = new LcmArchive(db);
|
|
694
|
+
archive.appendMessages("session-wide-script", [
|
|
695
|
+
{ turnIndex: 1, role: "user", content: "日本語".repeat(40) },
|
|
696
|
+
{ turnIndex: 2, role: "assistant", content: "日本語".repeat(40) },
|
|
697
|
+
{ turnIndex: 3, role: "user", content: "日本語".repeat(40) },
|
|
698
|
+
]);
|
|
699
|
+
} finally {
|
|
700
|
+
db.close();
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
const expanded = await engine.expandContext(
|
|
704
|
+
"session-wide-script",
|
|
705
|
+
1,
|
|
706
|
+
3,
|
|
707
|
+
10,
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
assert.ok(
|
|
711
|
+
expanded.reduce((sum, message) => sum + estimateTokenCount(message.content), 0) <= 10,
|
|
712
|
+
);
|
|
713
|
+
assert.ok(expanded.every((message) => message.content.length < 40));
|
|
714
|
+
} finally {
|
|
715
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
test("expandContext preserves the final message at the smallest positive budget", async () => {
|
|
719
|
+
const memoryDir = await mkdtemp(
|
|
720
|
+
path.join(os.tmpdir(), "engram-lcm-expand-minimum-budget-"),
|
|
721
|
+
);
|
|
722
|
+
|
|
723
|
+
let engine: LcmEngine | undefined;
|
|
724
|
+
try {
|
|
725
|
+
engine = new LcmEngine(
|
|
726
|
+
createPluginConfig(memoryDir),
|
|
727
|
+
async () => "summary",
|
|
728
|
+
);
|
|
729
|
+
await engine.ensureInitialized();
|
|
730
|
+
|
|
731
|
+
const db = openLcmDatabase(memoryDir);
|
|
732
|
+
try {
|
|
733
|
+
const archive = new LcmArchive(db);
|
|
734
|
+
archive.appendMessages("session-minimum-budget", [
|
|
735
|
+
{ turnIndex: 1, role: "user", content: "first message" },
|
|
736
|
+
{ turnIndex: 2, role: "assistant", content: "最後のメッセージ" },
|
|
737
|
+
]);
|
|
738
|
+
} finally {
|
|
739
|
+
db.close();
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
const expanded = await engine.expandContext(
|
|
743
|
+
"session-minimum-budget",
|
|
744
|
+
1,
|
|
745
|
+
2,
|
|
746
|
+
1,
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
assert.equal(expanded.at(-1)?.turn_index, 2);
|
|
750
|
+
assert.ok(
|
|
751
|
+
expanded.reduce((sum, message) => sum + estimateTokenCount(message.content), 0) <= 1,
|
|
752
|
+
);
|
|
753
|
+
} finally {
|
|
754
|
+
engine?.close();
|
|
755
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
756
|
+
}
|
|
757
|
+
});
|
|
678
758
|
|
|
679
759
|
test("assembleRecallWithTrace preserves text and reports selected summary metadata", async () => {
|
|
680
760
|
const memoryDir = await mkdtemp(
|
package/src/local-llm.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { log } from "./logger.js";
|
|
2
|
+
import { estimateTokenCount } from "./token-estimate.js";
|
|
2
3
|
import type { PluginConfig } from "./types.js";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import os from "node:os";
|
|
@@ -1431,18 +1432,15 @@ export class LocalLlmClient {
|
|
|
1431
1432
|
|
|
1432
1433
|
return await this.runChatCompletionRequest(messages, options);
|
|
1433
1434
|
}
|
|
1434
|
-
|
|
1435
1435
|
/**
|
|
1436
|
-
* Estimate tokens when local LLM
|
|
1437
|
-
* Rough estimate: 1 token ≈ 4 characters
|
|
1436
|
+
* Estimate tokens when local LLM does not return usage stats.
|
|
1438
1437
|
*/
|
|
1439
1438
|
private estimateTokens(
|
|
1440
1439
|
messages: Array<{ role: string; content: string }>,
|
|
1441
1440
|
response: string
|
|
1442
1441
|
): { promptTokens: number; completionTokens: number; totalTokens: number } {
|
|
1443
|
-
const
|
|
1444
|
-
const
|
|
1445
|
-
const completionTokens = Math.ceil(response.length / 4);
|
|
1442
|
+
const promptTokens = messages.reduce((sum, message) => sum + estimateTokenCount(message.content), 0);
|
|
1443
|
+
const completionTokens = estimateTokenCount(response);
|
|
1446
1444
|
|
|
1447
1445
|
return {
|
|
1448
1446
|
promptTokens,
|
|
@@ -6,16 +6,10 @@
|
|
|
6
6
|
* truncates with a footer listing omitted extensions when over budget.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { estimateTokenCount } from "../token-estimate.js";
|
|
9
10
|
import { REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT } from "./host-discovery.js";
|
|
10
11
|
import type { DiscoveredExtension } from "./types.js";
|
|
11
12
|
|
|
12
|
-
/**
|
|
13
|
-
* Approximate token count using the 4 chars per token heuristic.
|
|
14
|
-
*/
|
|
15
|
-
function estimateTokens(text: string): number {
|
|
16
|
-
return Math.ceil(text.length / 4);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
13
|
/**
|
|
20
14
|
* Render a markdown block containing extension instructions for injection
|
|
21
15
|
* into consolidation prompts.
|
|
@@ -36,14 +30,14 @@ extension produces or curates.
|
|
|
36
30
|
`;
|
|
37
31
|
|
|
38
32
|
let budget = REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT;
|
|
39
|
-
budget -=
|
|
33
|
+
budget -= estimateTokenCount(header);
|
|
40
34
|
|
|
41
35
|
const inlined: string[] = [];
|
|
42
36
|
const omitted: string[] = [];
|
|
43
37
|
|
|
44
38
|
for (const ext of extensions) {
|
|
45
39
|
const block = `### remnic-extension/${ext.name}\n\`\`\`\n${ext.instructions}\n\`\`\`\n\n`;
|
|
46
|
-
const cost =
|
|
40
|
+
const cost = estimateTokenCount(block);
|
|
47
41
|
if (cost <= budget) {
|
|
48
42
|
inlined.push(block);
|
|
49
43
|
budget -= cost;
|