@remnic/core 9.30.1 → 9.31.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 +10 -10
- package/dist/access-admin-ops-surface.js +50 -44
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +51 -45
- package/dist/access-boundary.d.ts +13 -11
- package/dist/access-boundary.js +50 -44
- package/dist/access-cli.js +168 -123
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.d.ts +119 -0
- package/dist/access-extraction-force-flush.js +166 -0
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +47 -13
- package/dist/access-http-lcm-compaction.js +7 -3
- package/dist/access-http-lifecycle-flush.d.ts +132 -0
- package/dist/access-http-lifecycle-flush.js +9 -0
- package/dist/access-http-lifecycle-flush.js.map +1 -0
- package/dist/access-http.d.ts +11 -10
- package/dist/access-http.js +66 -59
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +50 -44
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +50 -44
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +16 -10
- package/dist/access-mcp.js +58 -52
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-VfXssvoI.d.ts → access-namespace-preflight-D4vW97H1.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +50 -44
- package/dist/access-observe-helpers.d.ts +22 -0
- package/dist/access-observe-helpers.js +10 -0
- package/dist/access-observe-helpers.js.map +1 -0
- package/dist/access-observe-write-surface.d.ts +51 -47
- package/dist/access-observe-write-surface.js +50 -44
- package/dist/access-operations-batch.js +53 -47
- package/dist/access-operations.d.ts +11 -11
- package/dist/access-operations.js +55 -49
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +50 -44
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +50 -44
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +50 -44
- package/dist/access-schema.d.ts +37 -7
- package/dist/access-schema.js +5 -3
- package/dist/{access-service-B5RwVsTV.d.ts → access-service-B6PZ_xUL.d.ts} +44 -20
- package/dist/access-service-helpers.d.ts +113 -0
- package/dist/access-service-helpers.js +8 -0
- package/dist/access-service-helpers.js.map +1 -0
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +50 -44
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/access-surface-catalog.js +2 -0
- 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/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +8 -8
- 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 +5 -0
- package/dist/buffer-turn-helpers.js +24 -0
- package/dist/buffer-turn-helpers.js.map +1 -0
- package/dist/buffer.d.ts +17 -4
- package/dist/buffer.js +21 -1
- 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-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
- package/dist/{capsule-merge-5KKJQBWQ.js → capsule-merge-2H2IUTBT.js} +4 -4
- package/dist/{catalog-V7inUQdp.d.ts → catalog-CGFYmTT8.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 +19 -19
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-GIBMDSJ2.js → chunk-27P5YVDU.js} +2 -2
- package/dist/{chunk-2SA56WMI.js → chunk-2LTDWSR6.js} +4 -4
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-YTSNAUXN.js → chunk-3F2LKUMU.js} +22 -8
- package/dist/chunk-3F2LKUMU.js.map +1 -0
- package/dist/chunk-3QL24R5Y.js +9 -0
- package/dist/chunk-3QL24R5Y.js.map +1 -0
- package/dist/chunk-4RNZMRAV.js +60 -0
- package/dist/chunk-4RNZMRAV.js.map +1 -0
- package/dist/{chunk-6U7F52DE.js → chunk-4XHR3I67.js} +60 -60
- package/dist/chunk-5IVLTFOV.js +65 -0
- package/dist/chunk-5IVLTFOV.js.map +1 -0
- package/dist/{chunk-2EUVEDF5.js → chunk-5XA7PQ5I.js} +2 -2
- package/dist/{chunk-ALSGMEJR.js → chunk-65ZPVYTA.js} +7 -7
- package/dist/{chunk-5VQJBH2G.js → chunk-6TAUHL33.js} +2 -2
- package/dist/{chunk-HUHX2OCX.js → chunk-7DRETLP5.js} +1 -1
- package/dist/chunk-7DRETLP5.js.map +1 -0
- package/dist/{chunk-RGIWINDN.js → chunk-7G5MH4NT.js} +30 -30
- package/dist/{chunk-WVO4G37W.js → chunk-7TEZUUGM.js} +3 -3
- package/dist/{chunk-MJCGLM25.js → chunk-7VUAG236.js} +5 -5
- package/dist/{chunk-M3C2V3PV.js → chunk-AJEMDQNA.js} +12 -12
- package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
- package/dist/{chunk-ACXPX4AG.js → chunk-BR2K43MK.js} +2 -2
- package/dist/{chunk-IYZ5K7MU.js → chunk-BUE5E2HL.js} +4 -187
- package/dist/chunk-BUE5E2HL.js.map +1 -0
- package/dist/{chunk-CZRYLSSW.js → chunk-BUGVGH4N.js} +2 -2
- package/dist/{chunk-YTQNQ4KB.js → chunk-C4VQMFVM.js} +3 -3
- package/dist/{chunk-ZPSVBSOF.js → chunk-CIVDJD6P.js} +3 -3
- package/dist/{chunk-K5GB36ME.js → chunk-CZDOT5I2.js} +2 -2
- package/dist/{chunk-VI2JQPNQ.js → chunk-E4PWACUN.js} +2 -2
- package/dist/{chunk-D2ANTDGO.js → chunk-E6BMSH7U.js} +2 -2
- package/dist/{chunk-P5PXWTW7.js → chunk-EJCAV3QZ.js} +3 -3
- package/dist/{chunk-CKMO4RDY.js → chunk-EMDLM3LW.js} +4 -4
- package/dist/chunk-ER7W6H4T.js +112 -0
- package/dist/chunk-ER7W6H4T.js.map +1 -0
- package/dist/{chunk-6FUPCJUL.js → chunk-FI4F5X2V.js} +54 -54
- package/dist/chunk-FI4F5X2V.js.map +1 -0
- package/dist/{chunk-LGHKJABJ.js → chunk-GOUILH55.js} +40 -18
- package/dist/chunk-GOUILH55.js.map +1 -0
- package/dist/{chunk-G5R3D5UP.js → chunk-GTTAHHD3.js} +2 -2
- package/dist/{chunk-H5CPS5JP.js → chunk-H36LJIPD.js} +3 -3
- package/dist/{chunk-AITCS2RC.js → chunk-IJ7HK452.js} +4 -4
- package/dist/{chunk-D3LMYTBV.js → chunk-J7WZUL2K.js} +9 -9
- package/dist/{chunk-5W4ZLBEZ.js → chunk-JCFTIQBR.js} +2 -2
- package/dist/{chunk-XOZ4ALGB.js → chunk-KE353EWI.js} +3 -3
- package/dist/{chunk-W5EG6LE3.js → chunk-KIT6M7EB.js} +3 -3
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
- package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
- package/dist/chunk-N5Z4EVOR.js +123 -0
- package/dist/chunk-N5Z4EVOR.js.map +1 -0
- package/dist/{chunk-66772WBP.js → chunk-NFXQJHJD.js} +5 -5
- package/dist/{chunk-AZ5BTEKX.js → chunk-NQUF7XKR.js} +2 -2
- package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
- package/dist/{chunk-NHWB6HG2.js → chunk-NYCGIQRA.js} +2 -2
- package/dist/{chunk-4WKA6I65.js → chunk-OGCNZPKX.js} +1119 -309
- package/dist/chunk-OGCNZPKX.js.map +1 -0
- package/dist/{chunk-QJAQNXWI.js → chunk-ONHRRJZM.js} +6 -6
- package/dist/{chunk-FDAMS4PK.js → chunk-PNPOWBGC.js} +2 -2
- package/dist/{chunk-IC6CBHCA.js → chunk-QGENAYVS.js} +2 -2
- package/dist/{chunk-GBJ4RDFR.js → chunk-QIHIHZYC.js} +66 -91
- package/dist/chunk-QIHIHZYC.js.map +1 -0
- package/dist/{chunk-YNQBRLC5.js → chunk-RUYJ7TWU.js} +517 -2011
- package/dist/chunk-RUYJ7TWU.js.map +1 -0
- package/dist/{chunk-4A6YGWQN.js → chunk-TL4TO3EA.js} +115 -120
- package/dist/chunk-TL4TO3EA.js.map +1 -0
- package/dist/{chunk-SPJXKAVF.js → chunk-U52AKICI.js} +14 -13
- package/dist/chunk-U52AKICI.js.map +1 -0
- package/dist/chunk-ULARSG5Z.js +203 -0
- package/dist/chunk-ULARSG5Z.js.map +1 -0
- package/dist/{chunk-62U4J2GN.js → chunk-UR77VKF7.js} +2 -2
- package/dist/{chunk-JCBWCYEJ.js → chunk-VANLTS5F.js} +2 -2
- package/dist/{chunk-4Z4XNEWZ.js → chunk-VCD4PSK2.js} +56 -12
- package/dist/chunk-VCD4PSK2.js.map +1 -0
- package/dist/{chunk-RMMVQQA6.js → chunk-WDISJRMG.js} +2 -2
- package/dist/{chunk-B6JDYXL7.js → chunk-WWUVONGW.js} +7 -1
- package/dist/chunk-WWUVONGW.js.map +1 -0
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-TH2LSRMG.js → chunk-XHDIB4T4.js} +2 -2
- package/dist/{chunk-CVILPI77.js → chunk-XOQSEF7X.js} +6 -6
- package/dist/{chunk-LBOD4U5B.js → chunk-YFOMN2II.js} +6 -6
- package/dist/{chunk-RPW2NOU6.js → chunk-YIAA2X3D.js} +41 -1
- package/dist/chunk-YIAA2X3D.js.map +1 -0
- package/dist/chunk-YPC7W6GA.js +1604 -0
- package/dist/chunk-YPC7W6GA.js.map +1 -0
- package/dist/{chunk-I5NLEENJ.js → chunk-Z4SWV4VW.js} +3 -3
- package/dist/{chunk-PHWUFPCO.js → chunk-ZCPP5OW6.js} +61 -53
- package/dist/chunk-ZCPP5OW6.js.map +1 -0
- package/dist/{cli-C4GbETPC.d.ts → cli-BptUDTtp.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +91 -84
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +14 -14
- 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 +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +14 -14
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +17 -17
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-provenance-check.js +5 -5
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +4 -4
- 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 +26 -26
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +14 -14
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- 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-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +15 -2
- package/dist/extraction-source-grounding.js +10 -1
- package/dist/extraction.d.ts +2 -15
- package/dist/extraction.js +5 -4
- 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-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +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 +19 -19
- package/dist/index.js +215 -207
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +6 -6
- 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-helpers.d.ts +7 -0
- package/dist/local-llm-helpers.js +16 -0
- package/dist/local-llm-helpers.js.map +1 -0
- package/dist/local-llm.d.ts +3 -6
- 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 +14 -14
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +15 -15
- package/dist/{maintenance-CL30NWtc.d.ts → maintenance-b6f92bRz.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-corpus-version.js +2 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +24 -24
- 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 +14 -14
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +6 -5
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +29 -29
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-doctor-replica.js +3 -3
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +38 -37
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +22 -21
- package/dist/{orchestrator-CKTCRwWV.d.ts → orchestrator-3uGxC1qO.d.ts} +72 -34
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +167 -159
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-B7wj4rRZ.d.ts → pipeline-DepuNr-m.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/{qmd-q9tg4dHp.d.ts → qmd-Dalr3Jby.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/qmd.js +4 -4
- 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-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/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-divergence.js +2 -2
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +1 -1
- 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-CWDyglPM.d.ts → scope-profiles-BpiM5hTU.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 +12 -12
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-BUE3deLn.d.ts → semantic-consolidation-CMtVrf9f.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +16 -16
- package/dist/semantic-rule-promotion.js +14 -14
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +14 -14
- package/dist/{service-CXgM0bQG.d.ts → service-DuAxwSgg.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/{storage-DysJq-XH.d.ts → storage-CF0Ih8GP.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +13 -13
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- 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/tokens.js +2 -2
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +5 -5
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-aPPzhnjT.d.ts → types-BpaYvJ6v.d.ts} +22 -2
- 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 +14 -14
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-boundary.ts +3 -0
- package/src/access-cli.test.ts +93 -0
- package/src/access-cli.ts +56 -2
- package/src/access-extraction-force-flush.ts +177 -0
- package/src/access-http-extraction-force-flush.test.ts +132 -0
- package/src/access-http-lcm-compaction.ts +99 -22
- package/src/access-http-lifecycle-flush.ts +81 -0
- package/src/access-http.test.ts +227 -0
- package/src/access-http.ts +33 -40
- package/src/access-mcp-output-schemas.ts +6 -0
- package/src/access-mcp.test.ts +40 -0
- package/src/access-mcp.ts +32 -1
- package/src/access-observe-helpers.ts +180 -0
- package/src/access-observe-write-surface.ts +78 -19
- package/src/access-operations-batch.ts +2 -1
- package/src/access-schema-pi.test.ts +17 -0
- package/src/access-schema.ts +28 -11
- package/src/access-service-helpers.ts +46 -0
- package/src/access-service-observe-lcm-parity.test.ts +781 -31
- package/src/access-service-observe-scope.test.ts +88 -0
- package/src/access-service.ts +46 -128
- package/src/access-surface-catalog.test.ts +32 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/buffer-session.test.ts +148 -0
- package/src/buffer-turn-helpers.ts +152 -0
- package/src/buffer.ts +126 -201
- package/src/correction/correction-access-wiring.ts +79 -27
- package/src/correction/correction-executor.test.ts +542 -1
- package/src/correction/correction-executor.ts +309 -89
- package/src/correction/correction-planner.test.ts +35 -1
- package/src/correction/correction-planner.ts +50 -3
- package/src/correction/correction-service.ts +12 -7
- package/src/correction/correction-storage-integration.test.ts +172 -1
- package/src/correction/passive-capture.test.ts +35 -0
- package/src/correction/passive-capture.ts +17 -3
- package/src/extraction-source-grounding.ts +55 -1
- package/src/extraction-timeout.test.ts +51 -0
- package/src/extraction.ts +64 -90
- package/src/local-llm-headers-timeout.test.ts +48 -0
- package/src/local-llm-helpers.ts +58 -0
- package/src/local-llm.ts +62 -58
- package/src/orchestration/extraction-run-helpers.ts +309 -0
- package/src/orchestration/extraction-run.test.ts +350 -7
- package/src/orchestration/extraction-run.ts +327 -250
- package/src/orchestration/session-context.ts +193 -18
- package/src/orchestration/turn-ingestion.ts +61 -11
- package/src/orchestrator-flush.test.ts +511 -5
- package/src/orchestrator.ts +8 -6
- package/src/types.ts +2 -2
- package/dist/chunk-4A6YGWQN.js.map +0 -1
- package/dist/chunk-4WKA6I65.js.map +0 -1
- package/dist/chunk-4Z4XNEWZ.js.map +0 -1
- package/dist/chunk-6FUPCJUL.js.map +0 -1
- package/dist/chunk-B6JDYXL7.js.map +0 -1
- package/dist/chunk-GBJ4RDFR.js.map +0 -1
- package/dist/chunk-HUHX2OCX.js.map +0 -1
- package/dist/chunk-IYZ5K7MU.js.map +0 -1
- package/dist/chunk-LGHKJABJ.js.map +0 -1
- package/dist/chunk-PHWUFPCO.js.map +0 -1
- package/dist/chunk-RPW2NOU6.js.map +0 -1
- package/dist/chunk-SPJXKAVF.js.map +0 -1
- package/dist/chunk-YNQBRLC5.js.map +0 -1
- package/dist/chunk-YTSNAUXN.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
- /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-GIBMDSJ2.js.map → chunk-27P5YVDU.js.map} +0 -0
- /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-6U7F52DE.js.map → chunk-4XHR3I67.js.map} +0 -0
- /package/dist/{chunk-2EUVEDF5.js.map → chunk-5XA7PQ5I.js.map} +0 -0
- /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
- /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
- /package/dist/{chunk-RGIWINDN.js.map → chunk-7G5MH4NT.js.map} +0 -0
- /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
- /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
- /package/dist/{chunk-M3C2V3PV.js.map → chunk-AJEMDQNA.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
- /package/dist/{chunk-ACXPX4AG.js.map → chunk-BR2K43MK.js.map} +0 -0
- /package/dist/{chunk-CZRYLSSW.js.map → chunk-BUGVGH4N.js.map} +0 -0
- /package/dist/{chunk-YTQNQ4KB.js.map → chunk-C4VQMFVM.js.map} +0 -0
- /package/dist/{chunk-ZPSVBSOF.js.map → chunk-CIVDJD6P.js.map} +0 -0
- /package/dist/{chunk-K5GB36ME.js.map → chunk-CZDOT5I2.js.map} +0 -0
- /package/dist/{chunk-VI2JQPNQ.js.map → chunk-E4PWACUN.js.map} +0 -0
- /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
- /package/dist/{chunk-P5PXWTW7.js.map → chunk-EJCAV3QZ.js.map} +0 -0
- /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
- /package/dist/{chunk-G5R3D5UP.js.map → chunk-GTTAHHD3.js.map} +0 -0
- /package/dist/{chunk-H5CPS5JP.js.map → chunk-H36LJIPD.js.map} +0 -0
- /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
- /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
- /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-JCFTIQBR.js.map} +0 -0
- /package/dist/{chunk-XOZ4ALGB.js.map → chunk-KE353EWI.js.map} +0 -0
- /package/dist/{chunk-W5EG6LE3.js.map → chunk-KIT6M7EB.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
- /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
- /package/dist/{chunk-66772WBP.js.map → chunk-NFXQJHJD.js.map} +0 -0
- /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
- /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
- /package/dist/{chunk-NHWB6HG2.js.map → chunk-NYCGIQRA.js.map} +0 -0
- /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
- /package/dist/{chunk-FDAMS4PK.js.map → chunk-PNPOWBGC.js.map} +0 -0
- /package/dist/{chunk-IC6CBHCA.js.map → chunk-QGENAYVS.js.map} +0 -0
- /package/dist/{chunk-62U4J2GN.js.map → chunk-UR77VKF7.js.map} +0 -0
- /package/dist/{chunk-JCBWCYEJ.js.map → chunk-VANLTS5F.js.map} +0 -0
- /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-TH2LSRMG.js.map → chunk-XHDIB4T4.js.map} +0 -0
- /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
- /package/dist/{chunk-LBOD4U5B.js.map → chunk-YFOMN2II.js.map} +0 -0
- /package/dist/{chunk-I5NLEENJ.js.map → chunk-Z4SWV4VW.js.map} +0 -0
package/src/access-cli.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import os from "node:os";
|
|
5
6
|
import path from "node:path";
|
|
@@ -523,6 +524,98 @@ test("access-cli rejects adjacent option-looking values", async () => {
|
|
|
523
524
|
assert.match(output, /missing required option: --content/);
|
|
524
525
|
});
|
|
525
526
|
|
|
527
|
+
test("access-cli extraction-flush drains the requested session through the boundary", async () => {
|
|
528
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "remnic-access-cli-"));
|
|
529
|
+
let output = "";
|
|
530
|
+
const originalStdoutWrite = process.stdout.write;
|
|
531
|
+
process.stdout.write = ((chunk: string | Uint8Array) => {
|
|
532
|
+
output += String(chunk);
|
|
533
|
+
return true;
|
|
534
|
+
}) as typeof process.stdout.write;
|
|
535
|
+
|
|
536
|
+
try {
|
|
537
|
+
const configPath = path.join(tempDir, "openclaw.json");
|
|
538
|
+
writeOpenClawConfig(configPath, {
|
|
539
|
+
memoryDir: path.join(tempDir, "memory"),
|
|
540
|
+
defaultNamespace: "default",
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
await withPatchedEnv(
|
|
544
|
+
{
|
|
545
|
+
OPENCLAW_CONFIG_PATH: configPath,
|
|
546
|
+
OPENCLAW_ENGRAM_CONFIG_PATH: undefined,
|
|
547
|
+
},
|
|
548
|
+
async () => {
|
|
549
|
+
await main([
|
|
550
|
+
"extraction-flush",
|
|
551
|
+
"--session-key",
|
|
552
|
+
"cli:flush",
|
|
553
|
+
"--namespace",
|
|
554
|
+
"default",
|
|
555
|
+
"--deadline-ms",
|
|
556
|
+
String(Date.now() + 10_000),
|
|
557
|
+
]);
|
|
558
|
+
},
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
assert.match(output, /"flushed": true/);
|
|
562
|
+
assert.match(output, /"sessionKey": "cli:flush"/);
|
|
563
|
+
assert.match(output, /"effectiveNamespace": "default"/);
|
|
564
|
+
} finally {
|
|
565
|
+
process.stdout.write = originalStdoutWrite;
|
|
566
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
test("access-cli extraction-flush expands tilde in cwd before resolving project scope", async () => {
|
|
571
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "remnic-access-cli-"));
|
|
572
|
+
const repoDir = path.join(tempDir, "repo");
|
|
573
|
+
fs.mkdirSync(repoDir);
|
|
574
|
+
execFileSync("git", ["init", "-q"], { cwd: repoDir });
|
|
575
|
+
let output = "";
|
|
576
|
+
const originalStdoutWrite = process.stdout.write;
|
|
577
|
+
process.stdout.write = ((chunk: string | Uint8Array) => {
|
|
578
|
+
output += String(chunk);
|
|
579
|
+
return true;
|
|
580
|
+
}) as typeof process.stdout.write;
|
|
581
|
+
|
|
582
|
+
try {
|
|
583
|
+
const configPath = path.join(tempDir, "openclaw.json");
|
|
584
|
+
writeOpenClawConfig(configPath, {
|
|
585
|
+
namespacesEnabled: true,
|
|
586
|
+
defaultNamespace: "default",
|
|
587
|
+
agentAccessHttp: { principal: "pi-geek" },
|
|
588
|
+
principalFromSessionKeyMode: "prefix",
|
|
589
|
+
principalFromSessionKeyRules: [{ match: "cli:", principal: "pi-geek" }],
|
|
590
|
+
codingMode: { projectScope: true },
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
await withPatchedEnv(
|
|
594
|
+
{
|
|
595
|
+
HOME: tempDir,
|
|
596
|
+
OPENCLAW_CONFIG_PATH: configPath,
|
|
597
|
+
OPENCLAW_ENGRAM_CONFIG_PATH: undefined,
|
|
598
|
+
},
|
|
599
|
+
async () => {
|
|
600
|
+
await main([
|
|
601
|
+
"extraction-flush",
|
|
602
|
+
"--session-key",
|
|
603
|
+
"cli:tilde-cwd",
|
|
604
|
+
"--cwd",
|
|
605
|
+
"~/repo",
|
|
606
|
+
"--deadline-ms",
|
|
607
|
+
String(Date.now() + 10_000),
|
|
608
|
+
]);
|
|
609
|
+
},
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
assert.match(output, /"effectiveNamespace": "default-project-/);
|
|
613
|
+
} finally {
|
|
614
|
+
process.stdout.write = originalStdoutWrite;
|
|
615
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
|
|
526
619
|
// ──────────────────────────────────────────────────────────────────────────
|
|
527
620
|
// architecture command — wired through the boundary operation (#1548 PR3)
|
|
528
621
|
// ──────────────────────────────────────────────────────────────────────────
|
package/src/access-cli.ts
CHANGED
|
@@ -15,7 +15,14 @@ import { projectTagProjectId } from "./coding/coding-namespace.js";
|
|
|
15
15
|
|
|
16
16
|
const OPENCLAW_REMNIC_PLUGIN_IDS = ["openclaw-remnic", "openclaw-engram"] as const;
|
|
17
17
|
|
|
18
|
-
type CommandName =
|
|
18
|
+
type CommandName =
|
|
19
|
+
| "browse"
|
|
20
|
+
| "store"
|
|
21
|
+
| "extraction-flush"
|
|
22
|
+
| "decision"
|
|
23
|
+
| "architecture"
|
|
24
|
+
| "delta"
|
|
25
|
+
| "correct";
|
|
19
26
|
|
|
20
27
|
type ParsedArgs = {
|
|
21
28
|
command: CommandName;
|
|
@@ -136,6 +143,7 @@ function usage(): string {
|
|
|
136
143
|
return [
|
|
137
144
|
" engram-access browse [options]",
|
|
138
145
|
" engram-access store [options]",
|
|
146
|
+
" engram-access extraction-flush [options]",
|
|
139
147
|
" engram-access decision [options]",
|
|
140
148
|
" engram-access architecture [options]",
|
|
141
149
|
" engram-access delta [options]",
|
|
@@ -165,6 +173,14 @@ function usage(): string {
|
|
|
165
173
|
" --idempotency-key <key>",
|
|
166
174
|
" --dry-run",
|
|
167
175
|
"",
|
|
176
|
+
"Extraction flush options:",
|
|
177
|
+
" --session-key <key>",
|
|
178
|
+
" --namespace <name>",
|
|
179
|
+
" --principal <principal>",
|
|
180
|
+
" --cwd <path>",
|
|
181
|
+
" --project-tag <tag>",
|
|
182
|
+
" --deadline-ms <timestamp>",
|
|
183
|
+
"",
|
|
168
184
|
"Decision options:",
|
|
169
185
|
" --subcommand <list|get|record|supersede>",
|
|
170
186
|
" --namespace <name>",
|
|
@@ -233,6 +249,10 @@ const COMMAND_SPECS: Record<CommandName, CommandSpec> = {
|
|
|
233
249
|
]),
|
|
234
250
|
flagOptions: new Set(["dry-run"]),
|
|
235
251
|
},
|
|
252
|
+
"extraction-flush": {
|
|
253
|
+
valueOptions: new Set(["session-key", "namespace", "principal", "cwd", "project-tag", "deadline-ms"]),
|
|
254
|
+
flagOptions: new Set(),
|
|
255
|
+
},
|
|
236
256
|
decision: {
|
|
237
257
|
valueOptions: new Set([
|
|
238
258
|
"subcommand",
|
|
@@ -301,7 +321,15 @@ type BrowseSort = (typeof BROWSE_SORT_VALUES)[number];
|
|
|
301
321
|
* `command: commandRaw` assignment below (codex review P2).
|
|
302
322
|
*/
|
|
303
323
|
function isCommandName(value: string): value is CommandName {
|
|
304
|
-
return
|
|
324
|
+
return (
|
|
325
|
+
value === "browse" ||
|
|
326
|
+
value === "store" ||
|
|
327
|
+
value === "extraction-flush" ||
|
|
328
|
+
value === "decision" ||
|
|
329
|
+
value === "architecture" ||
|
|
330
|
+
value === "delta" ||
|
|
331
|
+
value === "correct"
|
|
332
|
+
);
|
|
305
333
|
}
|
|
306
334
|
|
|
307
335
|
function parseArgs(argv: string[]): ParsedArgs {
|
|
@@ -561,6 +589,28 @@ async function runStore(args: ParsedArgs, preferredId?: string): Promise<void> {
|
|
|
561
589
|
console.log(JSON.stringify(output.result, null, 2));
|
|
562
590
|
}
|
|
563
591
|
|
|
592
|
+
async function runExtractionFlush(args: ParsedArgs, preferredId?: string): Promise<void> {
|
|
593
|
+
const { config, service } = buildRuntime(preferredId);
|
|
594
|
+
const op = getOperation("extraction_force_flush");
|
|
595
|
+
if (!op) {
|
|
596
|
+
throw new Error("access-boundary: operation not registered: extraction_force_flush");
|
|
597
|
+
}
|
|
598
|
+
const output = (await op.run(
|
|
599
|
+
{
|
|
600
|
+
sessionKey: requireOption(args, "session-key"),
|
|
601
|
+
namespace: getLastOption(args, "namespace"),
|
|
602
|
+
cwd: expandOptionalPath(getLastOption(args, "cwd")),
|
|
603
|
+
projectTag: getLastOption(args, "project-tag"),
|
|
604
|
+
deadlineMs: parseIntegerOption(args, "deadline-ms", { min: 0 }),
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
service,
|
|
608
|
+
authenticatedPrincipal: getLastOption(args, "principal") ?? config.agentAccessHttp.principal,
|
|
609
|
+
},
|
|
610
|
+
)) as { result: unknown };
|
|
611
|
+
console.log(JSON.stringify(output.result, null, 2));
|
|
612
|
+
}
|
|
613
|
+
|
|
564
614
|
function expandOptionalPath(value: string | undefined): string | undefined {
|
|
565
615
|
return value === undefined ? undefined : expandTildePath(value);
|
|
566
616
|
}
|
|
@@ -805,6 +855,10 @@ export async function main(
|
|
|
805
855
|
await runBrowse(args, options.preferredId);
|
|
806
856
|
return;
|
|
807
857
|
}
|
|
858
|
+
if (args.command === "extraction-flush") {
|
|
859
|
+
await runExtractionFlush(args, options.preferredId);
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
808
862
|
if (args.command === "decision") {
|
|
809
863
|
await runDecision(args, options.preferredId);
|
|
810
864
|
return;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { isAbortError, throwIfAborted } from "./abort-error.js";
|
|
2
|
+
import { EngramAccessForbiddenError } from "./access-errors.js";
|
|
3
|
+
import type { AccessObserveWriteSurfaceDeps } from "./access-observe-write-surface.js";
|
|
4
|
+
import {
|
|
5
|
+
type EngramAccessExtractionForceFlushRequest,
|
|
6
|
+
type EngramAccessExtractionForceFlushResponse,
|
|
7
|
+
EngramAccessInputError,
|
|
8
|
+
} from "./access-service.js";
|
|
9
|
+
import { resolveNamespaceCapabilities } from "./capabilities.js";
|
|
10
|
+
import { log } from "./logger.js";
|
|
11
|
+
import { resolvePrincipal } from "./namespaces/principal.js";
|
|
12
|
+
import { ExtractionDeadlineError } from "./orchestration/extraction-run.js";
|
|
13
|
+
import { SessionOwnershipError, awaitSessionFlushPhase } from "./orchestration/session-context.js";
|
|
14
|
+
import { pendingObserveScopeHint } from "./access-observe-helpers.js";
|
|
15
|
+
|
|
16
|
+
type PendingObserveExtractionWaiter = (
|
|
17
|
+
sessionKey: string,
|
|
18
|
+
principal: string | undefined,
|
|
19
|
+
namespace: string | undefined,
|
|
20
|
+
abortSignal?: AbortSignal,
|
|
21
|
+
registerCancellation?: (cancel: () => void) => void,
|
|
22
|
+
scopeHint?: string,
|
|
23
|
+
) => Promise<void>;
|
|
24
|
+
|
|
25
|
+
export async function extractionForceFlush(
|
|
26
|
+
deps: AccessObserveWriteSurfaceDeps,
|
|
27
|
+
request: EngramAccessExtractionForceFlushRequest,
|
|
28
|
+
waitForPendingObserveExtraction?: PendingObserveExtractionWaiter
|
|
29
|
+
): Promise<EngramAccessExtractionForceFlushResponse> {
|
|
30
|
+
if (!request.sessionKey || typeof request.sessionKey !== "string" || request.sessionKey.trim().length === 0) {
|
|
31
|
+
throw new EngramAccessInputError("sessionKey is required and must be a non-empty string");
|
|
32
|
+
}
|
|
33
|
+
if (request.deadlineMs !== undefined && (!Number.isFinite(request.deadlineMs) || request.deadlineMs < 0)) {
|
|
34
|
+
throw new EngramAccessInputError("deadlineMs must be a finite non-negative number");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const authenticatedPrincipal = request.authenticatedPrincipal?.trim();
|
|
38
|
+
throwIfAborted(request.abortSignal, "extraction force-flush aborted");
|
|
39
|
+
|
|
40
|
+
const namespacesEnabled = resolveNamespaceCapabilities(deps.orchestrator.config).namespaces === true;
|
|
41
|
+
const sessionPrincipal = namespacesEnabled
|
|
42
|
+
? resolvePrincipal(request.sessionKey, deps.orchestrator.config)
|
|
43
|
+
: undefined;
|
|
44
|
+
if (namespacesEnabled) {
|
|
45
|
+
if (
|
|
46
|
+
!authenticatedPrincipal ||
|
|
47
|
+
(sessionPrincipal !== undefined && sessionPrincipal !== "default" && sessionPrincipal !== authenticatedPrincipal)
|
|
48
|
+
) {
|
|
49
|
+
throw new EngramAccessInputError("sessionKey is not owned by authenticated principal");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let committed = false;
|
|
54
|
+
const markCommitted = (): void => {
|
|
55
|
+
if (committed) return;
|
|
56
|
+
committed = true;
|
|
57
|
+
request.onCommitted?.();
|
|
58
|
+
};
|
|
59
|
+
let abortHandler: (() => void) | undefined;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const scope = await deps.resolveMemoryScopePlan(request);
|
|
63
|
+
const reservationScopeHint = pendingObserveScopeHint(request);
|
|
64
|
+
const cancelScopedPendingObserveExtractions = (): void => {
|
|
65
|
+
deps.cancelPendingObserveExtractions?.(
|
|
66
|
+
request.sessionKey,
|
|
67
|
+
scope.principal,
|
|
68
|
+
scope.writeNamespace,
|
|
69
|
+
reservationScopeHint,
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
if (request.abortSignal?.aborted) cancelScopedPendingObserveExtractions();
|
|
73
|
+
throwIfAborted(request.abortSignal, "extraction force-flush aborted");
|
|
74
|
+
if (typeof request.deadlineMs === "number" && request.deadlineMs <= Date.now()) {
|
|
75
|
+
cancelScopedPendingObserveExtractions();
|
|
76
|
+
throw new EngramAccessInputError("extraction force-flush deadline exceeded before buffer drain");
|
|
77
|
+
}
|
|
78
|
+
abortHandler = cancelScopedPendingObserveExtractions;
|
|
79
|
+
request.abortSignal?.addEventListener("abort", abortHandler, { once: true });
|
|
80
|
+
await awaitSessionFlushPhase(
|
|
81
|
+
() =>
|
|
82
|
+
deps.orchestrator.flushSession(request.sessionKey, {
|
|
83
|
+
reason: "access_force_flush",
|
|
84
|
+
abortSignal: request.abortSignal,
|
|
85
|
+
failOnExtractionFailure: true,
|
|
86
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
87
|
+
writeNamespaceOverride: scope.writeNamespace,
|
|
88
|
+
principalOverride:
|
|
89
|
+
typeof scope.principal === "string" && scope.principal.length > 0 ? scope.principal : undefined,
|
|
90
|
+
scopeProfileWritePlan: scope.scopeProfilePlan,
|
|
91
|
+
onCommitted: markCommitted,
|
|
92
|
+
}),
|
|
93
|
+
{
|
|
94
|
+
abortSignal: request.abortSignal,
|
|
95
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
96
|
+
reason: "access_force_flush",
|
|
97
|
+
deadlineStage: "buffer_drain",
|
|
98
|
+
onDeadline: cancelScopedPendingObserveExtractions,
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
// A flush with no buffered turns still consumes the lifecycle write;
|
|
102
|
+
// durable drains already invoked this idempotent callback.
|
|
103
|
+
markCommitted();
|
|
104
|
+
|
|
105
|
+
if (waitForPendingObserveExtraction) {
|
|
106
|
+
let cancelPendingObserveExtraction: (() => void) | undefined;
|
|
107
|
+
await awaitSessionFlushPhase(
|
|
108
|
+
() =>
|
|
109
|
+
waitForPendingObserveExtraction(
|
|
110
|
+
request.sessionKey,
|
|
111
|
+
scope.principal,
|
|
112
|
+
scope.writeNamespace,
|
|
113
|
+
request.abortSignal,
|
|
114
|
+
(cancel) => {
|
|
115
|
+
cancelPendingObserveExtraction = cancel;
|
|
116
|
+
},
|
|
117
|
+
reservationScopeHint,
|
|
118
|
+
),
|
|
119
|
+
{
|
|
120
|
+
abortSignal: request.abortSignal,
|
|
121
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
122
|
+
reason: "access_force_flush",
|
|
123
|
+
deadlineStage: "pending_observe_extraction",
|
|
124
|
+
onDeadline: () => {
|
|
125
|
+
cancelScopedPendingObserveExtractions();
|
|
126
|
+
cancelPendingObserveExtraction?.();
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const buffer = deps.orchestrator.buffer;
|
|
133
|
+
if (buffer && typeof buffer.clearRetainedTurnsForSession === "function") {
|
|
134
|
+
try {
|
|
135
|
+
await awaitSessionFlushPhase(
|
|
136
|
+
() =>
|
|
137
|
+
buffer.clearRetainedTurnsForSession(request.sessionKey, namespacesEnabled ? scope.principal : undefined, {
|
|
138
|
+
abortSignal: request.abortSignal,
|
|
139
|
+
deadlineMs: request.deadlineMs,
|
|
140
|
+
}),
|
|
141
|
+
{
|
|
142
|
+
abortSignal: request.abortSignal,
|
|
143
|
+
extractionDeadlineMs: request.deadlineMs,
|
|
144
|
+
reason: "access_force_flush",
|
|
145
|
+
deadlineStage: "retained_turn_cleanup",
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
} catch (cleanupError) {
|
|
149
|
+
if (isAbortError(cleanupError) || cleanupError instanceof ExtractionDeadlineError) {
|
|
150
|
+
throw cleanupError;
|
|
151
|
+
}
|
|
152
|
+
log.warn(
|
|
153
|
+
`extractionForceFlush: retained-turn cleanup failed after a successful flush, continuing: ${
|
|
154
|
+
cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
155
|
+
}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
flushed: true,
|
|
162
|
+
sessionKey: request.sessionKey,
|
|
163
|
+
namespace: deps.legacyResponseNamespaceForScope(scope),
|
|
164
|
+
effectiveNamespace: scope.writeNamespace,
|
|
165
|
+
};
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (error instanceof SessionOwnershipError) {
|
|
168
|
+
throw new EngramAccessForbiddenError(error.message);
|
|
169
|
+
}
|
|
170
|
+
if (error instanceof ExtractionDeadlineError) {
|
|
171
|
+
throw new EngramAccessInputError(error.message);
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
} finally {
|
|
175
|
+
if (abortHandler) request.abortSignal?.removeEventListener("abort", abortHandler);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import { EngramAccessHttpServer } from "./access-http.js";
|
|
5
|
+
import type {
|
|
6
|
+
EngramAccessExtractionForceFlushRequest,
|
|
7
|
+
EngramAccessLcmCompactionFlushRequest,
|
|
8
|
+
EngramAccessService,
|
|
9
|
+
} from "./access-service.js";
|
|
10
|
+
|
|
11
|
+
test("HTTP extraction force-flush forwards validated scope and deadline to the access service", async () => {
|
|
12
|
+
const requests: EngramAccessExtractionForceFlushRequest[] = [];
|
|
13
|
+
const service = {
|
|
14
|
+
extractionForceFlush: async (request: EngramAccessExtractionForceFlushRequest) => {
|
|
15
|
+
requests.push(request);
|
|
16
|
+
return {
|
|
17
|
+
flushed: true,
|
|
18
|
+
sessionKey: request.sessionKey,
|
|
19
|
+
namespace: request.namespace ?? "default",
|
|
20
|
+
effectiveNamespace: request.namespace ?? "default",
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
} as unknown as EngramAccessService;
|
|
24
|
+
const server = new EngramAccessHttpServer({
|
|
25
|
+
service,
|
|
26
|
+
port: 0,
|
|
27
|
+
authToken: "test-token",
|
|
28
|
+
adminConsoleEnabled: false,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const status = await server.start();
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(`http://127.0.0.1:${status.port}/engram/v1/extraction/flush`, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: {
|
|
36
|
+
authorization: "Bearer test-token",
|
|
37
|
+
"content-type": "application/json",
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify({
|
|
40
|
+
sessionKey: "pi:session-1",
|
|
41
|
+
namespace: "team-project",
|
|
42
|
+
cwd: "/workspace/project",
|
|
43
|
+
projectTag: "Acme/Webshop",
|
|
44
|
+
deadlineMs: 1_900_000_000_000,
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
assert.equal(response.status, 200);
|
|
49
|
+
assert.deepEqual(await response.json(), {
|
|
50
|
+
flushed: true,
|
|
51
|
+
sessionKey: "pi:session-1",
|
|
52
|
+
namespace: "team-project",
|
|
53
|
+
effectiveNamespace: "team-project",
|
|
54
|
+
});
|
|
55
|
+
assert.equal(requests.length, 1);
|
|
56
|
+
const [request] = requests;
|
|
57
|
+
assert.equal(request.sessionKey, "pi:session-1");
|
|
58
|
+
assert.equal(request.namespace, "team-project");
|
|
59
|
+
assert.equal(request.cwd, "/workspace/project");
|
|
60
|
+
assert.equal(request.projectTag, "Acme/Webshop");
|
|
61
|
+
assert.equal(request.deadlineMs, 1_900_000_000_000);
|
|
62
|
+
assert.ok(request.abortSignal instanceof AbortSignal);
|
|
63
|
+
|
|
64
|
+
const invalid = await fetch(`http://127.0.0.1:${status.port}/engram/v1/extraction/flush`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: {
|
|
67
|
+
authorization: "Bearer test-token",
|
|
68
|
+
"content-type": "application/json",
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({ sessionKey: "pi:session-1", deadlineMs: -1 }),
|
|
71
|
+
});
|
|
72
|
+
assert.equal(invalid.status, 400);
|
|
73
|
+
assert.equal(requests.length, 1, "invalid requests must not reach the access service");
|
|
74
|
+
} finally {
|
|
75
|
+
await server.stop();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("HTTP lifecycle flush preserves the scoped LCM compaction route", async () => {
|
|
80
|
+
const requests: EngramAccessLcmCompactionFlushRequest[] = [];
|
|
81
|
+
const service = {
|
|
82
|
+
lcmCompactionFlush: async (request: EngramAccessLcmCompactionFlushRequest) => {
|
|
83
|
+
requests.push(request);
|
|
84
|
+
return {
|
|
85
|
+
enabled: true,
|
|
86
|
+
flushed: true,
|
|
87
|
+
sessionKey: request.sessionKey,
|
|
88
|
+
namespace: request.namespace ?? "default",
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
} as unknown as EngramAccessService;
|
|
92
|
+
const server = new EngramAccessHttpServer({
|
|
93
|
+
service,
|
|
94
|
+
port: 0,
|
|
95
|
+
authToken: "test-token",
|
|
96
|
+
adminConsoleEnabled: false,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const status = await server.start();
|
|
100
|
+
try {
|
|
101
|
+
const response = await fetch(`http://127.0.0.1:${status.port}/remnic/v1/lcm/compaction/flush`, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: {
|
|
104
|
+
authorization: "Bearer test-token",
|
|
105
|
+
"content-type": "application/json",
|
|
106
|
+
},
|
|
107
|
+
body: JSON.stringify({
|
|
108
|
+
sessionKey: "pi:session-1",
|
|
109
|
+
namespace: "team-project",
|
|
110
|
+
cwd: "/workspace/project",
|
|
111
|
+
projectTag: "Acme/Webshop",
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
assert.equal(response.status, 200);
|
|
116
|
+
assert.deepEqual(await response.json(), {
|
|
117
|
+
enabled: true,
|
|
118
|
+
flushed: true,
|
|
119
|
+
sessionKey: "pi:session-1",
|
|
120
|
+
namespace: "team-project",
|
|
121
|
+
});
|
|
122
|
+
assert.deepEqual(requests, [{
|
|
123
|
+
sessionKey: "pi:session-1",
|
|
124
|
+
namespace: "team-project",
|
|
125
|
+
cwd: "/workspace/project",
|
|
126
|
+
projectTag: "Acme/Webshop",
|
|
127
|
+
authenticatedPrincipal: undefined,
|
|
128
|
+
}]);
|
|
129
|
+
} finally {
|
|
130
|
+
await server.stop();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { ServerResponse } from "node:http";
|
|
2
2
|
|
|
3
|
-
import type { LcmCompactionFlushRequest } from "./access-schema.js";
|
|
4
|
-
import type {
|
|
3
|
+
import type { LcmCompactionFlushRequest, LcmCompactionRecordRequest } from "./access-schema.js";
|
|
4
|
+
import type {
|
|
5
|
+
EngramAccessLcmCompactionFlushResponse,
|
|
6
|
+
EngramAccessLcmCompactionRecordResponse,
|
|
7
|
+
EngramAccessService,
|
|
8
|
+
} from "./access-service.js";
|
|
5
9
|
|
|
6
|
-
type LcmCompactionService = Pick<EngramAccessService, "lcmCompactionFlush">;
|
|
10
|
+
type LcmCompactionService = Pick<EngramAccessService, "lcmCompactionFlush" | "lcmCompactionRecord">;
|
|
7
11
|
type JsonResponder = (res: ServerResponse, status: number, payload: unknown) => void;
|
|
8
12
|
|
|
9
13
|
export interface LcmCompactionFlushHttpOptions {
|
|
@@ -24,28 +28,55 @@ export function respondLcmCompactionCapabilitiesHttp(response: ServerResponse):
|
|
|
24
28
|
response.end(JSON.stringify({ lcmCompactionFlushBatch: true }, null, 2));
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
export
|
|
31
|
+
export interface LcmCompactionFlushRunnerOptions {
|
|
32
|
+
body: LcmCompactionFlushRequest;
|
|
33
|
+
service: LcmCompactionService;
|
|
34
|
+
ensureWriteRateLimitAvailable: () => void;
|
|
35
|
+
recordWriteRateLimitHit: () => void;
|
|
36
|
+
resolveNamespace: (namespace?: string) => string | undefined;
|
|
37
|
+
defaultNamespace?: string;
|
|
38
|
+
resolveRequestPrincipal: () => string | undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type LcmCompactionFlushBatchResult =
|
|
42
|
+
| {
|
|
43
|
+
namespace: string;
|
|
44
|
+
status: "fulfilled";
|
|
45
|
+
result: EngramAccessLcmCompactionFlushResponse;
|
|
46
|
+
}
|
|
47
|
+
| { namespace: string; status: "rejected" };
|
|
48
|
+
|
|
49
|
+
type LcmCompactionFlushHttpResult =
|
|
50
|
+
| EngramAccessLcmCompactionFlushResponse
|
|
51
|
+
| {
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
flushed: boolean;
|
|
54
|
+
sessionKey: string;
|
|
55
|
+
namespaces: string[];
|
|
56
|
+
results: LcmCompactionFlushBatchResult[];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export async function runLcmCompactionFlushHttp({
|
|
28
60
|
body,
|
|
29
61
|
service,
|
|
30
|
-
response,
|
|
31
62
|
ensureWriteRateLimitAvailable,
|
|
32
63
|
recordWriteRateLimitHit,
|
|
33
64
|
resolveNamespace,
|
|
34
65
|
defaultNamespace,
|
|
35
66
|
resolveRequestPrincipal,
|
|
36
|
-
|
|
37
|
-
}: LcmCompactionFlushHttpOptions): Promise<void> {
|
|
67
|
+
}: LcmCompactionFlushRunnerOptions): Promise<LcmCompactionFlushHttpResult> {
|
|
38
68
|
ensureWriteRateLimitAvailable();
|
|
39
69
|
const requestedNamespaces = body.namespaces;
|
|
40
70
|
if (requestedNamespaces === undefined) {
|
|
41
71
|
const result = await service.lcmCompactionFlush({
|
|
42
72
|
sessionKey: body.sessionKey,
|
|
43
73
|
namespace: resolveNamespace(body.namespace),
|
|
74
|
+
...(body.cwd !== undefined ? { cwd: body.cwd } : {}),
|
|
75
|
+
...(body.projectTag !== undefined ? { projectTag: body.projectTag } : {}),
|
|
44
76
|
authenticatedPrincipal: resolveRequestPrincipal(),
|
|
45
77
|
});
|
|
46
78
|
recordWriteRateLimitHit();
|
|
47
|
-
|
|
48
|
-
return;
|
|
79
|
+
return result;
|
|
49
80
|
}
|
|
50
81
|
const resolutionOutcomes = await Promise.allSettled(
|
|
51
82
|
requestedNamespaces.map(async (requestedNamespace) => {
|
|
@@ -74,6 +105,8 @@ export async function handleLcmCompactionFlushHttp({
|
|
|
74
105
|
service.lcmCompactionFlush({
|
|
75
106
|
sessionKey: body.sessionKey,
|
|
76
107
|
namespace,
|
|
108
|
+
...(body.cwd !== undefined ? { cwd: body.cwd } : {}),
|
|
109
|
+
...(body.projectTag !== undefined ? { projectTag: body.projectTag } : {}),
|
|
77
110
|
authenticatedPrincipal: resolveRequestPrincipal(),
|
|
78
111
|
})
|
|
79
112
|
)
|
|
@@ -88,29 +121,73 @@ export async function handleLcmCompactionFlushHttp({
|
|
|
88
121
|
serviceOutcomesByEffectiveNamespace.set(resolved.effectiveNamespace, serviceOutcome);
|
|
89
122
|
}
|
|
90
123
|
}
|
|
91
|
-
|
|
92
|
-
| {
|
|
93
|
-
requestedNamespace: string;
|
|
94
|
-
status: "fulfilled";
|
|
95
|
-
result: EngramAccessLcmCompactionFlushResponse;
|
|
96
|
-
}
|
|
97
|
-
| { requestedNamespace: string; status: "rejected" };
|
|
98
|
-
const results: BatchResult[] = resolutionOutcomes.map((outcome, index) => {
|
|
124
|
+
const results = resolutionOutcomes.map((outcome, index): LcmCompactionFlushBatchResult => {
|
|
99
125
|
const requestedNamespace = requestedNamespaces[index] ?? "";
|
|
100
126
|
if (outcome.status === "rejected") {
|
|
101
|
-
return { status: "rejected", requestedNamespace };
|
|
127
|
+
return { status: "rejected", namespace: requestedNamespace };
|
|
102
128
|
}
|
|
103
129
|
const serviceOutcome = serviceOutcomesByEffectiveNamespace.get(outcome.value.effectiveNamespace);
|
|
104
130
|
return serviceOutcome?.status === "fulfilled"
|
|
105
|
-
? { status: "fulfilled", requestedNamespace, result: serviceOutcome.value }
|
|
106
|
-
: { status: "rejected", requestedNamespace };
|
|
131
|
+
? { status: "fulfilled", namespace: requestedNamespace, result: serviceOutcome.value }
|
|
132
|
+
: { status: "rejected", namespace: requestedNamespace };
|
|
107
133
|
});
|
|
108
134
|
recordWriteRateLimitHit();
|
|
109
|
-
|
|
135
|
+
return {
|
|
110
136
|
enabled: results.every((result) => result.status === "fulfilled" && result.result.enabled !== false),
|
|
111
137
|
flushed: results.every((result) => result.status === "fulfilled" && result.result.flushed !== false),
|
|
112
138
|
sessionKey: body.sessionKey,
|
|
113
139
|
namespaces: requestedNamespaces,
|
|
114
|
-
results
|
|
140
|
+
results,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export async function handleLcmCompactionFlushHttp({
|
|
144
|
+
body,
|
|
145
|
+
service,
|
|
146
|
+
response,
|
|
147
|
+
ensureWriteRateLimitAvailable,
|
|
148
|
+
recordWriteRateLimitHit,
|
|
149
|
+
resolveNamespace,
|
|
150
|
+
defaultNamespace,
|
|
151
|
+
resolveRequestPrincipal,
|
|
152
|
+
respondJson,
|
|
153
|
+
}: LcmCompactionFlushHttpOptions): Promise<void> {
|
|
154
|
+
const result = await runLcmCompactionFlushHttp({
|
|
155
|
+
body,
|
|
156
|
+
service,
|
|
157
|
+
ensureWriteRateLimitAvailable,
|
|
158
|
+
recordWriteRateLimitHit,
|
|
159
|
+
resolveNamespace,
|
|
160
|
+
defaultNamespace,
|
|
161
|
+
resolveRequestPrincipal,
|
|
115
162
|
});
|
|
163
|
+
respondJson(response, 200, result);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface LcmCompactionRecordHttpOptions {
|
|
167
|
+
body: LcmCompactionRecordRequest;
|
|
168
|
+
service: LcmCompactionService;
|
|
169
|
+
ensureWriteRateLimitAvailable: () => void;
|
|
170
|
+
recordWriteRateLimitHit: () => void;
|
|
171
|
+
resolveNamespace: (namespace?: string) => string | undefined;
|
|
172
|
+
resolveRequestPrincipal: () => string | undefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function runLcmCompactionRecordHttp({
|
|
176
|
+
body,
|
|
177
|
+
service,
|
|
178
|
+
ensureWriteRateLimitAvailable,
|
|
179
|
+
recordWriteRateLimitHit,
|
|
180
|
+
resolveNamespace,
|
|
181
|
+
resolveRequestPrincipal,
|
|
182
|
+
}: LcmCompactionRecordHttpOptions): Promise<EngramAccessLcmCompactionRecordResponse> {
|
|
183
|
+
ensureWriteRateLimitAvailable();
|
|
184
|
+
const response = await service.lcmCompactionRecord({
|
|
185
|
+
sessionKey: body.sessionKey,
|
|
186
|
+
namespace: resolveNamespace(body.namespace),
|
|
187
|
+
tokensBefore: body.tokensBefore,
|
|
188
|
+
tokensAfter: body.tokensAfter,
|
|
189
|
+
authenticatedPrincipal: resolveRequestPrincipal(),
|
|
190
|
+
});
|
|
191
|
+
recordWriteRateLimitHit();
|
|
192
|
+
return response;
|
|
116
193
|
}
|