@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/commands.js
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
|
-
import { STR } from "./lang.js";
|
|
3
|
-
|
|
4
|
-
// Custom slash-command manager: keeps the DSH command registry in sync with
|
|
5
|
-
// user-defined commands persisted in SQLite. Commands are registered on boot
|
|
6
|
-
// and (re)registered on add/remove through the API.
|
|
7
|
-
//
|
|
8
|
-
// Per the DSH command contract, a handler's CommandResult text is only a UI
|
|
9
|
-
// settlement notice and never reaches the model. To actually drive the agent,
|
|
10
|
-
// the handler submits the user-authored instruction itself as a user followup
|
|
11
|
-
// message on the receiving agent (same pattern as the official /goal command).
|
|
12
|
-
// The notice just acknowledges the submission; an optional rawInput suffix
|
|
13
|
-
// typed after the command is appended for the model.
|
|
14
|
-
|
|
15
|
-
export function createCommandManager({ ctx, settings, logger, language = "zh" }) {
|
|
16
|
-
const registered = new Map(); // name -> disposer
|
|
17
|
-
|
|
18
|
-
function registerOne(command) {
|
|
19
|
-
if (registered.has(command.name)) return;
|
|
20
|
-
let dispose;
|
|
21
|
-
try {
|
|
22
|
-
dispose = ctx.commands.register({
|
|
23
|
-
name: command.name,
|
|
24
|
-
// 缺省描述随实例语言(命令描述进命令注册表,对 LLM 可见)。
|
|
25
|
-
description: command.description || STR.commandFallbackDesc[language](command.name),
|
|
26
|
-
input: { hint: STR.commandInputHint[language] },
|
|
27
|
-
handler: (invocation) => submit(command, invocation)
|
|
28
|
-
});
|
|
29
|
-
} catch (error) {
|
|
30
|
-
logger?.warn?.(`dsh-mneme: failed to register command /${command.name}: ${String(error)}`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
registered.set(command.name, dispose);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Submit the instruction (plus optional rawInput suffix) to the receiving agent. */
|
|
37
|
-
function submit(command, invocation) {
|
|
38
|
-
const suffix = typeof invocation?.rawInput === "string" ? invocation.rawInput.trim() : "";
|
|
39
|
-
const text = suffix ? `${command.instruction}\n\n${suffix}` : command.instruction;
|
|
40
|
-
const agent = invocation?.agent;
|
|
41
|
-
if (typeof agent?.followup !== "function") {
|
|
42
|
-
// 兜底:宿主未提供接收 agent 时退回旧行为,至少把指令展示在 notice 里。
|
|
43
|
-
return { kind: "success", text };
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
agent.followup(createUserMessage({
|
|
47
|
-
content: [{ type: "text", text }],
|
|
48
|
-
source: { kind: "user" }
|
|
49
|
-
}));
|
|
50
|
-
} catch (error) {
|
|
51
|
-
logger?.warn?.(`dsh-mneme: failed to submit /${command.name} to agent: ${String(error)}`);
|
|
52
|
-
return { kind: "error", text: STR.commandSubmitFailed[language](command.name) };
|
|
53
|
-
}
|
|
54
|
-
return { kind: "success", text: STR.commandSubmitted[language](command.name) };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function unregisterOne(name) {
|
|
58
|
-
const dispose = registered.get(name);
|
|
59
|
-
if (dispose) {
|
|
60
|
-
try {
|
|
61
|
-
dispose();
|
|
62
|
-
} catch {
|
|
63
|
-
/* ignore double-dispose */
|
|
64
|
-
}
|
|
65
|
-
registered.delete(name);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Register every stored command (boot-time sync). */
|
|
70
|
-
function sync() {
|
|
71
|
-
for (const command of settings.listCommands()) registerOne(command);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Add (or replace) a command and register it live. */
|
|
75
|
-
function add({ name, description, instruction }) {
|
|
76
|
-
const command = settings.addCommand({ name, description, instruction });
|
|
77
|
-
registerOne(command);
|
|
78
|
-
return command;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Remove a command by id and unregister it live. */
|
|
82
|
-
function remove(id) {
|
|
83
|
-
const existing = settings.listCommands().find((c) => c.id === id);
|
|
84
|
-
if (!existing) return false;
|
|
85
|
-
if (!settings.removeCommand(id)) return false;
|
|
86
|
-
unregisterOne(existing.name);
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function dispose() {
|
|
91
|
-
for (const name of [...registered.keys()]) unregisterOne(name);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return { sync, add, remove, list: () => settings.listCommands(), dispose };
|
|
95
|
-
}
|
|
1
|
+
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
|
+
import { STR } from "./lang.js";
|
|
3
|
+
|
|
4
|
+
// Custom slash-command manager: keeps the DSH command registry in sync with
|
|
5
|
+
// user-defined commands persisted in SQLite. Commands are registered on boot
|
|
6
|
+
// and (re)registered on add/remove through the API.
|
|
7
|
+
//
|
|
8
|
+
// Per the DSH command contract, a handler's CommandResult text is only a UI
|
|
9
|
+
// settlement notice and never reaches the model. To actually drive the agent,
|
|
10
|
+
// the handler submits the user-authored instruction itself as a user followup
|
|
11
|
+
// message on the receiving agent (same pattern as the official /goal command).
|
|
12
|
+
// The notice just acknowledges the submission; an optional rawInput suffix
|
|
13
|
+
// typed after the command is appended for the model.
|
|
14
|
+
|
|
15
|
+
export function createCommandManager({ ctx, settings, logger, language = "zh" }) {
|
|
16
|
+
const registered = new Map(); // name -> disposer
|
|
17
|
+
|
|
18
|
+
function registerOne(command) {
|
|
19
|
+
if (registered.has(command.name)) return;
|
|
20
|
+
let dispose;
|
|
21
|
+
try {
|
|
22
|
+
dispose = ctx.commands.register({
|
|
23
|
+
name: command.name,
|
|
24
|
+
// 缺省描述随实例语言(命令描述进命令注册表,对 LLM 可见)。
|
|
25
|
+
description: command.description || STR.commandFallbackDesc[language](command.name),
|
|
26
|
+
input: { hint: STR.commandInputHint[language] },
|
|
27
|
+
handler: (invocation) => submit(command, invocation)
|
|
28
|
+
});
|
|
29
|
+
} catch (error) {
|
|
30
|
+
logger?.warn?.(`dsh-mneme: failed to register command /${command.name}: ${String(error)}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
registered.set(command.name, dispose);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Submit the instruction (plus optional rawInput suffix) to the receiving agent. */
|
|
37
|
+
function submit(command, invocation) {
|
|
38
|
+
const suffix = typeof invocation?.rawInput === "string" ? invocation.rawInput.trim() : "";
|
|
39
|
+
const text = suffix ? `${command.instruction}\n\n${suffix}` : command.instruction;
|
|
40
|
+
const agent = invocation?.agent;
|
|
41
|
+
if (typeof agent?.followup !== "function") {
|
|
42
|
+
// 兜底:宿主未提供接收 agent 时退回旧行为,至少把指令展示在 notice 里。
|
|
43
|
+
return { kind: "success", text };
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
agent.followup(createUserMessage({
|
|
47
|
+
content: [{ type: "text", text }],
|
|
48
|
+
source: { kind: "user" }
|
|
49
|
+
}));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger?.warn?.(`dsh-mneme: failed to submit /${command.name} to agent: ${String(error)}`);
|
|
52
|
+
return { kind: "error", text: STR.commandSubmitFailed[language](command.name) };
|
|
53
|
+
}
|
|
54
|
+
return { kind: "success", text: STR.commandSubmitted[language](command.name) };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function unregisterOne(name) {
|
|
58
|
+
const dispose = registered.get(name);
|
|
59
|
+
if (dispose) {
|
|
60
|
+
try {
|
|
61
|
+
dispose();
|
|
62
|
+
} catch {
|
|
63
|
+
/* ignore double-dispose */
|
|
64
|
+
}
|
|
65
|
+
registered.delete(name);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Register every stored command (boot-time sync). */
|
|
70
|
+
function sync() {
|
|
71
|
+
for (const command of settings.listCommands()) registerOne(command);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Add (or replace) a command and register it live. */
|
|
75
|
+
function add({ name, description, instruction }) {
|
|
76
|
+
const command = settings.addCommand({ name, description, instruction });
|
|
77
|
+
registerOne(command);
|
|
78
|
+
return command;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Remove a command by id and unregister it live. */
|
|
82
|
+
function remove(id) {
|
|
83
|
+
const existing = settings.listCommands().find((c) => c.id === id);
|
|
84
|
+
if (!existing) return false;
|
|
85
|
+
if (!settings.removeCommand(id)) return false;
|
|
86
|
+
unregisterOne(existing.name);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function dispose() {
|
|
91
|
+
for (const name of [...registered.keys()]) unregisterOne(name);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { sync, add, remove, list: () => settings.listCommands(), dispose };
|
|
95
|
+
}
|
package/lib/config-keys.js
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
// 配置键覆盖面的「唯一一份」描述(issue #386 第 7 条)。
|
|
2
|
-
//
|
|
3
|
-
// 为什么单独一个模块:面板上能改的键(settings.js 白名单)与 schema 里实际存在的
|
|
4
|
-
// 键(config.js 的 Config)是两张表,它们从来没被摆在同一个地方对过。于是
|
|
5
|
-
// 「用户能理解、但面板改不到」的键只能靠读源码 + 手数得到答案——issue #386 列了
|
|
6
|
-
// 七组、维护者另外复述了一遍,每次都要重新数。
|
|
7
|
-
//
|
|
8
|
-
// 这里只做「算」:把 schema 声明的叶子键与白名单取交/差,回三份清单。它不读
|
|
9
|
-
// 数据库、不碰 cfg 的实际值、**不返回任何键的值**——apiToken 这类敏感键的名字可以
|
|
10
|
-
// 出现在「仅配置文件」清单里(那正是这条 issue 想让用户看见的东西),值一个字节
|
|
11
|
-
// 都不出。判定口径住在 flagKeysFromSpec,api.js 的 featureSnapshot 用的也是它;
|
|
12
|
-
// 谁要是另抄一份白名单,test/config-keys-routes.test.js 的静态锁直接转红。
|
|
13
|
-
|
|
14
|
-
import { Config } from "./config.js";
|
|
15
|
-
import { FEATURE_FLAG_SPEC } from "./settings.js";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 白名单里的全部键(面板 PUT 能写、effective 会算的那些)。
|
|
19
|
-
*
|
|
20
|
-
* 顺序与 api.js 的 featureSnapshot 逐字对应:booleans → ints → numbers → strings
|
|
21
|
-
* → urls → enums。api.js 直接引这一份,不再自己拼一遍。
|
|
22
|
-
*/
|
|
23
|
-
export function flagKeysFromSpec() {
|
|
24
|
-
return [
|
|
25
|
-
...FEATURE_FLAG_SPEC.booleans,
|
|
26
|
-
...Object.keys(FEATURE_FLAG_SPEC.ints),
|
|
27
|
-
...Object.keys(FEATURE_FLAG_SPEC.numbers),
|
|
28
|
-
...FEATURE_FLAG_SPEC.strings,
|
|
29
|
-
...FEATURE_FLAG_SPEC.urls,
|
|
30
|
-
...Object.keys(FEATURE_FLAG_SPEC.enums)
|
|
31
|
-
];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 把「已解析的配置对象」摊平成叶子键清单。
|
|
36
|
-
*
|
|
37
|
-
* 这份清单的含义是**「有默认值因此会出现在 effective 里的键」**,不是「schema 声明
|
|
38
|
-
* 了哪些键」——两者不等。`Config({})` 解析后 `apiToken` 根本不存在(`z.string()`
|
|
39
|
-
* 没有 `.default()`),若拿它当 schema 清单,最该被用户看见的那个键反而消失了
|
|
40
|
-
* (第一版就是这么错的,被 `config-keys returns key names but never the apiToken
|
|
41
|
-
* value` 那条用例抓住)。
|
|
42
|
-
*
|
|
43
|
-
* 数组当叶子(`sessionGateSessions` 是 `z.array`,面板没有编辑器,整条替换不算
|
|
44
|
-
* 「改一个值」)。
|
|
45
|
-
*/
|
|
46
|
-
export function defaultedLeafKeys(instance = Config({})) {
|
|
47
|
-
const out = [];
|
|
48
|
-
const walk = (node, prefix) => {
|
|
49
|
-
for (const key of Object.keys(node)) {
|
|
50
|
-
const value = node[key];
|
|
51
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
52
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) walk(value, path);
|
|
53
|
-
else out.push(path);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
walk(instance, "");
|
|
57
|
-
return out;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* schema **声明**的全部叶子键(含没有默认值的那些,比如 apiToken)。
|
|
62
|
-
*
|
|
63
|
-
* 直接走 schema 的 ref 图而不是解析结果:`Config.dict` 里每一项都是
|
|
64
|
-
* `{ uid, refs }`,真实节点在 `refs[uid]`。三种形状要分开处理:
|
|
65
|
-
* - `object`:有 `dict`,递归进去;
|
|
66
|
-
* - `dict`:键是开放的(`heatTypeDecay` 就是),只能靠 `meta.default` 的对象键
|
|
67
|
-
* 把已知的那几个名字还原出来;没有默认值就整条当一个叶子;
|
|
68
|
-
* - 其它:叶子。
|
|
69
|
-
*
|
|
70
|
-
* 探针实测:声明叶子 196 个、解析结果 191 个、白名单 113 个。两边差的那五个是
|
|
71
|
-
* `dreamProvider` / `dreamModel` / `dreamReasoningEffort` / `apiToken` /
|
|
72
|
-
* `sleepReasoningEffort`——都只声明、没给默认值。
|
|
73
|
-
*/
|
|
74
|
-
export function schemaLeafKeys(schema = Config) {
|
|
75
|
-
const out = [];
|
|
76
|
-
const resolve = (node) => (node && node.refs && node.uid in node.refs ? node.refs[node.uid] : node);
|
|
77
|
-
const walk = (node, prefix) => {
|
|
78
|
-
const real = resolve(node);
|
|
79
|
-
if (!real) return;
|
|
80
|
-
if (real.type === "object" && real.dict) {
|
|
81
|
-
for (const key of Object.keys(real.dict)) walk(real.dict[key], prefix ? `${prefix}.${key}` : key);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (real.type === "dict") {
|
|
85
|
-
const def = real.meta && real.meta.default;
|
|
86
|
-
if (def && typeof def === "object" && !Array.isArray(def)) {
|
|
87
|
-
for (const key of Object.keys(def)) out.push(`${prefix}.${key}`);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
out.push(prefix);
|
|
92
|
-
};
|
|
93
|
-
if (schema && schema.dict) {
|
|
94
|
-
for (const key of Object.keys(schema.dict)) walk(schema.dict[key], key);
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* 三份清单 + 计数。#386 第 7 条要的答案全在这里。
|
|
101
|
-
*
|
|
102
|
-
* - `panelEditable`:schema 声明了、且白名单也登记了的键(面板能改)。
|
|
103
|
-
* - `fileOnly`:schema 声明了、面板改不到的键——issue 正文点名的那七组都在里面,
|
|
104
|
-
* 连同 `apiToken`、`memoryDir` 这类「知道它存在就够了」的键。
|
|
105
|
-
* - `undefaulted`:白名单登记了、schema 也有,**但没有 `.default()`**,所以
|
|
106
|
-
* `effective` 里根本不会出现它。**这是本轮读码发现的一处真实不对称**:
|
|
107
|
-
* `dreamProvider` / `dreamModel` 在 settings.js 的 STRINGS 表里,config.js 那边
|
|
108
|
-
* 只有 `z.string().description(...)` 而没有 `.default()`,于是面板有输入框、保存
|
|
109
|
-
* 也能存,但 `featureSnapshot()` 的 `configFlagValue` 取到 undefined 就不写进
|
|
110
|
-
* effective(api.js 的 `if (value !== undefined)`)。列出来而不擅自补默认值:
|
|
111
|
-
* 补默认值会改变「未配置时到底用哪个模型」的既有行为,那是另一个决定。
|
|
112
|
-
*
|
|
113
|
-
* 三份互不相交,并集 = 白名单 ∪(声明里不在白名单的那批)——探针实测白名单
|
|
114
|
-
* 113 个全部都在声明里,所以并集就是声明的 196 个,一个不漏也不重复。
|
|
115
|
-
*/
|
|
116
|
-
export function describeConfigKeys() {
|
|
117
|
-
const declared = schemaLeafKeys();
|
|
118
|
-
const declaredSet = new Set(declared);
|
|
119
|
-
const defaulted = new Set(defaultedLeafKeys());
|
|
120
|
-
const flags = flagKeysFromSpec();
|
|
121
|
-
const flagSet = new Set(flags);
|
|
122
|
-
|
|
123
|
-
const panelEditable = [];
|
|
124
|
-
const undefaulted = [];
|
|
125
|
-
for (const key of flags) {
|
|
126
|
-
if (!declaredSet.has(key)) continue;
|
|
127
|
-
if (defaulted.has(key)) panelEditable.push(key);
|
|
128
|
-
else undefaulted.push(key);
|
|
129
|
-
}
|
|
130
|
-
const fileOnly = declared.filter((key) => !flagSet.has(key));
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
counts: {
|
|
134
|
-
schemaLeaf: declared.length,
|
|
135
|
-
flag: flags.length,
|
|
136
|
-
panelEditable: panelEditable.length,
|
|
137
|
-
fileOnly: fileOnly.length,
|
|
138
|
-
undefaulted: undefaulted.length
|
|
139
|
-
},
|
|
140
|
-
panelEditable,
|
|
141
|
-
fileOnly,
|
|
142
|
-
undefaulted
|
|
143
|
-
};
|
|
144
|
-
}
|
|
1
|
+
// 配置键覆盖面的「唯一一份」描述(issue #386 第 7 条)。
|
|
2
|
+
//
|
|
3
|
+
// 为什么单独一个模块:面板上能改的键(settings.js 白名单)与 schema 里实际存在的
|
|
4
|
+
// 键(config.js 的 Config)是两张表,它们从来没被摆在同一个地方对过。于是
|
|
5
|
+
// 「用户能理解、但面板改不到」的键只能靠读源码 + 手数得到答案——issue #386 列了
|
|
6
|
+
// 七组、维护者另外复述了一遍,每次都要重新数。
|
|
7
|
+
//
|
|
8
|
+
// 这里只做「算」:把 schema 声明的叶子键与白名单取交/差,回三份清单。它不读
|
|
9
|
+
// 数据库、不碰 cfg 的实际值、**不返回任何键的值**——apiToken 这类敏感键的名字可以
|
|
10
|
+
// 出现在「仅配置文件」清单里(那正是这条 issue 想让用户看见的东西),值一个字节
|
|
11
|
+
// 都不出。判定口径住在 flagKeysFromSpec,api.js 的 featureSnapshot 用的也是它;
|
|
12
|
+
// 谁要是另抄一份白名单,test/config-keys-routes.test.js 的静态锁直接转红。
|
|
13
|
+
|
|
14
|
+
import { Config } from "./config.js";
|
|
15
|
+
import { FEATURE_FLAG_SPEC } from "./settings.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 白名单里的全部键(面板 PUT 能写、effective 会算的那些)。
|
|
19
|
+
*
|
|
20
|
+
* 顺序与 api.js 的 featureSnapshot 逐字对应:booleans → ints → numbers → strings
|
|
21
|
+
* → urls → enums。api.js 直接引这一份,不再自己拼一遍。
|
|
22
|
+
*/
|
|
23
|
+
export function flagKeysFromSpec() {
|
|
24
|
+
return [
|
|
25
|
+
...FEATURE_FLAG_SPEC.booleans,
|
|
26
|
+
...Object.keys(FEATURE_FLAG_SPEC.ints),
|
|
27
|
+
...Object.keys(FEATURE_FLAG_SPEC.numbers),
|
|
28
|
+
...FEATURE_FLAG_SPEC.strings,
|
|
29
|
+
...FEATURE_FLAG_SPEC.urls,
|
|
30
|
+
...Object.keys(FEATURE_FLAG_SPEC.enums)
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 把「已解析的配置对象」摊平成叶子键清单。
|
|
36
|
+
*
|
|
37
|
+
* 这份清单的含义是**「有默认值因此会出现在 effective 里的键」**,不是「schema 声明
|
|
38
|
+
* 了哪些键」——两者不等。`Config({})` 解析后 `apiToken` 根本不存在(`z.string()`
|
|
39
|
+
* 没有 `.default()`),若拿它当 schema 清单,最该被用户看见的那个键反而消失了
|
|
40
|
+
* (第一版就是这么错的,被 `config-keys returns key names but never the apiToken
|
|
41
|
+
* value` 那条用例抓住)。
|
|
42
|
+
*
|
|
43
|
+
* 数组当叶子(`sessionGateSessions` 是 `z.array`,面板没有编辑器,整条替换不算
|
|
44
|
+
* 「改一个值」)。
|
|
45
|
+
*/
|
|
46
|
+
export function defaultedLeafKeys(instance = Config({})) {
|
|
47
|
+
const out = [];
|
|
48
|
+
const walk = (node, prefix) => {
|
|
49
|
+
for (const key of Object.keys(node)) {
|
|
50
|
+
const value = node[key];
|
|
51
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
52
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) walk(value, path);
|
|
53
|
+
else out.push(path);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
walk(instance, "");
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* schema **声明**的全部叶子键(含没有默认值的那些,比如 apiToken)。
|
|
62
|
+
*
|
|
63
|
+
* 直接走 schema 的 ref 图而不是解析结果:`Config.dict` 里每一项都是
|
|
64
|
+
* `{ uid, refs }`,真实节点在 `refs[uid]`。三种形状要分开处理:
|
|
65
|
+
* - `object`:有 `dict`,递归进去;
|
|
66
|
+
* - `dict`:键是开放的(`heatTypeDecay` 就是),只能靠 `meta.default` 的对象键
|
|
67
|
+
* 把已知的那几个名字还原出来;没有默认值就整条当一个叶子;
|
|
68
|
+
* - 其它:叶子。
|
|
69
|
+
*
|
|
70
|
+
* 探针实测:声明叶子 196 个、解析结果 191 个、白名单 113 个。两边差的那五个是
|
|
71
|
+
* `dreamProvider` / `dreamModel` / `dreamReasoningEffort` / `apiToken` /
|
|
72
|
+
* `sleepReasoningEffort`——都只声明、没给默认值。
|
|
73
|
+
*/
|
|
74
|
+
export function schemaLeafKeys(schema = Config) {
|
|
75
|
+
const out = [];
|
|
76
|
+
const resolve = (node) => (node && node.refs && node.uid in node.refs ? node.refs[node.uid] : node);
|
|
77
|
+
const walk = (node, prefix) => {
|
|
78
|
+
const real = resolve(node);
|
|
79
|
+
if (!real) return;
|
|
80
|
+
if (real.type === "object" && real.dict) {
|
|
81
|
+
for (const key of Object.keys(real.dict)) walk(real.dict[key], prefix ? `${prefix}.${key}` : key);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (real.type === "dict") {
|
|
85
|
+
const def = real.meta && real.meta.default;
|
|
86
|
+
if (def && typeof def === "object" && !Array.isArray(def)) {
|
|
87
|
+
for (const key of Object.keys(def)) out.push(`${prefix}.${key}`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
out.push(prefix);
|
|
92
|
+
};
|
|
93
|
+
if (schema && schema.dict) {
|
|
94
|
+
for (const key of Object.keys(schema.dict)) walk(schema.dict[key], key);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 三份清单 + 计数。#386 第 7 条要的答案全在这里。
|
|
101
|
+
*
|
|
102
|
+
* - `panelEditable`:schema 声明了、且白名单也登记了的键(面板能改)。
|
|
103
|
+
* - `fileOnly`:schema 声明了、面板改不到的键——issue 正文点名的那七组都在里面,
|
|
104
|
+
* 连同 `apiToken`、`memoryDir` 这类「知道它存在就够了」的键。
|
|
105
|
+
* - `undefaulted`:白名单登记了、schema 也有,**但没有 `.default()`**,所以
|
|
106
|
+
* `effective` 里根本不会出现它。**这是本轮读码发现的一处真实不对称**:
|
|
107
|
+
* `dreamProvider` / `dreamModel` 在 settings.js 的 STRINGS 表里,config.js 那边
|
|
108
|
+
* 只有 `z.string().description(...)` 而没有 `.default()`,于是面板有输入框、保存
|
|
109
|
+
* 也能存,但 `featureSnapshot()` 的 `configFlagValue` 取到 undefined 就不写进
|
|
110
|
+
* effective(api.js 的 `if (value !== undefined)`)。列出来而不擅自补默认值:
|
|
111
|
+
* 补默认值会改变「未配置时到底用哪个模型」的既有行为,那是另一个决定。
|
|
112
|
+
*
|
|
113
|
+
* 三份互不相交,并集 = 白名单 ∪(声明里不在白名单的那批)——探针实测白名单
|
|
114
|
+
* 113 个全部都在声明里,所以并集就是声明的 196 个,一个不漏也不重复。
|
|
115
|
+
*/
|
|
116
|
+
export function describeConfigKeys() {
|
|
117
|
+
const declared = schemaLeafKeys();
|
|
118
|
+
const declaredSet = new Set(declared);
|
|
119
|
+
const defaulted = new Set(defaultedLeafKeys());
|
|
120
|
+
const flags = flagKeysFromSpec();
|
|
121
|
+
const flagSet = new Set(flags);
|
|
122
|
+
|
|
123
|
+
const panelEditable = [];
|
|
124
|
+
const undefaulted = [];
|
|
125
|
+
for (const key of flags) {
|
|
126
|
+
if (!declaredSet.has(key)) continue;
|
|
127
|
+
if (defaulted.has(key)) panelEditable.push(key);
|
|
128
|
+
else undefaulted.push(key);
|
|
129
|
+
}
|
|
130
|
+
const fileOnly = declared.filter((key) => !flagSet.has(key));
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
counts: {
|
|
134
|
+
schemaLeaf: declared.length,
|
|
135
|
+
flag: flags.length,
|
|
136
|
+
panelEditable: panelEditable.length,
|
|
137
|
+
fileOnly: fileOnly.length,
|
|
138
|
+
undefaulted: undefaulted.length
|
|
139
|
+
},
|
|
140
|
+
panelEditable,
|
|
141
|
+
fileOnly,
|
|
142
|
+
undefaulted
|
|
143
|
+
};
|
|
144
|
+
}
|