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.
- package/INSTALL.md +1 -3
- package/openclaw.plugin.json +10 -5
- package/package.json +17 -19
- package/scripts/acceptance-test.mjs +16 -73
- package/scripts/sync-plugin.mjs +382 -77
- package/src/commands/archive-impl.ts +2 -1
- package/src/commands/capabilities.ts +2 -2
- package/src/commands/context.ts +2 -2
- package/src/commands/disable-impl.ts +2 -1
- package/src/commands/evolution-status.ts +16 -16
- package/src/commands/export.ts +12 -67
- package/src/commands/pain.ts +91 -1
- package/src/commands/principle-rollback.ts +2 -1
- package/src/commands/promote-impl.ts +7 -43
- package/src/commands/rollback-impl.ts +2 -1
- package/src/commands/rollback.ts +2 -1
- package/src/commands/samples.ts +2 -1
- package/src/commands/thinking-os.ts +2 -1
- package/src/config/errors.ts +18 -2
- package/src/constants/diagnostician.ts +2 -2
- package/src/constants/tools.ts +2 -1
- package/src/core/__tests__/focus-history.test.ts +210 -0
- package/src/core/config.ts +1 -1
- package/src/core/correction-cue-learner.ts +2 -136
- package/src/core/correction-types.ts +16 -88
- package/src/core/dictionary.ts +19 -20
- package/src/core/empathy-keyword-matcher.ts +17 -289
- package/src/core/empathy-types.ts +18 -229
- package/src/core/event-log.ts +29 -132
- package/src/core/evolution-reducer.ts +21 -2
- package/src/core/evolution-types.ts +76 -464
- package/src/core/file-store.ts +80 -0
- package/src/core/focus-history.ts +228 -955
- package/src/core/local-worker-routing.ts +34 -314
- package/src/core/merge-gate-audit.ts +0 -195
- package/src/core/migration.ts +0 -1
- package/src/core/pain-diagnostic-gate.ts +154 -0
- package/src/core/pain-signal.ts +21 -138
- package/src/core/pain.ts +15 -88
- package/src/core/path-resolver.ts +0 -1
- package/src/core/paths.ts +0 -1
- package/src/core/pd-task-reconciler.ts +26 -115
- package/src/core/pd-task-service.ts +9 -9
- package/src/core/pd-task-types.ts +23 -127
- package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
- package/src/core/principle-compiler/code-validator.ts +15 -42
- package/src/core/principle-compiler/compiler.ts +100 -15
- package/src/core/principle-compiler/index.ts +5 -2
- package/src/core/principle-compiler/template-generator.ts +4 -104
- package/src/core/principle-injection.ts +10 -202
- package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
- package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
- package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
- package/src/core/principle-tree-ledger-adapter.ts +145 -0
- package/src/core/principle-tree-ledger.ts +8 -6
- package/src/core/reflection/reflection-context.ts +14 -109
- package/src/core/replay-engine.ts +8 -500
- package/src/core/rule-host-helpers.ts +5 -35
- package/src/core/rule-host-types.ts +10 -82
- package/src/core/rule-host.ts +6 -63
- package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
- package/src/core/session-tracker.ts +87 -101
- package/src/core/shadow-observation-registry.ts +19 -48
- package/src/core/trajectory.ts +3 -1
- package/src/core/workflow-funnel-loader.ts +62 -68
- package/src/core/workspace-context.ts +46 -0
- package/src/core/workspace-dir-service.ts +1 -1
- package/src/core/workspace-dir-validation.ts +18 -9
- package/src/hooks/AGENTS.md +1 -1
- package/src/hooks/gate-block-helper.ts +71 -64
- package/src/hooks/gate.ts +183 -31
- package/src/hooks/lifecycle.ts +30 -32
- package/src/hooks/llm.ts +60 -32
- package/src/hooks/pain.ts +297 -103
- package/src/hooks/prompt.ts +400 -440
- package/src/hooks/subagent.ts +2 -29
- package/src/i18n/commands.ts +2 -10
- package/src/index.ts +95 -85
- package/src/openclaw-sdk.ts +311 -0
- package/src/service/central-database.ts +8 -4
- package/src/service/evolution-queue-migration.ts +2 -1
- package/src/service/evolution-worker.ts +163 -1786
- package/src/service/internalization-trigger-adapter.ts +302 -0
- package/src/service/keyword-optimization-service.ts +4 -4
- package/src/service/monitoring-query-service.ts +1 -215
- package/src/service/queue-io.ts +60 -331
- package/src/service/runtime-summary-service.ts +59 -16
- package/src/service/subagent-workflow/index.ts +0 -41
- package/src/service/subagent-workflow/types.ts +9 -120
- package/src/service/subagent-workflow/workflow-store.ts +2 -119
- package/src/service/workflow-watchdog.ts +0 -43
- package/src/types/event-payload.ts +16 -74
- package/src/types/event-types.ts +38 -547
- package/src/types/hygiene-types.ts +7 -30
- package/src/types/principle-tree-schema.ts +20 -222
- package/src/types/queue.ts +15 -70
- package/src/types/runtime-summary.ts +5 -49
- package/src/utils/io.ts +8 -20
- package/src/utils/retry.ts +1 -1
- package/src/utils/shadow-fingerprint.ts +2 -2
- package/src/utils/workspace-resolver.ts +50 -0
- package/templates/langs/en/core/AGENTS.md +7 -7
- package/templates/langs/en/core/BOOT.md +1 -1
- package/templates/langs/en/core/HEARTBEAT.md +2 -2
- package/templates/langs/en/principles/THINKING_OS.md +3 -2
- package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/en/skills/evolve-task/SKILL.md +3 -3
- package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-mentor/SKILL.md +2 -3
- package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
- package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
- package/templates/langs/zh/core/AGENTS.md +7 -7
- package/templates/langs/zh/core/BOOT.md +1 -1
- package/templates/langs/zh/core/HEARTBEAT.md +2 -2
- package/templates/langs/zh/principles/THINKING_OS.md +3 -2
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
- package/templates/langs/zh/skills/evolve-task/SKILL.md +4 -4
- package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +2 -3
- package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
- package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
- package/tests/build-artifacts.test.ts +1 -3
- package/tests/commands/evolution-status.test.ts +0 -118
- package/tests/core/bootstrap-rules.test.ts +1 -1
- package/tests/core/config.test.ts +1 -1
- package/tests/core/event-log.test.ts +35 -0
- package/tests/core/evolution-engine.test.ts +610 -0
- package/tests/core/file-store.test.ts +102 -0
- package/tests/core/focus-history.test.ts +203 -11
- package/tests/core/merge-gate-audit.test.ts +2 -169
- package/tests/core/migration.test.ts +7 -7
- package/tests/core/model-deployment-registry.test.ts +7 -1
- package/tests/core/model-training-registry.test.ts +19 -0
- package/tests/core/observability.test.ts +0 -1
- package/tests/core/pain-diagnostic-gate.test.ts +498 -0
- package/tests/core/pain.test.ts +0 -1
- package/tests/core/path-resolver.test.ts +1 -1
- package/tests/core/paths-refactor.test.ts +0 -22
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
- package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
- package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
- package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
- package/tests/core/reflection-context.test.ts +0 -14
- package/tests/core/replay-engine.test.ts +127 -215
- package/tests/core/rule-host-helpers.test.ts +2 -2
- package/tests/core/rule-implementation-runtime.test.ts +0 -27
- package/tests/core/workflow-funnel-loader.test.ts +162 -0
- package/tests/core/workspace-context.test.ts +2 -2
- package/tests/core/workspace-dir-validation.test.ts +8 -1
- package/tests/core-anti-growth.test.ts +191 -0
- package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
- package/tests/hooks/confirm-first-removal.test.ts +188 -0
- package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
- package/tests/hooks/gate-auto-correct.test.ts +665 -0
- package/tests/hooks/gate-no-path-write-tool.test.ts +172 -0
- package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
- package/tests/hooks/pain.test.ts +269 -12
- package/tests/hooks/prompt-characterization.test.ts +500 -0
- package/tests/hooks/prompt-size-guard.test.ts +32 -17
- package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
- package/tests/index.test.ts +94 -1
- package/tests/integration/auto-entry-gate.test.ts +248 -0
- package/tests/integration/internalization-trigger-guard.test.ts +69 -0
- package/tests/integration/m8-legacy-paths.test.ts +63 -0
- package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
- package/tests/plugin-config-resolution-cutover.test.ts +359 -0
- package/tests/runtime-v2-discovery-guard.test.ts +154 -0
- package/tests/service/central-database.test.ts +457 -0
- package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
- package/tests/service/evolution-worker.timeout.test.ts +11 -129
- package/tests/service/internalization-trigger-adapter.test.ts +251 -0
- package/tests/service/monitoring-query-service.test.ts +1 -47
- package/tests/service/queue-io.test.ts +1 -62
- package/tests/service/runtime-summary-service.test.ts +3 -1
- package/tests/service/workflow-watchdog.test.ts +0 -91
- package/tests/utils/file-lock.test.ts +5 -3
- package/tests/utils/session-key.test.ts +52 -0
- package/tests/utils/subagent-probe.test.ts +48 -1
- package/vitest.config.ts +4 -11
- package/.planning/codebase/ARCHITECTURE.md +0 -157
- package/.planning/codebase/CONCERNS.md +0 -145
- package/.planning/codebase/CONVENTIONS.md +0 -148
- package/.planning/codebase/INTEGRATIONS.md +0 -81
- package/.planning/codebase/STACK.md +0 -87
- package/.planning/codebase/STRUCTURE.md +0 -193
- package/.planning/codebase/TESTING.md +0 -243
- package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
- package/docs/COMMAND_REFERENCE.md +0 -76
- package/docs/COMMAND_REFERENCE_EN.md +0 -79
- package/scripts/build-web.mjs +0 -46
- package/scripts/diagnose-nocturnal.mjs +0 -537
- package/scripts/seed-nocturnal-scenarios.mjs +0 -384
- package/src/commands/nocturnal-review.ts +0 -322
- package/src/commands/nocturnal-rollout.ts +0 -790
- package/src/commands/nocturnal-train.ts +0 -986
- package/src/commands/pd-reflect.ts +0 -88
- package/src/core/adaptive-thresholds.ts +0 -478
- package/src/core/diagnostician-task-store.ts +0 -192
- package/src/core/nocturnal-arbiter.ts +0 -715
- package/src/core/nocturnal-artifact-lineage.ts +0 -116
- package/src/core/nocturnal-artificer.ts +0 -257
- package/src/core/nocturnal-candidate-scoring.ts +0 -530
- package/src/core/nocturnal-compliance.ts +0 -1146
- package/src/core/nocturnal-dataset.ts +0 -763
- package/src/core/nocturnal-executability.ts +0 -428
- package/src/core/nocturnal-export.ts +0 -499
- package/src/core/nocturnal-paths.ts +0 -240
- package/src/core/nocturnal-reasoning-deriver.ts +0 -343
- package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
- package/src/core/nocturnal-snapshot-contract.ts +0 -99
- package/src/core/nocturnal-trajectory-extractor.ts +0 -512
- package/src/core/nocturnal-trinity-types.ts +0 -218
- package/src/core/nocturnal-trinity.ts +0 -2680
- package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
- package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
- package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
- package/src/http/principles-console-route.ts +0 -709
- package/src/service/central-health-service.ts +0 -49
- package/src/service/central-overview-service.ts +0 -138
- package/src/service/control-ui-query-service.ts +0 -900
- package/src/service/cooldown-strategy.ts +0 -97
- package/src/service/evolution-pain-context.ts +0 -79
- package/src/service/evolution-query-service.ts +0 -407
- package/src/service/health-query-service.ts +0 -1038
- package/src/service/nocturnal-config.ts +0 -214
- package/src/service/nocturnal-runtime.ts +0 -734
- package/src/service/nocturnal-service.ts +0 -1605
- package/src/service/nocturnal-target-selector.ts +0 -545
- package/src/service/sleep-cycle.ts +0 -157
- package/src/service/startup-reconciler.ts +0 -112
- package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
- package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
- package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
- package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
- package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
- package/src/tools/write-pain-flag.ts +0 -215
- package/templates/langs/en/skills/plan-script/SKILL.md +0 -32
- package/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
- package/tests/commands/nocturnal-review.test.ts +0 -448
- package/tests/commands/nocturnal-train.test.ts +0 -97
- package/tests/commands/pd-reflect.test.ts +0 -49
- package/tests/core/adaptive-thresholds.test.ts +0 -261
- package/tests/core/nocturnal-arbiter.test.ts +0 -559
- package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
- package/tests/core/nocturnal-artificer.test.ts +0 -241
- package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
- package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
- package/tests/core/nocturnal-compliance.test.ts +0 -646
- package/tests/core/nocturnal-dataset.test.ts +0 -892
- package/tests/core/nocturnal-e2e.test.ts +0 -234
- package/tests/core/nocturnal-executability.test.ts +0 -357
- package/tests/core/nocturnal-export.test.ts +0 -517
- package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
- package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
- package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
- package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
- package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
- package/tests/core/nocturnal-trinity.test.ts +0 -2053
- package/tests/core/pain-auto-repair.test.ts +0 -96
- package/tests/core/pain-integration.test.ts +0 -510
- package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
- package/tests/http/principles-console-route.test.ts +0 -162
- package/tests/integration/chaos-resilience.test.ts +0 -348
- package/tests/integration/empathy-workflow-integration.test.ts +0 -626
- package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
- package/tests/service/control-ui-query-service.test.ts +0 -121
- package/tests/service/cooldown-strategy.test.ts +0 -164
- package/tests/service/data-endpoints-regression.test.ts +0 -834
- package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
- package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
- package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
- package/tests/service/nocturnal-runtime.test.ts +0 -473
- package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
- package/tests/service/nocturnal-target-selector.test.ts +0 -615
- package/tests/service/startup-reconciler.test.ts +0 -148
- package/tests/tools/write-pain-flag.test.ts +0 -358
- package/ui/src/App.tsx +0 -45
- package/ui/src/api.ts +0 -220
- package/ui/src/charts.tsx +0 -955
- package/ui/src/components/ErrorState.tsx +0 -6
- package/ui/src/components/Loading.tsx +0 -13
- package/ui/src/components/ProtectedRoute.tsx +0 -12
- package/ui/src/components/Shell.tsx +0 -91
- package/ui/src/components/WorkspaceConfig.tsx +0 -178
- package/ui/src/components/index.ts +0 -5
- package/ui/src/context/auth.tsx +0 -80
- package/ui/src/context/theme.tsx +0 -66
- package/ui/src/hooks/useAutoRefresh.ts +0 -39
- package/ui/src/i18n/ui.ts +0 -473
- package/ui/src/main.tsx +0 -16
- package/ui/src/pages/EvolutionPage.tsx +0 -333
- package/ui/src/pages/FeedbackPage.tsx +0 -138
- package/ui/src/pages/GateMonitorPage.tsx +0 -136
- package/ui/src/pages/LoginPage.tsx +0 -89
- package/ui/src/pages/OverviewPage.tsx +0 -599
- package/ui/src/pages/SamplesPage.tsx +0 -174
- package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
- package/ui/src/styles.css +0 -2020
- package/ui/src/types.ts +0 -384
- package/ui/src/utils/format.ts +0 -15
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internalization Dumb Trigger Adapter (PRI-63)
|
|
3
|
+
*
|
|
4
|
+
* Thin adapter that wakes periodically to probe SQLite for ready
|
|
5
|
+
* internalization tasks. Plugin layer only — does NOT execute LLM calls,
|
|
6
|
+
* does NOT directly chain PeerRunners, does NOT modify task status.
|
|
7
|
+
*
|
|
8
|
+
* Core decision functions (validateInternalizationTaskReady) determine
|
|
9
|
+
* if a task is ready to be processed. This adapter is only responsible
|
|
10
|
+
* for waking and logging — actual dispatch is handled by future
|
|
11
|
+
* Orchestrator PRI.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/adr/0003-peer-agent-state-machine-orchestration.md
|
|
14
|
+
* @see packages/principles-core/src/runtime-v2/internalization/internalization-state-machine.ts (PRI-62)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { TaskRecord } from '@principles/core/runtime-v2';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
validateInternalizationTaskReady,
|
|
21
|
+
isPeerRunnerKind,
|
|
22
|
+
hydratePITaskRecord,
|
|
23
|
+
type PITaskRecord,
|
|
24
|
+
type PeerRunnerKind,
|
|
25
|
+
} from '@principles/core/runtime-v2';
|
|
26
|
+
|
|
27
|
+
// ── Structured log event types ───────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
type TriggerWakeEvent = {
|
|
30
|
+
event: 'INTERNALIZATION_TRIGGER_WAKE';
|
|
31
|
+
workspaceDir: string;
|
|
32
|
+
taskId: string;
|
|
33
|
+
taskKind: PeerRunnerKind;
|
|
34
|
+
correlationId?: string;
|
|
35
|
+
gateDecision: 'proceed';
|
|
36
|
+
timestamp: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type TriggerNoopEvent = {
|
|
40
|
+
event: 'INTERNALIZATION_TRIGGER_NOOP';
|
|
41
|
+
workspaceDir: string;
|
|
42
|
+
timestamp: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type TriggerBlockedEvent = {
|
|
46
|
+
event: 'INTERNALIZATION_TRIGGER_BLOCKED';
|
|
47
|
+
workspaceDir: string;
|
|
48
|
+
taskId: string;
|
|
49
|
+
taskKind: string;
|
|
50
|
+
gateDecision: 'blocked' | 'dependency_failed' | 'retry_wait_pending';
|
|
51
|
+
blockedBy?: string[];
|
|
52
|
+
failedDependencies?: string[];
|
|
53
|
+
retryAfter?: string;
|
|
54
|
+
timestamp: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type TriggerFailedEvent = {
|
|
58
|
+
event: 'INTERNALIZATION_TRIGGER_FAILED';
|
|
59
|
+
workspaceDir: string;
|
|
60
|
+
failureCategory: 'invalid_context' | 'provider_error' | 'unexpected_error';
|
|
61
|
+
error?: string;
|
|
62
|
+
timestamp: string;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type LogEvent = TriggerWakeEvent | TriggerNoopEvent | TriggerFailedEvent | TriggerBlockedEvent;
|
|
66
|
+
|
|
67
|
+
// ── Logger interface ─────────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
export interface TriggerLogger {
|
|
70
|
+
debug?(msg: string, meta?: Record<string, unknown>): void;
|
|
71
|
+
info?(msg: string, meta?: Record<string, unknown>): void;
|
|
72
|
+
warn?(msg: string, meta?: Record<string, unknown>): void;
|
|
73
|
+
error?(msg: string, meta?: Record<string, unknown>): void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ── Task provider interface (dependency injection for testability) ───────────
|
|
77
|
+
|
|
78
|
+
export interface InternalizationTaskProvider {
|
|
79
|
+
listTasks(filter?: { status?: string; taskKind?: string }): Promise<TaskRecord[]>;
|
|
80
|
+
getTask(taskId: string): Promise<TaskRecord | null>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── Wake context ──────────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
export interface TriggerContext {
|
|
86
|
+
workspaceDir: string;
|
|
87
|
+
stateDir: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── Adapter interface ─────────────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
export interface InternalizationTriggerAdapter {
|
|
93
|
+
wake(ctx: TriggerContext): Promise<void>;
|
|
94
|
+
start(ctx: TriggerContext, intervalMs?: number): () => void;
|
|
95
|
+
stop(): void;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ── Internal state ─────────────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
interface AdapterState {
|
|
101
|
+
intervalId: ReturnType<typeof setInterval> | null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ── Log helper ────────────────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
function emitLog(
|
|
107
|
+
logger: TriggerLogger | undefined,
|
|
108
|
+
event: LogEvent,
|
|
109
|
+
): void {
|
|
110
|
+
const { event: eventType, ...meta } = event;
|
|
111
|
+
|
|
112
|
+
switch (eventType) {
|
|
113
|
+
case 'INTERNALIZATION_TRIGGER_WAKE':
|
|
114
|
+
logger?.info?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_WAKE', meta);
|
|
115
|
+
break;
|
|
116
|
+
case 'INTERNALIZATION_TRIGGER_NOOP':
|
|
117
|
+
logger?.debug?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_NOOP', meta);
|
|
118
|
+
break;
|
|
119
|
+
case 'INTERNALIZATION_TRIGGER_BLOCKED':
|
|
120
|
+
logger?.debug?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_BLOCKED', meta);
|
|
121
|
+
break;
|
|
122
|
+
case 'INTERNALIZATION_TRIGGER_FAILED':
|
|
123
|
+
logger?.error?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_FAILED', meta);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── Core adapter factory ───────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Creates a dumb trigger adapter that probes for ready internalization tasks.
|
|
132
|
+
*
|
|
133
|
+
* Design constraints (enforced by architecture regression guards):
|
|
134
|
+
* - PLUGIN_NO_INLINE_EXECUTION: wake() is read-only, does not await long tasks
|
|
135
|
+
* - PEER_NO_DIRECT_CHAINING: adapter does not call Dreamer/Philosopher/Scribe
|
|
136
|
+
* - TASK_MODEL_REUSE: reuses PITaskRecord / TaskRecord, no second task model
|
|
137
|
+
*
|
|
138
|
+
* @param provider - Task data access abstraction (SqliteTaskStore in production)
|
|
139
|
+
* @param logger - Optional structured logger
|
|
140
|
+
*/
|
|
141
|
+
export function createInternalizationTrigger(
|
|
142
|
+
provider: InternalizationTaskProvider,
|
|
143
|
+
logger?: TriggerLogger,
|
|
144
|
+
): InternalizationTriggerAdapter {
|
|
145
|
+
const state: AdapterState = {
|
|
146
|
+
intervalId: null,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// ── wake: single trigger cycle ─────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
async function wake(ctx: TriggerContext): Promise<void> {
|
|
152
|
+
// Fail closed: missing workspaceDir or stateDir
|
|
153
|
+
if (!ctx.workspaceDir || !ctx.stateDir) {
|
|
154
|
+
emitLog(logger, {
|
|
155
|
+
event: 'INTERNALIZATION_TRIGGER_FAILED',
|
|
156
|
+
workspaceDir: ctx.workspaceDir ?? '(missing)',
|
|
157
|
+
failureCategory: 'invalid_context',
|
|
158
|
+
error: 'workspaceDir or stateDir is missing',
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
// Query pending and retry_wait tasks (non-terminal states that can be leased)
|
|
166
|
+
const pendingTasks = await provider.listTasks({ status: 'pending' });
|
|
167
|
+
const retryWaitTasks = await provider.listTasks({ status: 'retry_wait' });
|
|
168
|
+
|
|
169
|
+
// Filter to only PeerRunner tasks, then hydrate PI metadata from diagnosticJson.
|
|
170
|
+
// Tasks without valid PI metadata in diagnosticJson return null and are filtered out.
|
|
171
|
+
const pendingPITasks = pendingTasks
|
|
172
|
+
.filter(t => isPeerRunnerKind(t.taskKind))
|
|
173
|
+
.map(t => hydratePITaskRecord(t))
|
|
174
|
+
.filter((t): t is PITaskRecord => t !== null);
|
|
175
|
+
|
|
176
|
+
const retryWaitPITasks = retryWaitTasks
|
|
177
|
+
.filter(t => isPeerRunnerKind(t.taskKind))
|
|
178
|
+
.map(t => hydratePITaskRecord(t))
|
|
179
|
+
.filter((t): t is PITaskRecord => t !== null);
|
|
180
|
+
|
|
181
|
+
const candidateTasks = [...pendingPITasks, ...retryWaitPITasks];
|
|
182
|
+
|
|
183
|
+
// No candidates → NOOP
|
|
184
|
+
if (candidateTasks.length === 0) {
|
|
185
|
+
emitLog(logger, {
|
|
186
|
+
event: 'INTERNALIZATION_TRIGGER_NOOP',
|
|
187
|
+
workspaceDir: ctx.workspaceDir,
|
|
188
|
+
timestamp: new Date().toISOString(),
|
|
189
|
+
});
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Evaluate each candidate
|
|
194
|
+
let hasReadyTask = false;
|
|
195
|
+
|
|
196
|
+
for (const task of candidateTasks) {
|
|
197
|
+
// Fetch dependency tasks for gate validation
|
|
198
|
+
const dependencies: TaskRecord[] = [];
|
|
199
|
+
if (task.dependencyTaskIds && task.dependencyTaskIds.length > 0) {
|
|
200
|
+
for (const depId of task.dependencyTaskIds) {
|
|
201
|
+
const dep = await provider.getTask(depId);
|
|
202
|
+
if (dep) dependencies.push(dep);
|
|
203
|
+
// Fail closed: if dep not found, dependencies array is incomplete
|
|
204
|
+
// validateInternalizationTaskReady will return 'blocked'
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const gateResult = validateInternalizationTaskReady(task, dependencies);
|
|
209
|
+
|
|
210
|
+
if (gateResult.decision === 'proceed') {
|
|
211
|
+
// Task is ready — log WAKE event (read-only, no mutation)
|
|
212
|
+
emitLog(logger, {
|
|
213
|
+
event: 'INTERNALIZATION_TRIGGER_WAKE',
|
|
214
|
+
workspaceDir: ctx.workspaceDir,
|
|
215
|
+
taskId: task.taskId,
|
|
216
|
+
taskKind: task.taskKind,
|
|
217
|
+
correlationId: task.correlationId,
|
|
218
|
+
gateDecision: gateResult.decision,
|
|
219
|
+
timestamp: new Date().toISOString(),
|
|
220
|
+
});
|
|
221
|
+
hasReadyTask = true;
|
|
222
|
+
} else {
|
|
223
|
+
// blocked, dependency_failed, or retry_wait_pending — debug visibility for operators
|
|
224
|
+
emitLog(logger, {
|
|
225
|
+
event: 'INTERNALIZATION_TRIGGER_BLOCKED',
|
|
226
|
+
workspaceDir: ctx.workspaceDir,
|
|
227
|
+
taskId: task.taskId,
|
|
228
|
+
taskKind: task.taskKind,
|
|
229
|
+
gateDecision: gateResult.decision,
|
|
230
|
+
blockedBy: gateResult.decision === 'blocked' ? gateResult.blockedBy : undefined,
|
|
231
|
+
failedDependencies: gateResult.decision === 'dependency_failed' ? gateResult.failedDependencies : undefined,
|
|
232
|
+
retryAfter: gateResult.decision === 'retry_wait_pending' ? gateResult.retryAfter : undefined,
|
|
233
|
+
timestamp: new Date().toISOString(),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// All candidates were blocked
|
|
239
|
+
if (!hasReadyTask) {
|
|
240
|
+
emitLog(logger, {
|
|
241
|
+
event: 'INTERNALIZATION_TRIGGER_NOOP',
|
|
242
|
+
workspaceDir: ctx.workspaceDir,
|
|
243
|
+
timestamp: new Date().toISOString(),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
} catch (err) {
|
|
247
|
+
emitLog(logger, {
|
|
248
|
+
event: 'INTERNALIZATION_TRIGGER_FAILED',
|
|
249
|
+
workspaceDir: ctx.workspaceDir,
|
|
250
|
+
failureCategory: 'provider_error',
|
|
251
|
+
error: err instanceof Error ? err.message : String(err),
|
|
252
|
+
timestamp: new Date().toISOString(),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ── start: begin periodic wake cycles ─────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
function start(ctx: TriggerContext, intervalMs = 5 * 60 * 1000): () => void {
|
|
260
|
+
// Prevent re-entrancy: if already running, warn and return existing stop
|
|
261
|
+
if (state.intervalId !== null) {
|
|
262
|
+
logger?.warn?.('[PD:InternalizationTrigger] start() called while already running — returning existing stop', {
|
|
263
|
+
workspaceDir: ctx.workspaceDir,
|
|
264
|
+
stateDir: ctx.stateDir,
|
|
265
|
+
});
|
|
266
|
+
return stop;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Immediate first wake
|
|
270
|
+
wake(ctx).catch(err => {
|
|
271
|
+
logger?.error?.('[PD:InternalizationTrigger] start() initial wake failed', {
|
|
272
|
+
error: err instanceof Error ? err.message : String(err),
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Schedule periodic wake
|
|
277
|
+
state.intervalId = setInterval(() => {
|
|
278
|
+
wake(ctx).catch(err => {
|
|
279
|
+
logger?.error?.('[PD:InternalizationTrigger] periodic wake failed', {
|
|
280
|
+
error: err instanceof Error ? err.message : String(err),
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
}, intervalMs);
|
|
284
|
+
|
|
285
|
+
return stop;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ── stop: halt periodic wake ──────────────────────────────────────────────
|
|
289
|
+
|
|
290
|
+
function stop(): void {
|
|
291
|
+
if (state.intervalId !== null) {
|
|
292
|
+
clearInterval(state.intervalId);
|
|
293
|
+
state.intervalId = null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return { wake, start, stop };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ── Re-export types for consumers ────────────────────────────────────────────
|
|
301
|
+
|
|
302
|
+
export type { PITaskRecord, PeerRunnerKind } from '@principles/core/runtime-v2';
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { CorrectionCueLearner } from '../core/correction-cue-learner.js';
|
|
10
|
-
import type { CorrectionObserverResult } from '
|
|
10
|
+
import type { CorrectionObserverOutputV1 as CorrectionObserverResult } from '@principles/core/runtime-v2';
|
|
11
11
|
import type { PluginLogger } from '../openclaw-sdk.js';
|
|
12
12
|
import { TrajectoryRegistry } from '../core/trajectory.js';
|
|
13
13
|
|
|
@@ -83,8 +83,8 @@ export class KeywordOptimizationService {
|
|
|
83
83
|
const MAX_FP_TERMS = 20;
|
|
84
84
|
const normalizedFpTerms = [...new Set(
|
|
85
85
|
result.fpTerms
|
|
86
|
-
.map(t => t.trim().toLowerCase())
|
|
87
|
-
.filter(t => t.length > 0)
|
|
86
|
+
.map((t: string) => t.trim().toLowerCase())
|
|
87
|
+
.filter((t: string) => t.length > 0)
|
|
88
88
|
)].slice(0, MAX_FP_TERMS);
|
|
89
89
|
|
|
90
90
|
for (const term of normalizedFpTerms) {
|
|
@@ -166,4 +166,4 @@ export type TrajectoryHistoryEntry = {
|
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
/** Re-export CorrectionObserverPayload for convenience */
|
|
169
|
-
export type { CorrectionObserverPayload } from '
|
|
169
|
+
export type { CorrectionObserverPayload } from '@principles/core/runtime-v2';
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { WorkflowStore } from './subagent-workflow/workflow-store.js';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Monitoring query service for Nocturnal workflows and Trinity stages.
|
|
5
|
-
* Encapsulates all monitoring data queries, keeping logic separate from API routes.
|
|
6
|
-
*/
|
|
7
3
|
export class MonitoringQueryService {
|
|
8
4
|
private readonly workspaceDir: string;
|
|
9
5
|
private readonly store: WorkflowStore;
|
|
@@ -17,30 +13,20 @@ export class MonitoringQueryService {
|
|
|
17
13
|
this.store.dispose();
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
/**
|
|
21
|
-
* Get workflows with optional filtering and stuck detection.
|
|
22
|
-
* @param filters - Optional state and type filters
|
|
23
|
-
* @returns Workflow list with stuck detection
|
|
24
|
-
*/
|
|
25
16
|
getWorkflows(filters: { state?: string; type?: string } = {}): WorkflowListResponse {
|
|
26
|
-
// Query workflows from WorkflowStore
|
|
27
17
|
let workflows = filters.state
|
|
28
18
|
? this.store.listWorkflows(filters.state)
|
|
29
19
|
: this.store.listWorkflows();
|
|
30
20
|
|
|
31
|
-
// Filter by workflow type if specified
|
|
32
21
|
if (filters.type) {
|
|
33
22
|
workflows = workflows.filter(wf => wf.workflow_type === filters.type);
|
|
34
23
|
}
|
|
35
24
|
|
|
36
25
|
const now = Date.now();
|
|
37
26
|
const workflowsWithStuckDetection = workflows.map(wf => {
|
|
38
|
-
// Parse metadata for timeout configuration
|
|
39
|
-
|
|
40
27
|
const metadata = parseWorkflowMetadata(wf.metadata_json);
|
|
41
|
-
const timeoutMs = metadata.timeoutMs ?? 15 * 60 * 1000;
|
|
28
|
+
const timeoutMs = metadata.timeoutMs ?? 15 * 60 * 1000;
|
|
42
29
|
|
|
43
|
-
// Check if workflow is stuck (active and exceeded timeout)
|
|
44
30
|
const isStuck = wf.state === 'active' && (now - wf.created_at) > timeoutMs;
|
|
45
31
|
const stuckDuration = isStuck ? now - wf.created_at : null;
|
|
46
32
|
|
|
@@ -56,158 +42,6 @@ export class MonitoringQueryService {
|
|
|
56
42
|
|
|
57
43
|
return { workflows: workflowsWithStuckDetection };
|
|
58
44
|
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Get Trinity stage status for a specific workflow.
|
|
62
|
-
* @param workflowId - Workflow ID to query
|
|
63
|
-
* @returns Trinity stage status or null if workflow not found
|
|
64
|
-
*/
|
|
65
|
-
getTrinityStatus(workflowId: string): TrinityStatusResponse | null {
|
|
66
|
-
// Get workflow and validate
|
|
67
|
-
const workflow = this.store.getWorkflow(workflowId);
|
|
68
|
-
if (!workflow) {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Fetch stage data
|
|
73
|
-
const events = this.store.getEvents(workflowId);
|
|
74
|
-
const stageOutputs = this.store.getStageOutputs(workflowId);
|
|
75
|
-
|
|
76
|
-
// Define stage types
|
|
77
|
-
const stages = ['dreamer', 'philosopher', 'scribe'] as const;
|
|
78
|
-
|
|
79
|
-
// Compute stage states from events
|
|
80
|
-
const stagesInfo: TrinityStageInfo[] = stages.map(stage => {
|
|
81
|
-
// Find events for this stage
|
|
82
|
-
const startEvent = events.find(e => e.event_type === `trinity_${stage}_start`);
|
|
83
|
-
const completeEvent = events.find(e => e.event_type === `trinity_${stage}_complete`);
|
|
84
|
-
const failedEvent = events.find(e => e.event_type === `trinity_${stage}_failed`);
|
|
85
|
-
|
|
86
|
-
// Determine status
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
let status: 'pending' | 'running' | 'completed' | 'failed';
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
let reason: string | undefined;
|
|
93
|
-
|
|
94
|
-
if (!startEvent) {
|
|
95
|
-
status = 'pending';
|
|
96
|
-
reason = undefined;
|
|
97
|
-
} else if (failedEvent) {
|
|
98
|
-
status = 'failed';
|
|
99
|
-
({ reason } = failedEvent);
|
|
100
|
-
} else if (completeEvent) {
|
|
101
|
-
status = 'completed';
|
|
102
|
-
reason = undefined;
|
|
103
|
-
} else {
|
|
104
|
-
status = 'running';
|
|
105
|
-
reason = undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Count outputs for this stage
|
|
109
|
-
const outputCount = stageOutputs.filter(so => so.stage === stage).length;
|
|
110
|
-
|
|
111
|
-
// Calculate duration if stage started and completed/failed
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let duration: number | undefined;
|
|
115
|
-
if (startEvent && (completeEvent || failedEvent)) {
|
|
116
|
-
const endEvent = completeEvent || failedEvent;
|
|
117
|
-
if (endEvent) {
|
|
118
|
-
duration = endEvent.created_at - startEvent.created_at;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return {
|
|
123
|
-
stage,
|
|
124
|
-
status,
|
|
125
|
-
reason,
|
|
126
|
-
outputCount,
|
|
127
|
-
duration,
|
|
128
|
-
};
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
workflowId,
|
|
133
|
-
stages: stagesInfo,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Get aggregate health metrics for all Trinity workflows.
|
|
139
|
-
* @returns Aggregate health statistics
|
|
140
|
-
*/
|
|
141
|
-
getTrinityHealth(): TrinityHealthResponse {
|
|
142
|
-
// Get all workflows
|
|
143
|
-
const workflows = this.store.listWorkflows();
|
|
144
|
-
|
|
145
|
-
// Initialize counters
|
|
146
|
-
let totalCalls = 0;
|
|
147
|
-
let totalDuration = 0;
|
|
148
|
-
let failedCalls = 0;
|
|
149
|
-
|
|
150
|
-
// Initialize stage statistics
|
|
151
|
-
const stageStats = {
|
|
152
|
-
dreamer: { total: 0, completed: 0, failed: 0 },
|
|
153
|
-
philosopher: { total: 0, completed: 0, failed: 0 },
|
|
154
|
-
scribe: { total: 0, completed: 0, failed: 0 },
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// Iterate through workflows and aggregate
|
|
158
|
-
for (const workflow of workflows) {
|
|
159
|
-
const events = this.store.getEvents(workflow.workflow_id);
|
|
160
|
-
const isTerminal =
|
|
161
|
-
workflow.state === 'completed'
|
|
162
|
-
|| workflow.state === 'terminal_error'
|
|
163
|
-
|| workflow.state === 'expired'
|
|
164
|
-
|| workflow.state === 'cleanup_pending';
|
|
165
|
-
let workflowFailed = false;
|
|
166
|
-
|
|
167
|
-
// Aggregate stage statistics
|
|
168
|
-
for (const stage of ['dreamer', 'philosopher', 'scribe'] as const) {
|
|
169
|
-
// Check if stage started
|
|
170
|
-
const started = events.some(e => e.event_type === `trinity_${stage}_start`);
|
|
171
|
-
if (started) {
|
|
172
|
-
stageStats[stage].total++;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Check if completed
|
|
176
|
-
const completed = events.some(e => e.event_type === `trinity_${stage}_complete`);
|
|
177
|
-
if (completed) {
|
|
178
|
-
stageStats[stage].completed++;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Check if failed
|
|
182
|
-
const failed = events.some(e => e.event_type === `trinity_${stage}_failed`);
|
|
183
|
-
if (failed) {
|
|
184
|
-
stageStats[stage].failed++;
|
|
185
|
-
workflowFailed = true;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Calculate duration for terminal workflows so the aggregate reflects all finished runs.
|
|
190
|
-
if (isTerminal) {
|
|
191
|
-
totalCalls++;
|
|
192
|
-
const duration = workflow.duration_ms ?? (Date.now() - workflow.created_at);
|
|
193
|
-
totalDuration += duration;
|
|
194
|
-
if (workflowFailed || workflow.state === 'terminal_error' || workflow.state === 'expired') {
|
|
195
|
-
failedCalls++;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Calculate derived metrics
|
|
201
|
-
const avgDuration = totalCalls > 0 ? totalDuration / totalCalls : 0;
|
|
202
|
-
const failureRate = totalCalls > 0 ? failedCalls / totalCalls : 0;
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
totalCalls,
|
|
206
|
-
avgDuration: Math.round(avgDuration),
|
|
207
|
-
failureRate: Number(failureRate.toFixed(4)),
|
|
208
|
-
stageStats,
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
45
|
}
|
|
212
46
|
|
|
213
47
|
function parseWorkflowMetadata(metadataJson: string): { timeoutMs?: number } {
|
|
@@ -219,16 +53,10 @@ function parseWorkflowMetadata(metadataJson: string): { timeoutMs?: number } {
|
|
|
219
53
|
}
|
|
220
54
|
}
|
|
221
55
|
|
|
222
|
-
/**
|
|
223
|
-
* Response type for workflow listing endpoint.
|
|
224
|
-
*/
|
|
225
56
|
export interface WorkflowListResponse {
|
|
226
57
|
workflows: WorkflowInfo[];
|
|
227
58
|
}
|
|
228
59
|
|
|
229
|
-
/**
|
|
230
|
-
* Enriched workflow information with stuck detection.
|
|
231
|
-
*/
|
|
232
60
|
export interface WorkflowInfo {
|
|
233
61
|
workflowId: string;
|
|
234
62
|
type: string;
|
|
@@ -237,45 +65,3 @@ export interface WorkflowInfo {
|
|
|
237
65
|
createdAt: string;
|
|
238
66
|
stuckDuration: number | null;
|
|
239
67
|
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Response type for Trinity status endpoint.
|
|
243
|
-
*/
|
|
244
|
-
export interface TrinityStatusResponse {
|
|
245
|
-
workflowId: string;
|
|
246
|
-
stages: TrinityStageInfo[];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Information about a single Trinity stage.
|
|
251
|
-
*/
|
|
252
|
-
export interface TrinityStageInfo {
|
|
253
|
-
stage: 'dreamer' | 'philosopher' | 'scribe';
|
|
254
|
-
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
255
|
-
reason?: string;
|
|
256
|
-
outputCount: number;
|
|
257
|
-
duration?: number;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Response type for Trinity health metrics endpoint.
|
|
262
|
-
*/
|
|
263
|
-
export interface TrinityHealthResponse {
|
|
264
|
-
totalCalls: number;
|
|
265
|
-
avgDuration: number;
|
|
266
|
-
failureRate: number;
|
|
267
|
-
stageStats: {
|
|
268
|
-
dreamer: StageStats;
|
|
269
|
-
philosopher: StageStats;
|
|
270
|
-
scribe: StageStats;
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Per-stage statistics.
|
|
276
|
-
*/
|
|
277
|
-
export interface StageStats {
|
|
278
|
-
total: number;
|
|
279
|
-
completed: number;
|
|
280
|
-
failed: number;
|
|
281
|
-
}
|