principles-disciple 1.72.0 → 1.74.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.
Files changed (319) hide show
  1. package/INSTALL.md +1 -3
  2. package/openclaw.plugin.json +10 -5
  3. package/package.json +17 -19
  4. package/scripts/acceptance-test.mjs +16 -73
  5. package/scripts/sync-plugin.mjs +382 -77
  6. package/src/commands/archive-impl.ts +2 -1
  7. package/src/commands/capabilities.ts +2 -2
  8. package/src/commands/context.ts +2 -2
  9. package/src/commands/disable-impl.ts +2 -1
  10. package/src/commands/evolution-status.ts +16 -16
  11. package/src/commands/export.ts +12 -67
  12. package/src/commands/pain.ts +91 -1
  13. package/src/commands/principle-rollback.ts +2 -1
  14. package/src/commands/promote-impl.ts +7 -43
  15. package/src/commands/rollback-impl.ts +2 -1
  16. package/src/commands/rollback.ts +2 -1
  17. package/src/commands/samples.ts +2 -1
  18. package/src/commands/thinking-os.ts +2 -1
  19. package/src/config/errors.ts +18 -2
  20. package/src/constants/diagnostician.ts +2 -2
  21. package/src/constants/tools.ts +2 -1
  22. package/src/core/__tests__/focus-history.test.ts +210 -0
  23. package/src/core/config.ts +1 -1
  24. package/src/core/correction-cue-learner.ts +2 -136
  25. package/src/core/correction-types.ts +16 -88
  26. package/src/core/dictionary.ts +19 -20
  27. package/src/core/empathy-keyword-matcher.ts +17 -289
  28. package/src/core/empathy-types.ts +18 -229
  29. package/src/core/event-log.ts +29 -132
  30. package/src/core/evolution-reducer.ts +21 -2
  31. package/src/core/evolution-types.ts +76 -464
  32. package/src/core/file-store.ts +80 -0
  33. package/src/core/focus-history.ts +228 -955
  34. package/src/core/local-worker-routing.ts +34 -314
  35. package/src/core/merge-gate-audit.ts +0 -195
  36. package/src/core/migration.ts +0 -1
  37. package/src/core/pain-diagnostic-gate.ts +154 -0
  38. package/src/core/pain-signal.ts +21 -138
  39. package/src/core/pain.ts +15 -88
  40. package/src/core/path-resolver.ts +0 -1
  41. package/src/core/paths.ts +0 -1
  42. package/src/core/pd-task-reconciler.ts +26 -115
  43. package/src/core/pd-task-service.ts +9 -9
  44. package/src/core/pd-task-types.ts +23 -127
  45. package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
  46. package/src/core/principle-compiler/code-validator.ts +15 -42
  47. package/src/core/principle-compiler/compiler.ts +100 -15
  48. package/src/core/principle-compiler/index.ts +5 -2
  49. package/src/core/principle-compiler/template-generator.ts +4 -104
  50. package/src/core/principle-injection.ts +10 -202
  51. package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
  52. package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
  53. package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
  54. package/src/core/principle-tree-ledger-adapter.ts +145 -0
  55. package/src/core/principle-tree-ledger.ts +8 -6
  56. package/src/core/reflection/reflection-context.ts +14 -109
  57. package/src/core/replay-engine.ts +8 -500
  58. package/src/core/rule-host-helpers.ts +5 -35
  59. package/src/core/rule-host-types.ts +10 -82
  60. package/src/core/rule-host.ts +6 -63
  61. package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
  62. package/src/core/session-tracker.ts +87 -101
  63. package/src/core/shadow-observation-registry.ts +19 -48
  64. package/src/core/trajectory.ts +3 -1
  65. package/src/core/workflow-funnel-loader.ts +62 -68
  66. package/src/core/workspace-context.ts +46 -0
  67. package/src/core/workspace-dir-service.ts +1 -1
  68. package/src/core/workspace-dir-validation.ts +18 -9
  69. package/src/hooks/AGENTS.md +1 -1
  70. package/src/hooks/gate-block-helper.ts +71 -64
  71. package/src/hooks/gate.ts +183 -31
  72. package/src/hooks/lifecycle.ts +30 -32
  73. package/src/hooks/llm.ts +60 -32
  74. package/src/hooks/pain.ts +297 -103
  75. package/src/hooks/prompt.ts +400 -440
  76. package/src/hooks/subagent.ts +2 -29
  77. package/src/i18n/commands.ts +2 -10
  78. package/src/index.ts +95 -85
  79. package/src/openclaw-sdk.ts +311 -0
  80. package/src/service/central-database.ts +8 -4
  81. package/src/service/evolution-queue-migration.ts +2 -1
  82. package/src/service/evolution-worker.ts +163 -1786
  83. package/src/service/internalization-trigger-adapter.ts +302 -0
  84. package/src/service/keyword-optimization-service.ts +4 -4
  85. package/src/service/monitoring-query-service.ts +1 -215
  86. package/src/service/queue-io.ts +60 -331
  87. package/src/service/runtime-summary-service.ts +59 -16
  88. package/src/service/subagent-workflow/index.ts +0 -41
  89. package/src/service/subagent-workflow/types.ts +9 -120
  90. package/src/service/subagent-workflow/workflow-store.ts +2 -119
  91. package/src/service/workflow-watchdog.ts +0 -43
  92. package/src/types/event-payload.ts +16 -74
  93. package/src/types/event-types.ts +38 -547
  94. package/src/types/hygiene-types.ts +7 -30
  95. package/src/types/principle-tree-schema.ts +20 -222
  96. package/src/types/queue.ts +15 -70
  97. package/src/types/runtime-summary.ts +5 -49
  98. package/src/utils/io.ts +8 -20
  99. package/src/utils/retry.ts +1 -1
  100. package/src/utils/shadow-fingerprint.ts +2 -2
  101. package/src/utils/workspace-resolver.ts +50 -0
  102. package/templates/langs/en/core/AGENTS.md +7 -7
  103. package/templates/langs/en/core/BOOT.md +1 -1
  104. package/templates/langs/en/core/HEARTBEAT.md +2 -2
  105. package/templates/langs/en/principles/THINKING_OS.md +3 -2
  106. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  107. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  108. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  109. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  110. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  111. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  112. package/templates/langs/en/skills/evolve-task/SKILL.md +3 -3
  113. package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
  114. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
  115. package/templates/langs/en/skills/pd-mentor/SKILL.md +2 -3
  116. package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
  117. package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
  118. package/templates/langs/zh/core/AGENTS.md +7 -7
  119. package/templates/langs/zh/core/BOOT.md +1 -1
  120. package/templates/langs/zh/core/HEARTBEAT.md +2 -2
  121. package/templates/langs/zh/principles/THINKING_OS.md +3 -2
  122. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  123. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  124. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  125. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
  126. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  127. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  128. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  129. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
  130. package/templates/langs/zh/skills/evolve-task/SKILL.md +4 -4
  131. package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
  132. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
  133. package/templates/langs/zh/skills/pd-mentor/SKILL.md +2 -3
  134. package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
  135. package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
  136. package/tests/build-artifacts.test.ts +1 -3
  137. package/tests/commands/evolution-status.test.ts +0 -118
  138. package/tests/core/bootstrap-rules.test.ts +1 -1
  139. package/tests/core/config.test.ts +1 -1
  140. package/tests/core/event-log.test.ts +35 -0
  141. package/tests/core/evolution-engine.test.ts +610 -0
  142. package/tests/core/file-store.test.ts +102 -0
  143. package/tests/core/focus-history.test.ts +203 -11
  144. package/tests/core/merge-gate-audit.test.ts +2 -169
  145. package/tests/core/migration.test.ts +7 -7
  146. package/tests/core/model-deployment-registry.test.ts +7 -1
  147. package/tests/core/model-training-registry.test.ts +19 -0
  148. package/tests/core/observability.test.ts +0 -1
  149. package/tests/core/pain-diagnostic-gate.test.ts +498 -0
  150. package/tests/core/pain.test.ts +0 -1
  151. package/tests/core/path-resolver.test.ts +1 -1
  152. package/tests/core/paths-refactor.test.ts +0 -22
  153. package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
  154. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
  155. package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
  156. package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
  157. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
  158. package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
  159. package/tests/core/reflection-context.test.ts +0 -14
  160. package/tests/core/replay-engine.test.ts +127 -215
  161. package/tests/core/rule-host-helpers.test.ts +2 -2
  162. package/tests/core/rule-implementation-runtime.test.ts +0 -27
  163. package/tests/core/workflow-funnel-loader.test.ts +162 -0
  164. package/tests/core/workspace-context.test.ts +2 -2
  165. package/tests/core/workspace-dir-validation.test.ts +8 -1
  166. package/tests/core-anti-growth.test.ts +191 -0
  167. package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
  168. package/tests/hooks/confirm-first-removal.test.ts +188 -0
  169. package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
  170. package/tests/hooks/gate-auto-correct.test.ts +665 -0
  171. package/tests/hooks/gate-no-path-write-tool.test.ts +172 -0
  172. package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
  173. package/tests/hooks/pain.test.ts +269 -12
  174. package/tests/hooks/prompt-characterization.test.ts +500 -0
  175. package/tests/hooks/prompt-size-guard.test.ts +32 -17
  176. package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
  177. package/tests/index.test.ts +94 -1
  178. package/tests/integration/auto-entry-gate.test.ts +248 -0
  179. package/tests/integration/internalization-trigger-guard.test.ts +69 -0
  180. package/tests/integration/m8-legacy-paths.test.ts +63 -0
  181. package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
  182. package/tests/plugin-config-resolution-cutover.test.ts +359 -0
  183. package/tests/runtime-v2-discovery-guard.test.ts +154 -0
  184. package/tests/service/central-database.test.ts +457 -0
  185. package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
  186. package/tests/service/evolution-worker.timeout.test.ts +11 -129
  187. package/tests/service/internalization-trigger-adapter.test.ts +251 -0
  188. package/tests/service/monitoring-query-service.test.ts +1 -47
  189. package/tests/service/queue-io.test.ts +1 -62
  190. package/tests/service/runtime-summary-service.test.ts +3 -1
  191. package/tests/service/workflow-watchdog.test.ts +0 -91
  192. package/tests/utils/file-lock.test.ts +5 -3
  193. package/tests/utils/session-key.test.ts +52 -0
  194. package/tests/utils/subagent-probe.test.ts +48 -1
  195. package/vitest.config.ts +4 -11
  196. package/.planning/codebase/ARCHITECTURE.md +0 -157
  197. package/.planning/codebase/CONCERNS.md +0 -145
  198. package/.planning/codebase/CONVENTIONS.md +0 -148
  199. package/.planning/codebase/INTEGRATIONS.md +0 -81
  200. package/.planning/codebase/STACK.md +0 -87
  201. package/.planning/codebase/STRUCTURE.md +0 -193
  202. package/.planning/codebase/TESTING.md +0 -243
  203. package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
  204. package/docs/COMMAND_REFERENCE.md +0 -76
  205. package/docs/COMMAND_REFERENCE_EN.md +0 -79
  206. package/scripts/build-web.mjs +0 -46
  207. package/scripts/diagnose-nocturnal.mjs +0 -537
  208. package/scripts/seed-nocturnal-scenarios.mjs +0 -384
  209. package/src/commands/nocturnal-review.ts +0 -322
  210. package/src/commands/nocturnal-rollout.ts +0 -790
  211. package/src/commands/nocturnal-train.ts +0 -986
  212. package/src/commands/pd-reflect.ts +0 -88
  213. package/src/core/adaptive-thresholds.ts +0 -478
  214. package/src/core/diagnostician-task-store.ts +0 -192
  215. package/src/core/nocturnal-arbiter.ts +0 -715
  216. package/src/core/nocturnal-artifact-lineage.ts +0 -116
  217. package/src/core/nocturnal-artificer.ts +0 -257
  218. package/src/core/nocturnal-candidate-scoring.ts +0 -530
  219. package/src/core/nocturnal-compliance.ts +0 -1146
  220. package/src/core/nocturnal-dataset.ts +0 -763
  221. package/src/core/nocturnal-executability.ts +0 -428
  222. package/src/core/nocturnal-export.ts +0 -499
  223. package/src/core/nocturnal-paths.ts +0 -240
  224. package/src/core/nocturnal-reasoning-deriver.ts +0 -343
  225. package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
  226. package/src/core/nocturnal-snapshot-contract.ts +0 -99
  227. package/src/core/nocturnal-trajectory-extractor.ts +0 -512
  228. package/src/core/nocturnal-trinity-types.ts +0 -218
  229. package/src/core/nocturnal-trinity.ts +0 -2680
  230. package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
  231. package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
  232. package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
  233. package/src/http/principles-console-route.ts +0 -709
  234. package/src/service/central-health-service.ts +0 -49
  235. package/src/service/central-overview-service.ts +0 -138
  236. package/src/service/control-ui-query-service.ts +0 -900
  237. package/src/service/cooldown-strategy.ts +0 -97
  238. package/src/service/evolution-pain-context.ts +0 -79
  239. package/src/service/evolution-query-service.ts +0 -407
  240. package/src/service/health-query-service.ts +0 -1038
  241. package/src/service/nocturnal-config.ts +0 -214
  242. package/src/service/nocturnal-runtime.ts +0 -734
  243. package/src/service/nocturnal-service.ts +0 -1605
  244. package/src/service/nocturnal-target-selector.ts +0 -545
  245. package/src/service/sleep-cycle.ts +0 -157
  246. package/src/service/startup-reconciler.ts +0 -112
  247. package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
  248. package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
  249. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
  250. package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
  251. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
  252. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
  253. package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
  254. package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
  255. package/src/tools/write-pain-flag.ts +0 -215
  256. package/templates/langs/en/skills/plan-script/SKILL.md +0 -32
  257. package/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
  258. package/tests/commands/nocturnal-review.test.ts +0 -448
  259. package/tests/commands/nocturnal-train.test.ts +0 -97
  260. package/tests/commands/pd-reflect.test.ts +0 -49
  261. package/tests/core/adaptive-thresholds.test.ts +0 -261
  262. package/tests/core/nocturnal-arbiter.test.ts +0 -559
  263. package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
  264. package/tests/core/nocturnal-artificer.test.ts +0 -241
  265. package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
  266. package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
  267. package/tests/core/nocturnal-compliance.test.ts +0 -646
  268. package/tests/core/nocturnal-dataset.test.ts +0 -892
  269. package/tests/core/nocturnal-e2e.test.ts +0 -234
  270. package/tests/core/nocturnal-executability.test.ts +0 -357
  271. package/tests/core/nocturnal-export.test.ts +0 -517
  272. package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
  273. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
  274. package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
  275. package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
  276. package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
  277. package/tests/core/nocturnal-trinity.test.ts +0 -2053
  278. package/tests/core/pain-auto-repair.test.ts +0 -96
  279. package/tests/core/pain-integration.test.ts +0 -510
  280. package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
  281. package/tests/http/principles-console-route.test.ts +0 -162
  282. package/tests/integration/chaos-resilience.test.ts +0 -348
  283. package/tests/integration/empathy-workflow-integration.test.ts +0 -626
  284. package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
  285. package/tests/service/control-ui-query-service.test.ts +0 -121
  286. package/tests/service/cooldown-strategy.test.ts +0 -164
  287. package/tests/service/data-endpoints-regression.test.ts +0 -834
  288. package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
  289. package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
  290. package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
  291. package/tests/service/nocturnal-runtime.test.ts +0 -473
  292. package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
  293. package/tests/service/nocturnal-target-selector.test.ts +0 -615
  294. package/tests/service/startup-reconciler.test.ts +0 -148
  295. package/tests/tools/write-pain-flag.test.ts +0 -358
  296. package/ui/src/App.tsx +0 -45
  297. package/ui/src/api.ts +0 -220
  298. package/ui/src/charts.tsx +0 -955
  299. package/ui/src/components/ErrorState.tsx +0 -6
  300. package/ui/src/components/Loading.tsx +0 -13
  301. package/ui/src/components/ProtectedRoute.tsx +0 -12
  302. package/ui/src/components/Shell.tsx +0 -91
  303. package/ui/src/components/WorkspaceConfig.tsx +0 -178
  304. package/ui/src/components/index.ts +0 -5
  305. package/ui/src/context/auth.tsx +0 -80
  306. package/ui/src/context/theme.tsx +0 -66
  307. package/ui/src/hooks/useAutoRefresh.ts +0 -39
  308. package/ui/src/i18n/ui.ts +0 -473
  309. package/ui/src/main.tsx +0 -16
  310. package/ui/src/pages/EvolutionPage.tsx +0 -333
  311. package/ui/src/pages/FeedbackPage.tsx +0 -138
  312. package/ui/src/pages/GateMonitorPage.tsx +0 -136
  313. package/ui/src/pages/LoginPage.tsx +0 -89
  314. package/ui/src/pages/OverviewPage.tsx +0 -599
  315. package/ui/src/pages/SamplesPage.tsx +0 -174
  316. package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
  317. package/ui/src/styles.css +0 -2020
  318. package/ui/src/types.ts +0 -384
  319. package/ui/src/utils/format.ts +0 -15
@@ -1,97 +0,0 @@
1
- /**
2
- * Cooldown Strategy -- Tiered escalation for persistent task failures
3
- * ===========================================================
4
- *
5
- * Manages cooldown escalation state persisted to nocturnal-runtime.json.
6
- * When the failure classifier (failure-classifier.ts) detects persistent
7
- * failure (3+ consecutive failures), this module applies escalating
8
- * cooldowns: 30min -> 4h -> 24h (cap).
9
- *
10
- * State is stored in NocturnalRuntimeState.taskFailureState, keyed by
11
- * taskKind string. Uses exported readState/writeState from
12
- * nocturnal-runtime.ts for atomic file access with locking.
13
- */
14
-
15
- import { readState as readStateAsync, readStateSync, writeState } from './nocturnal-runtime.js';
16
- import type { CooldownEscalationConfig } from './nocturnal-config.js';
17
- import { loadCooldownEscalationConfig } from './nocturnal-config.js';
18
- import type { ClassifiableTaskKind } from './failure-classifier.js';
19
-
20
- /**
21
- * Record a persistent failure and escalate the cooldown tier.
22
- * Called when the failure classifier detects persistent failure pattern.
23
- *
24
- * State transitions:
25
- * No state -> Tier 1 (30min cooldown)
26
- * Tier 1 -> Tier 2 (4h cooldown)
27
- * Tier 2 -> Tier 3 (24h cooldown)
28
- * Tier 3 -> Tier 3 (24h cooldown, capped)
29
- */
30
- export async function recordPersistentFailure(
31
- stateDir: string,
32
- taskKind: ClassifiableTaskKind,
33
- config?: CooldownEscalationConfig,
34
- classifierCount?: number,
35
- ): Promise<void> {
36
- const resolvedConfig = config ?? loadCooldownEscalationConfig(stateDir);
37
-
38
- const state = await readStateAsync(stateDir);
39
- if (!state.taskFailureState) state.taskFailureState = {};
40
-
41
- const current = state.taskFailureState[taskKind] ?? {
42
- consecutiveFailures: 0,
43
- escalationTier: 0,
44
- };
45
-
46
- current.consecutiveFailures = classifierCount ?? (current.consecutiveFailures + 1);
47
- current.escalationTier = Math.min(current.escalationTier + 1, 3);
48
-
49
- const tierKey = current.escalationTier as 1 | 2 | 3;
50
- const durationMs = resolvedConfig[`tier${tierKey}_ms` as keyof CooldownEscalationConfig] as number;
51
- current.cooldownUntil = new Date(Date.now() + durationMs).toISOString();
52
-
53
- state.taskFailureState[taskKind] = current;
54
- await writeState(stateDir, state);
55
- }
56
-
57
- /**
58
- * Reset failure state for a task kind on successful completion.
59
- * Resets both consecutiveFailures and escalationTier to 0.
60
- */
61
- export async function resetFailureState(
62
- stateDir: string,
63
- taskKind: ClassifiableTaskKind,
64
- ): Promise<void> {
65
- const state = await readStateAsync(stateDir);
66
- if (!state.taskFailureState?.[taskKind]) return; // No state to reset
67
-
68
- state.taskFailureState[taskKind] = {
69
- consecutiveFailures: 0,
70
- escalationTier: 0,
71
- };
72
- await writeState(stateDir, state);
73
- }
74
-
75
- /**
76
- * Check if a task kind is currently in cooldown.
77
- * Returns remaining cooldown duration or 0 if not in cooldown.
78
- */
79
- export function isTaskKindInCooldown(
80
- stateDir: string,
81
- taskKind: ClassifiableTaskKind,
82
- ): { inCooldown: boolean; remainingMs: number; cooldownUntil: string | null } {
83
- const state = readStateSync(stateDir);
84
-
85
- const failureState = state.taskFailureState?.[taskKind];
86
- if (!failureState?.cooldownUntil) {
87
- return { inCooldown: false, remainingMs: 0, cooldownUntil: null };
88
- }
89
-
90
- const cooldownEnd = new Date(failureState.cooldownUntil).getTime();
91
- const remaining = cooldownEnd - Date.now();
92
- if (remaining <= 0) {
93
- return { inCooldown: false, remainingMs: 0, cooldownUntil: null };
94
- }
95
-
96
- return { inCooldown: true, remainingMs: remaining, cooldownUntil: failureState.cooldownUntil };
97
- }
@@ -1,79 +0,0 @@
1
- /**
2
- * Evolution Pain Context Reader
3
- *
4
- * Reads and processes pain signal context for task enrichment.
5
- * Extracted from evolution-worker.ts.
6
- */
7
-
8
- import type { WorkspaceContext } from '../core/workspace-context.js';
9
- import { readPainFlagContract } from '../core/pain.js';
10
- import type { EvolutionQueueItem } from './evolution-queue-migration.js';
11
- import type { RecentPainContext } from './evolution-queue-migration.js';
12
- import { SLEEP_REFLECTION_DEDUP_WINDOW_MS } from './queue-io.js';
13
-
14
- /**
15
- * Read recent pain context from PAIN_FLAG file.
16
- * Extracts session_id to link to trajectory DB.
17
- * Returns structured pain metadata for attaching to sleep_reflection tasks.
18
- * Returns null if no pain flag exists.
19
- */
20
- export function readRecentPainContext(wctx: WorkspaceContext): RecentPainContext {
21
- const contract = readPainFlagContract(wctx.workspaceDir);
22
- if (contract.status !== 'valid') {
23
- return { mostRecent: null, recentPainCount: 0, recentMaxPainScore: 0 };
24
- }
25
-
26
- try {
27
- const score = parseInt(contract.data.score ?? '0', 10) || 0;
28
- const source = contract.data.source ?? '';
29
- const reason = contract.data.reason ?? '';
30
- const timestamp = contract.data.time ?? '';
31
- const sessionId = contract.data.session_id ?? '';
32
-
33
- if (score > 0) {
34
- return {
35
- mostRecent: { score, source, reason, timestamp, sessionId },
36
- recentPainCount: 1,
37
- recentMaxPainScore: score,
38
- };
39
- }
40
- } catch {
41
- // Best effort — non-fatal
42
- }
43
-
44
- return { mostRecent: null, recentPainCount: 0, recentMaxPainScore: 0 };
45
- }
46
-
47
- /**
48
- * Build a dedup key from pain context.
49
- * Returns null when no pain context is available (bypasses dedup).
50
- */
51
- export function buildPainSourceKey(
52
- painCtx: ReturnType<typeof readRecentPainContext>,
53
- ): string | null {
54
- if (!painCtx.mostRecent) return null;
55
- return `${painCtx.mostRecent.source}::${painCtx.mostRecent.reason?.slice(0, 50) ?? ''}`;
56
- }
57
-
58
- /**
59
- * Check whether a similar sleep_reflection task completed recently.
60
- * Phase 3c: Prevents redundant reflections of the same underlying issue.
61
- */
62
- export function hasRecentSimilarReflection(
63
- queue: EvolutionQueueItem[],
64
- painSourceKey: string,
65
- now: number,
66
- ): EvolutionQueueItem | null {
67
- return queue.find((t) => {
68
- if (t.taskKind !== 'sleep_reflection') return false;
69
- // Only match completed tasks (exclude failed to allow retries)
70
- if (t.status !== 'completed') return false;
71
- if (!t.completed_at) return false;
72
- const age = now - new Date(t.completed_at).getTime();
73
- if (age > SLEEP_REFLECTION_DEDUP_WINDOW_MS) return false;
74
- const taskPainKey = buildPainSourceKey(t.recentPainContext ?? { mostRecent: null, recentPainCount: 0, recentMaxPainScore: 0 });
75
- // If either side has no pain context, they don't match
76
- if (!taskPainKey) return false;
77
- return taskPainKey === painSourceKey;
78
- }) ?? null;
79
- }
@@ -1,407 +0,0 @@
1
- /**
2
- * EvolutionQueryService - 进化流程查询服务
3
- *
4
- * 提供 WebUI 所需的查询 API:
5
- * - getTasks() - 获取任务列表
6
- * - getEvents() - 获取事件流
7
- * - getTrace() - 获取完整追踪
8
- * - getStats() - 获取统计数据
9
- */
10
-
11
- import type { TrajectoryDatabase, EvolutionTaskRecord } from '../core/trajectory.js';
12
- import { STAGE_LABELS, STAGE_COLORS } from '../core/evolution-logger.js';
13
-
14
- export interface TaskListFilters {
15
- status?: string;
16
- dateFrom?: string;
17
- dateTo?: string;
18
- page?: number;
19
- pageSize?: number;
20
- }
21
-
22
- export interface EventFilters {
23
- traceId?: string;
24
- stage?: string;
25
- limit?: number;
26
- offset?: number;
27
- }
28
-
29
- export interface TasksResponse {
30
- items: {
31
- taskId: string;
32
- traceId: string;
33
- source: string;
34
- reason: string | null;
35
- score: number;
36
- status: string;
37
- enqueuedAt: string | null;
38
- startedAt: string | null;
39
- completedAt: string | null;
40
- duration: number | null;
41
- resolution: string | null;
42
- eventCount: number;
43
- createdAt: string;
44
- }[];
45
- pagination: {
46
- page: number;
47
- pageSize: number;
48
- total: number;
49
- totalPages: number;
50
- };
51
- }
52
-
53
- export interface EventsResponse {
54
- items: {
55
- id: number;
56
- traceId: string;
57
- taskId: string | null;
58
- stage: string;
59
- stageLabel: string;
60
- stageColor: string;
61
- level: string;
62
- message: string;
63
- summary: string | null;
64
- metadata: Record<string, unknown>;
65
- createdAt: string;
66
- }[];
67
- pagination: {
68
- limit: number;
69
- offset: number;
70
- hasMore: boolean;
71
- };
72
- }
73
-
74
- export interface TraceDetailResponse {
75
- traceId: string;
76
- task: {
77
- taskId: string;
78
- traceId: string;
79
- source: string;
80
- reason: string | null;
81
- score: number;
82
- status: string;
83
- enqueuedAt: string | null;
84
- startedAt: string | null;
85
- completedAt: string | null;
86
- duration: number | null;
87
- resolution: string | null;
88
- createdAt: string;
89
- updatedAt: string;
90
- };
91
- events: {
92
- id: number;
93
- traceId: string;
94
- taskId: string | null;
95
- stage: string;
96
- stageLabel: string;
97
- stageColor: string;
98
- level: string;
99
- message: string;
100
- summary: string | null;
101
- metadata: Record<string, unknown>;
102
- createdAt: string;
103
- }[];
104
- timeline: {
105
- stage: string;
106
- stageLabel: string;
107
- stageColor: string;
108
- timestamp: string;
109
- message: string;
110
- summary: string | null;
111
- }[];
112
- }
113
-
114
- export interface EvolutionStatsResponse {
115
- total: number;
116
- pending: number;
117
- inProgress: number;
118
- completed: number;
119
- failed: number;
120
- recentActivity: {
121
- day: string;
122
- created: number;
123
- completed: number;
124
- }[];
125
- stageDistribution: {
126
- stage: string;
127
- stageLabel: string;
128
- count: number;
129
- }[];
130
- }
131
-
132
- /**
133
- * 计算任务持续时间(毫秒)
134
- */
135
- function calculateDuration(task: EvolutionTaskRecord): number | null {
136
- if (!task.startedAt) return null;
137
- const start = new Date(task.startedAt).getTime();
138
- const end = task.completedAt ? new Date(task.completedAt).getTime() : Date.now();
139
- return end - start;
140
- }
141
-
142
- /**
143
- * EvolutionQueryService 类
144
- * 封装进化流程的查询逻辑
145
- */
146
- export class EvolutionQueryService {
147
- private readonly trajectory: TrajectoryDatabase;
148
-
149
- constructor(trajectory: TrajectoryDatabase) {
150
- this.trajectory = trajectory;
151
- }
152
-
153
- /**
154
- * 释放资源
155
- * 注意:不关闭 trajectory,因为它是单例由 TrajectoryRegistry 管理
156
- */
157
-
158
-
159
- dispose(): void {
160
- // EvolutionQueryService 不拥有 trajectory,所以不关闭它
161
- // trajectory 是由 TrajectoryRegistry 管理的单例
162
- }
163
-
164
- /**
165
- * 获取任务列表(带分页、筛选)
166
- */
167
- getTasks(filters: TaskListFilters = {}): TasksResponse {
168
- const page = filters.page ?? 1;
169
- const pageSize = filters.pageSize ?? 20;
170
- const offset = (page - 1) * pageSize;
171
-
172
- // 获取任务列表
173
- const tasks = this.trajectory.listEvolutionTasks({
174
- status: filters.status,
175
- dateFrom: filters.dateFrom,
176
- dateTo: filters.dateTo,
177
- limit: pageSize + 1, // 多取一条判断 hasMore
178
- offset,
179
- });
180
-
181
- // 获取总数(简化实现,使用全量计数)
182
- const allTasks = this.trajectory.listEvolutionTasks({
183
- status: filters.status,
184
- dateFrom: filters.dateFrom,
185
- dateTo: filters.dateTo,
186
- limit: 10000,
187
- offset: 0,
188
- });
189
- const total = allTasks.length;
190
- const totalPages = Math.ceil(total / pageSize);
191
-
192
- // 组装响应
193
- const items = tasks.slice(0, pageSize).map((task) => {
194
- // 获取事件数量
195
- const events = this.trajectory.listEvolutionEvents(task.traceId, { limit: 1000 });
196
-
197
- return {
198
- taskId: task.taskId,
199
- traceId: task.traceId,
200
- source: task.source,
201
- reason: task.reason,
202
- score: task.score,
203
- status: task.status,
204
- enqueuedAt: task.enqueuedAt,
205
- startedAt: task.startedAt,
206
- completedAt: task.completedAt,
207
- duration: calculateDuration(task),
208
- resolution: task.resolution,
209
- eventCount: events.length,
210
- createdAt: task.createdAt,
211
- };
212
- });
213
-
214
- return {
215
- items,
216
- pagination: {
217
- page,
218
- pageSize,
219
- total,
220
- totalPages,
221
- },
222
- };
223
- }
224
-
225
- /**
226
- * 获取事件流
227
- */
228
- getEvents(filters: EventFilters = {}): EventsResponse {
229
- const limit = filters.limit ?? 100;
230
- const offset = filters.offset ?? 0;
231
-
232
- // 获取更多事件以支持 stage 过滤
233
- const fetchLimit = filters.stage ? 500 : limit + 1;
234
- const events = this.trajectory.listEvolutionEvents(filters.traceId, {
235
- limit: fetchLimit,
236
- offset: 0, // 从头获取,后续再过滤和分页
237
- });
238
-
239
- // 应用 stage 过滤
240
- let filteredEvents = events;
241
- if (filters.stage) {
242
- filteredEvents = events.filter(event => event.stage === filters.stage);
243
- }
244
-
245
- // 应用分页
246
- const hasMore = filteredEvents.length > offset + limit;
247
- const items = filteredEvents.slice(offset, offset + limit).map((event) => ({
248
- id: event.id,
249
- traceId: event.traceId,
250
- taskId: event.taskId,
251
- stage: event.stage,
252
- stageLabel: STAGE_LABELS[event.stage as keyof typeof STAGE_LABELS] || event.stage,
253
- stageColor: STAGE_COLORS[event.stage as keyof typeof STAGE_COLORS] || '#6b7280',
254
- level: event.level,
255
- message: event.message,
256
- summary: event.summary,
257
- metadata: event.metadata,
258
- createdAt: event.createdAt,
259
- }));
260
-
261
- return {
262
- items,
263
- pagination: {
264
- limit,
265
- offset,
266
- hasMore,
267
- },
268
- };
269
- }
270
-
271
- /**
272
- * 获取完整追踪(单个 trace 的所有事件)
273
- */
274
- getTrace(traceId: string): TraceDetailResponse | null {
275
- // 获取任务信息
276
- const task = this.trajectory.getEvolutionTaskByTraceId(traceId);
277
- if (!task) return null;
278
-
279
- // 获取所有事件
280
- const events = this.trajectory.listEvolutionEvents(traceId, { limit: 1000 });
281
-
282
- // 构建时间线
283
- const timeline = events.map((event) => ({
284
- stage: event.stage,
285
- stageLabel: STAGE_LABELS[event.stage as keyof typeof STAGE_LABELS] || event.stage,
286
- stageColor: STAGE_COLORS[event.stage as keyof typeof STAGE_COLORS] || '#6b7280',
287
- timestamp: event.createdAt,
288
- message: event.message,
289
- summary: event.summary,
290
- }));
291
-
292
- return {
293
- traceId,
294
- task: {
295
- taskId: task.taskId,
296
- traceId: task.traceId,
297
- source: task.source,
298
- reason: task.reason,
299
- score: task.score,
300
- status: task.status,
301
- enqueuedAt: task.enqueuedAt,
302
- startedAt: task.startedAt,
303
- completedAt: task.completedAt,
304
- duration: calculateDuration(task),
305
- resolution: task.resolution,
306
- createdAt: task.createdAt,
307
- updatedAt: task.updatedAt,
308
- },
309
- events: events.map((event) => ({
310
- id: event.id,
311
- traceId: event.traceId,
312
- taskId: event.taskId,
313
- stage: event.stage,
314
- stageLabel: STAGE_LABELS[event.stage as keyof typeof STAGE_LABELS] || event.stage,
315
- stageColor: STAGE_COLORS[event.stage as keyof typeof STAGE_COLORS] || '#6b7280',
316
- level: event.level,
317
- message: event.message,
318
- summary: event.summary,
319
- metadata: event.metadata,
320
- createdAt: event.createdAt,
321
- })),
322
- timeline,
323
- };
324
- }
325
-
326
- /**
327
- * 获取统计数据
328
- */
329
- getStats(days = 30): EvolutionStatsResponse {
330
- // 获取基础统计
331
- const stats = this.trajectory.getEvolutionStats();
332
-
333
- // 获取近期活动
334
- const now = new Date();
335
- const daysAgo = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
336
- const recentTasks = this.trajectory.listEvolutionTasks({
337
- dateFrom: daysAgo.toISOString(),
338
- limit: 10000,
339
- });
340
-
341
- // 按天分组
342
- const activityByDay = new Map<string, { created: number; completed: number }>();
343
- for (let i = 0; i < days; i++) {
344
- const day = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
345
- const [dayStr] = day.toISOString().split('T');
346
- activityByDay.set(dayStr, { created: 0, completed: 0 });
347
- }
348
-
349
- for (const task of recentTasks) {
350
- const [createdDay] = task.createdAt.split('T');
351
- if (activityByDay.has(createdDay)) {
352
-
353
- activityByDay.get(createdDay)!.created++;
354
- }
355
- if (task.completedAt) {
356
- const [completedDay] = task.completedAt.split('T');
357
- if (activityByDay.has(completedDay)) {
358
-
359
- activityByDay.get(completedDay)!.completed++;
360
- }
361
- }
362
- }
363
-
364
- const recentActivity = Array.from(activityByDay.entries())
365
- .map(([day, data]) => ({ day, ...data }))
366
- .sort((a, b) => a.day.localeCompare(b.day));
367
-
368
- // 获取阶段分布
369
- const allEvents = this.trajectory.listEvolutionEvents(undefined, { limit: 10000 });
370
- const stageCount = new Map<string, number>();
371
- for (const event of allEvents) {
372
- stageCount.set(event.stage, (stageCount.get(event.stage) || 0) + 1);
373
- }
374
-
375
- const stageDistribution = Array.from(stageCount.entries())
376
- .map(([stage, count]) => ({
377
- stage,
378
- stageLabel: STAGE_LABELS[stage as keyof typeof STAGE_LABELS] || stage,
379
- count,
380
- }))
381
- .sort((a, b) => b.count - a.count);
382
-
383
- return {
384
- ...stats,
385
- recentActivity,
386
- stageDistribution,
387
- };
388
- }
389
- }
390
-
391
- // 单例缓存
392
- const serviceCache = new Map<string, EvolutionQueryService>();
393
-
394
- /**
395
- * 获取 EvolutionQueryService 实例(单例)
396
- */
397
- export function getEvolutionQueryService(trajectory: TrajectoryDatabase): EvolutionQueryService {
398
- // 使用 trajectory 的 dbPath 作为缓存键
399
- const cacheKey = (trajectory as unknown as { dbPath?: string }).dbPath || 'default';
400
- const cached = serviceCache.get(cacheKey);
401
- if (cached) {
402
- return cached;
403
- }
404
- const service = new EvolutionQueryService(trajectory);
405
- serviceCache.set(cacheKey, service);
406
- return service;
407
- }