principles-disciple 1.127.0 → 1.129.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/commands/archive-impl.d.ts +18 -0
- package/dist/commands/archive-impl.js +105 -0
- package/dist/commands/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.js +76 -0
- package/dist/commands/context.d.ts +5 -0
- package/{src/commands/context.ts → dist/commands/context.js} +34 -83
- package/dist/commands/disable-impl.d.ts +22 -0
- package/dist/commands/disable-impl.js +118 -0
- package/dist/commands/evolution-status.d.ts +4 -0
- package/dist/commands/evolution-status.js +187 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +53 -0
- package/dist/commands/focus.d.ts +14 -0
- package/dist/commands/focus.js +443 -0
- package/dist/commands/pain.d.ts +6 -0
- package/{src/commands/pain.ts → dist/commands/pain.js} +137 -188
- package/dist/commands/principle-rollback.d.ts +4 -0
- package/dist/commands/principle-rollback.js +26 -0
- package/dist/commands/promote-impl.d.ts +22 -0
- package/dist/commands/promote-impl.js +194 -0
- package/dist/commands/rollback-impl.d.ts +32 -0
- package/dist/commands/rollback-impl.js +180 -0
- package/dist/commands/rollback.d.ts +19 -0
- package/{src/commands/rollback.ts → dist/commands/rollback.js} +10 -53
- package/dist/commands/samples.d.ts +2 -0
- package/dist/commands/samples.js +58 -0
- package/dist/commands/strategy.d.ts +2 -0
- package/dist/commands/strategy.js +16 -0
- package/dist/commands/thinking-os.d.ts +2 -0
- package/{src/commands/thinking-os.ts → dist/commands/thinking-os.js} +35 -58
- package/dist/commands/workflow-debug.d.ts +6 -0
- package/{src/commands/workflow-debug.ts → dist/commands/workflow-debug.js} +13 -33
- package/dist/config/defaults/runtime.d.ts +58 -0
- package/{src/config/defaults/runtime.ts → dist/config/defaults/runtime.js} +4 -41
- package/dist/config/errors.d.ts +86 -0
- package/dist/config/errors.js +107 -0
- package/{src/config/index.ts → dist/config/index.d.ts} +1 -2
- package/dist/config/index.js +7 -0
- package/dist/constants/diagnostician.d.ts +12 -0
- package/{src/constants/diagnostician.ts → dist/constants/diagnostician.js} +0 -1
- package/dist/constants/tools.d.ts +17 -0
- package/dist/constants/tools.js +53 -0
- package/dist/core/__tests__/focus-history.test.d.ts +1 -0
- package/dist/core/__tests__/focus-history.test.js +160 -0
- package/dist/core/bootstrap-rules.d.ts +50 -0
- package/dist/core/bootstrap-rules.js +187 -0
- package/dist/core/code-implementation-storage.d.ts +71 -0
- package/dist/core/code-implementation-storage.js +139 -0
- package/dist/core/config-health.d.ts +27 -0
- package/dist/core/config-health.js +60 -0
- package/dist/core/config-service.d.ts +15 -0
- package/{src/core/config-service.ts → dist/core/config-service.js} +4 -7
- package/dist/core/config.d.ts +111 -0
- package/{src/core/config.ts → dist/core/config.js} +46 -146
- package/dist/core/control-ui-db.d.ts +106 -0
- package/dist/core/control-ui-db.js +309 -0
- package/dist/core/correction-cue-learner.d.ts +33 -0
- package/dist/core/correction-cue-learner.js +184 -0
- package/dist/core/correction-types.d.ts +3 -0
- package/dist/core/correction-types.js +1 -0
- package/dist/core/detection-funnel.d.ts +33 -0
- package/{src/core/detection-funnel.ts → dist/core/detection-funnel.js} +17 -37
- package/dist/core/detection-service.d.ts +15 -0
- package/{src/core/detection-service.ts → dist/core/detection-service.js} +4 -7
- package/dist/core/dictionary-service.d.ts +15 -0
- package/{src/core/dictionary-service.ts → dist/core/dictionary-service.js} +4 -7
- package/dist/core/dictionary.d.ts +38 -0
- package/{src/core/dictionary.ts → dist/core/dictionary.js} +33 -59
- package/dist/core/empathy-keyword-matcher.d.ts +5 -0
- package/dist/core/empathy-keyword-matcher.js +40 -0
- package/dist/core/empathy-types.d.ts +2 -0
- package/dist/core/empathy-types.js +1 -0
- package/dist/core/event-log.d.ts +90 -0
- package/dist/core/event-log.js +702 -0
- package/dist/core/evolution-engine.d.ts +119 -0
- package/dist/core/evolution-engine.js +460 -0
- package/dist/core/evolution-logger.d.ts +137 -0
- package/dist/core/evolution-logger.js +261 -0
- package/dist/core/evolution-migration.d.ts +5 -0
- package/dist/core/evolution-migration.js +65 -0
- package/dist/core/evolution-reducer.d.ts +124 -0
- package/dist/core/evolution-reducer.js +730 -0
- package/dist/core/evolution-types.d.ts +50 -0
- package/dist/core/evolution-types.js +11 -0
- package/dist/core/external-training-contract.d.ts +276 -0
- package/dist/core/external-training-contract.js +269 -0
- package/dist/core/file-store.d.ts +41 -0
- package/dist/core/file-store.js +46 -0
- package/dist/core/focus-history.d.ts +50 -0
- package/dist/core/focus-history.js +574 -0
- package/dist/core/hygiene/tracker.d.ts +22 -0
- package/dist/core/hygiene/tracker.js +110 -0
- package/dist/core/init.d.ts +30 -0
- package/{src/core/init.ts → dist/core/init.js} +87 -118
- package/dist/core/local-worker-routing.d.ts +124 -0
- package/dist/core/local-worker-routing.js +216 -0
- package/dist/core/migration.d.ts +6 -0
- package/{src/core/migration.ts → dist/core/migration.js} +10 -18
- package/dist/core/model-deployment-registry.d.ts +218 -0
- package/dist/core/model-deployment-registry.js +502 -0
- package/dist/core/model-training-registry.d.ts +295 -0
- package/dist/core/model-training-registry.js +474 -0
- package/dist/core/observability.d.ts +40 -0
- package/dist/core/observability.js +164 -0
- package/dist/core/pain-diagnostic-gate.d.ts +36 -0
- package/dist/core/pain-diagnostic-gate.js +105 -0
- package/dist/core/pain.d.ts +87 -0
- package/dist/core/pain.js +223 -0
- package/dist/core/path-resolver.d.ts +60 -0
- package/{src/core/path-resolver.ts → dist/core/path-resolver.js} +41 -131
- package/dist/core/paths.d.ts +60 -0
- package/{src/core/paths.ts → dist/core/paths.js} +4 -13
- package/dist/core/pd-config-loader.d.ts +96 -0
- package/dist/core/pd-config-loader.js +307 -0
- package/dist/core/pd-task-reconciler.d.ts +89 -0
- package/dist/core/pd-task-reconciler.js +262 -0
- package/dist/core/pd-task-service.d.ts +2 -0
- package/dist/core/pd-task-service.js +32 -0
- package/dist/core/pd-task-store.d.ts +5 -0
- package/dist/core/pd-task-store.js +62 -0
- package/dist/core/pd-task-types.d.ts +8 -0
- package/dist/core/pd-task-types.js +2 -0
- package/dist/core/principle-compiler/__tests__/compiler-replay-gate.test.d.ts +1 -0
- package/dist/core/principle-compiler/__tests__/compiler-replay-gate.test.js +132 -0
- package/dist/core/principle-compiler/code-validator.d.ts +14 -0
- package/dist/core/principle-compiler/code-validator.js +86 -0
- package/dist/core/principle-compiler/compiler.d.ts +45 -0
- package/dist/core/principle-compiler/compiler.js +287 -0
- package/{src/core/principle-compiler/index.ts → dist/core/principle-compiler/index.d.ts} +0 -1
- package/dist/core/principle-compiler/index.js +10 -0
- package/dist/core/principle-compiler/ledger-registrar.d.ts +28 -0
- package/dist/core/principle-compiler/ledger-registrar.js +95 -0
- package/{src/core/principle-compiler/template-generator.ts → dist/core/principle-compiler/template-generator.d.ts} +0 -1
- package/dist/core/principle-compiler/template-generator.js +7 -0
- package/{src/core/principle-injection.ts → dist/core/principle-injection.d.ts} +1 -7
- package/dist/core/principle-injection.js +10 -0
- package/dist/core/principle-internalization/filesystem-lifecycle-datasource.d.ts +15 -0
- package/dist/core/principle-internalization/filesystem-lifecycle-datasource.js +34 -0
- package/dist/core/principle-internalization/lifecycle-read-model.d.ts +17 -0
- package/{src/core/principle-internalization/lifecycle-read-model.ts → dist/core/principle-internalization/lifecycle-read-model.js} +2 -21
- package/dist/core/principle-internalization/lifecycle-refresh.d.ts +2 -0
- package/dist/core/principle-internalization/lifecycle-refresh.js +4 -0
- package/dist/core/principle-internalization/principle-lifecycle-service.d.ts +28 -0
- package/dist/core/principle-internalization/principle-lifecycle-service.js +89 -0
- package/dist/core/principle-training-state.d.ts +47 -0
- package/dist/core/principle-training-state.js +113 -0
- package/dist/core/principle-tree-ledger-adapter.d.ts +32 -0
- package/dist/core/principle-tree-ledger-adapter.js +125 -0
- package/dist/core/principle-tree-ledger.d.ts +82 -0
- package/dist/core/principle-tree-ledger.js +527 -0
- package/dist/core/profile.d.ts +62 -0
- package/dist/core/profile.js +211 -0
- package/dist/core/promotion-gate.d.ts +243 -0
- package/dist/core/promotion-gate.js +554 -0
- package/dist/core/reflection/reflection-context.d.ts +31 -0
- package/dist/core/reflection/reflection-context.js +91 -0
- package/dist/core/replay-engine.d.ts +12 -0
- package/dist/core/replay-engine.js +82 -0
- package/dist/core/risk-calculator.d.ts +22 -0
- package/{src/core/risk-calculator.ts → dist/core/risk-calculator.js} +19 -49
- package/{src/core/rule-host-helpers.ts → dist/core/rule-host-helpers.d.ts} +0 -1
- package/dist/core/rule-host-helpers.js +7 -0
- package/{src/core/rule-host-types.ts → dist/core/rule-host-types.d.ts} +1 -8
- package/dist/core/rule-host-types.js +7 -0
- package/dist/core/rule-host.d.ts +86 -0
- package/dist/core/rule-host.js +311 -0
- package/dist/core/rule-implementation-runtime.d.ts +18 -0
- package/dist/core/rule-implementation-runtime.js +112 -0
- package/dist/core/runtime-v2-prompt-activation-reader.d.ts +22 -0
- package/dist/core/runtime-v2-prompt-activation-reader.js +99 -0
- package/{src/core/schema/db-types.ts → dist/core/schema/db-types.d.ts} +4 -9
- package/dist/core/schema/db-types.js +5 -0
- package/{src/core/schema/index.ts → dist/core/schema/index.d.ts} +1 -10
- package/dist/core/schema/index.js +15 -0
- package/dist/core/schema/migration-runner.d.ts +53 -0
- package/dist/core/schema/migration-runner.js +170 -0
- package/dist/core/schema/migrations/001-init-trajectory.d.ts +6 -0
- package/{src/core/schema/migrations/001-init-trajectory.ts → dist/core/schema/migrations/001-init-trajectory.js} +38 -56
- package/dist/core/schema/migrations/002-init-central.d.ts +5 -0
- package/{src/core/schema/migrations/002-init-central.ts → dist/core/schema/migrations/002-init-central.js} +27 -41
- package/dist/core/schema/migrations/003-init-workflow.d.ts +5 -0
- package/{src/core/schema/migrations/003-init-workflow.ts → dist/core/schema/migrations/003-init-workflow.js} +16 -21
- package/dist/core/schema/migrations/004-add-thinking-and-gfi.d.ts +8 -0
- package/{src/core/schema/migrations/004-add-thinking-and-gfi.ts → dist/core/schema/migrations/004-add-thinking-and-gfi.js} +19 -27
- package/{src/core/schema/migrations/index.ts → dist/core/schema/migrations/index.d.ts} +1 -16
- package/dist/core/schema/migrations/index.js +27 -0
- package/dist/core/schema/schema-definitions.d.ts +46 -0
- package/{src/core/schema/schema-definitions.ts → dist/core/schema/schema-definitions.js} +242 -291
- package/dist/core/session-tracker.d.ts +119 -0
- package/{src/core/session-tracker.ts → dist/core/session-tracker.js} +96 -239
- package/dist/core/shadow-observation-registry.d.ts +217 -0
- package/dist/core/shadow-observation-registry.js +280 -0
- package/dist/core/surface-guard.d.ts +31 -0
- package/dist/core/surface-guard.js +131 -0
- package/dist/core/system-logger.d.ts +8 -0
- package/{src/core/system-logger.ts → dist/core/system-logger.js} +20 -34
- package/dist/core/thinking-models.d.ts +70 -0
- package/dist/core/thinking-models.js +300 -0
- package/dist/core/thinking-os-parser.d.ts +35 -0
- package/dist/core/thinking-os-parser.js +123 -0
- package/dist/core/trajectory-types.d.ts +220 -0
- package/dist/core/trajectory-types.js +8 -0
- package/dist/core/trajectory.d.ts +242 -0
- package/dist/core/trajectory.js +1500 -0
- package/dist/core/workflow-funnel-loader.d.ts +72 -0
- package/dist/core/workflow-funnel-loader.js +135 -0
- package/dist/core/workspace-context.d.ts +111 -0
- package/{src/core/workspace-context.ts → dist/core/workspace-context.js} +50 -105
- package/dist/core/workspace-dir-validation.d.ts +11 -0
- package/dist/core/workspace-dir-validation.js +37 -0
- package/dist/core/workspace-guidance-migrator.d.ts +12 -0
- package/{src/core/workspace-guidance-migrator.ts → dist/core/workspace-guidance-migrator.js} +21 -59
- package/dist/hooks/after-tool-call-helpers.d.ts +89 -0
- package/dist/hooks/after-tool-call-helpers.js +475 -0
- package/dist/hooks/after-tool-call-types.d.ts +86 -0
- package/dist/hooks/after-tool-call-types.js +13 -0
- package/dist/hooks/gate-block-helper.d.ts +44 -0
- package/dist/hooks/gate-block-helper.js +209 -0
- package/dist/hooks/gate.d.ts +16 -0
- package/dist/hooks/gate.js +381 -0
- package/dist/hooks/lifecycle.d.ts +5 -0
- package/dist/hooks/lifecycle.js +287 -0
- package/dist/hooks/llm.d.ts +13 -0
- package/{src/hooks/llm.ts → dist/hooks/llm.js} +63 -117
- package/dist/hooks/message-sanitize.d.ts +24 -0
- package/dist/hooks/message-sanitize.js +77 -0
- package/dist/hooks/pain.d.ts +33 -0
- package/dist/hooks/pain.js +294 -0
- package/dist/hooks/prompt.d.ts +52 -0
- package/dist/hooks/prompt.js +930 -0
- package/dist/hooks/raw-observation-adapter.d.ts +57 -0
- package/dist/hooks/raw-observation-adapter.js +170 -0
- package/dist/hooks/raw-observation-types.d.ts +62 -0
- package/dist/hooks/raw-observation-types.js +15 -0
- package/dist/hooks/subagent.d.ts +9 -0
- package/{src/hooks/subagent.ts → dist/hooks/subagent.js} +20 -60
- package/dist/hooks/trajectory-collector.d.ts +25 -0
- package/dist/hooks/trajectory-collector.js +225 -0
- package/dist/hooks/trajectory-evidence.d.ts +11 -0
- package/dist/hooks/trajectory-evidence.js +88 -0
- package/dist/hooks/triage-adapter.d.ts +58 -0
- package/{src/hooks/triage-adapter.ts → dist/hooks/triage-adapter.js} +36 -68
- package/dist/hooks/trigger-cooldown-tracker.d.ts +30 -0
- package/dist/hooks/trigger-cooldown-tracker.js +55 -0
- package/dist/i18n/commands.d.ts +26 -0
- package/dist/i18n/commands.js +96 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +829 -0
- package/dist/openclaw-sdk.d.ts +293 -0
- package/dist/openclaw-sdk.js +4 -0
- package/dist/service/central-database.d.ts +138 -0
- package/dist/service/central-database.js +731 -0
- package/dist/service/central-sync-service.d.ts +8 -0
- package/dist/service/central-sync-service.js +71 -0
- package/dist/service/correction-observer-service.d.ts +19 -0
- package/{src/service/correction-observer-service.ts → dist/service/correction-observer-service.js} +36 -76
- package/dist/service/evolution-dedup.d.ts +27 -0
- package/{src/service/evolution-dedup.ts → dist/service/evolution-dedup.js} +11 -31
- package/{src/service/evolution-queue-migration.ts → dist/service/evolution-queue-migration.d.ts} +15 -62
- package/dist/service/evolution-queue-migration.js +53 -0
- package/dist/service/evolution-worker.d.ts +103 -0
- package/{src/service/evolution-worker.ts → dist/service/evolution-worker.js} +169 -331
- package/dist/service/internalization-auto-consumer-service.d.ts +8 -0
- package/dist/service/internalization-auto-consumer-service.js +322 -0
- package/dist/service/keyword-optimization-service.d.ts +44 -0
- package/dist/service/keyword-optimization-service.js +137 -0
- package/dist/service/phase3-input-filter.d.ts +73 -0
- package/dist/service/phase3-input-filter.js +172 -0
- package/dist/service/queue-io.d.ts +30 -0
- package/dist/service/queue-io.js +79 -0
- package/{src/service/queue-migration.ts → dist/service/queue-migration.d.ts} +6 -45
- package/dist/service/queue-migration.js +56 -0
- package/dist/service/runtime-summary-service.d.ts +158 -0
- package/dist/service/runtime-summary-service.js +636 -0
- package/dist/service/subagent-workflow/subagent-error-utils.d.ts +8 -0
- package/{src/service/subagent-workflow/subagent-error-utils.ts → dist/service/subagent-workflow/subagent-error-utils.js} +3 -6
- package/{src/service/subagent-workflow/types.ts → dist/service/subagent-workflow/types.d.ts} +17 -80
- package/dist/service/subagent-workflow/types.js +11 -0
- package/dist/service/subagent-workflow/workflow-store.d.ts +30 -0
- package/{src/service/subagent-workflow/workflow-store.ts → dist/service/subagent-workflow/workflow-store.js} +43 -108
- package/dist/service/trajectory-service.d.ts +2 -0
- package/dist/service/trajectory-service.js +16 -0
- package/dist/service/workflow-watchdog.d.ts +23 -0
- package/dist/service/workflow-watchdog.js +103 -0
- package/dist/types/event-types.d.ts +2 -0
- package/dist/types/event-types.js +1 -0
- package/dist/types/hygiene-types.d.ts +2 -0
- package/dist/types/hygiene-types.js +1 -0
- package/{src/types/principle-tree-schema.ts → dist/types/principle-tree-schema.d.ts} +2 -25
- package/dist/types/principle-tree-schema.js +24 -0
- package/dist/types/queue.d.ts +2 -0
- package/dist/types/queue.js +1 -0
- package/dist/types/runtime-summary.d.ts +1 -0
- package/dist/types/runtime-summary.js +1 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.js +16 -0
- package/dist/utils/file-lock.d.ts +68 -0
- package/dist/utils/file-lock.js +310 -0
- package/dist/utils/hashing.d.ts +9 -0
- package/{src/utils/hashing.ts → dist/utils/hashing.js} +4 -6
- package/dist/utils/io.d.ts +11 -0
- package/dist/utils/io.js +174 -0
- package/dist/utils/node-vm-polyfill.d.ts +9 -0
- package/{src/utils/node-vm-polyfill.ts → dist/utils/node-vm-polyfill.js} +0 -2
- package/dist/utils/retry.d.ts +210 -0
- package/dist/utils/retry.js +375 -0
- package/dist/utils/session-key.d.ts +10 -0
- package/{src/utils/session-key.ts → dist/utils/session-key.js} +5 -4
- package/dist/utils/shadow-fingerprint.d.ts +16 -0
- package/dist/utils/shadow-fingerprint.js +34 -0
- package/dist/utils/workspace-resolver.d.ts +82 -0
- package/dist/utils/workspace-resolver.js +288 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -2
- package/templates/workspace/.principles/DECISION_POLICY.json +44 -0
- package/templates/workspace/.principles/PRINCIPLES.md +20 -0
- package/templates/workspace/.principles/PROFILE.json +54 -0
- package/templates/workspace/.principles/PROFILE.schema.json +56 -0
- package/templates/workspace/.principles/THINKING_OS.md +65 -0
- package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +7 -0
- package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +9 -0
- package/templates/workspace/.principles/models/_INDEX.md +27 -0
- package/templates/workspace/.principles/models/first_principles.md +62 -0
- package/templates/workspace/.principles/models/marketing_4p.md +52 -0
- package/templates/workspace/.principles/models/porter_five.md +63 -0
- package/templates/workspace/.principles/models/swot.md +60 -0
- package/templates/workspace/.principles/models/user_story_map.md +63 -0
- package/templates/workspace/.state/WORKBOARD.json +4 -0
- package/.dependency-cruiser.json +0 -19
- package/ADVANCED_CONFIG_ZH.md +0 -93
- package/AGENT_INSTALL.md +0 -173
- package/AGENT_INSTALL_EN.md +0 -173
- package/CHANGELOG.md +0 -26
- package/INSTALL.md +0 -254
- package/SKILL.md +0 -63
- package/esbuild.config.js +0 -104
- package/src/commands/archive-impl.ts +0 -147
- package/src/commands/capabilities.ts +0 -89
- package/src/commands/disable-impl.ts +0 -159
- package/src/commands/evolution-status.ts +0 -247
- package/src/commands/export.ts +0 -59
- package/src/commands/focus.ts +0 -523
- package/src/commands/principle-rollback.ts +0 -32
- package/src/commands/promote-impl.ts +0 -254
- package/src/commands/rollback-impl.ts +0 -246
- package/src/commands/samples.ts +0 -65
- package/src/commands/strategy.ts +0 -21
- package/src/config/errors.ts +0 -180
- package/src/constants/tools.ts +0 -62
- package/src/core/AGENTS.md +0 -34
- package/src/core/__tests__/focus-history.test.ts +0 -210
- package/src/core/bootstrap-rules.ts +0 -216
- package/src/core/code-implementation-storage.ts +0 -213
- package/src/core/config-health.ts +0 -72
- package/src/core/control-ui-db.ts +0 -454
- package/src/core/correction-cue-learner.ts +0 -239
- package/src/core/correction-types.ts +0 -16
- package/src/core/empathy-keyword-matcher.ts +0 -64
- package/src/core/empathy-types.ts +0 -18
- package/src/core/event-log.ts +0 -787
- package/src/core/evolution-engine.ts +0 -613
- package/src/core/evolution-logger.ts +0 -357
- package/src/core/evolution-migration.ts +0 -77
- package/src/core/evolution-reducer.ts +0 -891
- package/src/core/evolution-types.ts +0 -110
- package/src/core/external-training-contract.ts +0 -530
- package/src/core/file-store.ts +0 -80
- package/src/core/focus-history.ts +0 -763
- package/src/core/hygiene/tracker.ts +0 -122
- package/src/core/local-worker-routing.ts +0 -337
- package/src/core/model-deployment-registry.ts +0 -724
- package/src/core/model-training-registry.ts +0 -815
- package/src/core/observability.ts +0 -242
- package/src/core/pain-diagnostic-gate.ts +0 -169
- package/src/core/pain.ts +0 -309
- package/src/core/pd-config-loader.ts +0 -400
- package/src/core/pd-task-reconciler.ts +0 -380
- package/src/core/pd-task-service.ts +0 -43
- package/src/core/pd-task-store.ts +0 -78
- package/src/core/pd-task-types.ts +0 -24
- package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +0 -174
- package/src/core/principle-compiler/code-validator.ts +0 -96
- package/src/core/principle-compiler/compiler.ts +0 -327
- package/src/core/principle-compiler/ledger-registrar.ts +0 -116
- package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +0 -42
- package/src/core/principle-internalization/lifecycle-refresh.ts +0 -11
- package/src/core/principle-internalization/principle-lifecycle-service.ts +0 -170
- package/src/core/principle-training-state.ts +0 -177
- package/src/core/principle-tree-ledger-adapter.ts +0 -145
- package/src/core/principle-tree-ledger.ts +0 -725
- package/src/core/profile.ts +0 -228
- package/src/core/promotion-gate.ts +0 -854
- package/src/core/reflection/reflection-context.ts +0 -133
- package/src/core/replay-engine.ts +0 -106
- package/src/core/rule-host.ts +0 -386
- package/src/core/rule-implementation-runtime.ts +0 -145
- package/src/core/runtime-v2-prompt-activation-reader.ts +0 -114
- package/src/core/schema/migration-runner.ts +0 -207
- package/src/core/shadow-observation-registry.ts +0 -508
- package/src/core/surface-guard.ts +0 -188
- package/src/core/thinking-models.ts +0 -377
- package/src/core/thinking-os-parser.ts +0 -165
- package/src/core/trajectory-types.ts +0 -247
- package/src/core/trajectory.ts +0 -1831
- package/src/core/workflow-funnel-loader.ts +0 -195
- package/src/core/workspace-dir-validation.ts +0 -52
- package/src/hooks/AGENTS.md +0 -31
- package/src/hooks/after-tool-call-helpers.ts +0 -601
- package/src/hooks/after-tool-call-types.ts +0 -99
- package/src/hooks/gate-block-helper.ts +0 -265
- package/src/hooks/gate.ts +0 -394
- package/src/hooks/lifecycle.ts +0 -334
- package/src/hooks/message-sanitize.ts +0 -102
- package/src/hooks/pain.ts +0 -358
- package/src/hooks/prompt.ts +0 -1102
- package/src/hooks/raw-observation-adapter.ts +0 -215
- package/src/hooks/raw-observation-types.ts +0 -77
- package/src/hooks/trajectory-collector.ts +0 -253
- package/src/hooks/trajectory-evidence.ts +0 -97
- package/src/hooks/trigger-cooldown-tracker.ts +0 -82
- package/src/i18n/commands.ts +0 -101
- package/src/index.ts +0 -939
- package/src/openclaw-sdk.ts +0 -312
- package/src/service/central-database.ts +0 -936
- package/src/service/central-sync-service.ts +0 -85
- package/src/service/internalization-auto-consumer-service.ts +0 -397
- package/src/service/keyword-optimization-service.ts +0 -169
- package/src/service/phase3-input-filter.ts +0 -237
- package/src/service/queue-io.ts +0 -108
- package/src/service/runtime-summary-service.ts +0 -990
- package/src/service/trajectory-service.ts +0 -16
- package/src/service/workflow-watchdog.ts +0 -125
- package/src/types/event-types.ts +0 -39
- package/src/types/hygiene-types.ts +0 -8
- package/src/types/queue.ts +0 -15
- package/src/types/runtime-summary.ts +0 -5
- package/src/types.ts +0 -53
- package/src/utils/file-lock.ts +0 -394
- package/src/utils/io.ts +0 -176
- package/src/utils/retry.ts +0 -573
- package/src/utils/shadow-fingerprint.ts +0 -42
- package/src/utils/workspace-resolver.ts +0 -393
- package/tests/README.md +0 -120
- package/tests/build-artifacts.test.ts +0 -55
- package/tests/commands/evolution-status.test.ts +0 -511
- package/tests/commands/export.test.ts +0 -78
- package/tests/commands/pain.test.ts +0 -287
- package/tests/commands/samples.test.ts +0 -65
- package/tests/commands/strategy.test.ts +0 -19
- package/tests/commands/thinking-os.test.ts +0 -88
- package/tests/core/bootstrap-rules.test.ts +0 -596
- package/tests/core/code-implementation-storage.test.ts +0 -300
- package/tests/core/code-validator.test.ts +0 -197
- package/tests/core/config-service.test.ts +0 -89
- package/tests/core/config.test.ts +0 -90
- package/tests/core/control-ui-db.test.ts +0 -75
- package/tests/core/core-principle-registry-drift.test.ts +0 -39
- package/tests/core/core-template-guidance.test.ts +0 -21
- package/tests/core/correction-cue-learner.test.ts +0 -345
- package/tests/core/detection-service.test.ts +0 -50
- package/tests/core/dictionary-service.test.ts +0 -116
- package/tests/core/dictionary.test.ts +0 -171
- package/tests/core/empathy-keyword-matcher.test.ts +0 -209
- package/tests/core/event-log.test.ts +0 -484
- package/tests/core/evolution-engine.test.ts +0 -610
- package/tests/core/evolution-logger.test.ts +0 -148
- package/tests/core/evolution-migration.test.ts +0 -374
- package/tests/core/evolution-paths.test.ts +0 -21
- package/tests/core/evolution-reducer.compilation-retry.test.ts +0 -189
- package/tests/core/evolution-reducer.detector-metadata.test.ts +0 -602
- package/tests/core/evolution-types-loop.test.ts +0 -48
- package/tests/core/external-training-contract.test.ts +0 -463
- package/tests/core/file-store.test.ts +0 -102
- package/tests/core/focus-history.test.ts +0 -874
- package/tests/core/init-flatten.test.ts +0 -69
- package/tests/core/init-refactor.test.ts +0 -87
- package/tests/core/init-v1.3.test.ts +0 -46
- package/tests/core/init.test.ts +0 -190
- package/tests/core/ledger-registrar.test.ts +0 -235
- package/tests/core/migration.test.ts +0 -84
- package/tests/core/model-deployment-registry.test.ts +0 -858
- package/tests/core/model-training-registry.test.ts +0 -908
- package/tests/core/observability.test.ts +0 -382
- package/tests/core/pain-diagnostic-gate.test.ts +0 -614
- package/tests/core/pain-score.property.test.ts +0 -19
- package/tests/core/pain.test.ts +0 -132
- package/tests/core/path-resolver.test.ts +0 -57
- package/tests/core/paths-refactor.test.ts +0 -20
- package/tests/core/pd-config-loader.test.ts +0 -407
- package/tests/core/pd-task-store.test.ts +0 -126
- package/tests/core/phase7-rollout-integration.test.ts +0 -477
- package/tests/core/principle-compiler.test.ts +0 -350
- package/tests/core/principle-injection.test.ts +0 -223
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +0 -193
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +0 -350
- package/tests/core/principle-internalization/lifecycle-routing-policy.test.ts +0 -212
- package/tests/core/principle-internalization/lineage-source-retired.test.ts +0 -56
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +0 -189
- package/tests/core/principle-training-state.test.ts +0 -939
- package/tests/core/principle-tree-ledger-adapter.test.ts +0 -253
- package/tests/core/principle-tree-ledger.test.ts +0 -423
- package/tests/core/profile.test.ts +0 -56
- package/tests/core/promotion-gate.test.ts +0 -561
- package/tests/core/queue-purge.test.ts +0 -337
- package/tests/core/reflection-context.test.ts +0 -342
- package/tests/core/regression-v1-9-1.test.ts +0 -266
- package/tests/core/replay-engine.test.ts +0 -165
- package/tests/core/risk-calculator.test.ts +0 -168
- package/tests/core/rule-host-adversarial-output.test.ts +0 -242
- package/tests/core/rule-host-autocorrect-vm.test.ts +0 -163
- package/tests/core/rule-host-helpers.test.ts +0 -120
- package/tests/core/rule-host-resource-bounds.test.ts +0 -231
- package/tests/core/rule-host-sqlite-source.test.ts +0 -720
- package/tests/core/rule-host-unhealthy-visibility.test.ts +0 -261
- package/tests/core/rule-host-validation.test.ts +0 -315
- package/tests/core/rule-implementation-runtime.test.ts +0 -49
- package/tests/core/session-tracker.test.ts +0 -191
- package/tests/core/surface-guard.test.ts +0 -338
- package/tests/core/template-generator.test.ts +0 -101
- package/tests/core/trajectory.test.ts +0 -427
- package/tests/core/workflow-funnel-loader.test.ts +0 -1028
- package/tests/core/workspace-context-factory.test.ts +0 -18
- package/tests/core/workspace-context.test.ts +0 -187
- package/tests/core/workspace-guidance-migrator.test.ts +0 -248
- package/tests/core-anti-growth.test.ts +0 -182
- package/tests/evolution-worker-quarantine.test.ts +0 -400
- package/tests/evolution-worker-slimming.test.ts +0 -380
- package/tests/fixtures/legacy-queue-v1.json +0 -74
- package/tests/fixtures/production-compatibility.test.ts +0 -147
- package/tests/fixtures/production-mock-generator.ts +0 -282
- package/tests/globalSetup.ts +0 -38
- package/tests/hook-workspace-nextaction-contract.test.ts +0 -50
- package/tests/hooks/confirm-first-removal.test.ts +0 -188
- package/tests/hooks/gate-auto-correct-shadow.test.ts +0 -309
- package/tests/hooks/gate-auto-correct.test.ts +0 -664
- package/tests/hooks/gate-block-helper-profile.test.ts +0 -186
- package/tests/hooks/gate-no-path-write-tool.test.ts +0 -171
- package/tests/hooks/gate-rule-host-pipeline.test.ts +0 -230
- package/tests/hooks/gate-rule-host-real-pipeline.test.ts +0 -190
- package/tests/hooks/lifecycle.test.ts +0 -248
- package/tests/hooks/message-sanitize.test.ts +0 -244
- package/tests/hooks/pain-emission-characterization.test.ts +0 -420
- package/tests/hooks/pain.test.ts +0 -795
- package/tests/hooks/prompt-characterization.test.ts +0 -476
- package/tests/hooks/prompt-diet.test.ts +0 -335
- package/tests/hooks/prompt-size-guard.test.ts +0 -319
- package/tests/hooks/raw-observation-adapter.test.ts +0 -312
- package/tests/hooks/runtime-v2-prompt-activation.test.ts +0 -895
- package/tests/hooks/single-gate-pain-admission.test.ts +0 -258
- package/tests/hooks/subagent.test.ts +0 -469
- package/tests/hooks/trajectory-collector.test.ts +0 -269
- package/tests/hooks/trajectory-evidence.test.ts +0 -280
- package/tests/hooks/triage-adapter.test.ts +0 -331
- package/tests/hygiene-tracker.test.ts +0 -77
- package/tests/index.test.ts +0 -142
- package/tests/integration/auto-entry-gate.test.ts +0 -256
- package/tests/integration/gate-real-io.e2e.test.ts +0 -248
- package/tests/integration/m8-legacy-paths.test.ts +0 -63
- package/tests/integration/mvp-surface-registry-guard.test.ts +0 -536
- package/tests/integration/pain-id-chain-e2e.test.ts +0 -313
- package/tests/integration/principle-compiler-e2e.test.ts +0 -403
- package/tests/integration/principle-lifecycle.e2e.test.ts +0 -198
- package/tests/integration/runtime-v2-pain-guard.test.ts +0 -125
- package/tests/integration/trajectory-lifecycle.e2e.test.ts +0 -523
- package/tests/internalization-auto-consumer-gate.test.ts +0 -158
- package/tests/internalization-auto-consumer-service.test.ts +0 -219
- package/tests/plugin-config-resolution-cutover.test.ts +0 -359
- package/tests/queue/async-lock.test.ts +0 -200
- package/tests/runtime-v2-discovery-guard.test.ts +0 -153
- package/tests/scripts/validate-live-path.test.ts +0 -286
- package/tests/service/central-database.test.ts +0 -457
- package/tests/service/correction-observer-service.test.ts +0 -505
- package/tests/service/evolution-worker.compilation-backfill.test.ts +0 -203
- package/tests/service/evolution-worker.correction-observer.test.ts +0 -50
- package/tests/service/evolution-worker.queue.test.ts +0 -296
- package/tests/service/evolution-worker.timeout.test.ts +0 -233
- package/tests/service/keyword-optimization-service.test.ts +0 -121
- package/tests/service/phase3-input-filter.test.ts +0 -289
- package/tests/service/queue-io.test.ts +0 -168
- package/tests/service/queue-migration.test.ts +0 -147
- package/tests/service/runtime-summary-service.test.ts +0 -1100
- package/tests/service/workflow-watchdog.test.ts +0 -281
- package/tests/task-compliance.test.ts +0 -166
- package/tests/test-utils.ts +0 -48
- package/tests/utils/file-lock.test.ts +0 -409
- package/tests/utils/hashing.test.ts +0 -32
- package/tests/utils/hook-workspace-resolver.test.ts +0 -524
- package/tests/utils/io.test.ts +0 -39
- package/tests/utils/retry.test.ts +0 -327
- package/tests/utils/session-key.test.ts +0 -52
- package/tsconfig.json +0 -16
- package/vitest.config.ts +0 -61
- package/vitest.unit.config.ts +0 -12
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { withLock } from '../utils/file-lock.js';
|
|
5
|
+
import { resolvePdPath } from './paths.js';
|
|
6
|
+
const DEFAULT_BUSY_TIMEOUT_MS = 5000;
|
|
7
|
+
function safeJson(value) {
|
|
8
|
+
return JSON.stringify(value ?? []);
|
|
9
|
+
}
|
|
10
|
+
export class ControlUiDatabase {
|
|
11
|
+
workspaceDir;
|
|
12
|
+
dbPath;
|
|
13
|
+
blobDir;
|
|
14
|
+
db;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
this.workspaceDir = path.resolve(opts.workspaceDir);
|
|
17
|
+
this.dbPath = resolvePdPath(this.workspaceDir, 'TRAJECTORY_DB');
|
|
18
|
+
this.blobDir = resolvePdPath(this.workspaceDir, 'TRAJECTORY_BLOBS_DIR');
|
|
19
|
+
fs.mkdirSync(path.dirname(this.dbPath), { recursive: true });
|
|
20
|
+
fs.mkdirSync(this.blobDir, { recursive: true });
|
|
21
|
+
this.db = new Database(this.dbPath);
|
|
22
|
+
this.db.pragma('journal_mode = WAL');
|
|
23
|
+
this.db.pragma('foreign_keys = ON');
|
|
24
|
+
this.db.pragma('synchronous = NORMAL');
|
|
25
|
+
this.db.pragma(`busy_timeout = ${Math.max(0, opts.busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS)}`);
|
|
26
|
+
this.initSchema();
|
|
27
|
+
}
|
|
28
|
+
dispose() {
|
|
29
|
+
this.db.close();
|
|
30
|
+
}
|
|
31
|
+
recordThinkingModelEvent(input) {
|
|
32
|
+
return this.withWrite(() => {
|
|
33
|
+
const result = this.db.prepare(`
|
|
34
|
+
INSERT INTO thinking_model_events (
|
|
35
|
+
session_id, run_id, assistant_turn_id, model_id, matched_pattern, scenario_json,
|
|
36
|
+
tool_context_json, pain_context_json, principle_context_json, trigger_excerpt, created_at
|
|
37
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
38
|
+
`).run(input.sessionId, input.runId, input.assistantTurnId, input.modelId, input.matchedPattern, safeJson(input.scenarioJson), safeJson(input.toolContextJson), safeJson(input.painContextJson), safeJson(input.principleContextJson), input.triggerExcerpt, input.createdAt);
|
|
39
|
+
return Number(result.lastInsertRowid);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get recent thinking context for a session.
|
|
44
|
+
*
|
|
45
|
+
* Returns: Analytics data (read model) aggregated from trajectory database.
|
|
46
|
+
* Not: Runtime truth or real-time queue state.
|
|
47
|
+
*/
|
|
48
|
+
getRecentThinkingContext(sessionId, beforeCreatedAt, limit = 5) {
|
|
49
|
+
return {
|
|
50
|
+
toolCalls: this.all(`
|
|
51
|
+
SELECT id, tool_name, outcome, error_type, error_message, created_at
|
|
52
|
+
FROM tool_calls
|
|
53
|
+
WHERE session_id = ? AND created_at <= ?
|
|
54
|
+
ORDER BY created_at DESC
|
|
55
|
+
LIMIT ?
|
|
56
|
+
`, sessionId, beforeCreatedAt, limit).map((row) => ({
|
|
57
|
+
id: Number(row.id),
|
|
58
|
+
toolName: String(row.tool_name),
|
|
59
|
+
outcome: row.outcome,
|
|
60
|
+
errorType: row.error_type,
|
|
61
|
+
errorMessage: row.error_message,
|
|
62
|
+
createdAt: String(row.created_at),
|
|
63
|
+
})),
|
|
64
|
+
painEvents: this.all(`
|
|
65
|
+
SELECT id, source, score, reason, created_at
|
|
66
|
+
FROM pain_events
|
|
67
|
+
WHERE session_id = ? AND created_at <= ?
|
|
68
|
+
ORDER BY created_at DESC
|
|
69
|
+
LIMIT ?
|
|
70
|
+
`, sessionId, beforeCreatedAt, limit).map((row) => ({
|
|
71
|
+
id: Number(row.id),
|
|
72
|
+
source: String(row.source),
|
|
73
|
+
score: Number(row.score),
|
|
74
|
+
reason: row.reason,
|
|
75
|
+
createdAt: String(row.created_at),
|
|
76
|
+
})),
|
|
77
|
+
gateBlocks: this.all(`
|
|
78
|
+
SELECT id, tool_name, reason, file_path, created_at
|
|
79
|
+
FROM gate_blocks
|
|
80
|
+
WHERE session_id = ? AND created_at <= ?
|
|
81
|
+
ORDER BY created_at DESC
|
|
82
|
+
LIMIT ?
|
|
83
|
+
`, sessionId, beforeCreatedAt, limit).map((row) => ({
|
|
84
|
+
id: Number(row.id),
|
|
85
|
+
toolName: String(row.tool_name),
|
|
86
|
+
reason: String(row.reason),
|
|
87
|
+
filePath: row.file_path,
|
|
88
|
+
createdAt: String(row.created_at),
|
|
89
|
+
})),
|
|
90
|
+
userCorrections: this.all(`
|
|
91
|
+
SELECT id, correction_cue, raw_excerpt, created_at
|
|
92
|
+
FROM user_turns
|
|
93
|
+
WHERE session_id = ? AND correction_detected = 1 AND created_at <= ?
|
|
94
|
+
ORDER BY created_at DESC
|
|
95
|
+
LIMIT ?
|
|
96
|
+
`, sessionId, beforeCreatedAt, limit).map((row) => ({
|
|
97
|
+
id: Number(row.id),
|
|
98
|
+
correctionCue: row.correction_cue,
|
|
99
|
+
rawExcerpt: row.raw_excerpt,
|
|
100
|
+
createdAt: String(row.created_at),
|
|
101
|
+
})),
|
|
102
|
+
principleEvents: this.all(`
|
|
103
|
+
SELECT id, principle_id, event_type, created_at
|
|
104
|
+
FROM principle_events
|
|
105
|
+
WHERE created_at <= ?
|
|
106
|
+
ORDER BY created_at DESC
|
|
107
|
+
LIMIT ?
|
|
108
|
+
`, beforeCreatedAt, limit).map((row) => ({
|
|
109
|
+
id: Number(row.id),
|
|
110
|
+
principleId: row.principle_id,
|
|
111
|
+
eventType: String(row.event_type),
|
|
112
|
+
createdAt: String(row.created_at),
|
|
113
|
+
})),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Execute SQL query and return all rows.
|
|
118
|
+
*
|
|
119
|
+
* Returns: Analytics data (read model) aggregated from trajectory database.
|
|
120
|
+
* Not: Runtime truth or real-time queue state.
|
|
121
|
+
*/
|
|
122
|
+
all(sql, ...params) {
|
|
123
|
+
return this.db.prepare(sql).all(...params);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Execute SQL query and return first row.
|
|
127
|
+
*
|
|
128
|
+
* Returns: Analytics data (read model) aggregated from trajectory database.
|
|
129
|
+
* Not: Runtime truth or real-time queue state.
|
|
130
|
+
*/
|
|
131
|
+
get(sql, ...params) {
|
|
132
|
+
return this.db.prepare(sql).get(...params);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Execute SQL statement that does not return rows (DDL, CREATE TABLE, etc.).
|
|
136
|
+
*
|
|
137
|
+
* Returns: void (executes directly)
|
|
138
|
+
* Not for: SELECT queries (use all() or get() instead)
|
|
139
|
+
*/
|
|
140
|
+
execute(sql) {
|
|
141
|
+
this.db.exec(sql);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Execute a parameterized write statement (INSERT, UPDATE, DELETE).
|
|
145
|
+
*/
|
|
146
|
+
run(sql, ...params) {
|
|
147
|
+
this.withWrite(() => {
|
|
148
|
+
this.db.prepare(sql).run(...params);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
restoreRawText(inlineText, blobRef) {
|
|
152
|
+
if (inlineText)
|
|
153
|
+
return inlineText;
|
|
154
|
+
if (!blobRef)
|
|
155
|
+
return '';
|
|
156
|
+
const fullPath = path.join(this.blobDir, blobRef);
|
|
157
|
+
return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8') : '';
|
|
158
|
+
}
|
|
159
|
+
initSchema() {
|
|
160
|
+
this.db.exec(`
|
|
161
|
+
CREATE TABLE IF NOT EXISTS thinking_model_events (
|
|
162
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
163
|
+
session_id TEXT NOT NULL,
|
|
164
|
+
run_id TEXT NOT NULL,
|
|
165
|
+
assistant_turn_id INTEGER NOT NULL,
|
|
166
|
+
model_id TEXT NOT NULL,
|
|
167
|
+
matched_pattern TEXT NOT NULL,
|
|
168
|
+
scenario_json TEXT NOT NULL,
|
|
169
|
+
tool_context_json TEXT NOT NULL,
|
|
170
|
+
pain_context_json TEXT NOT NULL,
|
|
171
|
+
principle_context_json TEXT NOT NULL,
|
|
172
|
+
trigger_excerpt TEXT NOT NULL,
|
|
173
|
+
created_at TEXT NOT NULL
|
|
174
|
+
);
|
|
175
|
+
CREATE INDEX IF NOT EXISTS idx_thinking_model_events_model_created
|
|
176
|
+
ON thinking_model_events(model_id, created_at);
|
|
177
|
+
CREATE INDEX IF NOT EXISTS idx_thinking_model_events_session_created
|
|
178
|
+
ON thinking_model_events(session_id, created_at);
|
|
179
|
+
CREATE INDEX IF NOT EXISTS idx_thinking_model_events_assistant_turn
|
|
180
|
+
ON thinking_model_events(assistant_turn_id);
|
|
181
|
+
CREATE INDEX IF NOT EXISTS idx_thinking_model_events_run_id
|
|
182
|
+
ON thinking_model_events(run_id);
|
|
183
|
+
|
|
184
|
+
DROP VIEW IF EXISTS v_thinking_model_usage;
|
|
185
|
+
CREATE VIEW v_thinking_model_usage AS
|
|
186
|
+
WITH totals AS (
|
|
187
|
+
SELECT COUNT(*) AS assistant_turns FROM assistant_turns
|
|
188
|
+
),
|
|
189
|
+
usage_rows AS (
|
|
190
|
+
SELECT
|
|
191
|
+
model_id,
|
|
192
|
+
COUNT(*) AS hits,
|
|
193
|
+
COUNT(DISTINCT session_id) AS distinct_sessions,
|
|
194
|
+
COUNT(DISTINCT assistant_turn_id) AS distinct_turns
|
|
195
|
+
FROM thinking_model_events
|
|
196
|
+
GROUP BY model_id
|
|
197
|
+
)
|
|
198
|
+
SELECT
|
|
199
|
+
usage_rows.model_id AS model_id,
|
|
200
|
+
usage_rows.hits AS hits,
|
|
201
|
+
usage_rows.distinct_sessions AS distinct_sessions,
|
|
202
|
+
usage_rows.distinct_turns AS distinct_turns,
|
|
203
|
+
CASE
|
|
204
|
+
WHEN totals.assistant_turns = 0 THEN 0
|
|
205
|
+
ELSE ROUND(CAST(usage_rows.distinct_turns AS REAL) / CAST(totals.assistant_turns AS REAL), 4)
|
|
206
|
+
END AS coverage_rate
|
|
207
|
+
FROM usage_rows, totals
|
|
208
|
+
ORDER BY usage_rows.hits DESC, usage_rows.model_id ASC;
|
|
209
|
+
|
|
210
|
+
DROP VIEW IF EXISTS v_thinking_model_effectiveness;
|
|
211
|
+
CREATE VIEW v_thinking_model_effectiveness AS
|
|
212
|
+
WITH event_windows AS (
|
|
213
|
+
SELECT
|
|
214
|
+
e.id,
|
|
215
|
+
e.session_id,
|
|
216
|
+
e.model_id,
|
|
217
|
+
e.created_at,
|
|
218
|
+
(
|
|
219
|
+
SELECT MIN(a.created_at)
|
|
220
|
+
FROM assistant_turns a
|
|
221
|
+
WHERE a.session_id = e.session_id AND a.created_at > e.created_at
|
|
222
|
+
) AS next_assistant_at,
|
|
223
|
+
datetime(e.created_at, '+10 minutes') AS max_window_end
|
|
224
|
+
FROM thinking_model_events e
|
|
225
|
+
),
|
|
226
|
+
bounded_windows AS (
|
|
227
|
+
SELECT
|
|
228
|
+
id,
|
|
229
|
+
session_id,
|
|
230
|
+
model_id,
|
|
231
|
+
created_at,
|
|
232
|
+
CASE
|
|
233
|
+
WHEN next_assistant_at IS NULL THEN max_window_end
|
|
234
|
+
WHEN next_assistant_at < max_window_end THEN next_assistant_at
|
|
235
|
+
ELSE max_window_end
|
|
236
|
+
END AS window_end
|
|
237
|
+
FROM event_windows
|
|
238
|
+
)
|
|
239
|
+
SELECT
|
|
240
|
+
b.model_id AS model_id,
|
|
241
|
+
COUNT(*) AS events,
|
|
242
|
+
SUM(CASE WHEN EXISTS (
|
|
243
|
+
SELECT 1 FROM tool_calls t
|
|
244
|
+
WHERE t.session_id = b.session_id
|
|
245
|
+
AND t.created_at > b.created_at
|
|
246
|
+
AND t.created_at <= b.window_end
|
|
247
|
+
AND t.outcome = 'success'
|
|
248
|
+
) THEN 1 ELSE 0 END) AS success_windows,
|
|
249
|
+
SUM(CASE WHEN EXISTS (
|
|
250
|
+
SELECT 1 FROM tool_calls t
|
|
251
|
+
WHERE t.session_id = b.session_id
|
|
252
|
+
AND t.created_at > b.created_at
|
|
253
|
+
AND t.created_at <= b.window_end
|
|
254
|
+
AND t.outcome = 'failure'
|
|
255
|
+
) THEN 1 ELSE 0 END) AS failure_windows,
|
|
256
|
+
SUM(CASE WHEN EXISTS (
|
|
257
|
+
SELECT 1 FROM pain_events p
|
|
258
|
+
WHERE p.session_id = b.session_id
|
|
259
|
+
AND p.created_at > b.created_at
|
|
260
|
+
AND p.created_at <= b.window_end
|
|
261
|
+
) THEN 1 ELSE 0 END) AS pain_windows,
|
|
262
|
+
SUM(CASE WHEN EXISTS (
|
|
263
|
+
SELECT 1 FROM user_turns u
|
|
264
|
+
WHERE u.session_id = b.session_id
|
|
265
|
+
AND u.created_at > b.created_at
|
|
266
|
+
AND u.created_at <= b.window_end
|
|
267
|
+
AND u.correction_detected = 1
|
|
268
|
+
) THEN 1 ELSE 0 END) AS correction_windows,
|
|
269
|
+
SUM(CASE WHEN EXISTS (
|
|
270
|
+
SELECT 1 FROM correction_samples c
|
|
271
|
+
WHERE c.session_id = b.session_id
|
|
272
|
+
AND c.created_at > b.created_at
|
|
273
|
+
AND c.created_at <= b.window_end
|
|
274
|
+
) THEN 1 ELSE 0 END) AS correction_sample_windows
|
|
275
|
+
FROM bounded_windows b
|
|
276
|
+
GROUP BY b.model_id
|
|
277
|
+
ORDER BY events DESC, model_id ASC;
|
|
278
|
+
|
|
279
|
+
DROP VIEW IF EXISTS v_thinking_model_scenarios;
|
|
280
|
+
CREATE VIEW v_thinking_model_scenarios AS
|
|
281
|
+
SELECT
|
|
282
|
+
e.model_id AS model_id,
|
|
283
|
+
CAST(j.value AS TEXT) AS scenario,
|
|
284
|
+
COUNT(*) AS hits
|
|
285
|
+
FROM thinking_model_events e
|
|
286
|
+
JOIN json_each(
|
|
287
|
+
CASE
|
|
288
|
+
WHEN json_valid(e.scenario_json) THEN e.scenario_json
|
|
289
|
+
ELSE '[]'
|
|
290
|
+
END
|
|
291
|
+
) AS j
|
|
292
|
+
GROUP BY e.model_id, CAST(j.value AS TEXT)
|
|
293
|
+
ORDER BY hits DESC, scenario ASC;
|
|
294
|
+
|
|
295
|
+
DROP VIEW IF EXISTS v_thinking_model_daily_trend;
|
|
296
|
+
CREATE VIEW v_thinking_model_daily_trend AS
|
|
297
|
+
SELECT
|
|
298
|
+
substr(created_at, 1, 10) AS day,
|
|
299
|
+
model_id,
|
|
300
|
+
COUNT(*) AS hits
|
|
301
|
+
FROM thinking_model_events
|
|
302
|
+
GROUP BY substr(created_at, 1, 10), model_id
|
|
303
|
+
ORDER BY day ASC, model_id ASC;
|
|
304
|
+
`);
|
|
305
|
+
}
|
|
306
|
+
withWrite(fn) {
|
|
307
|
+
return withLock(this.dbPath, fn, { lockSuffix: '.trajectory.lock', lockStaleMs: 30000 });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Correction Cue Learner
|
|
3
|
+
*
|
|
4
|
+
* Persistent, learnable keyword store for correction cue detection.
|
|
5
|
+
* Replaces the hardcoded cue list in detectCorrectionCue() with a
|
|
6
|
+
* crash-safe JSON store that can grow over time.
|
|
7
|
+
*
|
|
8
|
+
* Persistence contract:
|
|
9
|
+
* - Atomic write: temp-file-then-rename (T-38-02)
|
|
10
|
+
* - Cache invalidated after every write (D-05)
|
|
11
|
+
* - 200-term hard cap enforced before any write (T-38-01)
|
|
12
|
+
*/
|
|
13
|
+
import type { CorrectionKeyword, CorrectionKeywordStore, CorrectionMatchResult } from './correction-types.js';
|
|
14
|
+
export declare function _resetCorrectionCueCache(): void;
|
|
15
|
+
export declare function loadCorrectionKeywordStore(stateDir: string): CorrectionKeywordStore;
|
|
16
|
+
export declare function saveCorrectionKeywordStore(stateDir: string, store: CorrectionKeywordStore): void;
|
|
17
|
+
export declare function _resetCorrectionCueLearnerInstance(): void;
|
|
18
|
+
export declare class CorrectionCueLearner {
|
|
19
|
+
private readonly store;
|
|
20
|
+
private readonly stateDir;
|
|
21
|
+
constructor(stateDir: string);
|
|
22
|
+
match(text: string): CorrectionMatchResult;
|
|
23
|
+
recordHits(terms: string[]): void;
|
|
24
|
+
recordTruePositive(term: string): void;
|
|
25
|
+
recordFalsePositive(term: string): void;
|
|
26
|
+
add(keyword: Omit<CorrectionKeyword, 'addedAt'>): void;
|
|
27
|
+
updateWeight(term: string, weight: number): void;
|
|
28
|
+
remove(term: string): void;
|
|
29
|
+
getStore(): CorrectionKeywordStore;
|
|
30
|
+
getLastOptimizedAt(): string;
|
|
31
|
+
flush(): void;
|
|
32
|
+
static get(stateDir: string): CorrectionCueLearner;
|
|
33
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Correction Cue Learner
|
|
3
|
+
*
|
|
4
|
+
* Persistent, learnable keyword store for correction cue detection.
|
|
5
|
+
* Replaces the hardcoded cue list in detectCorrectionCue() with a
|
|
6
|
+
* crash-safe JSON store that can grow over time.
|
|
7
|
+
*
|
|
8
|
+
* Persistence contract:
|
|
9
|
+
* - Atomic write: temp-file-then-rename (T-38-02)
|
|
10
|
+
* - Cache invalidated after every write (D-05)
|
|
11
|
+
* - 200-term hard cap enforced before any write (T-38-01)
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { CORRECTION_SEED_KEYWORDS, MAX_CORRECTION_KEYWORDS, } from './correction-types.js';
|
|
16
|
+
import { atomicWriteFileSync } from '../utils/io.js';
|
|
17
|
+
const KEYWORD_STORE_FILE = 'correction_keywords.json';
|
|
18
|
+
const MIN_KEYWORD_WEIGHT = 0.1;
|
|
19
|
+
const MAX_KEYWORD_WEIGHT = 0.9;
|
|
20
|
+
let _correctionCueCache = null;
|
|
21
|
+
export function _resetCorrectionCueCache() {
|
|
22
|
+
_correctionCueCache = null;
|
|
23
|
+
}
|
|
24
|
+
function createDefaultStore() {
|
|
25
|
+
const now = new Date().toISOString();
|
|
26
|
+
const keywords = CORRECTION_SEED_KEYWORDS.map((k) => ({
|
|
27
|
+
...k,
|
|
28
|
+
source: 'seed',
|
|
29
|
+
addedAt: now,
|
|
30
|
+
}));
|
|
31
|
+
return { keywords, version: 1, lastOptimizedAt: now };
|
|
32
|
+
}
|
|
33
|
+
export function loadCorrectionKeywordStore(stateDir) {
|
|
34
|
+
if (_correctionCueCache)
|
|
35
|
+
return _correctionCueCache;
|
|
36
|
+
const filePath = path.join(stateDir, KEYWORD_STORE_FILE);
|
|
37
|
+
if (fs.existsSync(filePath)) {
|
|
38
|
+
try {
|
|
39
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
40
|
+
_correctionCueCache = JSON.parse(raw);
|
|
41
|
+
return _correctionCueCache;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
void 0;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const defaultStore = createDefaultStore();
|
|
48
|
+
saveCorrectionKeywordStore(stateDir, defaultStore);
|
|
49
|
+
_correctionCueCache = defaultStore;
|
|
50
|
+
return _correctionCueCache;
|
|
51
|
+
}
|
|
52
|
+
export function saveCorrectionKeywordStore(stateDir, store) {
|
|
53
|
+
const filePath = path.join(stateDir, KEYWORD_STORE_FILE);
|
|
54
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
55
|
+
atomicWriteFileSync(filePath, JSON.stringify(store, null, 2));
|
|
56
|
+
_correctionCueCache = null;
|
|
57
|
+
}
|
|
58
|
+
let _instance = null;
|
|
59
|
+
let _lastStateDir = null;
|
|
60
|
+
export function _resetCorrectionCueLearnerInstance() {
|
|
61
|
+
_instance = null;
|
|
62
|
+
_lastStateDir = null;
|
|
63
|
+
}
|
|
64
|
+
export class CorrectionCueLearner {
|
|
65
|
+
store;
|
|
66
|
+
stateDir;
|
|
67
|
+
constructor(stateDir) {
|
|
68
|
+
this.stateDir = stateDir;
|
|
69
|
+
this.store = loadCorrectionKeywordStore(stateDir);
|
|
70
|
+
}
|
|
71
|
+
match(text) {
|
|
72
|
+
const normalized = text
|
|
73
|
+
.trim()
|
|
74
|
+
.toLowerCase()
|
|
75
|
+
.replace(/[.,!?;:,。!?;:]/g, '');
|
|
76
|
+
const matchedTerms = [];
|
|
77
|
+
let totalScore = 0;
|
|
78
|
+
for (const keyword of this.store.keywords) {
|
|
79
|
+
if (normalized.includes(keyword.term.toLowerCase())) {
|
|
80
|
+
const tp = keyword.truePositiveCount ?? 0;
|
|
81
|
+
const fp = keyword.falsePositiveCount ?? 0;
|
|
82
|
+
const accuracy = (tp + fp) > 0 ? tp / (tp + fp) : 1;
|
|
83
|
+
const score = keyword.weight * accuracy;
|
|
84
|
+
totalScore += score;
|
|
85
|
+
matchedTerms.push(keyword.term);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const cappedScore = Math.min(1, totalScore);
|
|
89
|
+
const isMatched = matchedTerms.length > 0;
|
|
90
|
+
const termConfidence = Math.min(1, matchedTerms.length / 3);
|
|
91
|
+
const scoreConfidence = Math.min(1, cappedScore / 0.8);
|
|
92
|
+
const confidence = Math.max(termConfidence, scoreConfidence);
|
|
93
|
+
return {
|
|
94
|
+
matched: isMatched,
|
|
95
|
+
matchedTerms: matchedTerms.slice(0, 5),
|
|
96
|
+
score: cappedScore,
|
|
97
|
+
confidence,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
recordHits(terms) {
|
|
101
|
+
for (const term of terms) {
|
|
102
|
+
const keywordIndex = this.store.keywords.findIndex(k => k.term.toLowerCase() === term.toLowerCase());
|
|
103
|
+
if (keywordIndex < 0)
|
|
104
|
+
continue;
|
|
105
|
+
const keyword = this.store.keywords[keywordIndex];
|
|
106
|
+
this.store.keywords[keywordIndex] = {
|
|
107
|
+
...keyword,
|
|
108
|
+
hitCount: (keyword.hitCount ?? 0) + 1,
|
|
109
|
+
lastHitAt: new Date().toISOString(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
recordTruePositive(term) {
|
|
114
|
+
const keyword = this.store.keywords.find(k => k.term.toLowerCase() === term.toLowerCase());
|
|
115
|
+
if (!keyword)
|
|
116
|
+
return;
|
|
117
|
+
keyword.truePositiveCount = (keyword.truePositiveCount ?? 0) + 1;
|
|
118
|
+
const keywordIndex = this.store.keywords.findIndex(k => k.term.toLowerCase() === term.toLowerCase());
|
|
119
|
+
if (keywordIndex >= 0) {
|
|
120
|
+
this.store.keywords[keywordIndex] = { ...keyword };
|
|
121
|
+
}
|
|
122
|
+
this.flush();
|
|
123
|
+
}
|
|
124
|
+
recordFalsePositive(term) {
|
|
125
|
+
const keyword = this.store.keywords.find(k => k.term.toLowerCase() === term.toLowerCase());
|
|
126
|
+
if (!keyword)
|
|
127
|
+
return;
|
|
128
|
+
keyword.falsePositiveCount = (keyword.falsePositiveCount ?? 0) + 1;
|
|
129
|
+
keyword.weight = Math.max(MIN_KEYWORD_WEIGHT, keyword.weight * 0.8);
|
|
130
|
+
keyword.lastHitAt = new Date().toISOString();
|
|
131
|
+
const keywordIndex = this.store.keywords.findIndex(k => k.term.toLowerCase() === term.toLowerCase());
|
|
132
|
+
if (keywordIndex >= 0) {
|
|
133
|
+
this.store.keywords[keywordIndex] = { ...keyword };
|
|
134
|
+
}
|
|
135
|
+
this.flush();
|
|
136
|
+
}
|
|
137
|
+
add(keyword) {
|
|
138
|
+
if (this.store.keywords.length >= MAX_CORRECTION_KEYWORDS) {
|
|
139
|
+
throw new Error('Correction keyword store limit reached (200 terms)');
|
|
140
|
+
}
|
|
141
|
+
const entry = {
|
|
142
|
+
...keyword,
|
|
143
|
+
addedAt: new Date().toISOString(),
|
|
144
|
+
};
|
|
145
|
+
this.store.keywords.push(entry);
|
|
146
|
+
this.flush();
|
|
147
|
+
}
|
|
148
|
+
updateWeight(term, weight) {
|
|
149
|
+
const keyword = this.store.keywords.find(k => k.term.toLowerCase() === term.toLowerCase());
|
|
150
|
+
if (!keyword) {
|
|
151
|
+
throw new Error(`Keyword not found: ${term}`);
|
|
152
|
+
}
|
|
153
|
+
keyword.weight = Math.max(MIN_KEYWORD_WEIGHT, Math.min(MAX_KEYWORD_WEIGHT, weight));
|
|
154
|
+
const idx = this.store.keywords.findIndex(k => k.term.toLowerCase() === term.toLowerCase());
|
|
155
|
+
if (idx >= 0) {
|
|
156
|
+
this.store.keywords[idx] = { ...keyword };
|
|
157
|
+
}
|
|
158
|
+
this.flush();
|
|
159
|
+
}
|
|
160
|
+
remove(term) {
|
|
161
|
+
const idx = this.store.keywords.findIndex(k => k.term.toLowerCase() === term.toLowerCase());
|
|
162
|
+
if (idx < 0) {
|
|
163
|
+
throw new Error(`Keyword not found: ${term}`);
|
|
164
|
+
}
|
|
165
|
+
this.store.keywords.splice(idx, 1);
|
|
166
|
+
this.flush();
|
|
167
|
+
}
|
|
168
|
+
getStore() {
|
|
169
|
+
return this.store;
|
|
170
|
+
}
|
|
171
|
+
getLastOptimizedAt() {
|
|
172
|
+
return this.store.lastOptimizedAt;
|
|
173
|
+
}
|
|
174
|
+
flush() {
|
|
175
|
+
saveCorrectionKeywordStore(this.stateDir, this.store);
|
|
176
|
+
}
|
|
177
|
+
static get(stateDir) {
|
|
178
|
+
if (!_instance || _lastStateDir !== stateDir) {
|
|
179
|
+
_instance = new CorrectionCueLearner(stateDir);
|
|
180
|
+
_lastStateDir = stateDir;
|
|
181
|
+
}
|
|
182
|
+
return _instance;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CorrectionKeyword, CorrectionKeywordStore, CorrectionMatchResult } from '@principles/core/runtime-v2';
|
|
2
|
+
export type { CorrectionKeyword, CorrectionKeywordStore, CorrectionMatchResult, };
|
|
3
|
+
export { MAX_CORRECTION_KEYWORDS, CORRECTION_SEED_KEYWORDS, } from '@principles/core/runtime-v2';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MAX_CORRECTION_KEYWORDS, CORRECTION_SEED_KEYWORDS, } from '@principles/core/runtime-v2';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type PainDictionary } from './dictionary.js';
|
|
2
|
+
export interface DetectionResult {
|
|
3
|
+
detected: boolean;
|
|
4
|
+
severity?: number;
|
|
5
|
+
ruleId?: string;
|
|
6
|
+
source: 'l1_exact' | 'l2_cache' | 'l3_async_queued' | 'l3_semantic_hit';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Orchestrates the three-layer detection funnel for pain signals.
|
|
10
|
+
*/
|
|
11
|
+
export declare class DetectionFunnel {
|
|
12
|
+
private readonly cache;
|
|
13
|
+
private asyncQueue;
|
|
14
|
+
private readonly dictionary;
|
|
15
|
+
constructor(dictionary: PainDictionary);
|
|
16
|
+
/**
|
|
17
|
+
* Detects pain in the given text using L1 (Exact), L2 (Cache), and L3 (Async).
|
|
18
|
+
*/
|
|
19
|
+
detect(text: string): DetectionResult;
|
|
20
|
+
private static computeHash;
|
|
21
|
+
private enqueueAsync;
|
|
22
|
+
/**
|
|
23
|
+
* Internal method for the worker to update the cache after a semantic hit.
|
|
24
|
+
*/
|
|
25
|
+
updateCache(text: string, result: {
|
|
26
|
+
detected: boolean;
|
|
27
|
+
severity?: number;
|
|
28
|
+
}): void;
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves and clears the current asynchronous queue.
|
|
31
|
+
*/
|
|
32
|
+
flushQueue(): string[];
|
|
33
|
+
}
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
-
import { shouldIgnorePainProtocolText
|
|
3
|
-
|
|
4
|
-
export interface DetectionResult {
|
|
5
|
-
detected: boolean;
|
|
6
|
-
severity?: number;
|
|
7
|
-
ruleId?: string;
|
|
8
|
-
source: 'l1_exact' | 'l2_cache' | 'l3_async_queued' | 'l3_semantic_hit';
|
|
9
|
-
}
|
|
10
|
-
|
|
2
|
+
import { shouldIgnorePainProtocolText } from './dictionary.js';
|
|
11
3
|
/**
|
|
12
4
|
* A simple LRU Cache implementation using Map.
|
|
13
5
|
*/
|
|
14
|
-
class SimpleLRU
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
class SimpleLRU {
|
|
7
|
+
cache;
|
|
8
|
+
maxSize;
|
|
17
9
|
constructor(maxSize = 100) {
|
|
18
10
|
this.cache = new Map();
|
|
19
11
|
this.maxSize = maxSize;
|
|
20
12
|
}
|
|
21
|
-
|
|
22
|
-
get(key: K): V | undefined {
|
|
13
|
+
get(key) {
|
|
23
14
|
const item = this.cache.get(key);
|
|
24
15
|
if (item !== undefined) {
|
|
25
16
|
// Refresh: delete and re-insert
|
|
@@ -28,11 +19,11 @@ class SimpleLRU<K, V> {
|
|
|
28
19
|
}
|
|
29
20
|
return item;
|
|
30
21
|
}
|
|
31
|
-
|
|
32
|
-
set(key: K, value: V): void {
|
|
22
|
+
set(key, value) {
|
|
33
23
|
if (this.cache.has(key)) {
|
|
34
24
|
this.cache.delete(key);
|
|
35
|
-
}
|
|
25
|
+
}
|
|
26
|
+
else if (this.cache.size >= this.maxSize) {
|
|
36
27
|
// Remove the oldest (first) item
|
|
37
28
|
const firstKey = this.cache.keys().next().value;
|
|
38
29
|
if (firstKey !== undefined) {
|
|
@@ -42,27 +33,23 @@ class SimpleLRU<K, V> {
|
|
|
42
33
|
this.cache.set(key, value);
|
|
43
34
|
}
|
|
44
35
|
}
|
|
45
|
-
|
|
46
36
|
/**
|
|
47
37
|
* Orchestrates the three-layer detection funnel for pain signals.
|
|
48
38
|
*/
|
|
49
39
|
export class DetectionFunnel {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
constructor(dictionary: PainDictionary) {
|
|
40
|
+
cache = new SimpleLRU(100);
|
|
41
|
+
asyncQueue = [];
|
|
42
|
+
dictionary;
|
|
43
|
+
constructor(dictionary) {
|
|
55
44
|
this.dictionary = dictionary;
|
|
56
45
|
}
|
|
57
|
-
|
|
58
46
|
/**
|
|
59
47
|
* Detects pain in the given text using L1 (Exact), L2 (Cache), and L3 (Async).
|
|
60
48
|
*/
|
|
61
|
-
detect(text
|
|
49
|
+
detect(text) {
|
|
62
50
|
if (shouldIgnorePainProtocolText(text)) {
|
|
63
51
|
return { detected: false, source: 'l1_exact' };
|
|
64
52
|
}
|
|
65
|
-
|
|
66
53
|
// --- Layer 1: Exact Match (Sync) ---
|
|
67
54
|
const exactMatch = this.dictionary.match(text);
|
|
68
55
|
if (exactMatch) {
|
|
@@ -73,7 +60,6 @@ export class DetectionFunnel {
|
|
|
73
60
|
source: 'l1_exact'
|
|
74
61
|
};
|
|
75
62
|
}
|
|
76
|
-
|
|
77
63
|
// --- Layer 2: LRU Cache (Sync) ---
|
|
78
64
|
const hash = DetectionFunnel.computeHash(text);
|
|
79
65
|
const cached = this.cache.get(hash);
|
|
@@ -84,39 +70,33 @@ export class DetectionFunnel {
|
|
|
84
70
|
source: 'l2_cache'
|
|
85
71
|
};
|
|
86
72
|
}
|
|
87
|
-
|
|
88
73
|
// --- Layer 3: Async Semantic Queue ---
|
|
89
74
|
this.enqueueAsync(text);
|
|
90
|
-
|
|
91
75
|
return {
|
|
92
76
|
detected: false,
|
|
93
77
|
source: 'l3_async_queued'
|
|
94
78
|
};
|
|
95
79
|
}
|
|
96
|
-
|
|
97
|
-
private static computeHash(text: string): string {
|
|
80
|
+
static computeHash(text) {
|
|
98
81
|
return createHash('sha256').update(text).digest('hex');
|
|
99
82
|
}
|
|
100
|
-
|
|
101
|
-
private enqueueAsync(text: string): void {
|
|
83
|
+
enqueueAsync(text) {
|
|
102
84
|
if (this.asyncQueue.length < 1000) {
|
|
103
85
|
this.asyncQueue.push(text);
|
|
104
86
|
}
|
|
105
87
|
// Worker will pick this up and perform semantic search via createMemorySearchTool
|
|
106
88
|
}
|
|
107
|
-
|
|
108
89
|
/**
|
|
109
90
|
* Internal method for the worker to update the cache after a semantic hit.
|
|
110
91
|
*/
|
|
111
|
-
updateCache(text
|
|
92
|
+
updateCache(text, result) {
|
|
112
93
|
const hash = DetectionFunnel.computeHash(text);
|
|
113
94
|
this.cache.set(hash, result);
|
|
114
95
|
}
|
|
115
|
-
|
|
116
96
|
/**
|
|
117
97
|
* Retrieves and clears the current asynchronous queue.
|
|
118
98
|
*/
|
|
119
|
-
flushQueue()
|
|
99
|
+
flushQueue() {
|
|
120
100
|
const queue = [...this.asyncQueue];
|
|
121
101
|
this.asyncQueue = [];
|
|
122
102
|
return queue;
|