principles-disciple 1.11.0 → 1.13.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/CHANGELOG.md +26 -0
- package/README.md +66 -0
- package/esbuild.config.js +1 -1
- package/openclaw.plugin.json +4 -4
- package/package.json +2 -3
- package/run-nocturnal.mjs +30 -0
- package/scripts/db-migrate.mjs +170 -0
- package/scripts/sync-plugin.mjs +250 -6
- package/src/commands/archive-impl.ts +136 -0
- package/src/commands/capabilities.ts +4 -2
- package/src/commands/context.ts +5 -1
- package/src/commands/disable-impl.ts +151 -0
- package/src/commands/evolution-status.ts +64 -19
- package/src/commands/export.ts +8 -6
- package/src/commands/focus.ts +8 -20
- package/src/commands/nocturnal-review.ts +5 -7
- package/src/commands/nocturnal-rollout.ts +1 -12
- package/src/commands/nocturnal-train.ts +21 -47
- package/src/commands/pain.ts +10 -5
- package/src/commands/principle-rollback.ts +4 -2
- package/src/commands/promote-impl.ts +274 -0
- package/src/commands/rollback-impl.ts +234 -0
- package/src/commands/rollback.ts +6 -3
- package/src/commands/samples.ts +2 -0
- package/src/commands/thinking-os.ts +3 -4
- package/src/commands/workflow-debug.ts +2 -1
- package/src/config/errors.ts +1 -0
- package/src/core/AGENTS.md +34 -0
- package/src/core/adaptive-thresholds.ts +4 -3
- package/src/core/code-implementation-storage.ts +241 -0
- package/src/core/config.ts +5 -2
- package/src/core/control-ui-db.ts +29 -10
- package/src/core/detection-funnel.ts +12 -7
- package/src/core/diagnostician-task-store.ts +156 -0
- package/src/core/dictionary.ts +4 -4
- package/src/core/empathy-keyword-matcher.ts +7 -3
- package/src/core/empathy-types.ts +13 -2
- package/src/core/event-log.ts +14 -6
- package/src/core/evolution-engine.ts +27 -31
- package/src/core/evolution-logger.ts +3 -2
- package/src/core/evolution-reducer.ts +110 -31
- package/src/core/evolution-types.ts +10 -0
- package/src/core/external-training-contract.ts +1 -0
- package/src/core/focus-history.ts +38 -24
- package/src/core/hygiene/tracker.ts +10 -6
- package/src/core/init.ts +5 -2
- package/src/core/migration.ts +3 -3
- package/src/core/model-deployment-registry.ts +6 -4
- package/src/core/model-training-registry.ts +5 -3
- package/src/core/nocturnal-arbiter.ts +13 -14
- package/src/core/nocturnal-artifact-lineage.ts +117 -0
- package/src/core/nocturnal-artificer.ts +257 -0
- package/src/core/nocturnal-candidate-scoring.ts +4 -2
- package/src/core/nocturnal-compliance.ts +67 -19
- package/src/core/nocturnal-dataset.ts +95 -2
- package/src/core/nocturnal-executability.ts +2 -3
- package/src/core/nocturnal-export.ts +6 -3
- package/src/core/nocturnal-rule-implementation-validator.ts +245 -0
- package/src/core/nocturnal-trajectory-extractor.ts +10 -3
- package/src/core/nocturnal-trinity.ts +319 -61
- package/src/core/pain-context-extractor.ts +29 -15
- package/src/core/pain.ts +7 -5
- package/src/core/path-resolver.ts +16 -15
- package/src/core/paths.ts +2 -1
- package/src/core/pd-task-reconciler.ts +463 -0
- package/src/core/pd-task-service.ts +42 -0
- package/src/core/pd-task-store.ts +77 -0
- package/src/core/pd-task-types.ts +128 -0
- package/src/core/principle-internalization/deprecated-readiness.ts +91 -0
- package/src/core/principle-internalization/internalization-routing-policy.ts +208 -0
- package/src/core/principle-internalization/lifecycle-metrics.ts +149 -0
- package/src/core/principle-internalization/lifecycle-read-model.ts +243 -0
- package/src/core/principle-internalization/lifecycle-refresh.ts +11 -0
- package/src/core/principle-internalization/principle-lifecycle-service.ts +167 -0
- package/src/core/principle-training-state.ts +95 -370
- package/src/core/principle-tree-ledger.ts +733 -0
- package/src/core/principle-tree-migration.ts +195 -0
- package/src/core/profile.ts +3 -1
- package/src/core/promotion-gate.ts +14 -18
- package/src/core/replay-engine.ts +562 -0
- package/src/core/risk-calculator.ts +6 -4
- package/src/core/rule-host-helpers.ts +39 -0
- package/src/core/rule-host-types.ts +82 -0
- package/src/core/rule-host.ts +245 -0
- package/src/core/rule-implementation-runtime.ts +38 -0
- package/src/core/schema/db-types.ts +16 -0
- package/src/core/schema/index.ts +26 -0
- package/src/core/schema/migration-runner.ts +207 -0
- package/src/core/schema/migrations/001-init-trajectory.ts +211 -0
- package/src/core/schema/migrations/002-init-central.ts +122 -0
- package/src/core/schema/migrations/003-init-workflow.ts +55 -0
- package/src/core/schema/migrations/004-add-thinking-and-gfi.ts +74 -0
- package/src/core/schema/migrations/index.ts +31 -0
- package/src/core/schema/schema-definitions.ts +650 -0
- package/src/core/session-tracker.ts +6 -4
- package/src/core/shadow-observation-registry.ts +6 -3
- package/src/core/system-logger.ts +2 -2
- package/src/core/thinking-models.ts +182 -46
- package/src/core/thinking-os-parser.ts +156 -0
- package/src/core/training-program.ts +7 -7
- package/src/core/trajectory.ts +42 -36
- package/src/core/workspace-context.ts +77 -11
- package/src/core/workspace-dir-validation.ts +152 -0
- package/src/hooks/AGENTS.md +31 -0
- package/src/hooks/bash-risk.ts +3 -1
- package/src/hooks/edit-verification.ts +9 -5
- package/src/hooks/gate-block-helper.ts +5 -1
- package/src/hooks/gate.ts +152 -5
- package/src/hooks/gfi-gate.ts +9 -2
- package/src/hooks/lifecycle-routing.ts +124 -0
- package/src/hooks/lifecycle.ts +12 -12
- package/src/hooks/llm.ts +17 -109
- package/src/hooks/message-sanitize.ts +5 -3
- package/src/hooks/pain.ts +19 -15
- package/src/hooks/progressive-trust-gate.ts +7 -1
- package/src/hooks/prompt.ts +169 -60
- package/src/hooks/subagent.ts +5 -4
- package/src/hooks/thinking-checkpoint.ts +2 -0
- package/src/hooks/trajectory-collector.ts +15 -12
- package/src/http/principles-console-route.ts +31 -68
- package/src/i18n/commands.ts +2 -2
- package/src/index.ts +130 -40
- package/src/service/central-database.ts +131 -43
- package/src/service/central-health-service.ts +47 -0
- package/src/service/central-overview-service.ts +135 -0
- package/src/service/central-sync-service.ts +87 -0
- package/src/service/control-ui-query-service.ts +46 -36
- package/src/service/event-log-auditor.ts +261 -0
- package/src/service/evolution-query-service.ts +23 -22
- package/src/service/evolution-worker.ts +565 -261
- package/src/service/health-query-service.ts +213 -36
- package/src/service/nocturnal-runtime.ts +8 -4
- package/src/service/nocturnal-service.ts +503 -59
- package/src/service/nocturnal-target-selector.ts +5 -7
- package/src/service/runtime-summary-service.ts +2 -1
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +25 -336
- package/src/service/subagent-workflow/dynamic-timeout.ts +30 -0
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +48 -386
- package/src/service/subagent-workflow/index.ts +2 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +169 -284
- package/src/service/subagent-workflow/runtime-direct-driver.ts +114 -16
- package/src/service/subagent-workflow/subagent-error-utils.ts +25 -0
- package/src/service/subagent-workflow/types.ts +9 -4
- package/src/service/subagent-workflow/workflow-manager-base.ts +573 -0
- package/src/service/subagent-workflow/workflow-store.ts +71 -11
- package/src/service/trajectory-service.ts +2 -1
- package/src/tools/critique-prompt.ts +1 -1
- package/src/tools/deep-reflect.ts +175 -209
- package/src/tools/model-index.ts +2 -1
- package/src/types/event-types.ts +2 -2
- package/src/types/principle-tree-schema.ts +29 -23
- package/src/utils/file-lock.ts +5 -3
- package/src/utils/io.ts +5 -2
- package/src/utils/nlp.ts +5 -46
- package/src/utils/node-vm-polyfill.ts +11 -0
- package/src/utils/plugin-logger.ts +2 -0
- package/src/utils/retry.ts +572 -0
- package/src/utils/subagent-probe.ts +1 -1
- package/templates/langs/en/core/AGENTS.md +0 -13
- package/templates/langs/en/core/SOUL.md +1 -31
- package/templates/langs/en/core/TOOLS.md +0 -4
- package/templates/langs/en/principles/THINKING_OS.md +77 -0
- package/templates/langs/en/skills/admin/SKILL.md +0 -1
- package/templates/langs/en/skills/evolution-framework-update/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-diagnostician/SKILL.md +18 -5
- package/templates/langs/zh/core/AGENTS.md +0 -22
- package/templates/langs/zh/core/SOUL.md +1 -31
- package/templates/langs/zh/core/TOOLS.md +0 -4
- package/templates/langs/zh/principles/THINKING_OS.md +77 -0
- package/templates/langs/zh/skills/admin/SKILL.md +0 -1
- package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +25 -4
- package/tests/commands/evolution-status.test.ts +119 -0
- package/tests/commands/implementation-lifecycle.test.ts +362 -0
- package/tests/core/code-implementation-storage.test.ts +398 -0
- package/tests/core/evolution-reducer.detector-metadata.test.ts +28 -28
- package/tests/core/nocturnal-artifact-lineage.test.ts +53 -0
- package/tests/core/nocturnal-artificer.test.ts +241 -0
- package/tests/core/nocturnal-compliance-p-principles.test.ts +133 -0
- package/tests/core/nocturnal-rule-implementation-validator.test.ts +127 -0
- package/tests/core/pd-task-store.test.ts +126 -0
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +193 -0
- package/tests/core/principle-internalization/internalization-routing-policy.test.ts +212 -0
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +350 -0
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +211 -0
- package/tests/core/principle-training-state.test.ts +228 -1
- package/tests/core/principle-tree-ledger.test.ts +423 -0
- package/tests/core/regression-v1-9-1.test.ts +265 -0
- package/tests/core/replay-engine.test.ts +234 -0
- package/tests/core/rule-host-helpers.test.ts +120 -0
- package/tests/core/rule-host.test.ts +389 -0
- package/tests/core/rule-implementation-runtime.test.ts +64 -0
- package/tests/core/workspace-context.test.ts +53 -0
- package/tests/core/workspace-dir-validation.test.ts +272 -0
- package/tests/hooks/gate-rule-host-pipeline.test.ts +385 -0
- package/tests/hooks/pain.test.ts +74 -10
- package/tests/hooks/prompt.test.ts +63 -1
- package/tests/integration/principle-lifecycle.e2e.test.ts +197 -0
- package/tests/integration/tool-hooks-workspace-dir.e2e.test.ts +211 -0
- package/tests/service/data-endpoints-regression.test.ts +834 -0
- package/tests/service/evolution-worker.test.ts +0 -123
- package/tests/service/nocturnal-service-code-candidate.test.ts +330 -0
- package/tests/utils/nlp.test.ts +1 -19
- package/tests/utils/retry.test.ts +327 -0
- package/ui/src/App.tsx +1 -1
- package/ui/src/api.ts +4 -0
- package/ui/src/charts.tsx +366 -0
- package/ui/src/components/WorkspaceConfig.tsx +107 -75
- package/ui/src/i18n/ui.ts +89 -31
- package/ui/src/pages/EvolutionPage.tsx +1 -1
- package/ui/src/pages/OverviewPage.tsx +441 -81
- package/ui/src/pages/ThinkingModelsPage.tsx +287 -69
- package/ui/src/styles.css +43 -0
- package/ui/src/types.ts +17 -1
- package/src/agents/nocturnal-dreamer.md +0 -152
- package/src/agents/nocturnal-philosopher.md +0 -138
- package/src/agents/nocturnal-reflector.md +0 -126
- package/src/agents/nocturnal-scribe.md +0 -164
- package/templates/workspace/.principles/00-kernel.md +0 -51
- package/templates/workspace/.principles/DECISION_POLICY.json +0 -44
- package/templates/workspace/.principles/PRINCIPLES.md +0 -20
- package/templates/workspace/.principles/PROFILE.json +0 -54
- package/templates/workspace/.principles/PROFILE.schema.json +0 -56
- package/templates/workspace/.principles/THINKING_OS.md +0 -64
- package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +0 -7
- package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +0 -9
- package/templates/workspace/.principles/models/_INDEX.md +0 -27
- package/templates/workspace/.principles/models/first_principles.md +0 -62
- package/templates/workspace/.principles/models/marketing_4p.md +0 -52
- package/templates/workspace/.principles/models/porter_five.md +0 -63
- package/templates/workspace/.principles/models/swot.md +0 -60
- package/templates/workspace/.principles/models/user_story_map.md +0 -63
- package/templates/workspace/.state/WORKBOARD.json +0 -4
|
@@ -27,11 +27,9 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { randomUUID } from 'crypto';
|
|
30
|
-
import * as fs from 'fs';
|
|
31
|
-
import * as path from 'path';
|
|
32
|
-
import * as url from 'url';
|
|
33
30
|
import type { NocturnalSessionSnapshot } from './nocturnal-trajectory-extractor.js';
|
|
34
31
|
import { computeThinkingModelDelta } from './nocturnal-trajectory-extractor.js';
|
|
32
|
+
import type { TrinityArtificerContext } from './nocturnal-artificer.js';
|
|
35
33
|
import {
|
|
36
34
|
runTournament,
|
|
37
35
|
DEFAULT_SCORING_WEIGHTS,
|
|
@@ -45,22 +43,231 @@ import {
|
|
|
45
43
|
} from './adaptive-thresholds.js';
|
|
46
44
|
|
|
47
45
|
// ---------------------------------------------------------------------------
|
|
48
|
-
// Role
|
|
46
|
+
// Embedded Role Prompts
|
|
49
47
|
// ---------------------------------------------------------------------------
|
|
48
|
+
// These prompts are embedded at build time to eliminate file system dependency.
|
|
49
|
+
// Previously loaded from src/agents/*.md at runtime — fragile because esbuild
|
|
50
|
+
// did not copy the agents/ directory into the bundle.
|
|
50
51
|
|
|
51
|
-
const
|
|
52
|
-
const AGENTS_DIR = path.join(__dirname, '../agents');
|
|
52
|
+
const NOCTURNAL_DREAMER_PROMPT = `# Nocturnal Dreamer — Candidate Generation
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
> System prompt for Trinity Dreamer stage.
|
|
55
|
+
> Role: Generate multiple alternative "better decision" candidates from a session snapshot.
|
|
56
|
+
|
|
57
|
+
## Role
|
|
58
|
+
|
|
59
|
+
You are a principles analyst specializing in identifying decision alternatives.
|
|
60
|
+
Your task is to analyze a session trajectory and generate **multiple candidate corrections**,
|
|
61
|
+
each representing a different valid approach to the same problem.
|
|
62
|
+
|
|
63
|
+
## Input
|
|
64
|
+
|
|
65
|
+
You will receive:
|
|
66
|
+
- A **target principle** (principle ID and description)
|
|
67
|
+
- A **session trajectory snapshot** containing:
|
|
68
|
+
- Assistant turns (sanitized text, no raw content)
|
|
69
|
+
- User turns (correction cues only, no raw content)
|
|
70
|
+
- Tool calls with outcomes and error messages
|
|
71
|
+
- Pain events and gate blocks
|
|
72
|
+
- Session metadata
|
|
73
|
+
|
|
74
|
+
## Task
|
|
75
|
+
|
|
76
|
+
Analyze the session and generate **2-3 candidate corrections**, each capturing:
|
|
77
|
+
|
|
78
|
+
1. **The bad decision**: What the agent decided or did that violated the target principle
|
|
79
|
+
2. **The better decision**: What the agent should have done instead (unique per candidate)
|
|
80
|
+
3. **The rationale**: Why this alternative is better
|
|
81
|
+
4. **Confidence**: How confident you are this is a valid alternative (0.0-1.0)
|
|
82
|
+
|
|
83
|
+
## Output Format
|
|
84
|
+
|
|
85
|
+
You MUST respond with ONLY a valid JSON object. No markdown, no explanation, no preamble.
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
"valid": true,
|
|
89
|
+
"candidates": [
|
|
90
|
+
{
|
|
91
|
+
"candidateIndex": 0,
|
|
92
|
+
"badDecision": "<what the agent did wrong>",
|
|
93
|
+
"betterDecision": "<what the agent should have done>",
|
|
94
|
+
"rationale": "<why this is better>",
|
|
95
|
+
"confidence": 0.95
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"generatedAt": "<ISO timestamp>"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
## Quality Standards
|
|
102
|
+
|
|
103
|
+
### Each candidate MUST:
|
|
104
|
+
- Have a candidateIndex that is unique within the candidate list
|
|
105
|
+
- Describe a specific, concrete badDecision (not generic anti-patterns)
|
|
106
|
+
- Propose a specific, actionable betterDecision (contains an action verb)
|
|
107
|
+
- Provide a principle-grounded rationale (explicitly references the principle)
|
|
108
|
+
- Include a confidence score (0.0-1.0, higher = more confident)
|
|
109
|
+
|
|
110
|
+
### Candidates should DIFFER from each other:
|
|
111
|
+
- Different candidates should represent genuinely different approaches
|
|
112
|
+
- Do not generate candidates with identical betterDecisions
|
|
113
|
+
- Vary the confidence scores to reflect genuine uncertainty
|
|
114
|
+
|
|
115
|
+
### Candidates must NOT:
|
|
116
|
+
- Contain raw user text or private content
|
|
117
|
+
- Reference non-existent tools or impossible actions
|
|
118
|
+
- Propose vague improvements ("be more careful")
|
|
119
|
+
- Exceed the requested number of candidates
|
|
120
|
+
|
|
121
|
+
## Validation
|
|
122
|
+
|
|
123
|
+
If you cannot generate valid candidates (e.g., no clear violation found, insufficient data), respond with:
|
|
124
|
+
|
|
125
|
+
{
|
|
126
|
+
"valid": false,
|
|
127
|
+
"candidates": [],
|
|
128
|
+
"reason": "<why valid candidates cannot be generated>",
|
|
129
|
+
"generatedAt": "<ISO timestamp>"
|
|
130
|
+
}`;
|
|
131
|
+
|
|
132
|
+
const NOCTURNAL_PHILOSOPHER_PROMPT = `# Nocturnal Philosopher — Candidate Evaluation and Ranking
|
|
133
|
+
|
|
134
|
+
> System prompt for Trinity Philosopher stage.
|
|
135
|
+
> Role: Evaluate Dreamer's candidates and rank them by principle alignment and quality.
|
|
136
|
+
|
|
137
|
+
## Role
|
|
138
|
+
|
|
139
|
+
You are a principles analyst specializing in critical evaluation.
|
|
140
|
+
Your task is to evaluate Dreamer's candidate corrections and rank them
|
|
141
|
+
based on principle alignment, specificity, and actionability.
|
|
142
|
+
|
|
143
|
+
## Input
|
|
144
|
+
|
|
145
|
+
You will receive:
|
|
146
|
+
- A **target principle** (principle ID and description)
|
|
147
|
+
- **Dreamer's candidates** — a list of alternative corrections to evaluate
|
|
148
|
+
|
|
149
|
+
## Task
|
|
150
|
+
|
|
151
|
+
For each candidate, provide:
|
|
152
|
+
1. **Critique**: A principle-grounded assessment of this candidate's strengths and weaknesses
|
|
153
|
+
2. **Principle alignment**: Whether this candidate properly aligns with the target principle
|
|
154
|
+
3. **Score**: Overall quality score (0.0-1.0, higher = better)
|
|
155
|
+
4. **Rank**: Relative ranking among all candidates (1 = best)
|
|
156
|
+
|
|
157
|
+
Finally, provide an **overall assessment** of the candidate set.
|
|
158
|
+
|
|
159
|
+
## Output Format
|
|
160
|
+
|
|
161
|
+
You MUST respond with ONLY a valid JSON object. No markdown, no explanation, no preamble.
|
|
162
|
+
|
|
163
|
+
{
|
|
164
|
+
"valid": true,
|
|
165
|
+
"judgments": [
|
|
166
|
+
{
|
|
167
|
+
"candidateIndex": 0,
|
|
168
|
+
"critique": "<principle-grounded critique>",
|
|
169
|
+
"principleAligned": true,
|
|
170
|
+
"score": 0.92,
|
|
171
|
+
"rank": 1
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"overallAssessment": "<summary of candidate set quality>",
|
|
175
|
+
"generatedAt": "<ISO timestamp>"
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
## Evaluation Criteria
|
|
179
|
+
|
|
180
|
+
### Score Components (0-1 scale each):
|
|
181
|
+
1. **Principle Alignment** (weight: 0.4) — Does the betterDecision properly reflect the target principle?
|
|
182
|
+
2. **Specificity** (weight: 0.3) — Is badDecision specific? Is betterDecision actionable?
|
|
183
|
+
3. **Actionability** (weight: 0.3) — Does betterDecision describe a specific next step?
|
|
184
|
+
|
|
185
|
+
### Ranking Rules:
|
|
186
|
+
- Candidates are ranked by score (highest = rank 1)
|
|
187
|
+
- Ties broken by: higher principle alignment, then lower candidateIndex
|
|
188
|
+
|
|
189
|
+
## Validation
|
|
190
|
+
|
|
191
|
+
If you cannot judge the candidates, respond with:
|
|
192
|
+
|
|
193
|
+
{
|
|
194
|
+
"valid": false,
|
|
195
|
+
"judgments": [],
|
|
196
|
+
"overallAssessment": "",
|
|
197
|
+
"reason": "<why judgment cannot be produced>",
|
|
198
|
+
"generatedAt": "<ISO timestamp>"
|
|
199
|
+
}`;
|
|
200
|
+
|
|
201
|
+
const NOCTURNAL_SCRIBE_PROMPT = `# Nocturnal Scribe — Final Artifact Synthesis
|
|
202
|
+
|
|
203
|
+
> System prompt for Trinity Scribe stage.
|
|
204
|
+
> Role: Synthesize the best candidate into a final structured artifact.
|
|
205
|
+
|
|
206
|
+
## Role
|
|
207
|
+
|
|
208
|
+
You are a principles analyst specializing in structured output.
|
|
209
|
+
Your task is to take the top-ranked candidate from Philosopher's evaluation
|
|
210
|
+
and synthesize it into a final decision-point artifact that passes arbiter validation.
|
|
211
|
+
|
|
212
|
+
## Input
|
|
213
|
+
|
|
214
|
+
You will receive:
|
|
215
|
+
- A **target principle** (principle ID and description)
|
|
216
|
+
- A **session trajectory snapshot**
|
|
217
|
+
- **Philosopher's judgments** — ranked candidates with critiques
|
|
218
|
+
- **Dreamer's candidates** — the original candidate list
|
|
219
|
+
|
|
220
|
+
## Task
|
|
221
|
+
|
|
222
|
+
Select the best candidate (Philosopher's rank 1) and synthesize it into
|
|
223
|
+
a final TrinityDraftArtifact.
|
|
224
|
+
|
|
225
|
+
## Output Format
|
|
226
|
+
|
|
227
|
+
You MUST respond with ONLY a valid JSON object. No markdown, no explanation, no preamble.
|
|
228
|
+
|
|
229
|
+
{
|
|
230
|
+
"selectedCandidateIndex": 0,
|
|
231
|
+
"badDecision": "<final bad decision text>",
|
|
232
|
+
"betterDecision": "<final better decision text>",
|
|
233
|
+
"rationale": "<final rationale text>",
|
|
234
|
+
"sessionId": "<source session ID>",
|
|
235
|
+
"principleId": "<principle ID>",
|
|
236
|
+
"sourceSnapshotRef": "<snapshot reference>",
|
|
237
|
+
"telemetry": {
|
|
238
|
+
"chainMode": "trinity",
|
|
239
|
+
"dreamerPassed": true,
|
|
240
|
+
"philosopherPassed": true,
|
|
241
|
+
"scribePassed": true,
|
|
242
|
+
"candidateCount": 2,
|
|
243
|
+
"selectedCandidateIndex": 0,
|
|
244
|
+
"stageFailures": []
|
|
61
245
|
}
|
|
62
246
|
}
|
|
63
247
|
|
|
248
|
+
## Validation
|
|
249
|
+
|
|
250
|
+
If you cannot synthesize an artifact:
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
"selectedCandidateIndex": -1,
|
|
254
|
+
"badDecision": "",
|
|
255
|
+
"betterDecision": "",
|
|
256
|
+
"rationale": "",
|
|
257
|
+
"sessionId": "<source session ID>",
|
|
258
|
+
"principleId": "<principle ID>",
|
|
259
|
+
"sourceSnapshotRef": "",
|
|
260
|
+
"telemetry": {
|
|
261
|
+
"chainMode": "trinity",
|
|
262
|
+
"dreamerPassed": true,
|
|
263
|
+
"philosopherPassed": false,
|
|
264
|
+
"scribePassed": false,
|
|
265
|
+
"candidateCount": 2,
|
|
266
|
+
"selectedCandidateIndex": -1,
|
|
267
|
+
"stageFailures": ["Philosopher: no valid judgments produced"]
|
|
268
|
+
}
|
|
269
|
+
}`;
|
|
270
|
+
|
|
64
271
|
// ---------------------------------------------------------------------------
|
|
65
272
|
// Trinity Runtime Adapter
|
|
66
273
|
// ---------------------------------------------------------------------------
|
|
@@ -69,6 +276,7 @@ function loadRolePrompt(filename: string): string {
|
|
|
69
276
|
* Interface for Trinity stage invocation.
|
|
70
277
|
* Implementations can use real subagent runtimes or stubs.
|
|
71
278
|
*/
|
|
279
|
+
/* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, not implementations */
|
|
72
280
|
export interface TrinityRuntimeAdapter {
|
|
73
281
|
/**
|
|
74
282
|
* Invoke the Dreamer stage.
|
|
@@ -78,9 +286,9 @@ export interface TrinityRuntimeAdapter {
|
|
|
78
286
|
* @returns Dreamer output JSON
|
|
79
287
|
*/
|
|
80
288
|
invokeDreamer(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
289
|
+
_snapshot: NocturnalSessionSnapshot,
|
|
290
|
+
_principleId: string,
|
|
291
|
+
_maxCandidates: number
|
|
84
292
|
): Promise<DreamerOutput>;
|
|
85
293
|
|
|
86
294
|
/**
|
|
@@ -90,8 +298,8 @@ export interface TrinityRuntimeAdapter {
|
|
|
90
298
|
* @returns Philosopher output JSON
|
|
91
299
|
*/
|
|
92
300
|
invokePhilosopher(
|
|
93
|
-
|
|
94
|
-
|
|
301
|
+
_dreamerOutput: DreamerOutput,
|
|
302
|
+
_principleId: string
|
|
95
303
|
): Promise<PhilosopherOutput>;
|
|
96
304
|
|
|
97
305
|
/**
|
|
@@ -105,12 +313,12 @@ export interface TrinityRuntimeAdapter {
|
|
|
105
313
|
* @returns Scribe draft artifact or null if failed
|
|
106
314
|
*/
|
|
107
315
|
invokeScribe(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
316
|
+
_dreamerOutput: DreamerOutput,
|
|
317
|
+
_philosopherOutput: PhilosopherOutput,
|
|
318
|
+
_snapshot: NocturnalSessionSnapshot,
|
|
319
|
+
_principleId: string,
|
|
320
|
+
_telemetry: TrinityTelemetry,
|
|
321
|
+
_config: TrinityConfig
|
|
114
322
|
): Promise<TrinityDraftArtifact | null>;
|
|
115
323
|
|
|
116
324
|
/**
|
|
@@ -119,6 +327,7 @@ export interface TrinityRuntimeAdapter {
|
|
|
119
327
|
*/
|
|
120
328
|
close?(): Promise<void>;
|
|
121
329
|
}
|
|
330
|
+
/* eslint-enable no-unused-vars */
|
|
122
331
|
|
|
123
332
|
// ---------------------------------------------------------------------------
|
|
124
333
|
// OpenClaw Runtime Adapter
|
|
@@ -130,38 +339,40 @@ export interface TrinityRuntimeAdapter {
|
|
|
130
339
|
* Does NOT depend on OpenClaw internals.
|
|
131
340
|
*/
|
|
132
341
|
export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
342
|
+
/* eslint-disable no-unused-vars -- Reason: type-level function parameter names are documentation */
|
|
133
343
|
private readonly api: {
|
|
134
344
|
runtime: {
|
|
135
345
|
subagent: {
|
|
136
|
-
run: (
|
|
346
|
+
run: (_opts: {
|
|
137
347
|
sessionKey: string;
|
|
138
348
|
message: string;
|
|
139
349
|
extraSystemPrompt?: string;
|
|
140
350
|
deliver?: boolean;
|
|
141
351
|
}) => Promise<{ runId: string }>;
|
|
142
|
-
waitForRun: (
|
|
352
|
+
waitForRun: (_opts: { runId: string; timeoutMs: number }) => Promise<{
|
|
143
353
|
status: string;
|
|
144
354
|
error?: string;
|
|
145
355
|
}>;
|
|
146
|
-
getSessionMessages: (
|
|
356
|
+
getSessionMessages: (_opts: {
|
|
147
357
|
sessionKey: string;
|
|
148
358
|
limit: number;
|
|
149
359
|
}) => Promise<{
|
|
150
360
|
messages: unknown[];
|
|
151
361
|
}>;
|
|
152
|
-
deleteSession: (
|
|
362
|
+
deleteSession: (_opts: {
|
|
153
363
|
sessionKey: string;
|
|
154
364
|
deleteTranscript?: boolean;
|
|
155
365
|
}) => Promise<void>;
|
|
156
366
|
};
|
|
157
367
|
};
|
|
158
368
|
};
|
|
369
|
+
/* eslint-enable no-unused-vars */
|
|
159
370
|
|
|
160
371
|
private readonly stageTimeoutMs: number;
|
|
161
372
|
|
|
162
373
|
constructor(
|
|
163
374
|
api: OpenClawTrinityRuntimeAdapter['api'],
|
|
164
|
-
stageTimeoutMs =
|
|
375
|
+
stageTimeoutMs = 300_000 // 5 min — increased from 3 min to accommodate slower LLM responses
|
|
165
376
|
) {
|
|
166
377
|
this.api = api;
|
|
167
378
|
this.stageTimeoutMs = stageTimeoutMs;
|
|
@@ -173,7 +384,7 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
173
384
|
maxCandidates: number
|
|
174
385
|
): Promise<DreamerOutput> {
|
|
175
386
|
const sessionKey = `agent:main:subagent:ne-dreamer-${randomUUID()}`;
|
|
176
|
-
const systemPrompt =
|
|
387
|
+
const systemPrompt = NOCTURNAL_DREAMER_PROMPT;
|
|
177
388
|
|
|
178
389
|
const prompt = this.buildDreamerPrompt(snapshot, principleId, maxCandidates);
|
|
179
390
|
|
|
@@ -204,13 +415,13 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
204
415
|
limit: 5,
|
|
205
416
|
});
|
|
206
417
|
|
|
207
|
-
const outputText = this.extractAssistantText(messages.messages as
|
|
418
|
+
const outputText = this.extractAssistantText(messages.messages as { role: string; text?: string; content?: string }[]);
|
|
208
419
|
return this.parseDreamerOutput(outputText);
|
|
209
420
|
} finally {
|
|
210
421
|
await this.api.runtime.subagent.deleteSession({
|
|
211
422
|
sessionKey,
|
|
212
423
|
deleteTranscript: true,
|
|
213
|
-
}).catch(() => {});
|
|
424
|
+
}).catch(() => { /* intentionally empty - fire-and-forget session cleanup */ });
|
|
214
425
|
}
|
|
215
426
|
}
|
|
216
427
|
|
|
@@ -219,7 +430,7 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
219
430
|
principleId: string
|
|
220
431
|
): Promise<PhilosopherOutput> {
|
|
221
432
|
const sessionKey = `agent:main:subagent:ne-philosopher-${randomUUID()}`;
|
|
222
|
-
const systemPrompt =
|
|
433
|
+
const systemPrompt = NOCTURNAL_PHILOSOPHER_PROMPT;
|
|
223
434
|
|
|
224
435
|
const prompt = this.buildPhilosopherPrompt(dreamerOutput, principleId);
|
|
225
436
|
|
|
@@ -251,26 +462,28 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
251
462
|
limit: 5,
|
|
252
463
|
});
|
|
253
464
|
|
|
254
|
-
const outputText = this.extractAssistantText(messages.messages as
|
|
465
|
+
const outputText = this.extractAssistantText(messages.messages as { role: string; text?: string; content?: string }[]);
|
|
255
466
|
return this.parsePhilosopherOutput(outputText);
|
|
256
467
|
} finally {
|
|
257
468
|
await this.api.runtime.subagent.deleteSession({
|
|
258
469
|
sessionKey,
|
|
259
470
|
deleteTranscript: true,
|
|
260
|
-
}).catch(() => {});
|
|
471
|
+
}).catch(() => { /* intentionally empty - fire-and-forget session cleanup */ });
|
|
261
472
|
}
|
|
262
473
|
}
|
|
263
474
|
|
|
475
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- Reason: scribe invocation requires all context parameters - refactoring would break API
|
|
264
476
|
async invokeScribe(
|
|
265
477
|
dreamerOutput: DreamerOutput,
|
|
266
478
|
philosopherOutput: PhilosopherOutput,
|
|
267
479
|
snapshot: NocturnalSessionSnapshot,
|
|
268
480
|
principleId: string,
|
|
269
481
|
telemetry: TrinityTelemetry,
|
|
270
|
-
|
|
482
|
+
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars -- Reason: interface requires this param but implementation doesn't use it
|
|
483
|
+
_config: TrinityConfig
|
|
271
484
|
): Promise<TrinityDraftArtifact | null> {
|
|
272
485
|
const sessionKey = `agent:main:subagent:ne-scribe-${randomUUID()}`;
|
|
273
|
-
const systemPrompt =
|
|
486
|
+
const systemPrompt = NOCTURNAL_SCRIBE_PROMPT;
|
|
274
487
|
|
|
275
488
|
const prompt = this.buildScribePrompt(dreamerOutput, philosopherOutput, snapshot, principleId);
|
|
276
489
|
|
|
@@ -296,16 +509,17 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
296
509
|
limit: 5,
|
|
297
510
|
});
|
|
298
511
|
|
|
299
|
-
const outputText = this.extractAssistantText(messages.messages as
|
|
512
|
+
const outputText = this.extractAssistantText(messages.messages as { role: string; text?: string; content?: string }[]);
|
|
300
513
|
return this.parseScribeOutput(outputText, snapshot, principleId, telemetry);
|
|
301
514
|
} finally {
|
|
302
515
|
await this.api.runtime.subagent.deleteSession({
|
|
303
516
|
sessionKey,
|
|
304
517
|
deleteTranscript: true,
|
|
305
|
-
}).catch(() => {});
|
|
518
|
+
}).catch(() => { /* intentionally empty - fire-and-forget session cleanup */ });
|
|
306
519
|
}
|
|
307
520
|
}
|
|
308
521
|
|
|
522
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Reason: interface-required close() with no-op implementation
|
|
309
523
|
async close(): Promise<void> {
|
|
310
524
|
// Nothing to clean up in this implementation
|
|
311
525
|
}
|
|
@@ -314,8 +528,9 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
314
528
|
// Private Helper Methods
|
|
315
529
|
// ---------------------------------------------------------------------------
|
|
316
530
|
|
|
531
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Reason: pure utility function that doesn't need instance state
|
|
317
532
|
private extractAssistantText(
|
|
318
|
-
messages:
|
|
533
|
+
messages: { role: string; text?: string; content?: string }[]
|
|
319
534
|
): string {
|
|
320
535
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
321
536
|
const msg = messages[i] as { role: string; text?: string; content?: string };
|
|
@@ -326,6 +541,7 @@ export class OpenClawTrinityRuntimeAdapter implements TrinityRuntimeAdapter {
|
|
|
326
541
|
return '';
|
|
327
542
|
}
|
|
328
543
|
|
|
544
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Reason: pure utility function that doesn't need instance state
|
|
329
545
|
private buildDreamerPrompt(
|
|
330
546
|
snapshot: NocturnalSessionSnapshot,
|
|
331
547
|
principleId: string,
|
|
@@ -346,6 +562,7 @@ Please analyze this session and generate ${maxCandidates} candidate corrections.
|
|
|
346
562
|
Respond with ONLY a valid JSON object matching the DreamerOutput contract.`;
|
|
347
563
|
}
|
|
348
564
|
|
|
565
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Reason: utility method doesn't require this - pure prompt building function
|
|
349
566
|
private buildPhilosopherPrompt(
|
|
350
567
|
dreamerOutput: DreamerOutput,
|
|
351
568
|
principleId: string
|
|
@@ -359,6 +576,7 @@ ${candidatesJson}
|
|
|
359
576
|
Please evaluate each candidate and rank them by principle alignment, specificity, and actionability. Respond with ONLY a valid JSON object matching the PhilosopherOutput contract.`;
|
|
360
577
|
}
|
|
361
578
|
|
|
579
|
+
/* eslint-disable @typescript-eslint/class-methods-use-this, @typescript-eslint/max-params -- Reason: helper function needs all 4 context params and doesn't use instance state */
|
|
362
580
|
private buildScribePrompt(
|
|
363
581
|
dreamerOutput: DreamerOutput,
|
|
364
582
|
philosopherOutput: PhilosopherOutput,
|
|
@@ -378,6 +596,7 @@ ${judgmentsJson}
|
|
|
378
596
|
|
|
379
597
|
Select the best candidate (Philosopher's rank 1) and synthesize it into a final TrinityDraftArtifact. Respond with ONLY a valid JSON object.`;
|
|
380
598
|
}
|
|
599
|
+
/* eslint-enable @typescript-eslint/class-methods-use-this, @typescript-eslint/max-params */
|
|
381
600
|
|
|
382
601
|
private parseDreamerOutput(text: string): DreamerOutput {
|
|
383
602
|
const json = this.extractJson(text);
|
|
@@ -475,11 +694,13 @@ Select the best candidate (Philosopher's rank 1) and synthesize it into a final
|
|
|
475
694
|
}
|
|
476
695
|
}
|
|
477
696
|
|
|
697
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- Reason: output parsing requires text + snapshot + principleId + telemetry - refactoring would break API
|
|
478
698
|
private parseScribeOutput(
|
|
479
699
|
text: string,
|
|
480
700
|
snapshot: NocturnalSessionSnapshot,
|
|
481
701
|
principleId: string,
|
|
482
|
-
|
|
702
|
+
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars -- Reason: interface requires this param but implementation doesn't use it
|
|
703
|
+
_telemetry: TrinityTelemetry
|
|
483
704
|
): TrinityDraftArtifact | null {
|
|
484
705
|
const json = this.extractJson(text);
|
|
485
706
|
if (!json) {
|
|
@@ -519,6 +740,7 @@ Select the best candidate (Philosopher's rank 1) and synthesize it into a final
|
|
|
519
740
|
/**
|
|
520
741
|
* Extract JSON object from text that may contain markdown code blocks.
|
|
521
742
|
*/
|
|
743
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Reason: pure utility function that doesn't need instance state
|
|
522
744
|
private extractJson(text: string): string | null {
|
|
523
745
|
// Try direct parse first
|
|
524
746
|
try {
|
|
@@ -529,7 +751,7 @@ Select the best candidate (Philosopher's rank 1) and synthesize it into a final
|
|
|
529
751
|
}
|
|
530
752
|
|
|
531
753
|
// Match triple-backtick JSON blocks
|
|
532
|
-
const codeBlockMatch =
|
|
754
|
+
const codeBlockMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?```/.exec(text);
|
|
533
755
|
if (codeBlockMatch) {
|
|
534
756
|
const extracted = codeBlockMatch[1].trim();
|
|
535
757
|
try {
|
|
@@ -696,6 +918,8 @@ export interface TrinityDraftArtifact {
|
|
|
696
918
|
thinkingModelDelta?: number;
|
|
697
919
|
/** Reflection quality: gain in planning ratio (-1 to 1) */
|
|
698
920
|
planningRatioGain?: number;
|
|
921
|
+
/** Optional routing context for a follow-on Artificer stage */
|
|
922
|
+
artificerContext?: TrinityArtificerContext;
|
|
699
923
|
}
|
|
700
924
|
|
|
701
925
|
export interface TrinityTelemetry {
|
|
@@ -749,19 +973,14 @@ export interface TrinityResult {
|
|
|
749
973
|
failures: TrinityStageFailure[];
|
|
750
974
|
/** Whether fallback to single-reflector occurred */
|
|
751
975
|
fallbackOccurred: boolean;
|
|
976
|
+
/** Optional routing context for a follow-on Artificer stage */
|
|
977
|
+
artificerContext?: TrinityArtificerContext;
|
|
752
978
|
}
|
|
753
979
|
|
|
754
980
|
// ---------------------------------------------------------------------------
|
|
755
981
|
// Internal Types for Trinity Execution
|
|
756
982
|
// ---------------------------------------------------------------------------
|
|
757
983
|
|
|
758
|
-
/**
|
|
759
|
-
* Enriched candidate after Philosopher judgment.
|
|
760
|
-
*/
|
|
761
|
-
interface EnrichedCandidate extends DreamerCandidate {
|
|
762
|
-
judgment: PhilosopherJudgment;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
984
|
// ---------------------------------------------------------------------------
|
|
766
985
|
// Stub Stage Implementations (Phase 2 — no real subagent calls)
|
|
767
986
|
// ---------------------------------------------------------------------------
|
|
@@ -781,6 +1000,10 @@ export function invokeStubDreamer(
|
|
|
781
1000
|
const hasPain = snapshot.stats.totalPainEvents > 0;
|
|
782
1001
|
const hasGateBlocks = snapshot.stats.totalGateBlocks > 0;
|
|
783
1002
|
|
|
1003
|
+
// #219: Detect fallback data source - stats may be incomplete
|
|
1004
|
+
const isFallback = snapshot._dataSource === 'pain_context_fallback';
|
|
1005
|
+
const fallbackWarning = isFallback ? ' [fallback data: stats may be incomplete]' : '';
|
|
1006
|
+
|
|
784
1007
|
const candidates: DreamerCandidate[] = [];
|
|
785
1008
|
|
|
786
1009
|
// Generate candidates based on available signals
|
|
@@ -879,11 +1102,19 @@ export function invokeStubDreamer(
|
|
|
879
1102
|
// Ensure we don't exceed maxCandidates
|
|
880
1103
|
const limitedCandidates = candidates.slice(0, Math.min(candidates.length, maxCandidates));
|
|
881
1104
|
|
|
1105
|
+
// #219: Add fallback warning to rationales if data source is fallback
|
|
1106
|
+
const annotatedCandidates = isFallback
|
|
1107
|
+
? limitedCandidates.map((c) => ({
|
|
1108
|
+
...c,
|
|
1109
|
+
rationale: c.rationale + fallbackWarning,
|
|
1110
|
+
}))
|
|
1111
|
+
: limitedCandidates;
|
|
1112
|
+
|
|
882
1113
|
return {
|
|
883
|
-
valid:
|
|
884
|
-
candidates:
|
|
1114
|
+
valid: annotatedCandidates.length > 0,
|
|
1115
|
+
candidates: annotatedCandidates,
|
|
885
1116
|
generatedAt: new Date().toISOString(),
|
|
886
|
-
reason:
|
|
1117
|
+
reason: annotatedCandidates.length === 0 ? 'No signal available for candidate generation' : undefined,
|
|
887
1118
|
};
|
|
888
1119
|
}
|
|
889
1120
|
|
|
@@ -895,7 +1126,8 @@ export function invokeStubDreamer(
|
|
|
895
1126
|
*/
|
|
896
1127
|
export function invokeStubPhilosopher(
|
|
897
1128
|
dreamerOutput: DreamerOutput,
|
|
898
|
-
|
|
1129
|
+
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars -- Reason: interface requires this param but stub implementation doesn't use it
|
|
1130
|
+
_principleId: string
|
|
899
1131
|
): PhilosopherOutput {
|
|
900
1132
|
if (!dreamerOutput.valid || dreamerOutput.candidates.length === 0) {
|
|
901
1133
|
return {
|
|
@@ -953,7 +1185,7 @@ export function invokeStubPhilosopher(
|
|
|
953
1185
|
j.rank = idx + 1;
|
|
954
1186
|
});
|
|
955
1187
|
|
|
956
|
-
const topJudgment = judgments
|
|
1188
|
+
const [topJudgment] = judgments;
|
|
957
1189
|
|
|
958
1190
|
return {
|
|
959
1191
|
valid: true,
|
|
@@ -969,6 +1201,7 @@ export function invokeStubPhilosopher(
|
|
|
969
1201
|
* In production, this would call the actual Scribe subagent.
|
|
970
1202
|
* The stub uses tournament selection (scoring + thresholds) to pick the winner.
|
|
971
1203
|
*/
|
|
1204
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- Reason: stub scribe requires all context parameters - refactoring would break API
|
|
972
1205
|
export function invokeStubScribe(
|
|
973
1206
|
dreamerOutput: DreamerOutput,
|
|
974
1207
|
philosopherOutput: PhilosopherOutput,
|
|
@@ -998,7 +1231,7 @@ export function invokeStubScribe(
|
|
|
998
1231
|
return null;
|
|
999
1232
|
}
|
|
1000
1233
|
|
|
1001
|
-
const winner = tournamentResult
|
|
1234
|
+
const {winner} = tournamentResult;
|
|
1002
1235
|
|
|
1003
1236
|
// Update telemetry with tournament info
|
|
1004
1237
|
const updatedTelemetry: TrinityTelemetry = {
|
|
@@ -1046,6 +1279,7 @@ export function runTrinity(options: RunTrinityOptions): TrinityResult {
|
|
|
1046
1279
|
|
|
1047
1280
|
// Stub path: use synchronous stub implementations
|
|
1048
1281
|
if (config.useStubs) {
|
|
1282
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- Reason: function is defined later in file but callback order makes this necessary
|
|
1049
1283
|
return runTrinityWithStubs(snapshot, principleId, config);
|
|
1050
1284
|
}
|
|
1051
1285
|
|
|
@@ -1084,6 +1318,7 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1084
1318
|
|
|
1085
1319
|
if (config.useStubs) {
|
|
1086
1320
|
// Stub path: use synchronous stubs
|
|
1321
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- Reason: function is defined later in file but callback order makes this necessary
|
|
1087
1322
|
return runTrinityWithStubs(snapshot, principleId, config);
|
|
1088
1323
|
}
|
|
1089
1324
|
|
|
@@ -1125,14 +1360,19 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1125
1360
|
|
|
1126
1361
|
try {
|
|
1127
1362
|
// Step 1: Dreamer — generate candidates via real subagent
|
|
1363
|
+
const dreamerStart = Date.now();
|
|
1364
|
+
console.log(`[Trinity] Step 1/3: Invoking Dreamer (principleId=${principleId}, maxCandidates=${config.maxCandidates})`);
|
|
1128
1365
|
const dreamerOutput = await adapter.invokeDreamer(snapshot, principleId, config.maxCandidates);
|
|
1366
|
+
console.log(`[Trinity] Dreamer completed in ${Date.now() - dreamerStart}ms, valid=${dreamerOutput.valid}, candidates=${dreamerOutput.candidates?.length ?? 0}`);
|
|
1129
1367
|
|
|
1130
1368
|
if (!dreamerOutput.valid || dreamerOutput.candidates.length === 0) {
|
|
1369
|
+
const reason = dreamerOutput.reason ?? 'No valid candidates generated';
|
|
1370
|
+
console.warn(`[Trinity] Dreamer failed: ${reason}`);
|
|
1131
1371
|
failures.push({
|
|
1132
1372
|
stage: 'dreamer',
|
|
1133
|
-
reason
|
|
1373
|
+
reason,
|
|
1134
1374
|
});
|
|
1135
|
-
telemetry.stageFailures.push(`Dreamer: ${
|
|
1375
|
+
telemetry.stageFailures.push(`Dreamer: ${reason}`);
|
|
1136
1376
|
return { success: false, telemetry, failures, fallbackOccurred: false };
|
|
1137
1377
|
}
|
|
1138
1378
|
|
|
@@ -1140,20 +1380,27 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1140
1380
|
telemetry.candidateCount = dreamerOutput.candidates.length;
|
|
1141
1381
|
|
|
1142
1382
|
// Step 2: Philosopher — rank candidates via real subagent
|
|
1383
|
+
const philosopherStart = Date.now();
|
|
1384
|
+
console.log(`[Trinity] Step 2/3: Invoking Philosopher (${dreamerOutput.candidates.length} candidates)`);
|
|
1143
1385
|
const philosopherOutput = await adapter.invokePhilosopher(dreamerOutput, principleId);
|
|
1386
|
+
console.log(`[Trinity] Philosopher completed in ${Date.now() - philosopherStart}ms, valid=${philosopherOutput.valid}, judgments=${philosopherOutput.judgments?.length ?? 0}`);
|
|
1144
1387
|
|
|
1145
1388
|
if (!philosopherOutput.valid || philosopherOutput.judgments.length === 0) {
|
|
1389
|
+
const reason = philosopherOutput.reason ?? 'No judgments produced';
|
|
1390
|
+
console.warn(`[Trinity] Philosopher failed: ${reason}`);
|
|
1146
1391
|
failures.push({
|
|
1147
1392
|
stage: 'philosopher',
|
|
1148
|
-
reason
|
|
1393
|
+
reason,
|
|
1149
1394
|
});
|
|
1150
|
-
telemetry.stageFailures.push(`Philosopher: ${
|
|
1395
|
+
telemetry.stageFailures.push(`Philosopher: ${reason}`);
|
|
1151
1396
|
return { success: false, telemetry, failures, fallbackOccurred: false };
|
|
1152
1397
|
}
|
|
1153
1398
|
|
|
1154
1399
|
telemetry.philosopherPassed = true;
|
|
1155
1400
|
|
|
1156
1401
|
// Step 3: Scribe — synthesize final artifact via real subagent
|
|
1402
|
+
const scribeStart = Date.now();
|
|
1403
|
+
console.log(`[Trinity] Step 3/3: Invoking Scribe (synthesizing artifact)`);
|
|
1157
1404
|
const draftArtifact = await adapter.invokeScribe(
|
|
1158
1405
|
dreamerOutput,
|
|
1159
1406
|
philosopherOutput,
|
|
@@ -1162,8 +1409,10 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1162
1409
|
telemetry,
|
|
1163
1410
|
config
|
|
1164
1411
|
);
|
|
1412
|
+
console.log(`[Trinity] Scribe completed in ${Date.now() - scribeStart}ms, artifact=${!!draftArtifact}`);
|
|
1165
1413
|
|
|
1166
1414
|
if (!draftArtifact) {
|
|
1415
|
+
console.warn(`[Trinity] Scribe failed: Failed to synthesize artifact from candidates`);
|
|
1167
1416
|
failures.push({ stage: 'scribe', reason: 'Failed to synthesize artifact from candidates' });
|
|
1168
1417
|
telemetry.stageFailures.push('Scribe: synthesis failed');
|
|
1169
1418
|
return { success: false, telemetry, failures, fallbackOccurred: false };
|
|
@@ -1171,6 +1420,7 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1171
1420
|
|
|
1172
1421
|
telemetry.scribePassed = true;
|
|
1173
1422
|
telemetry.selectedCandidateIndex = draftArtifact.selectedCandidateIndex;
|
|
1423
|
+
console.log(`[Trinity] Trinity chain completed successfully: selectedCandidateIndex=${draftArtifact.selectedCandidateIndex}`);
|
|
1174
1424
|
|
|
1175
1425
|
if (draftArtifact.telemetry) {
|
|
1176
1426
|
telemetry.tournamentTrace = draftArtifact.telemetry.tournamentTrace;
|
|
@@ -1179,10 +1429,17 @@ export async function runTrinityAsync(options: RunTrinityOptions): Promise<Trini
|
|
|
1179
1429
|
telemetry.eligibleCandidateCount = draftArtifact.telemetry.eligibleCandidateCount;
|
|
1180
1430
|
}
|
|
1181
1431
|
|
|
1182
|
-
return {
|
|
1432
|
+
return {
|
|
1433
|
+
success: true,
|
|
1434
|
+
artifact: draftArtifact,
|
|
1435
|
+
telemetry,
|
|
1436
|
+
failures: [],
|
|
1437
|
+
fallbackOccurred: false,
|
|
1438
|
+
artificerContext: draftArtifact.artificerContext,
|
|
1439
|
+
};
|
|
1183
1440
|
} finally {
|
|
1184
1441
|
if (adapter.close) {
|
|
1185
|
-
await adapter.close().catch(() => {});
|
|
1442
|
+
await adapter.close().catch(() => { /* intentionally empty - adapter cleanup error ignored */ });
|
|
1186
1443
|
}
|
|
1187
1444
|
}
|
|
1188
1445
|
}
|
|
@@ -1280,6 +1537,7 @@ function runTrinityWithStubs(
|
|
|
1280
1537
|
telemetry,
|
|
1281
1538
|
failures: [],
|
|
1282
1539
|
fallbackOccurred: false,
|
|
1540
|
+
artificerContext: draftArtifact.artificerContext,
|
|
1283
1541
|
};
|
|
1284
1542
|
}
|
|
1285
1543
|
|