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
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
1
2
|
import type {
|
|
2
3
|
SubagentRunResult,
|
|
3
4
|
SubagentWaitResult,
|
|
4
5
|
SubagentGetSessionMessagesResult,
|
|
5
6
|
PluginLogger,
|
|
6
7
|
} from '../../openclaw-sdk.js';
|
|
8
|
+
import { isExpectedSubagentError } from './subagent-error-utils.js';
|
|
7
9
|
|
|
8
10
|
export interface TransportDriver {
|
|
11
|
+
/* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
|
|
9
12
|
run(params: RunParams): Promise<RunResult>;
|
|
10
13
|
wait(params: WaitParams): Promise<WaitResult>;
|
|
11
14
|
getResult(params: GetResultParams): Promise<GetResultResult>;
|
|
12
15
|
cleanup(params: CleanupParams): Promise<void>;
|
|
16
|
+
/* eslint-enable no-unused-vars */
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export interface RunParams {
|
|
@@ -51,6 +55,7 @@ export interface CleanupParams {
|
|
|
51
55
|
deleteTranscript?: boolean;
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/* eslint-disable no-unused-vars -- Reason: type method params are type signatures, implementations use actual values */
|
|
54
59
|
type PluginRuntimeSubagent = {
|
|
55
60
|
run: (params: {
|
|
56
61
|
sessionKey: string;
|
|
@@ -74,21 +79,45 @@ type PluginRuntimeSubagent = {
|
|
|
74
79
|
deleteTranscript?: boolean;
|
|
75
80
|
}) => Promise<void>;
|
|
76
81
|
};
|
|
82
|
+
/* eslint-enable no-unused-vars */
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* OpenClaw plugin SDK's agent.session namespace — always available (not gateway-scoped).
|
|
86
|
+
* These functions are imported directly from OpenClaw's session store module.
|
|
87
|
+
*/
|
|
88
|
+
export type AgentSessionAPI = {
|
|
89
|
+
/* eslint-disable no-unused-vars -- Reason: type method params are type signatures, implementations use actual values */
|
|
90
|
+
resolveStorePath: () => string;
|
|
91
|
+
loadSessionStore: (storePath: string, opts?: { skipCache?: boolean }) => Record<string, unknown>;
|
|
92
|
+
saveSessionStore: (storePath: string, store: Record<string, unknown>) => Promise<void>;
|
|
93
|
+
resolveSessionFilePath: (sessionKey: string) => string;
|
|
94
|
+
/** Optional: OpenClaw config object needed for session path resolution */
|
|
95
|
+
config?: unknown;
|
|
96
|
+
/* eslint-enable no-unused-vars */
|
|
97
|
+
};
|
|
77
98
|
|
|
78
99
|
export class RuntimeDirectDriver implements TransportDriver {
|
|
79
100
|
private readonly subagent: PluginRuntimeSubagent;
|
|
80
101
|
private readonly logger: PluginLogger;
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
/** Agent-level session store API — works outside gateway request context (#188) */
|
|
103
|
+
private readonly agentSession: AgentSessionAPI | undefined;
|
|
104
|
+
|
|
105
|
+
constructor(options: {
|
|
106
|
+
subagent: PluginRuntimeSubagent;
|
|
107
|
+
logger: PluginLogger;
|
|
108
|
+
/** Pass api.runtime.agent.session to enable heartbeat-safe cleanup (#188) */
|
|
109
|
+
agentSession?: AgentSessionAPI;
|
|
110
|
+
}) {
|
|
83
111
|
this.subagent = options.subagent;
|
|
84
112
|
this.logger = options.logger;
|
|
113
|
+
this.agentSession = options.agentSession;
|
|
85
114
|
}
|
|
86
115
|
|
|
87
116
|
/** Expose subagent for availability checking (used by workflow manager for surface degrade) */
|
|
88
117
|
getSubagent(): PluginRuntimeSubagent {
|
|
89
118
|
return this.subagent;
|
|
90
119
|
}
|
|
91
|
-
|
|
120
|
+
|
|
92
121
|
async run(params: RunParams): Promise<RunResult> {
|
|
93
122
|
// DEFENSIVE: Gateway AgentParamsSchema requires idempotencyKey as NonEmptyString (required).
|
|
94
123
|
// server-plugins.ts uses conditional spread: ...(v && { v }), so falsy = omitted = validation failure.
|
|
@@ -96,7 +125,7 @@ export class RuntimeDirectDriver implements TransportDriver {
|
|
|
96
125
|
const idempotencyKey = params.idempotencyKey || `pd:${params.sessionKey}:${Date.now()}`;
|
|
97
126
|
|
|
98
127
|
this.logger.info(`[PD:RuntimeDirectDriver] Spawning subagent: sessionKey=${params.sessionKey}, idemKey=${idempotencyKey.substring(0, 40)}`);
|
|
99
|
-
|
|
128
|
+
|
|
100
129
|
try {
|
|
101
130
|
const result = await this.subagent.run({
|
|
102
131
|
sessionKey: params.sessionKey,
|
|
@@ -107,24 +136,28 @@ export class RuntimeDirectDriver implements TransportDriver {
|
|
|
107
136
|
expectsCompletionMessage: params.expectsCompletionMessage ?? true,
|
|
108
137
|
extraSystemPrompt: params.extraSystemPrompt,
|
|
109
138
|
});
|
|
110
|
-
|
|
139
|
+
|
|
111
140
|
this.logger.info(`[PD:RuntimeDirectDriver] Spawn succeeded: runId=${result.runId}`);
|
|
112
141
|
return { runId: result.runId };
|
|
113
142
|
} catch (error) {
|
|
114
|
-
|
|
143
|
+
// Suppress expected errors during cron jobs, boot sessions, or isolated sessions.
|
|
144
|
+
// These are not real failures — subagent runtime is only available in gateway requests.
|
|
145
|
+
if (!isExpectedSubagentError(error)) {
|
|
146
|
+
this.logger.error(`[PD:RuntimeDirectDriver] Spawn failed: ${String(error)}`);
|
|
147
|
+
}
|
|
115
148
|
throw error;
|
|
116
149
|
}
|
|
117
150
|
}
|
|
118
|
-
|
|
151
|
+
|
|
119
152
|
async wait(params: WaitParams): Promise<WaitResult> {
|
|
120
153
|
this.logger.info(`[PD:RuntimeDirectDriver] Waiting for run: runId=${params.runId}, timeout=${params.timeoutMs}ms`);
|
|
121
|
-
|
|
154
|
+
|
|
122
155
|
try {
|
|
123
156
|
const result = await this.subagent.waitForRun({
|
|
124
157
|
runId: params.runId,
|
|
125
158
|
timeoutMs: params.timeoutMs,
|
|
126
159
|
});
|
|
127
|
-
|
|
160
|
+
|
|
128
161
|
this.logger.info(`[PD:RuntimeDirectDriver] Wait completed: status=${result.status}`);
|
|
129
162
|
return result;
|
|
130
163
|
} catch (error) {
|
|
@@ -132,26 +165,26 @@ export class RuntimeDirectDriver implements TransportDriver {
|
|
|
132
165
|
throw error;
|
|
133
166
|
}
|
|
134
167
|
}
|
|
135
|
-
|
|
168
|
+
|
|
136
169
|
async getResult(params: GetResultParams): Promise<GetResultResult> {
|
|
137
170
|
this.logger.info(`[PD:RuntimeDirectDriver] Getting messages: sessionKey=${params.sessionKey}`);
|
|
138
|
-
|
|
171
|
+
|
|
139
172
|
try {
|
|
140
173
|
const result = await this.subagent.getSessionMessages({
|
|
141
174
|
sessionKey: params.sessionKey,
|
|
142
175
|
limit: params.limit ?? 20,
|
|
143
176
|
});
|
|
144
|
-
|
|
177
|
+
|
|
145
178
|
return result;
|
|
146
179
|
} catch (error) {
|
|
147
180
|
this.logger.error(`[PD:RuntimeDirectDriver] GetResult failed: ${String(error)}`);
|
|
148
181
|
throw error;
|
|
149
182
|
}
|
|
150
183
|
}
|
|
151
|
-
|
|
184
|
+
|
|
152
185
|
async cleanup(params: CleanupParams): Promise<void> {
|
|
153
186
|
this.logger.info(`[PD:RuntimeDirectDriver] Cleaning up session: sessionKey=${params.sessionKey}`);
|
|
154
|
-
|
|
187
|
+
|
|
155
188
|
try {
|
|
156
189
|
await this.subagent.deleteSession({
|
|
157
190
|
sessionKey: params.sessionKey,
|
|
@@ -159,8 +192,73 @@ export class RuntimeDirectDriver implements TransportDriver {
|
|
|
159
192
|
});
|
|
160
193
|
this.logger.info(`[PD:RuntimeDirectDriver] Cleanup succeeded`);
|
|
161
194
|
} catch (error) {
|
|
162
|
-
|
|
163
|
-
|
|
195
|
+
const errMsg = String(error);
|
|
196
|
+
// #188/#219: runtime.subagent.deleteSession() only works during gateway requests.
|
|
197
|
+
// Fall back to agent.session API which is always available (not gateway-scoped).
|
|
198
|
+
// Handle multiple error patterns that indicate non-gateway context:
|
|
199
|
+
// - 'gateway request' - Not in a gateway request scope
|
|
200
|
+
// - 'missing scope' - Missing required scope (e.g., operator.admin)
|
|
201
|
+
const isNonGatewayContext =
|
|
202
|
+
errMsg.includes('gateway request') ||
|
|
203
|
+
errMsg.includes('missing scope');
|
|
204
|
+
|
|
205
|
+
if (isNonGatewayContext && this.agentSession) {
|
|
206
|
+
this.logger.info(`[PD:RuntimeDirectDriver] Gateway-scoped cleanup unavailable (${errMsg.split(':')[0]}), falling back to agent.session`);
|
|
207
|
+
await this.cleanupViaAgentSession(params.sessionKey);
|
|
208
|
+
this.logger.info(`[PD:RuntimeDirectDriver] Fallback cleanup succeeded`);
|
|
209
|
+
} else {
|
|
210
|
+
this.logger.error(`[PD:RuntimeDirectDriver] Cleanup failed: ${errMsg}`);
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Heartbeat-safe session cleanup by directly manipulating the session store file.
|
|
218
|
+
* This bypasses the gateway request scope requirement entirely.
|
|
219
|
+
* Also removes transcript files from disk to avoid orphaned files.
|
|
220
|
+
*/
|
|
221
|
+
private async cleanupViaAgentSession(sessionKey: string): Promise<void> {
|
|
222
|
+
if (!this.agentSession) {
|
|
223
|
+
throw new Error('agentSession not available for fallback cleanup');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const { resolveStorePath, loadSessionStore, saveSessionStore, resolveSessionFilePath } = this.agentSession;
|
|
227
|
+
|
|
228
|
+
// Get the session store file path
|
|
229
|
+
const storePath = resolveStorePath();
|
|
230
|
+
|
|
231
|
+
if (!fs.existsSync(storePath)) {
|
|
232
|
+
return; // No store file, nothing to clean up
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Read the store
|
|
236
|
+
const store = loadSessionStore(storePath, { skipCache: true });
|
|
237
|
+
if (!store || typeof store !== 'object') {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Normalize session key matches OpenClaw's internal lowercase normalization
|
|
242
|
+
const normalizedKey = sessionKey.toLowerCase();
|
|
243
|
+
|
|
244
|
+
if (normalizedKey in store) {
|
|
245
|
+
const entry = store[normalizedKey] as { sessionId?: string; sessionFile?: string } | undefined;
|
|
246
|
+
|
|
247
|
+
// Archive or delete transcript files before removing store entry
|
|
248
|
+
if (entry?.sessionFile) {
|
|
249
|
+
try {
|
|
250
|
+
const transcriptPath = resolveSessionFilePath(normalizedKey);
|
|
251
|
+
if (fs.existsSync(transcriptPath)) {
|
|
252
|
+
fs.unlinkSync(transcriptPath);
|
|
253
|
+
this.logger.info(`[PD:RuntimeDirectDriver] Removed transcript file: ${transcriptPath}`);
|
|
254
|
+
}
|
|
255
|
+
} catch (unlinkErr) {
|
|
256
|
+
this.logger.warn(`[PD:RuntimeDirectDriver] Failed to remove transcript file: ${String(unlinkErr)}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
delete store[normalizedKey];
|
|
261
|
+
await saveSessionStore(storePath, store);
|
|
164
262
|
}
|
|
165
263
|
}
|
|
166
264
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for detecting expected subagent unavailability errors.
|
|
3
|
+
* These occur during cron jobs, boot sessions, daemon mode, or isolated sessions
|
|
4
|
+
* where the gateway request context is not available.
|
|
5
|
+
*
|
|
6
|
+
* Callers should suppress warnings for these errors — they are not real failures.
|
|
7
|
+
*/
|
|
8
|
+
export function isExpectedSubagentError(err: unknown): boolean {
|
|
9
|
+
const msg = String(err);
|
|
10
|
+
return (
|
|
11
|
+
msg.includes('Plugin runtime subagent methods are only available during a gateway request') ||
|
|
12
|
+
msg.includes('cannot start workflow for boot session') ||
|
|
13
|
+
msg.includes('subagent runtime unavailable') ||
|
|
14
|
+
// #208/#209: Daemon mode — subagent process not connected
|
|
15
|
+
msg.includes('subagent is not available') ||
|
|
16
|
+
// NocturnalWorkflowManager explicit throw when subagent unavailable
|
|
17
|
+
(msg.includes('NocturnalWorkflowManager') && msg.includes('subagent runtime unavailable')) ||
|
|
18
|
+
// Gateway not running (daemon/cron context)
|
|
19
|
+
msg.includes('gateway is not running') ||
|
|
20
|
+
// Process isolation in cron jobs
|
|
21
|
+
msg.includes('process isolation') ||
|
|
22
|
+
// Review fix: Subagent connection issues in daemon mode (more specific to reduce false positives)
|
|
23
|
+
(msg.includes('subagent') && msg.toLowerCase().includes('connection') && (msg.includes('refused') || msg.includes('reset') || msg.includes('econnrefused')))
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -145,6 +145,7 @@ export interface WorkflowHandle {
|
|
|
145
145
|
* ```
|
|
146
146
|
*/
|
|
147
147
|
export interface SubagentWorkflowSpec<TResult> {
|
|
148
|
+
/* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
|
|
148
149
|
/** Unique identifier for this workflow type */
|
|
149
150
|
workflowType: string;
|
|
150
151
|
/** Which transport mechanism to use */
|
|
@@ -171,6 +172,7 @@ export interface SubagentWorkflowSpec<TResult> {
|
|
|
171
172
|
* For runtime_direct: typically finalize only on 'ok', skip on 'timeout'/'error'.
|
|
172
173
|
*/
|
|
173
174
|
shouldFinalizeOnWaitStatus: (status: 'ok' | 'error' | 'timeout') => boolean;
|
|
175
|
+
/* eslint-enable no-unused-vars */
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
// ── Empathy Observer Specific Types ──────────────────────────────────────────
|
|
@@ -227,6 +229,7 @@ export interface EmpathyObserverWorkflowSpec extends SubagentWorkflowSpec<Empath
|
|
|
227
229
|
* This is what the helper exposes to business modules.
|
|
228
230
|
*/
|
|
229
231
|
export interface WorkflowManager {
|
|
232
|
+
/* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
|
|
230
233
|
/**
|
|
231
234
|
* Start a new workflow.
|
|
232
235
|
* Creates workflow state, spawns subagent, and returns handle.
|
|
@@ -286,6 +289,7 @@ export interface WorkflowManager {
|
|
|
286
289
|
* Release resources (DB connections, timers).
|
|
287
290
|
*/
|
|
288
291
|
dispose: () => void;
|
|
292
|
+
/* eslint-enable no-unused-vars */
|
|
289
293
|
}
|
|
290
294
|
|
|
291
295
|
// ── Workflow Store (for SQLite persistence) ──────────────────────────────────
|
|
@@ -305,6 +309,7 @@ export interface WorkflowRow {
|
|
|
305
309
|
created_at: number;
|
|
306
310
|
updated_at: number;
|
|
307
311
|
last_observed_at?: number | null;
|
|
312
|
+
duration_ms: number | null;
|
|
308
313
|
metadata_json: string;
|
|
309
314
|
}
|
|
310
315
|
|
|
@@ -332,21 +337,21 @@ export interface WorkflowDebugSummary {
|
|
|
332
337
|
cleanupState: 'none' | 'pending' | 'failed' | 'completed';
|
|
333
338
|
lastObservedAt: number | null;
|
|
334
339
|
metadata: WorkflowMetadata;
|
|
335
|
-
recentEvents:
|
|
340
|
+
recentEvents: {
|
|
336
341
|
eventType: string;
|
|
337
342
|
fromState: WorkflowState | null;
|
|
338
343
|
toState: WorkflowState;
|
|
339
344
|
reason: string;
|
|
340
345
|
createdAt: number;
|
|
341
346
|
payload: Record<string, unknown>;
|
|
342
|
-
}
|
|
347
|
+
}[];
|
|
343
348
|
// NOC-16: Trinity stage states
|
|
344
|
-
trinityStageStates?:
|
|
349
|
+
trinityStageStates?: {
|
|
345
350
|
stage: 'dreamer' | 'philosopher' | 'scribe';
|
|
346
351
|
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
347
352
|
reason?: string;
|
|
348
353
|
completedAt?: number;
|
|
349
|
-
}
|
|
354
|
+
}[];
|
|
350
355
|
}
|
|
351
356
|
|
|
352
357
|
// ── Convenience Re-exports ────────────────────────────────────────────────────
|