@modusensus/dsh-mneme 0.13.0 → 0.14.0-beta.2
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/LICENSE +21 -21
- package/README.md +830 -828
- package/assets/icon.svg +3 -3
- package/bin/cli.mjs +964 -964
- package/bin/dsh-mneme-choro.mjs +262 -254
- package/bin/dsh-mneme-mcp.mjs +510 -510
- package/bin/dsh-mneme-serve.mjs +151 -151
- package/cordis.patch.yml +21 -21
- package/docs/CONFIGURATION.md +407 -402
- package/docs/CONTINUITY.md +139 -139
- package/docs/DAEMON.md +57 -57
- package/docs/DIRECTORIES.md +114 -114
- package/docs/DISTILL.md +397 -371
- package/docs/DSH-GO.md +97 -97
- package/docs/ENTITIES.md +247 -247
- package/docs/FORGET.md +77 -77
- package/docs/KB.md +110 -110
- package/docs/LOCAL_MODEL.md +222 -222
- package/docs/SEMANTIC.md +256 -256
- package/docs/SHARE.md +552 -552
- package/docs/SLEEP.md +202 -202
- package/docs/STORAGE.md +122 -122
- package/docs/WORKFLOWS.md +366 -366
- package/lib/api-standalone.js +1007 -1007
- package/lib/api.js +3600 -3394
- package/lib/attachment-text.js +122 -122
- package/lib/bootstrap-http.js +105 -105
- package/lib/bootstrap.js +215 -215
- package/lib/candidates.js +454 -454
- package/lib/capabilities.js +819 -819
- package/lib/choro-command.js +111 -111
- package/lib/client.js +14420 -13436
- package/lib/commands.js +95 -95
- package/lib/config-keys.js +144 -144
- package/lib/config.js +1361 -1317
- package/lib/content-hash.js +54 -54
- package/lib/continuity.js +258 -258
- package/lib/date-hint.js +32 -0
- package/lib/diary/auto.js +190 -190
- package/lib/diary/compose.js +440 -440
- package/lib/diary/dir.js +59 -59
- package/lib/diary/export.js +97 -97
- package/lib/diary/index.js +26 -26
- package/lib/diary/library.js +189 -189
- package/lib/diary/qq-inbox.js +142 -142
- package/lib/diary/rollover.js +61 -61
- package/lib/diary/session-provider.js +122 -122
- package/lib/document-index.js +94 -94
- package/lib/document.js +322 -322
- package/lib/dream/clustering.js +123 -123
- package/lib/dream/decisions.js +945 -907
- package/lib/dream/narratives.js +44 -44
- package/lib/dream/sleep.js +2027 -1887
- package/lib/dream/triage.js +139 -0
- package/lib/dream.js +1879 -1764
- package/lib/dsh-go/host.js +162 -162
- package/lib/dsh-go/panel.js +2091 -2091
- package/lib/dsh-go/text.js +342 -342
- package/lib/dsh-go/views/common.js +68 -68
- package/lib/dsh-go/views/entity.js +48 -48
- package/lib/dsh-go/views/memory.js +198 -198
- package/lib/dsh-go/views/root.js +30 -30
- package/lib/dsh-go/views/settings.js +398 -398
- package/lib/dsh-go/views/status.js +51 -51
- package/lib/embedding.js +342 -342
- package/lib/entities/extractor.js +285 -285
- package/lib/fence.js +24 -24
- package/lib/graph/anchoring.js +184 -184
- package/lib/guide.js +74 -74
- package/lib/heat.js +144 -144
- package/lib/hot-memory.js +119 -107
- package/lib/image-describe.js +158 -0
- package/lib/index.js +852 -822
- package/lib/inject.js +656 -639
- package/lib/kb/index.js +309 -309
- package/lib/kb/routes.js +219 -219
- package/lib/kb/tools.js +148 -148
- package/lib/lang.js +607 -584
- package/lib/local-embedder.js +358 -358
- package/lib/maintenance.js +162 -162
- package/lib/memory-source.js +9 -9
- package/lib/mirror.js +330 -330
- package/lib/organize.js +456 -456
- package/lib/peak-hours.js +172 -172
- package/lib/pipeline-activities.js +178 -178
- package/lib/pipeline-attribution.js +165 -165
- package/lib/pipeline-command.js +279 -279
- package/lib/pipeline-confirm.js +142 -142
- package/lib/pipeline-exec.js +174 -174
- package/lib/pipeline-nudge-auto.js +129 -129
- package/lib/pipeline-nudge.js +1623 -1623
- package/lib/pipeline-observations.js +181 -181
- package/lib/pipeline-observe.js +133 -133
- package/lib/pipeline-runner.js +361 -361
- package/lib/pipeline-runs.js +442 -442
- package/lib/pipeline.js +716 -716
- package/lib/placement.js +13 -13
- package/lib/pre-inject-gate.js +354 -354
- package/lib/profile-extract.js +164 -164
- package/lib/profile-facts.js +356 -356
- package/lib/provenance-http.js +251 -251
- package/lib/quality-filter.js +162 -162
- package/lib/recall-stats.js +190 -190
- package/lib/reclaim-http.js +150 -150
- package/lib/reranker.js +269 -269
- package/lib/runtime/adopt.js +176 -176
- package/lib/runtime/closure.js +172 -172
- package/lib/runtime/download.js +247 -247
- package/lib/runtime/layout.js +265 -265
- package/lib/runtime/loader.js +252 -252
- package/lib/runtime/model-fetch.js +361 -361
- package/lib/runtime/provision.js +237 -237
- package/lib/runtime/tarball.js +130 -130
- package/lib/runtime/verify.js +223 -223
- package/lib/safe-slice.js +18 -18
- package/lib/scope-state.js +277 -277
- package/lib/scope.js +187 -187
- package/lib/search/adaptive.js +60 -60
- package/lib/search/bm25.js +96 -96
- package/lib/semantic.js +572 -572
- package/lib/sensitive-scan.js +209 -209
- package/lib/serve.js +228 -228
- package/lib/service.js +3268 -3196
- package/lib/session-gate.js +91 -91
- package/lib/session-usage.js +350 -350
- package/lib/settings.js +827 -802
- package/lib/share-http.js +281 -281
- package/lib/share-import.js +234 -234
- package/lib/share.js +335 -335
- package/lib/store.js +5895 -5662
- package/lib/summarize.js +1388 -1343
- package/lib/tools.js +1370 -1356
- package/lib/user-settings.js +230 -230
- package/lib/vector-index.js +180 -180
- package/lib/version-check.js +122 -122
- package/lib/wiki/claims.js +267 -0
- package/lib/wiki/cli-hint.js +90 -90
- package/lib/wiki/inject.js +164 -164
- package/lib/wiki/partition.js +200 -200
- package/lib/wiki/plan.js +214 -214
- package/lib/wiki/queries.js +640 -474
- package/lib/wiki/render.js +261 -187
- package/lib/wiki/scan.js +371 -371
- package/lib/wiki/t0.js +500 -463
- package/lib/wiki/t1-jobs.js +232 -232
- package/lib/wiki/t1.js +609 -502
- package/lib/write-admission.js +404 -404
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/package.json +15 -1
- package/runtime-manifest.json +526 -526
- package/scripts/benchmark-embed.js +201 -201
- package/scripts/benchmark-recall.js +249 -249
- package/scripts/benchmark-rerank.js +166 -166
- package/scripts/build-runtime-manifest.mjs +224 -224
- package/scripts/changelog-prep.mjs +91 -91
- package/scripts/check-sync.js +44 -44
- package/scripts/e2e-dsh.js +220 -220
- package/scripts/mneme-runtime.mjs +277 -277
- package/scripts/publish-gate.mjs +197 -197
- package/scripts/release-docs.mjs +210 -204
- package/scripts/release-notes.mjs +164 -161
- package/scripts/stress-dsh.js +255 -255
- package/scripts/sync-lib.js +47 -47
- package/scripts/sync-test-badge.mjs +69 -69
- package/scripts/test-count-sync.mjs +48 -48
- package/src/api-standalone.js +1007 -1007
- package/src/api.js +3600 -3394
- package/src/attachment-text.js +122 -122
- package/src/bootstrap-http.js +105 -105
- package/src/bootstrap.js +215 -215
- package/src/candidates.js +454 -454
- package/src/capabilities.js +819 -819
- package/src/choro-command.js +111 -111
- package/src/commands.js +95 -95
- package/src/config-keys.js +144 -144
- package/src/config.js +1361 -1317
- package/src/content-hash.js +54 -54
- package/src/continuity.js +258 -258
- package/src/date-hint.js +32 -0
- package/src/diary/auto.js +190 -190
- package/src/diary/compose.js +440 -440
- package/src/diary/dir.js +59 -59
- package/src/diary/export.js +97 -97
- package/src/diary/index.js +26 -26
- package/src/diary/library.js +189 -189
- package/src/diary/qq-inbox.js +142 -142
- package/src/diary/rollover.js +61 -61
- package/src/diary/session-provider.js +122 -122
- package/src/document-index.js +94 -94
- package/src/document.js +322 -322
- package/src/dream/clustering.js +123 -123
- package/src/dream/decisions.js +945 -907
- package/src/dream/narratives.js +44 -44
- package/src/dream/sleep.js +2027 -1887
- package/src/dream/triage.js +139 -0
- package/src/dream.js +1879 -1764
- package/src/dsh-go/host.js +162 -162
- package/src/dsh-go/panel.js +2091 -2091
- package/src/dsh-go/text.js +342 -342
- package/src/dsh-go/views/common.js +68 -68
- package/src/dsh-go/views/entity.js +48 -48
- package/src/dsh-go/views/memory.js +198 -198
- package/src/dsh-go/views/root.js +30 -30
- package/src/dsh-go/views/settings.js +398 -398
- package/src/dsh-go/views/status.js +51 -51
- package/src/embedding.js +342 -342
- package/src/entities/extractor.js +285 -285
- package/src/fence.js +24 -24
- package/src/graph/anchoring.js +184 -184
- package/src/guide.js +74 -74
- package/src/heat.js +144 -144
- package/src/hot-memory.js +119 -107
- package/src/image-describe.js +158 -0
- package/src/index.js +852 -822
- package/src/inject.js +656 -639
- package/src/kb/index.js +309 -309
- package/src/kb/routes.js +219 -219
- package/src/kb/tools.js +148 -148
- package/src/lang.js +607 -584
- package/src/local-embedder.js +358 -358
- package/src/maintenance.js +162 -162
- package/src/memory-source.js +9 -9
- package/src/mirror.js +330 -330
- package/src/organize.js +456 -456
- package/src/peak-hours.js +172 -172
- package/src/pipeline-activities.js +178 -178
- package/src/pipeline-attribution.js +165 -165
- package/src/pipeline-command.js +279 -279
- package/src/pipeline-confirm.js +142 -142
- package/src/pipeline-exec.js +174 -174
- package/src/pipeline-nudge-auto.js +129 -129
- package/src/pipeline-nudge.js +1623 -1623
- package/src/pipeline-observations.js +181 -181
- package/src/pipeline-observe.js +133 -133
- package/src/pipeline-runner.js +361 -361
- package/src/pipeline-runs.js +442 -442
- package/src/pipeline.js +716 -716
- package/src/placement.js +13 -13
- package/src/pre-inject-gate.js +354 -354
- package/src/profile-extract.js +164 -164
- package/src/profile-facts.js +356 -356
- package/src/provenance-http.js +251 -251
- package/src/quality-filter.js +162 -162
- package/src/recall-stats.js +190 -190
- package/src/reclaim-http.js +150 -150
- package/src/reranker.js +269 -269
- package/src/runtime/adopt.js +176 -176
- package/src/runtime/closure.js +172 -172
- package/src/runtime/download.js +247 -247
- package/src/runtime/layout.js +265 -265
- package/src/runtime/loader.js +252 -252
- package/src/runtime/model-fetch.js +361 -361
- package/src/runtime/provision.js +237 -237
- package/src/runtime/tarball.js +130 -130
- package/src/runtime/verify.js +223 -223
- package/src/safe-slice.js +18 -18
- package/src/scope-state.js +277 -277
- package/src/scope.js +187 -187
- package/src/search/adaptive.js +60 -60
- package/src/search/bm25.js +96 -96
- package/src/semantic.js +572 -572
- package/src/sensitive-scan.js +209 -209
- package/src/serve.js +228 -228
- package/src/service.js +3268 -3196
- package/src/session-gate.js +91 -91
- package/src/session-usage.js +350 -350
- package/src/settings.js +827 -802
- package/src/share-http.js +281 -281
- package/src/share-import.js +234 -234
- package/src/share.js +335 -335
- package/src/store.js +5895 -5662
- package/src/summarize.js +1388 -1343
- package/src/tools.js +1370 -1356
- package/src/user-settings.js +230 -230
- package/src/vector-index.js +180 -180
- package/src/version-check.js +122 -122
- package/src/wiki/claims.js +267 -0
- package/src/wiki/cli-hint.js +90 -90
- package/src/wiki/inject.js +164 -164
- package/src/wiki/partition.js +200 -200
- package/src/wiki/plan.js +214 -214
- package/src/wiki/queries.js +640 -474
- package/src/wiki/render.js +261 -187
- package/src/wiki/scan.js +371 -371
- package/src/wiki/t0.js +500 -463
- package/src/wiki/t1-jobs.js +232 -232
- package/src/wiki/t1.js +609 -502
- package/src/write-admission.js +404 -404
- package/test/adaptive-inject-budget.test.js +85 -85
- package/test/api-hardening.test.js +173 -173
- package/test/api-nudge-route.test.js +259 -259
- package/test/api-routes-gaps.test.js +1092 -1092
- package/test/api.test.js +3007 -2988
- package/test/attachment-text.test.js +139 -139
- package/test/audit.test.js +448 -448
- package/test/baseline-persist.test.js +248 -248
- package/test/benchmark.test.js +94 -94
- package/test/bm25-corpus-cache.test.js +145 -145
- package/test/bootstrap.test.js +228 -228
- package/test/candidates.test.js +345 -345
- package/test/capabilities.test.js +577 -577
- package/test/capacity-warning.test.js +262 -262
- package/test/changelog-prep.test.js +125 -125
- package/test/choro-command.test.js +218 -218
- package/test/cli-enums.test.js +37 -37
- package/test/cli-flag-value.test.js +86 -86
- package/test/cli-receive.test.js +390 -390
- package/test/cli-share.test.js +437 -437
- package/test/client-share.test.js +225 -225
- package/test/client.test.js +4595 -4184
- package/test/clustering.test.js +100 -100
- package/test/commands.test.js +106 -106
- package/test/config-keys-routes.test.js +233 -233
- package/test/config.test.js +153 -153
- package/test/conflict-freeze.test.js +344 -344
- package/test/conflict-ledger-enforce.test.js +452 -0
- package/test/conflict-ledger.test.js +242 -0
- package/test/conflict-reviewed.test.js +79 -79
- package/test/content-hash.test.js +204 -204
- package/test/continuity.test.js +452 -452
- package/test/contrast.test.js +432 -320
- package/test/date-hint.test.js +156 -0
- package/test/dedupe-candidate-window.test.js +180 -180
- package/test/dependency-overrides.test.js +78 -78
- package/test/diary-library.test.js +187 -187
- package/test/diary.test.js +576 -576
- package/test/differentiate-feedback.test.js +248 -248
- package/test/distill-tx-embed-gap.test.js +110 -110
- package/test/docs-config-keys.test.js +65 -65
- package/test/document-dir.test.js +233 -233
- package/test/document.test.js +703 -703
- package/test/dream-archive-guardrail.test.js +116 -116
- package/test/dream-baseline-clamp.test.js +174 -0
- package/test/dream-candidate-hybrid.test.js +281 -281
- package/test/dream-coverage-degrade.test.js +86 -86
- package/test/dream-decision-evidence.test.js +314 -314
- package/test/dream-failure-backoff.test.js +173 -173
- package/test/dream-fence.test.js +207 -207
- package/test/dream-maxtokens-fallback.test.js +132 -132
- package/test/dream-merge-guardrail.test.js +219 -219
- package/test/dream-peak-hours.test.js +194 -194
- package/test/dream.test.js +1528 -1528
- package/test/dsh-go-host.test.js +134 -134
- package/test/dsh-go-panel-actions.test.js +854 -854
- package/test/dsh-go-panel.test.js +251 -251
- package/test/embed-ready-poll.test.js +94 -94
- package/test/embed-text-reasons.test.js +112 -112
- package/test/embedding-cache-f32.test.js +276 -276
- package/test/embedding-ready.test.js +226 -226
- package/test/entities.test.js +711 -711
- package/test/entity-recall.test.js +179 -179
- package/test/epistemic.test.js +325 -325
- package/test/failure-query.test.js +147 -147
- package/test/failure-retention.test.js +105 -105
- package/test/fnew-0112.test.js +311 -311
- package/test/fnew-03.test.js +422 -422
- package/test/forget-corrections.test.js +70 -70
- package/test/graph-anchoring.test.js +184 -184
- package/test/graph-api.test.js +333 -209
- package/test/graph-boosted-relations.test.js +189 -189
- package/test/graph-inject-budget.test.js +103 -103
- package/test/graph-multipath.test.js +269 -269
- package/test/graph-passive-confirm.test.js +91 -91
- package/test/graph-weight-evolution.test.js +104 -104
- package/test/heat.test.js +175 -175
- package/test/helpers/dream-mock.js +86 -86
- package/test/helpers/peer-worker.mjs +25 -25
- package/test/helpers/runtime-source.js +60 -60
- package/test/helpers/tar-builder.js +80 -80
- package/test/helpers/write-admission-samples.js +312 -312
- package/test/hot-memory.test.js +259 -211
- package/test/image-description.test.js +271 -0
- package/test/image-memory.test.js +170 -170
- package/test/inject-content-cap.test.js +91 -91
- package/test/inject-first-round-bm25.test.js +89 -89
- package/test/inject-heat.test.js +77 -77
- package/test/inject-parent-gate.test.js +134 -106
- package/test/inject-pin-explicit.test.js +300 -300
- package/test/inject-pin-vector-crowd.test.js +225 -225
- package/test/inject-pools.test.js +195 -195
- package/test/inject-recall.test.js +172 -172
- package/test/inject-rotation.test.js +161 -161
- package/test/inject.test.js +553 -494
- package/test/issue-617-step1-query-and-fusion.test.js +361 -361
- package/test/kb-api-wiring.test.js +128 -128
- package/test/kb-collections.test.js +272 -272
- package/test/kb-routes.test.js +379 -379
- package/test/lang.test.js +98 -98
- package/test/lastrunat-persist.test.js +101 -101
- package/test/lib-smoke.test.js +116 -116
- package/test/llm-audit.test.js +815 -815
- package/test/llm-message-source.test.js +207 -207
- package/test/local-embedder.test.js +292 -292
- package/test/maintenance.test.js +501 -501
- package/test/mcp-stdio.test.js +385 -385
- package/test/mint-source.test.js +311 -311
- package/test/mirror-dirty.test.js +424 -424
- package/test/mirror-edit-digest.test.js +187 -187
- package/test/mirror-generation.test.js +499 -499
- package/test/mirror-types.test.js +208 -208
- package/test/mirror.test.js +249 -249
- package/test/narrative-bars.test.js +162 -162
- package/test/organize-tool.test.js +232 -232
- package/test/organize.test.js +418 -418
- package/test/panel-chart-scale.test.js +90 -0
- package/test/panel-tokens.test.js +245 -0
- package/test/peak-hours-observability.test.js +70 -70
- package/test/peer-blockers.test.js +193 -193
- package/test/persona-addressing.test.js +83 -83
- package/test/persona-api.test.js +172 -172
- package/test/persona-by-session.test.js +568 -568
- package/test/persona-flag.test.js +36 -36
- package/test/persona-inject.test.js +145 -145
- package/test/persona-settings.test.js +198 -198
- package/test/pipeline-activities.test.js +155 -155
- package/test/pipeline-attribution.test.js +175 -175
- package/test/pipeline-command.test.js +243 -243
- package/test/pipeline-confirm.test.js +148 -148
- package/test/pipeline-exec.test.js +172 -172
- package/test/pipeline-nudge-auto.test.js +248 -248
- package/test/pipeline-nudge.test.js +1278 -1278
- package/test/pipeline-observations.test.js +157 -157
- package/test/pipeline-observe.test.js +127 -127
- package/test/pipeline-r1r2.test.js +278 -278
- package/test/pipeline-runner.test.js +468 -468
- package/test/pipeline-runs.test.js +767 -767
- package/test/pipeline.test.js +636 -636
- package/test/placement.test.js +36 -36
- package/test/policy-epoch.test.js +259 -259
- package/test/pre-inject-gate.test.js +444 -444
- package/test/profile-extract.test.js +269 -269
- package/test/profile-facts.test.js +492 -492
- package/test/prompt-stance.test.js +128 -128
- package/test/provenance-http.test.js +367 -367
- package/test/publish-gate.test.js +272 -272
- package/test/quality-backfill.test.js +290 -290
- package/test/quality-filter.test.js +295 -295
- package/test/readme-claims.test.js +113 -113
- package/test/reasoning-effort.test.js +752 -752
- package/test/recall-anti-update.test.js +82 -82
- package/test/recall-evals.test.js +253 -253
- package/test/recall-layer.test.js +326 -326
- package/test/recall-retention.test.js +128 -128
- package/test/recall-stats.test.js +274 -274
- package/test/receipt-chain.test.js +451 -451
- package/test/reclaim-http.test.js +209 -209
- package/test/reflection-update-gate.test.js +129 -129
- package/test/reflection.test.js +226 -226
- package/test/reindex-backfill.test.js +475 -475
- package/test/reindex-scheduler.test.js +369 -369
- package/test/release-docs.test.js +156 -136
- package/test/release-notes.test.js +265 -240
- package/test/release-workflow.test.js +93 -93
- package/test/reranker-single-logit.test.js +73 -73
- package/test/reranker.test.js +197 -197
- package/test/resident-status.test.js +83 -83
- package/test/route-policy.test.js +113 -113
- package/test/runtime-adopt.test.js +206 -206
- package/test/runtime-cli.test.js +89 -89
- package/test/runtime-closure.test.js +193 -193
- package/test/runtime-download.test.js +302 -302
- package/test/runtime-layout.test.js +163 -163
- package/test/runtime-loader.test.js +255 -255
- package/test/runtime-manifest.test.js +159 -159
- package/test/runtime-model-fetch.test.js +348 -348
- package/test/runtime-provision.test.js +101 -101
- package/test/runtime-tarball.test.js +81 -81
- package/test/runtime-verify.test.js +319 -319
- package/test/scope-candidates.test.js +491 -491
- package/test/scope-distill-stamp.test.js +134 -134
- package/test/scope-explicit.test.js +452 -452
- package/test/scope-inject-soft.test.js +106 -106
- package/test/scope-optional-service.test.js +110 -110
- package/test/scope-retrieval.test.js +197 -197
- package/test/scope-state.test.js +610 -610
- package/test/scope-storage.test.js +255 -255
- package/test/scope-strict.test.js +367 -367
- package/test/search-fusion.test.js +90 -90
- package/test/security-doc.test.js +188 -178
- package/test/semantic.test.js +124 -124
- package/test/sensitive-scan.test.js +251 -251
- package/test/serve-bin.test.js +121 -121
- package/test/serve.test.js +258 -258
- package/test/service-search.test.js +174 -174
- package/test/service.test.js +410 -410
- package/test/session-gate.test.js +264 -264
- package/test/session-usage.test.js +317 -317
- package/test/settings.test.js +273 -273
- package/test/share-foreign-rows.test.js +144 -144
- package/test/share-http.test.js +144 -144
- package/test/share-import.test.js +577 -577
- package/test/share-imported-guard.test.js +311 -311
- package/test/share-imported-identity.test.js +111 -111
- package/test/share-pack.test.js +511 -511
- package/test/share-receive-http.test.js +756 -756
- package/test/share-routes.test.js +337 -337
- package/test/share-store.test.js +133 -133
- package/test/share-validate.test.js +101 -101
- package/test/skip-invalid-restore.test.js +262 -262
- package/test/sleep-action-set.test.js +441 -441
- package/test/sleep-catchup.test.js +315 -315
- package/test/sleep-failure-backoff.test.js +156 -156
- package/test/sleep-heat.test.js +174 -174
- package/test/sleep-scheduler-rearm.test.js +89 -89
- package/test/sleep.test.js +1455 -1418
- package/test/standalone-api.test.js +1344 -1344
- package/test/store-vector-cache.test.js +98 -98
- package/test/store-write-path-columns.test.js +191 -191
- package/test/store.test.js +744 -744
- package/test/stress.test.js +209 -209
- package/test/summarize-occurred-at.test.js +127 -127
- package/test/summarize-parse-diagnostics.test.js +75 -75
- package/test/summarize-reasoning-effort.test.js +189 -189
- package/test/summarize.test.js +2251 -2251
- package/test/supersede-state-tracking.test.js +394 -394
- package/test/test-count-sync.test.js +71 -71
- package/test/tool-state-ignore.test.js +65 -65
- package/test/tools-dto-schema-matrix.test.js +398 -398
- package/test/tools-memory-get-schema.test.js +65 -65
- package/test/tools.test.js +585 -585
- package/test/updated-at-semantics.test.js +113 -113
- package/test/user-settings-preview.test.js +127 -127
- package/test/user-settings-segments.test.js +527 -527
- package/test/vector-index.test.js +334 -334
- package/test/version-check.test.js +152 -152
- package/test/webServer-optional.test.js +82 -82
- package/test/wiki-api.test.js +734 -627
- package/test/wiki-claims.test.js +194 -0
- package/test/wiki-cli-hint.test.js +118 -118
- package/test/wiki-inject.test.js +265 -265
- package/test/wiki-partition.test.js +112 -112
- package/test/wiki-plan.test.js +80 -80
- package/test/wiki-provenance.test.js +202 -0
- package/test/wiki-queries.test.js +398 -277
- package/test/wiki-scan.test.js +208 -208
- package/test/wiki-store.test.js +190 -190
- package/test/wiki-t0.test.js +456 -380
- package/test/wiki-t1-jobs.test.js +125 -125
- package/test/wiki-t1.test.js +460 -235
- package/test/wiki-tools.test.js +176 -176
- package/test/workflow-guards.test.js +155 -155
- package/test/write-admission.test.js +668 -668
package/lib/diary/rollover.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 跨天判定:本机没有日历调度原语(cordis.patch.yml 没有 schedules 服务,
|
|
3
|
-
* node_modules 里唯一的 scheduler 是 React 那个),所以「每天 0 点写一篇」写不出来。
|
|
4
|
-
*
|
|
5
|
-
* 可实现的等价形态是**跨天惰性判定**:在 turn/end 与插件启动两个既有挂载点上问
|
|
6
|
-
* 「上一次写的日期是不是今天」,不是才写。差别只在于「今天一句话没说」那天没有日记
|
|
7
|
-
* ——而那恰好是对的:没有素材就不该编。
|
|
8
|
-
*
|
|
9
|
-
* 全部是纯函数(时间由调用方注入),所以「跨 5 天只补 1 天」这类边界能被真的测出来。
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/** 宿主本地时区的 `YYYY-MM-DD`。刻意不用 UTC:日记的「今天」是用户感知的今天。 */
|
|
13
|
-
export function localDateString(date) {
|
|
14
|
-
const d = date instanceof Date ? date : new Date(date);
|
|
15
|
-
const y = d.getFullYear();
|
|
16
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
17
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
18
|
-
return `${y}-${m}-${day}`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function toUtcMs(dateLocal) {
|
|
22
|
-
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(dateLocal ?? ""));
|
|
23
|
-
if (!m) return null;
|
|
24
|
-
return Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** `to - from` 的整数天数;任一参数形状不对返回 null(调用方据此走「当作首次」)。 */
|
|
28
|
-
export function dayGap(fromDate, toDate) {
|
|
29
|
-
const a = toUtcMs(fromDate);
|
|
30
|
-
const b = toUtcMs(toDate);
|
|
31
|
-
if (a === null || b === null) return null;
|
|
32
|
-
return Math.round((b - a) / 86400000);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** 一次最多回补几天。默认 1:睡得久一点就补一篇,不该醒来一次补十篇把模型配额烧光。 */
|
|
36
|
-
export const MAX_CATCH_UP_DAYS = 1;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 今天该不该写。
|
|
40
|
-
*
|
|
41
|
-
* 返回 `{roll, gapDays, gap}`:
|
|
42
|
-
* - `roll` 要不要写。`lastDate` 为空(从没写过)→ 写。
|
|
43
|
-
* - `gapDays` 距上次写的天数(null = 没写过或日期形状不对)。
|
|
44
|
-
* - `gap` 中间有没有「永久丢掉」的日子(超过回补上限)——必须如实写进日记头部,
|
|
45
|
-
* 不能假装连续。这是本模块唯一允许对读者撒谎的地方,所以它必须是个返回值,
|
|
46
|
-
* 不是一个可选参数。
|
|
47
|
-
*
|
|
48
|
-
* 时钟往回调(`lastDate` 比今天还新)时不写:那不是「跨天」,那是同一份时间被
|
|
49
|
-
* 重算了一次,再写一次只会覆盖掉今天已经写好的那篇。
|
|
50
|
-
*/
|
|
51
|
-
export function shouldRollDay(lastDate, today, { maxCatchUpDays = MAX_CATCH_UP_DAYS } = {}) {
|
|
52
|
-
const now = String(today ?? "");
|
|
53
|
-
if (!/^\d{4}-\d{2}-\d{2}$/.test(now)) return { roll: false, gapDays: null, gap: false };
|
|
54
|
-
const last = String(lastDate ?? "");
|
|
55
|
-
if (!/^\d{4}-\d{2}-\d{2}$/.test(last)) return { roll: true, gapDays: null, gap: false };
|
|
56
|
-
if (last === now) return { roll: false, gapDays: 0, gap: false };
|
|
57
|
-
const gapDays = dayGap(last, now);
|
|
58
|
-
if (gapDays === null || gapDays < 0) return { roll: false, gapDays, gap: false };
|
|
59
|
-
const limit = Number.isFinite(maxCatchUpDays) && maxCatchUpDays >= 0 ? maxCatchUpDays : MAX_CATCH_UP_DAYS;
|
|
60
|
-
return { roll: true, gapDays, gap: gapDays > limit };
|
|
61
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 跨天判定:本机没有日历调度原语(cordis.patch.yml 没有 schedules 服务,
|
|
3
|
+
* node_modules 里唯一的 scheduler 是 React 那个),所以「每天 0 点写一篇」写不出来。
|
|
4
|
+
*
|
|
5
|
+
* 可实现的等价形态是**跨天惰性判定**:在 turn/end 与插件启动两个既有挂载点上问
|
|
6
|
+
* 「上一次写的日期是不是今天」,不是才写。差别只在于「今天一句话没说」那天没有日记
|
|
7
|
+
* ——而那恰好是对的:没有素材就不该编。
|
|
8
|
+
*
|
|
9
|
+
* 全部是纯函数(时间由调用方注入),所以「跨 5 天只补 1 天」这类边界能被真的测出来。
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** 宿主本地时区的 `YYYY-MM-DD`。刻意不用 UTC:日记的「今天」是用户感知的今天。 */
|
|
13
|
+
export function localDateString(date) {
|
|
14
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
15
|
+
const y = d.getFullYear();
|
|
16
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
17
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
18
|
+
return `${y}-${m}-${day}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function toUtcMs(dateLocal) {
|
|
22
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(dateLocal ?? ""));
|
|
23
|
+
if (!m) return null;
|
|
24
|
+
return Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** `to - from` 的整数天数;任一参数形状不对返回 null(调用方据此走「当作首次」)。 */
|
|
28
|
+
export function dayGap(fromDate, toDate) {
|
|
29
|
+
const a = toUtcMs(fromDate);
|
|
30
|
+
const b = toUtcMs(toDate);
|
|
31
|
+
if (a === null || b === null) return null;
|
|
32
|
+
return Math.round((b - a) / 86400000);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 一次最多回补几天。默认 1:睡得久一点就补一篇,不该醒来一次补十篇把模型配额烧光。 */
|
|
36
|
+
export const MAX_CATCH_UP_DAYS = 1;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 今天该不该写。
|
|
40
|
+
*
|
|
41
|
+
* 返回 `{roll, gapDays, gap}`:
|
|
42
|
+
* - `roll` 要不要写。`lastDate` 为空(从没写过)→ 写。
|
|
43
|
+
* - `gapDays` 距上次写的天数(null = 没写过或日期形状不对)。
|
|
44
|
+
* - `gap` 中间有没有「永久丢掉」的日子(超过回补上限)——必须如实写进日记头部,
|
|
45
|
+
* 不能假装连续。这是本模块唯一允许对读者撒谎的地方,所以它必须是个返回值,
|
|
46
|
+
* 不是一个可选参数。
|
|
47
|
+
*
|
|
48
|
+
* 时钟往回调(`lastDate` 比今天还新)时不写:那不是「跨天」,那是同一份时间被
|
|
49
|
+
* 重算了一次,再写一次只会覆盖掉今天已经写好的那篇。
|
|
50
|
+
*/
|
|
51
|
+
export function shouldRollDay(lastDate, today, { maxCatchUpDays = MAX_CATCH_UP_DAYS } = {}) {
|
|
52
|
+
const now = String(today ?? "");
|
|
53
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(now)) return { roll: false, gapDays: null, gap: false };
|
|
54
|
+
const last = String(lastDate ?? "");
|
|
55
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(last)) return { roll: true, gapDays: null, gap: false };
|
|
56
|
+
if (last === now) return { roll: false, gapDays: 0, gap: false };
|
|
57
|
+
const gapDays = dayGap(last, now);
|
|
58
|
+
if (gapDays === null || gapDays < 0) return { roll: false, gapDays, gap: false };
|
|
59
|
+
const limit = Number.isFinite(maxCatchUpDays) && maxCatchUpDays >= 0 ? maxCatchUpDays : MAX_CATCH_UP_DAYS;
|
|
60
|
+
return { roll: true, gapDays, gap: gapDays > limit };
|
|
61
|
+
}
|
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 素材来源之二:当前会话自己的转录(**主来源**)。
|
|
3
|
-
*
|
|
4
|
-
* 需求原话是「与人格注入绑定,当前的拥有人格的 agent 写日记」——那就意味着日记的
|
|
5
|
-
* 素材首先得是**这个 agent 自己这一天经历过的对话**,而不是 QQ 收件箱里别人的消息。
|
|
6
|
-
* QQ inbox 只是没有会话上下文时(启动补写)的兜底来源。
|
|
7
|
-
*
|
|
8
|
-
* 口径与 summarize.js 的蒸馏转录**刻意同源**(那里已把隐私边界定完,不重写第二份):
|
|
9
|
-
* - 只认 `user/message` 与 `assistant/message`;
|
|
10
|
-
* - 机器注入内容(AGENTS.md、skill 正文、文件变更通知)按 `source.kind` 挡掉;
|
|
11
|
-
* - assistant 的 reasoning 私有思考块不采集(textOf 只认 `type:"text"`);
|
|
12
|
-
* - 工具调用/结果不进日记(那是过程,不是这一天发生的事)。
|
|
13
|
-
*
|
|
14
|
-
* 这个模块是纯的:会话对象由调用方给,时间由事件带,不读盘、不联网、不碰 ctx。
|
|
15
|
-
*/
|
|
16
|
-
import { localDateString } from "./rollover.js";
|
|
17
|
-
import { redactDigits } from "./qq-inbox.js";
|
|
18
|
-
|
|
19
|
-
/** 单条消息进 prompt 的上限:一条超长粘贴不该把整篇日记的预算吃掉。 */
|
|
20
|
-
export const MAX_ITEM_CHARS = 1200;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 会话身份(决定用哪张人格卡)。与 `src/inject.js:311-336` 同一口径。
|
|
24
|
-
*
|
|
25
|
-
* ⚠️ 不能先读 `requestHeader()`:那返回的是请求级模型路由头,会把 `agentPreset`
|
|
26
|
-
* 遮蔽成空(scope.js 里记着本地 web 实测踩中过)。身份只在 `session.header` 里。
|
|
27
|
-
*/
|
|
28
|
-
export function sessionAgentId(session) {
|
|
29
|
-
try {
|
|
30
|
-
const header = session?.header ?? null;
|
|
31
|
-
const preset = header?.agentPreset;
|
|
32
|
-
return typeof preset === "string" && preset.trim() ? preset.trim() : null;
|
|
33
|
-
} catch {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** 会话事件里可选的时间字段。三个都试是因为宿主各版本用过不同的名字。 */
|
|
39
|
-
function eventTimeMs(event) {
|
|
40
|
-
for (const key of ["at", "time", "ts"]) {
|
|
41
|
-
const v = event?.[key];
|
|
42
|
-
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
43
|
-
if (typeof v === "string" && v.trim()) {
|
|
44
|
-
const parsed = Date.parse(v);
|
|
45
|
-
if (Number.isFinite(parsed)) return parsed;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function textOf(content) {
|
|
52
|
-
if (typeof content === "string") return content;
|
|
53
|
-
if (!Array.isArray(content)) return "";
|
|
54
|
-
return content
|
|
55
|
-
.map((block) => (typeof block === "string" ? block : block && block.type === "text" && typeof block.text === "string" ? block.text : ""))
|
|
56
|
-
.filter(Boolean)
|
|
57
|
-
.join("\n");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** 事件里有没有**可公开的会话正文**。与 summarize.js 的 publicTranscriptParts 同一套判据。 */
|
|
61
|
-
function bodyOf(event) {
|
|
62
|
-
const data = event?.data ?? {};
|
|
63
|
-
const kind = data?.source?.kind;
|
|
64
|
-
if (event?.type === "user/message") {
|
|
65
|
-
// 机器注入内容(kind 非 user)不进素材:那不是「你们今天聊的」。
|
|
66
|
-
if (kind !== undefined && kind !== "user") return null;
|
|
67
|
-
const text = textOf(data?.content).trim();
|
|
68
|
-
return text ? { role: "user", text } : null;
|
|
69
|
-
}
|
|
70
|
-
if (event?.type === "assistant/message") {
|
|
71
|
-
const text = textOf(data?.message?.content).trim();
|
|
72
|
-
return text ? { role: "assistant", text } : null;
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* 采当前会话的转录。
|
|
79
|
-
*
|
|
80
|
-
* `dateLocal` 为 null 时取**全部**事件(手动按钮的语义:「就把现在这段写下来」,
|
|
81
|
-
* 不按自然日切)。给日期时只留那一天的事件——事件没有时间戳的一律丢弃:无法证明
|
|
82
|
-
* 它属于今天,就不能把它写进今天。
|
|
83
|
-
*
|
|
84
|
-
* 返回 `{items, scanned, ignored}`(items 可以为空)或 `{error}`。
|
|
85
|
-
*/
|
|
86
|
-
export function collectSessionTranscript({ session, dateLocal = null, maxItems = 400, maxChars = MAX_ITEM_CHARS } = {}) {
|
|
87
|
-
if (!session) return { error: "no-session" };
|
|
88
|
-
let events = null;
|
|
89
|
-
try {
|
|
90
|
-
events = typeof session.snapshotEvents === "function" ? session.snapshotEvents() : session.events;
|
|
91
|
-
} catch {
|
|
92
|
-
events = session?.events ?? null;
|
|
93
|
-
}
|
|
94
|
-
if (!Array.isArray(events)) return { error: "session-unreadable" };
|
|
95
|
-
|
|
96
|
-
const items = [];
|
|
97
|
-
let scanned = 0;
|
|
98
|
-
let ignored = 0;
|
|
99
|
-
for (const event of events) {
|
|
100
|
-
const body = bodyOf(event);
|
|
101
|
-
if (!body) {
|
|
102
|
-
// 工具调用/系统事件占了绝对多数,数进 ignored 会让「忽略」这个词失真。
|
|
103
|
-
// 只把它们跳过,不计入 ignored。
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
scanned += 1;
|
|
107
|
-
const ts = eventTimeMs(event);
|
|
108
|
-
if (dateLocal !== null && dateLocal !== undefined) {
|
|
109
|
-
if (ts === null || localDateString(new Date(ts)) !== dateLocal) {
|
|
110
|
-
// 别的日子不算「忽略」,无时间戳才算读不懂。
|
|
111
|
-
if (ts === null) ignored += 1;
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
items.push({
|
|
116
|
-
ts,
|
|
117
|
-
role: body.role,
|
|
118
|
-
text: redactDigits(body.text).slice(0, maxChars)
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
return { items: items.slice(-maxItems), scanned, ignored };
|
|
122
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 素材来源之二:当前会话自己的转录(**主来源**)。
|
|
3
|
+
*
|
|
4
|
+
* 需求原话是「与人格注入绑定,当前的拥有人格的 agent 写日记」——那就意味着日记的
|
|
5
|
+
* 素材首先得是**这个 agent 自己这一天经历过的对话**,而不是 QQ 收件箱里别人的消息。
|
|
6
|
+
* QQ inbox 只是没有会话上下文时(启动补写)的兜底来源。
|
|
7
|
+
*
|
|
8
|
+
* 口径与 summarize.js 的蒸馏转录**刻意同源**(那里已把隐私边界定完,不重写第二份):
|
|
9
|
+
* - 只认 `user/message` 与 `assistant/message`;
|
|
10
|
+
* - 机器注入内容(AGENTS.md、skill 正文、文件变更通知)按 `source.kind` 挡掉;
|
|
11
|
+
* - assistant 的 reasoning 私有思考块不采集(textOf 只认 `type:"text"`);
|
|
12
|
+
* - 工具调用/结果不进日记(那是过程,不是这一天发生的事)。
|
|
13
|
+
*
|
|
14
|
+
* 这个模块是纯的:会话对象由调用方给,时间由事件带,不读盘、不联网、不碰 ctx。
|
|
15
|
+
*/
|
|
16
|
+
import { localDateString } from "./rollover.js";
|
|
17
|
+
import { redactDigits } from "./qq-inbox.js";
|
|
18
|
+
|
|
19
|
+
/** 单条消息进 prompt 的上限:一条超长粘贴不该把整篇日记的预算吃掉。 */
|
|
20
|
+
export const MAX_ITEM_CHARS = 1200;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 会话身份(决定用哪张人格卡)。与 `src/inject.js:311-336` 同一口径。
|
|
24
|
+
*
|
|
25
|
+
* ⚠️ 不能先读 `requestHeader()`:那返回的是请求级模型路由头,会把 `agentPreset`
|
|
26
|
+
* 遮蔽成空(scope.js 里记着本地 web 实测踩中过)。身份只在 `session.header` 里。
|
|
27
|
+
*/
|
|
28
|
+
export function sessionAgentId(session) {
|
|
29
|
+
try {
|
|
30
|
+
const header = session?.header ?? null;
|
|
31
|
+
const preset = header?.agentPreset;
|
|
32
|
+
return typeof preset === "string" && preset.trim() ? preset.trim() : null;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** 会话事件里可选的时间字段。三个都试是因为宿主各版本用过不同的名字。 */
|
|
39
|
+
function eventTimeMs(event) {
|
|
40
|
+
for (const key of ["at", "time", "ts"]) {
|
|
41
|
+
const v = event?.[key];
|
|
42
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
43
|
+
if (typeof v === "string" && v.trim()) {
|
|
44
|
+
const parsed = Date.parse(v);
|
|
45
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function textOf(content) {
|
|
52
|
+
if (typeof content === "string") return content;
|
|
53
|
+
if (!Array.isArray(content)) return "";
|
|
54
|
+
return content
|
|
55
|
+
.map((block) => (typeof block === "string" ? block : block && block.type === "text" && typeof block.text === "string" ? block.text : ""))
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join("\n");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 事件里有没有**可公开的会话正文**。与 summarize.js 的 publicTranscriptParts 同一套判据。 */
|
|
61
|
+
function bodyOf(event) {
|
|
62
|
+
const data = event?.data ?? {};
|
|
63
|
+
const kind = data?.source?.kind;
|
|
64
|
+
if (event?.type === "user/message") {
|
|
65
|
+
// 机器注入内容(kind 非 user)不进素材:那不是「你们今天聊的」。
|
|
66
|
+
if (kind !== undefined && kind !== "user") return null;
|
|
67
|
+
const text = textOf(data?.content).trim();
|
|
68
|
+
return text ? { role: "user", text } : null;
|
|
69
|
+
}
|
|
70
|
+
if (event?.type === "assistant/message") {
|
|
71
|
+
const text = textOf(data?.message?.content).trim();
|
|
72
|
+
return text ? { role: "assistant", text } : null;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 采当前会话的转录。
|
|
79
|
+
*
|
|
80
|
+
* `dateLocal` 为 null 时取**全部**事件(手动按钮的语义:「就把现在这段写下来」,
|
|
81
|
+
* 不按自然日切)。给日期时只留那一天的事件——事件没有时间戳的一律丢弃:无法证明
|
|
82
|
+
* 它属于今天,就不能把它写进今天。
|
|
83
|
+
*
|
|
84
|
+
* 返回 `{items, scanned, ignored}`(items 可以为空)或 `{error}`。
|
|
85
|
+
*/
|
|
86
|
+
export function collectSessionTranscript({ session, dateLocal = null, maxItems = 400, maxChars = MAX_ITEM_CHARS } = {}) {
|
|
87
|
+
if (!session) return { error: "no-session" };
|
|
88
|
+
let events = null;
|
|
89
|
+
try {
|
|
90
|
+
events = typeof session.snapshotEvents === "function" ? session.snapshotEvents() : session.events;
|
|
91
|
+
} catch {
|
|
92
|
+
events = session?.events ?? null;
|
|
93
|
+
}
|
|
94
|
+
if (!Array.isArray(events)) return { error: "session-unreadable" };
|
|
95
|
+
|
|
96
|
+
const items = [];
|
|
97
|
+
let scanned = 0;
|
|
98
|
+
let ignored = 0;
|
|
99
|
+
for (const event of events) {
|
|
100
|
+
const body = bodyOf(event);
|
|
101
|
+
if (!body) {
|
|
102
|
+
// 工具调用/系统事件占了绝对多数,数进 ignored 会让「忽略」这个词失真。
|
|
103
|
+
// 只把它们跳过,不计入 ignored。
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
scanned += 1;
|
|
107
|
+
const ts = eventTimeMs(event);
|
|
108
|
+
if (dateLocal !== null && dateLocal !== undefined) {
|
|
109
|
+
if (ts === null || localDateString(new Date(ts)) !== dateLocal) {
|
|
110
|
+
// 别的日子不算「忽略」,无时间戳才算读不懂。
|
|
111
|
+
if (ts === null) ignored += 1;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
items.push({
|
|
116
|
+
ts,
|
|
117
|
+
role: body.role,
|
|
118
|
+
text: redactDigits(body.text).slice(0, maxChars)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return { items: items.slice(-maxItems), scanned, ignored };
|
|
122
|
+
}
|
package/lib/document-index.js
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
// dsh-mneme/src/document-index.js
|
|
2
|
-
// documentDir 的索引(issue #296 第二批)。`<documentDir>/index.md` 整文件机器所有,
|
|
3
|
-
// 可从库随时重建:内容里没有任何「生成时间」,所以删掉再同步一次得到逐字节相同的
|
|
4
|
-
// 文件(test/document-dir.test.js 钉住这一条)。
|
|
5
|
-
//
|
|
6
|
-
// 与镜像侧 documents.md 的分工(#296 第 2 节表格):这里是 document 子系统自己的
|
|
7
|
-
// 索引(id + 标题 + 定位 + managed 标记),那份是带 frontmatter 的镜像只读视图
|
|
8
|
-
// (多一个摘要首句)。两份都只列指针行,都不含正文——正文永远在 doc_path 指向的
|
|
9
|
-
// 文件里,那是 agent 的东西。
|
|
10
|
-
import { readFileSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
11
|
-
import { join } from "node:path";
|
|
12
|
-
import { STR } from "./lang.js";
|
|
13
|
-
import { isManagedDocumentPath } from "./document.js";
|
|
14
|
-
|
|
15
|
-
function oneLine(text) {
|
|
16
|
-
return String(text ?? "").replace(/\s+/g, " ").trim();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} dir resolved documentDir (see resolveDocumentDir)
|
|
21
|
-
* @param {"zh"|"en"} language instance language, same as the mirror
|
|
22
|
-
*/
|
|
23
|
-
export function createDocumentIndex(dir, language = "zh") {
|
|
24
|
-
const filePath = join(dir, "index.md");
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Render the whole file from the given rows. Sorted updated_at DESC, id ASC:
|
|
28
|
-
* the same store state must always render the same bytes (rebuildable).
|
|
29
|
-
*/
|
|
30
|
-
function render(memories) {
|
|
31
|
-
const items = (memories ?? []).slice().sort((a, b) => {
|
|
32
|
-
if (a.updated_at !== b.updated_at) return a.updated_at < b.updated_at ? 1 : -1;
|
|
33
|
-
return a.id < b.id ? -1 : 1;
|
|
34
|
-
});
|
|
35
|
-
const lines = [STR.documentIndexHeader[language]()];
|
|
36
|
-
for (const m of items) {
|
|
37
|
-
const where = isManagedDocumentPath(dir, m.doc_path) ? "managed" : "external";
|
|
38
|
-
// doc_path 理论上必带(store.saveDocument 是唯一铸造口),缺了就只写定位
|
|
39
|
-
// 标记,不编造路径。
|
|
40
|
-
const path = m.doc_path ? ` · \`${oneLine(m.doc_path)}\`` : "";
|
|
41
|
-
lines.push(`- \`${m.id}\` **${oneLine(m.title)}** · ${where}${path}`);
|
|
42
|
-
}
|
|
43
|
-
return `${lines.join("\n")}\n`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Ensure the directory exists (recursive). Never throws: callers warn and move
|
|
48
|
-
* on — a managed directory that cannot be created must not fail plugin boot.
|
|
49
|
-
*/
|
|
50
|
-
function ensure() {
|
|
51
|
-
try {
|
|
52
|
-
mkdirSync(dir, { recursive: true });
|
|
53
|
-
return { ok: true };
|
|
54
|
-
} catch (error) {
|
|
55
|
-
return { ok: false, error: error?.message ?? String(error) };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Write the index if it changed. Never throws: a failed index write must not
|
|
61
|
-
* fail the business write that triggered it (same fail-safe shape as
|
|
62
|
-
* mirror.sync). Returns { ok, changed } or { ok: false, error }.
|
|
63
|
-
*/
|
|
64
|
-
function sync(memories) {
|
|
65
|
-
const text = render(memories);
|
|
66
|
-
let prev = null;
|
|
67
|
-
try { prev = readFileSync(filePath, "utf8"); } catch { /* first write */ }
|
|
68
|
-
if (prev === text) return { ok: true, changed: false };
|
|
69
|
-
const ready = ensure();
|
|
70
|
-
if (!ready.ok) return { ok: false, error: ready.error };
|
|
71
|
-
try {
|
|
72
|
-
writeFileSync(filePath, text, "utf8");
|
|
73
|
-
return { ok: true, changed: true };
|
|
74
|
-
} catch (error) {
|
|
75
|
-
return { ok: false, error: error?.message ?? String(error) };
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Drop the index file (闸关时用)。闸关意味着 document 子系统整体退出,留一份
|
|
81
|
-
* 陈旧索引会列出已归档、已遗忘的指针行——正是 documents.md 在闸关时被镜像删掉
|
|
82
|
-
* 要避免的那种「看着还在、其实已关」的视图。删掉不从库取数,O(1),也不抛。
|
|
83
|
-
*/
|
|
84
|
-
function remove() {
|
|
85
|
-
try {
|
|
86
|
-
rmSync(filePath, { force: true });
|
|
87
|
-
return { ok: true };
|
|
88
|
-
} catch (error) {
|
|
89
|
-
return { ok: false, error: error?.message ?? String(error) };
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return { filePath, render, sync, ensure, remove };
|
|
94
|
-
}
|
|
1
|
+
// dsh-mneme/src/document-index.js
|
|
2
|
+
// documentDir 的索引(issue #296 第二批)。`<documentDir>/index.md` 整文件机器所有,
|
|
3
|
+
// 可从库随时重建:内容里没有任何「生成时间」,所以删掉再同步一次得到逐字节相同的
|
|
4
|
+
// 文件(test/document-dir.test.js 钉住这一条)。
|
|
5
|
+
//
|
|
6
|
+
// 与镜像侧 documents.md 的分工(#296 第 2 节表格):这里是 document 子系统自己的
|
|
7
|
+
// 索引(id + 标题 + 定位 + managed 标记),那份是带 frontmatter 的镜像只读视图
|
|
8
|
+
// (多一个摘要首句)。两份都只列指针行,都不含正文——正文永远在 doc_path 指向的
|
|
9
|
+
// 文件里,那是 agent 的东西。
|
|
10
|
+
import { readFileSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { STR } from "./lang.js";
|
|
13
|
+
import { isManagedDocumentPath } from "./document.js";
|
|
14
|
+
|
|
15
|
+
function oneLine(text) {
|
|
16
|
+
return String(text ?? "").replace(/\s+/g, " ").trim();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} dir resolved documentDir (see resolveDocumentDir)
|
|
21
|
+
* @param {"zh"|"en"} language instance language, same as the mirror
|
|
22
|
+
*/
|
|
23
|
+
export function createDocumentIndex(dir, language = "zh") {
|
|
24
|
+
const filePath = join(dir, "index.md");
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Render the whole file from the given rows. Sorted updated_at DESC, id ASC:
|
|
28
|
+
* the same store state must always render the same bytes (rebuildable).
|
|
29
|
+
*/
|
|
30
|
+
function render(memories) {
|
|
31
|
+
const items = (memories ?? []).slice().sort((a, b) => {
|
|
32
|
+
if (a.updated_at !== b.updated_at) return a.updated_at < b.updated_at ? 1 : -1;
|
|
33
|
+
return a.id < b.id ? -1 : 1;
|
|
34
|
+
});
|
|
35
|
+
const lines = [STR.documentIndexHeader[language]()];
|
|
36
|
+
for (const m of items) {
|
|
37
|
+
const where = isManagedDocumentPath(dir, m.doc_path) ? "managed" : "external";
|
|
38
|
+
// doc_path 理论上必带(store.saveDocument 是唯一铸造口),缺了就只写定位
|
|
39
|
+
// 标记,不编造路径。
|
|
40
|
+
const path = m.doc_path ? ` · \`${oneLine(m.doc_path)}\`` : "";
|
|
41
|
+
lines.push(`- \`${m.id}\` **${oneLine(m.title)}** · ${where}${path}`);
|
|
42
|
+
}
|
|
43
|
+
return `${lines.join("\n")}\n`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Ensure the directory exists (recursive). Never throws: callers warn and move
|
|
48
|
+
* on — a managed directory that cannot be created must not fail plugin boot.
|
|
49
|
+
*/
|
|
50
|
+
function ensure() {
|
|
51
|
+
try {
|
|
52
|
+
mkdirSync(dir, { recursive: true });
|
|
53
|
+
return { ok: true };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return { ok: false, error: error?.message ?? String(error) };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Write the index if it changed. Never throws: a failed index write must not
|
|
61
|
+
* fail the business write that triggered it (same fail-safe shape as
|
|
62
|
+
* mirror.sync). Returns { ok, changed } or { ok: false, error }.
|
|
63
|
+
*/
|
|
64
|
+
function sync(memories) {
|
|
65
|
+
const text = render(memories);
|
|
66
|
+
let prev = null;
|
|
67
|
+
try { prev = readFileSync(filePath, "utf8"); } catch { /* first write */ }
|
|
68
|
+
if (prev === text) return { ok: true, changed: false };
|
|
69
|
+
const ready = ensure();
|
|
70
|
+
if (!ready.ok) return { ok: false, error: ready.error };
|
|
71
|
+
try {
|
|
72
|
+
writeFileSync(filePath, text, "utf8");
|
|
73
|
+
return { ok: true, changed: true };
|
|
74
|
+
} catch (error) {
|
|
75
|
+
return { ok: false, error: error?.message ?? String(error) };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Drop the index file (闸关时用)。闸关意味着 document 子系统整体退出,留一份
|
|
81
|
+
* 陈旧索引会列出已归档、已遗忘的指针行——正是 documents.md 在闸关时被镜像删掉
|
|
82
|
+
* 要避免的那种「看着还在、其实已关」的视图。删掉不从库取数,O(1),也不抛。
|
|
83
|
+
*/
|
|
84
|
+
function remove() {
|
|
85
|
+
try {
|
|
86
|
+
rmSync(filePath, { force: true });
|
|
87
|
+
return { ok: true };
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return { ok: false, error: error?.message ?? String(error) };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { filePath, render, sync, ensure, remove };
|
|
94
|
+
}
|