principles-disciple 1.72.0 → 1.73.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 (309) hide show
  1. package/openclaw.plugin.json +10 -5
  2. package/package.json +17 -19
  3. package/scripts/acceptance-test.mjs +16 -73
  4. package/scripts/sync-plugin.mjs +382 -77
  5. package/src/commands/archive-impl.ts +2 -1
  6. package/src/commands/capabilities.ts +2 -2
  7. package/src/commands/context.ts +2 -2
  8. package/src/commands/disable-impl.ts +2 -1
  9. package/src/commands/evolution-status.ts +16 -16
  10. package/src/commands/export.ts +12 -67
  11. package/src/commands/pain.ts +91 -1
  12. package/src/commands/principle-rollback.ts +2 -1
  13. package/src/commands/promote-impl.ts +7 -43
  14. package/src/commands/rollback-impl.ts +2 -1
  15. package/src/commands/rollback.ts +2 -1
  16. package/src/commands/samples.ts +2 -1
  17. package/src/commands/thinking-os.ts +2 -1
  18. package/src/config/errors.ts +18 -2
  19. package/src/constants/diagnostician.ts +2 -2
  20. package/src/constants/tools.ts +2 -1
  21. package/src/core/__tests__/focus-history.test.ts +210 -0
  22. package/src/core/config.ts +1 -1
  23. package/src/core/confirm-first-gate.ts +255 -0
  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 +38 -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/pain-diagnostic-gate.ts +154 -0
  37. package/src/core/pain-signal.ts +21 -138
  38. package/src/core/pain.ts +15 -88
  39. package/src/core/pd-task-reconciler.ts +26 -115
  40. package/src/core/pd-task-service.ts +9 -9
  41. package/src/core/pd-task-types.ts +23 -127
  42. package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
  43. package/src/core/principle-compiler/code-validator.ts +15 -42
  44. package/src/core/principle-compiler/compiler.ts +100 -15
  45. package/src/core/principle-compiler/index.ts +5 -2
  46. package/src/core/principle-compiler/template-generator.ts +4 -104
  47. package/src/core/principle-injection.ts +10 -202
  48. package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
  49. package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
  50. package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
  51. package/src/core/principle-tree-ledger-adapter.ts +145 -0
  52. package/src/core/principle-tree-ledger.ts +8 -6
  53. package/src/core/reflection/reflection-context.ts +14 -109
  54. package/src/core/replay-engine.ts +8 -500
  55. package/src/core/rule-host-helpers.ts +5 -35
  56. package/src/core/rule-host-types.ts +10 -82
  57. package/src/core/rule-host.ts +6 -63
  58. package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
  59. package/src/core/session-tracker.ts +87 -101
  60. package/src/core/shadow-observation-registry.ts +19 -48
  61. package/src/core/trajectory.ts +3 -1
  62. package/src/core/workflow-funnel-loader.ts +62 -68
  63. package/src/core/workspace-context.ts +46 -0
  64. package/src/core/workspace-dir-service.ts +1 -1
  65. package/src/core/workspace-dir-validation.ts +18 -9
  66. package/src/hooks/AGENTS.md +1 -1
  67. package/src/hooks/gate-block-helper.ts +46 -44
  68. package/src/hooks/gate.ts +207 -7
  69. package/src/hooks/lifecycle.ts +30 -32
  70. package/src/hooks/llm.ts +60 -32
  71. package/src/hooks/pain.ts +297 -103
  72. package/src/hooks/prompt.ts +459 -439
  73. package/src/hooks/subagent.ts +2 -29
  74. package/src/i18n/commands.ts +2 -10
  75. package/src/index.ts +95 -85
  76. package/src/openclaw-sdk.ts +311 -0
  77. package/src/service/central-database.ts +8 -4
  78. package/src/service/evolution-queue-migration.ts +2 -1
  79. package/src/service/evolution-worker.ts +163 -1786
  80. package/src/service/internalization-trigger-adapter.ts +302 -0
  81. package/src/service/keyword-optimization-service.ts +4 -4
  82. package/src/service/monitoring-query-service.ts +1 -215
  83. package/src/service/queue-io.ts +60 -331
  84. package/src/service/runtime-summary-service.ts +59 -16
  85. package/src/service/subagent-workflow/index.ts +0 -41
  86. package/src/service/subagent-workflow/types.ts +9 -120
  87. package/src/service/subagent-workflow/workflow-store.ts +2 -119
  88. package/src/service/workflow-watchdog.ts +0 -43
  89. package/src/types/event-payload.ts +16 -74
  90. package/src/types/event-types.ts +39 -547
  91. package/src/types/hygiene-types.ts +7 -30
  92. package/src/types/principle-tree-schema.ts +20 -222
  93. package/src/types/queue.ts +15 -70
  94. package/src/types/runtime-summary.ts +5 -49
  95. package/src/utils/io.ts +10 -0
  96. package/src/utils/retry.ts +1 -1
  97. package/src/utils/shadow-fingerprint.ts +2 -2
  98. package/src/utils/workspace-resolver.ts +50 -0
  99. package/templates/langs/en/core/AGENTS.md +2 -2
  100. package/templates/langs/en/core/BOOT.md +1 -1
  101. package/templates/langs/en/core/HEARTBEAT.md +2 -2
  102. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  103. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  104. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  105. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  106. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  107. package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
  108. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  109. package/templates/langs/en/skills/evolve-task/SKILL.md +1 -1
  110. package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
  111. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
  112. package/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  113. package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
  114. package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
  115. package/templates/langs/zh/core/AGENTS.md +2 -2
  116. package/templates/langs/zh/core/BOOT.md +1 -1
  117. package/templates/langs/zh/core/HEARTBEAT.md +2 -2
  118. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  119. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  120. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  121. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
  122. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  123. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  124. package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
  125. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  126. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
  127. package/templates/langs/zh/skills/evolve-task/SKILL.md +2 -2
  128. package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
  129. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
  130. package/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  131. package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
  132. package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
  133. package/tests/build-artifacts.test.ts +1 -3
  134. package/tests/commands/evolution-status.test.ts +0 -118
  135. package/tests/core/bootstrap-rules.test.ts +1 -1
  136. package/tests/core/config.test.ts +1 -1
  137. package/tests/core/event-log.test.ts +35 -0
  138. package/tests/core/evolution-engine.test.ts +610 -0
  139. package/tests/core/file-store.test.ts +102 -0
  140. package/tests/core/focus-history.test.ts +203 -11
  141. package/tests/core/merge-gate-audit.test.ts +2 -169
  142. package/tests/core/model-deployment-registry.test.ts +7 -1
  143. package/tests/core/model-training-registry.test.ts +19 -0
  144. package/tests/core/observability.test.ts +0 -1
  145. package/tests/core/pain-diagnostic-gate.test.ts +498 -0
  146. package/tests/core/pain.test.ts +0 -1
  147. package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
  148. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
  149. package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
  150. package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
  151. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
  152. package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
  153. package/tests/core/reflection-context.test.ts +0 -14
  154. package/tests/core/replay-engine.test.ts +127 -215
  155. package/tests/core/rule-host-helpers.test.ts +2 -2
  156. package/tests/core/rule-implementation-runtime.test.ts +0 -27
  157. package/tests/core/workflow-funnel-loader.test.ts +162 -0
  158. package/tests/core/workspace-dir-validation.test.ts +8 -1
  159. package/tests/core-anti-growth.test.ts +192 -0
  160. package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
  161. package/tests/hooks/confirm-first-gate.test.ts +333 -0
  162. package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
  163. package/tests/hooks/gate-auto-correct.test.ts +665 -0
  164. package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
  165. package/tests/hooks/pain.test.ts +269 -12
  166. package/tests/hooks/prompt-characterization.test.ts +500 -0
  167. package/tests/hooks/prompt-size-guard.test.ts +32 -17
  168. package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
  169. package/tests/index.test.ts +94 -1
  170. package/tests/integration/auto-entry-gate.test.ts +248 -0
  171. package/tests/integration/internalization-trigger-guard.test.ts +69 -0
  172. package/tests/integration/m8-legacy-paths.test.ts +63 -0
  173. package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
  174. package/tests/plugin-config-resolution-cutover.test.ts +359 -0
  175. package/tests/runtime-v2-discovery-guard.test.ts +154 -0
  176. package/tests/service/central-database.test.ts +457 -0
  177. package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
  178. package/tests/service/evolution-worker.timeout.test.ts +11 -129
  179. package/tests/service/internalization-trigger-adapter.test.ts +251 -0
  180. package/tests/service/monitoring-query-service.test.ts +1 -47
  181. package/tests/service/queue-io.test.ts +1 -62
  182. package/tests/service/runtime-summary-service.test.ts +3 -1
  183. package/tests/service/workflow-watchdog.test.ts +0 -91
  184. package/tests/utils/file-lock.test.ts +5 -3
  185. package/tests/utils/session-key.test.ts +52 -0
  186. package/tests/utils/subagent-probe.test.ts +48 -1
  187. package/vitest.config.ts +4 -11
  188. package/.planning/codebase/ARCHITECTURE.md +0 -157
  189. package/.planning/codebase/CONCERNS.md +0 -145
  190. package/.planning/codebase/CONVENTIONS.md +0 -148
  191. package/.planning/codebase/INTEGRATIONS.md +0 -81
  192. package/.planning/codebase/STACK.md +0 -87
  193. package/.planning/codebase/STRUCTURE.md +0 -193
  194. package/.planning/codebase/TESTING.md +0 -243
  195. package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
  196. package/docs/COMMAND_REFERENCE.md +0 -76
  197. package/docs/COMMAND_REFERENCE_EN.md +0 -79
  198. package/scripts/build-web.mjs +0 -46
  199. package/scripts/diagnose-nocturnal.mjs +0 -537
  200. package/scripts/seed-nocturnal-scenarios.mjs +0 -384
  201. package/src/commands/nocturnal-review.ts +0 -322
  202. package/src/commands/nocturnal-rollout.ts +0 -790
  203. package/src/commands/nocturnal-train.ts +0 -986
  204. package/src/commands/pd-reflect.ts +0 -88
  205. package/src/core/adaptive-thresholds.ts +0 -478
  206. package/src/core/diagnostician-task-store.ts +0 -192
  207. package/src/core/nocturnal-arbiter.ts +0 -715
  208. package/src/core/nocturnal-artifact-lineage.ts +0 -116
  209. package/src/core/nocturnal-artificer.ts +0 -257
  210. package/src/core/nocturnal-candidate-scoring.ts +0 -530
  211. package/src/core/nocturnal-compliance.ts +0 -1146
  212. package/src/core/nocturnal-dataset.ts +0 -763
  213. package/src/core/nocturnal-executability.ts +0 -428
  214. package/src/core/nocturnal-export.ts +0 -499
  215. package/src/core/nocturnal-paths.ts +0 -240
  216. package/src/core/nocturnal-reasoning-deriver.ts +0 -343
  217. package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
  218. package/src/core/nocturnal-snapshot-contract.ts +0 -99
  219. package/src/core/nocturnal-trajectory-extractor.ts +0 -512
  220. package/src/core/nocturnal-trinity-types.ts +0 -218
  221. package/src/core/nocturnal-trinity.ts +0 -2680
  222. package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
  223. package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
  224. package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
  225. package/src/http/principles-console-route.ts +0 -709
  226. package/src/service/central-health-service.ts +0 -49
  227. package/src/service/central-overview-service.ts +0 -138
  228. package/src/service/control-ui-query-service.ts +0 -900
  229. package/src/service/cooldown-strategy.ts +0 -97
  230. package/src/service/evolution-pain-context.ts +0 -79
  231. package/src/service/evolution-query-service.ts +0 -407
  232. package/src/service/health-query-service.ts +0 -1038
  233. package/src/service/nocturnal-config.ts +0 -214
  234. package/src/service/nocturnal-runtime.ts +0 -734
  235. package/src/service/nocturnal-service.ts +0 -1605
  236. package/src/service/nocturnal-target-selector.ts +0 -545
  237. package/src/service/sleep-cycle.ts +0 -157
  238. package/src/service/startup-reconciler.ts +0 -112
  239. package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
  240. package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
  241. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
  242. package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
  243. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
  244. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
  245. package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
  246. package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
  247. package/src/tools/write-pain-flag.ts +0 -215
  248. package/tests/commands/nocturnal-review.test.ts +0 -448
  249. package/tests/commands/nocturnal-train.test.ts +0 -97
  250. package/tests/commands/pd-reflect.test.ts +0 -49
  251. package/tests/core/adaptive-thresholds.test.ts +0 -261
  252. package/tests/core/nocturnal-arbiter.test.ts +0 -559
  253. package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
  254. package/tests/core/nocturnal-artificer.test.ts +0 -241
  255. package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
  256. package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
  257. package/tests/core/nocturnal-compliance.test.ts +0 -646
  258. package/tests/core/nocturnal-dataset.test.ts +0 -892
  259. package/tests/core/nocturnal-e2e.test.ts +0 -234
  260. package/tests/core/nocturnal-executability.test.ts +0 -357
  261. package/tests/core/nocturnal-export.test.ts +0 -517
  262. package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
  263. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
  264. package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
  265. package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
  266. package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
  267. package/tests/core/nocturnal-trinity.test.ts +0 -2053
  268. package/tests/core/pain-auto-repair.test.ts +0 -96
  269. package/tests/core/pain-integration.test.ts +0 -510
  270. package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
  271. package/tests/http/principles-console-route.test.ts +0 -162
  272. package/tests/integration/chaos-resilience.test.ts +0 -348
  273. package/tests/integration/empathy-workflow-integration.test.ts +0 -626
  274. package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
  275. package/tests/service/control-ui-query-service.test.ts +0 -121
  276. package/tests/service/cooldown-strategy.test.ts +0 -164
  277. package/tests/service/data-endpoints-regression.test.ts +0 -834
  278. package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
  279. package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
  280. package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
  281. package/tests/service/nocturnal-runtime.test.ts +0 -473
  282. package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
  283. package/tests/service/nocturnal-target-selector.test.ts +0 -615
  284. package/tests/service/startup-reconciler.test.ts +0 -148
  285. package/tests/tools/write-pain-flag.test.ts +0 -358
  286. package/ui/src/App.tsx +0 -45
  287. package/ui/src/api.ts +0 -220
  288. package/ui/src/charts.tsx +0 -955
  289. package/ui/src/components/ErrorState.tsx +0 -6
  290. package/ui/src/components/Loading.tsx +0 -13
  291. package/ui/src/components/ProtectedRoute.tsx +0 -12
  292. package/ui/src/components/Shell.tsx +0 -91
  293. package/ui/src/components/WorkspaceConfig.tsx +0 -178
  294. package/ui/src/components/index.ts +0 -5
  295. package/ui/src/context/auth.tsx +0 -80
  296. package/ui/src/context/theme.tsx +0 -66
  297. package/ui/src/hooks/useAutoRefresh.ts +0 -39
  298. package/ui/src/i18n/ui.ts +0 -473
  299. package/ui/src/main.tsx +0 -16
  300. package/ui/src/pages/EvolutionPage.tsx +0 -333
  301. package/ui/src/pages/FeedbackPage.tsx +0 -138
  302. package/ui/src/pages/GateMonitorPage.tsx +0 -136
  303. package/ui/src/pages/LoginPage.tsx +0 -89
  304. package/ui/src/pages/OverviewPage.tsx +0 -599
  305. package/ui/src/pages/SamplesPage.tsx +0 -174
  306. package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
  307. package/ui/src/styles.css +0 -2020
  308. package/ui/src/types.ts +0 -384
  309. 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
- }