principles-disciple 1.42.0 → 1.44.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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/commands/archive-impl.ts +5 -3
- package/src/commands/capabilities.ts +1 -1
- package/src/commands/context.ts +1 -0
- package/src/commands/disable-impl.ts +1 -1
- package/src/commands/evolution-status.ts +2 -2
- package/src/commands/export.ts +6 -6
- package/src/commands/nocturnal-train.ts +1 -1
- package/src/commands/principle-rollback.ts +1 -1
- package/src/commands/rollback.ts +0 -1
- package/src/commands/samples.ts +1 -1
- package/src/commands/thinking-os.ts +1 -0
- package/src/commands/workflow-debug.ts +1 -1
- package/src/core/adaptive-thresholds.ts +3 -3
- package/src/core/config.ts +2 -1
- package/src/core/dictionary.ts +1 -0
- package/src/core/event-log.ts +3 -3
- package/src/core/evolution-engine.ts +1 -1
- package/src/core/external-training-contract.ts +1 -1
- package/src/core/merge-gate-audit.ts +3 -3
- package/src/core/nocturnal-arbiter.ts +1 -1
- package/src/core/nocturnal-compliance.ts +28 -28
- package/src/core/nocturnal-executability.ts +1 -1
- package/src/core/nocturnal-reasoning-deriver.ts +4 -4
- package/src/core/nocturnal-rule-implementation-validator.ts +1 -1
- package/src/core/nocturnal-snapshot-contract.ts +1 -1
- package/src/core/pain-context-extractor.ts +2 -2
- package/src/core/path-resolver.ts +1 -0
- package/src/core/pd-task-reconciler.ts +1 -0
- package/src/core/pd-task-service.ts +1 -1
- package/src/core/pd-task-store.ts +1 -0
- package/src/core/principle-internalization/deprecated-readiness.ts +1 -1
- package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -1
- package/src/core/principle-training-state.ts +2 -2
- package/src/core/principle-tree-migration.ts +1 -1
- package/src/core/profile.ts +1 -1
- package/src/core/promotion-gate.ts +0 -2
- package/src/core/replay-engine.ts +1 -0
- package/src/core/risk-calculator.ts +2 -1
- package/src/core/rule-host.ts +1 -1
- package/src/core/session-tracker.ts +1 -0
- package/src/core/shadow-observation-registry.ts +1 -1
- package/src/core/thinking-models.ts +1 -1
- package/src/core/thinking-os-parser.ts +1 -1
- package/src/core/trajectory.ts +2 -4
- package/src/core/workspace-context.ts +1 -1
- package/src/hooks/bash-risk.ts +2 -2
- package/src/hooks/edit-verification.ts +4 -4
- package/src/hooks/gate.ts +8 -8
- package/src/hooks/gfi-gate.ts +2 -2
- package/src/hooks/lifecycle-routing.ts +1 -1
- package/src/hooks/pain.ts +2 -2
- package/src/hooks/progressive-trust-gate.ts +3 -3
- package/src/hooks/prompt.ts +3 -5
- package/src/hooks/thinking-checkpoint.ts +1 -1
- package/src/index.ts +8 -8
- package/src/service/central-database.ts +3 -2
- package/src/service/central-health-service.ts +2 -1
- package/src/service/central-overview-service.ts +3 -2
- package/src/service/control-ui-query-service.ts +2 -2
- package/src/service/event-log-auditor.ts +2 -2
- package/src/service/evolution-query-service.ts +3 -3
- package/src/service/evolution-worker.ts +11 -18
- package/src/service/health-query-service.ts +11 -10
- package/src/service/monitoring-query-service.ts +4 -4
- package/src/service/nocturnal-runtime.ts +0 -3
- package/src/service/nocturnal-service.ts +8 -8
- package/src/service/nocturnal-target-selector.ts +2 -2
- package/src/service/queue-io.ts +5 -5
- package/src/service/runtime-summary-service.ts +1 -1
- package/src/service/sleep-cycle.ts +1 -1
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +1 -1
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +1 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +1 -1
- package/src/service/subagent-workflow/subagent-error-utils.ts +1 -1
- package/src/service/subagent-workflow/workflow-store.ts +3 -2
- package/src/service/workflow-watchdog.ts +1 -1
- package/src/tools/critique-prompt.ts +1 -1
- package/src/tools/model-index.ts +1 -1
- package/src/utils/file-lock.ts +1 -1
- package/src/utils/io.ts +1 -1
- package/src/utils/retry.ts +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
/* global NodeJS */
|
|
2
3
|
import * as fs from 'fs';
|
|
3
4
|
import { isRisky } from '../utils/io.js';
|
|
@@ -95,7 +96,7 @@ export function getTargetFileLineCount(absoluteFilePath: string): number | null
|
|
|
95
96
|
* @returns Maximum allowed lines (at least minLines, at most maxLines if provided)
|
|
96
97
|
*/
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
export function calculatePercentageThreshold(
|
|
100
101
|
targetLineCount: number,
|
|
101
102
|
percentage: number,
|
package/src/core/rule-host.ts
CHANGED
|
@@ -202,7 +202,7 @@ let _cachedWorkspace: string | null = null;
|
|
|
202
202
|
*
|
|
203
203
|
* @param workspaceDir Optional. If provided, loads from that workspace's THINKING_OS.md.
|
|
204
204
|
*/
|
|
205
|
-
|
|
205
|
+
|
|
206
206
|
export function listThinkingModels(workspaceDir?: string): ThinkingModelDefinition[] {
|
|
207
207
|
const cacheKey = workspaceDir ?? '__global__';
|
|
208
208
|
if (_cachedDefinitions && _cachedWorkspace === cacheKey) {
|
|
@@ -45,7 +45,7 @@ export function parseThinkingOsMd(content: string): ThinkingOsDirective[] {
|
|
|
45
45
|
// Match all <directive ...> ... </directive> blocks
|
|
46
46
|
const directiveRegex = /<directive\s+([^>]*)>([\s\S]*?)<\/directive>/gi;
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
let _match: RegExpExecArray | null = null;
|
|
50
50
|
|
|
51
51
|
while ((_match = directiveRegex.exec(content)) !== null) {
|
package/src/core/trajectory.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
1
3
|
import Database from 'better-sqlite3';
|
|
2
4
|
import fs from 'fs';
|
|
3
5
|
import path from 'path';
|
|
@@ -207,10 +209,6 @@ export class TrajectoryDatabase {
|
|
|
207
209
|
recordToolCall(input: TrajectoryToolCallInput): number {
|
|
208
210
|
this.recordSession({ sessionId: input.sessionId, startedAt: input.createdAt });
|
|
209
211
|
const createdAt = input.createdAt ?? nowIso();
|
|
210
|
-
// Extract filePath from paramsJson if provided and is an object with filePath
|
|
211
|
-
const paramsObj = input.paramsJson as Record<string, unknown> | undefined;
|
|
212
|
-
|
|
213
|
-
const _filePath = paramsObj && typeof paramsObj.filePath === 'string' ? paramsObj.filePath : null;
|
|
214
212
|
const rowId = this.withWrite(() => {
|
|
215
213
|
const result = this.db.prepare(`
|
|
216
214
|
INSERT INTO tool_calls (
|
|
@@ -173,7 +173,7 @@ export class WorkspaceContext {
|
|
|
173
173
|
* Uses PathResolver to handle path normalization and fallback logic.
|
|
174
174
|
* @throws Error if workspaceDir is missing and no fallback available.
|
|
175
175
|
*/
|
|
176
|
-
|
|
176
|
+
|
|
177
177
|
static fromHookContext(ctx: any): WorkspaceContext {
|
|
178
178
|
const {logger} = ctx;
|
|
179
179
|
const log = (msg: string) => logger?.info?.(msg);
|
package/src/hooks/bash-risk.ts
CHANGED
|
@@ -39,7 +39,7 @@ export type BashRiskLevel = 'safe' | 'dangerous' | 'normal';
|
|
|
39
39
|
* @returns The risk level: 'safe', 'dangerous', or 'normal'
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
export function analyzeBashCommand(
|
|
44
44
|
command: string,
|
|
45
45
|
safePatterns: string[],
|
|
@@ -154,7 +154,7 @@ export interface DynamicThresholdConfig {
|
|
|
154
154
|
* @param config - Configuration with large_change_lines and ep_tier_multipliers
|
|
155
155
|
* @returns The adjusted threshold (minimum 0)
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
export function calculateDynamicThreshold(
|
|
159
159
|
baseThreshold: number,
|
|
160
160
|
epTier: number,
|
|
@@ -127,11 +127,11 @@ This is enforced by P-03 (精确匹配前验证原则).`;
|
|
|
127
127
|
* This enforces P-03 at the tool layer
|
|
128
128
|
*/
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
export function handleEditVerification(
|
|
132
132
|
event: PluginHookBeforeToolCallEvent,
|
|
133
133
|
wctx: WorkspaceContext,
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
ctx: { logger?: any; sessionId?: string },
|
|
136
136
|
config: EditVerificationConfig = {}
|
|
137
137
|
): PluginHookBeforeToolCallResult | void {
|
|
@@ -157,7 +157,7 @@ export function handleEditVerification(
|
|
|
157
157
|
|
|
158
158
|
// 2. Resolve and read file
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
let absolutePath: string;
|
|
162
162
|
try {
|
|
163
163
|
absolutePath = wctx.resolve(filePath);
|
|
@@ -225,7 +225,7 @@ export function handleEditVerification(
|
|
|
225
225
|
|
|
226
226
|
// 3. Read current file content with improved error handling
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
let currentContent: string;
|
|
230
230
|
try {
|
|
231
231
|
currentContent = fs.readFileSync(absolutePath, 'utf-8');
|
package/src/hooks/gate.ts
CHANGED
|
@@ -135,7 +135,7 @@ export function handleBeforeToolCall(
|
|
|
135
135
|
|
|
136
136
|
if (mutationMatch) {
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
|
|
139
139
|
filePath = mutationMatch[1];
|
|
140
140
|
} else {
|
|
141
141
|
const hasRiskPath = profile.risk_paths.some(rp => command.includes(rp));
|
|
@@ -169,36 +169,36 @@ export function handleBeforeToolCall(
|
|
|
169
169
|
toolName: event.toolName,
|
|
170
170
|
normalizedPath: relPath,
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
|
|
173
173
|
paramsSummary: _extractParamsSummary(event.params),
|
|
174
174
|
},
|
|
175
175
|
workspace: {
|
|
176
176
|
isRiskPath: risky,
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
|
|
179
179
|
planStatus: _getPlanStatus(ctx.workspaceDir),
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
hasPlanFile: _hasPlanFile(ctx.workspaceDir),
|
|
183
183
|
},
|
|
184
184
|
session: {
|
|
185
185
|
sessionId: ctx.sessionId,
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
|
|
188
188
|
currentGfi: _getCurrentGfi(ctx.sessionId),
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
recentThinking: _hasRecentThinking(ctx.sessionId),
|
|
192
192
|
},
|
|
193
193
|
evolution: {
|
|
194
194
|
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
epTier: _getEpTier(wctx.workspaceDir),
|
|
197
197
|
},
|
|
198
198
|
derived: {
|
|
199
199
|
estimatedLineChanges: estimateLineChanges({ toolName: event.toolName, params: event.params }),
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
|
|
202
202
|
bashRisk: _getBashRisk(event, profile),
|
|
203
203
|
},
|
|
204
204
|
};
|
package/src/hooks/gfi-gate.ts
CHANGED
|
@@ -48,7 +48,7 @@ export interface GfiGateConfig {
|
|
|
48
48
|
* Internal helper to call the shared block helper with gfi-gate source tag.
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
function block(
|
|
53
53
|
wctx: WorkspaceContext,
|
|
54
54
|
filePath: string,
|
|
@@ -70,7 +70,7 @@ function block(
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
export function checkGfiGate(
|
|
75
75
|
event: PluginHookBeforeToolCallEvent,
|
|
76
76
|
wctx: WorkspaceContext,
|
|
@@ -66,7 +66,7 @@ export type LifecycleIntent = 'promote' | 'disable' | 'rollback' | null;
|
|
|
66
66
|
* Detect implementation lifecycle intent from user message.
|
|
67
67
|
* Returns the detected intent type or null.
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
export function detectLifecycleIntent(message: string): LifecycleIntent {
|
|
71
71
|
// Check promote patterns
|
|
72
72
|
for (const p of PROMOTE_PATTERNS_EN) {
|
package/src/hooks/pain.ts
CHANGED
|
@@ -131,7 +131,7 @@ export function handleAfterToolCall(
|
|
|
131
131
|
|
|
132
132
|
// ── Trust Engine: Record failure ──
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
const errorType = extractErrorType(event.error || errorText);
|
|
136
136
|
const filePath = params.file_path || params.path || params.file;
|
|
137
137
|
const relPath = typeof filePath === 'string' ? normalizePath(filePath, effectiveWorkspaceDir) : 'unknown';
|
|
@@ -194,7 +194,7 @@ export function handleAfterToolCall(
|
|
|
194
194
|
const session = getSession(sessionId);
|
|
195
195
|
const toolFailureGfi = session?.gfiBySource?.tool_failure || 0;
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
let resetState: SessionState;
|
|
199
199
|
if (toolFailureGfi > 0) {
|
|
200
200
|
// Reduce tool_failure source by 50% (relief from successful tool execution)
|
|
@@ -87,7 +87,7 @@ export function buildEvolutionGateReason(
|
|
|
87
87
|
* Internal helper to call the shared block helper with progressive-trust-gate source tag.
|
|
88
88
|
*/
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
function block(
|
|
92
92
|
filePath: string,
|
|
93
93
|
reason: string,
|
|
@@ -121,7 +121,7 @@ function block(
|
|
|
121
121
|
* @returns PluginHookBeforeToolCallResult to block, or undefined to allow
|
|
122
122
|
*/
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
export function checkProgressiveTrustGate(
|
|
126
126
|
event: PluginHookBeforeToolCallEvent,
|
|
127
127
|
wctx: WorkspaceContext,
|
|
@@ -154,7 +154,7 @@ export function checkProgressiveTrustGate(
|
|
|
154
154
|
|
|
155
155
|
const currentTier = epDecision.currentTier ?? 1;
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
const tierName = getTierName(currentTier);
|
|
159
159
|
|
|
160
160
|
logger.info?.(`[PD_GATE] EP Gate: Tier ${currentTier} (${tierName}), Tool: ${event.toolName}, Risk: ${risky}, Allowed: ${epDecision.allowed}`);
|
package/src/hooks/prompt.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
1
3
|
import * as fs from 'fs';
|
|
2
4
|
import * as path from 'path';
|
|
3
5
|
import type { PluginHookBeforePromptBuildEvent, PluginHookAgentContext, PluginHookBeforePromptBuildResult, PluginLogger, OpenClawPluginApi } from '../openclaw-sdk.js';
|
|
@@ -979,12 +981,8 @@ ${taskBlocks}${processingNote}
|
|
|
979
981
|
const filePattern = /\b([a-zA-Z]:\\?[^\s,]+\.[a-z]{2,10}|[./][^\s,]+\.[a-z]{2,10})\b/gi;
|
|
980
982
|
const toolMatches = toolPatterns.flatMap(({ pattern, tool }) => {
|
|
981
983
|
const matches: string[] = [];
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
let _m;
|
|
985
984
|
const r = new RegExp(pattern.source, pattern.flags);
|
|
986
|
-
|
|
987
|
-
while ((_m = r.exec(latestUserText)) !== null) matches.push(tool);
|
|
985
|
+
while (r.exec(latestUserText) !== null) matches.push(tool);
|
|
988
986
|
return matches;
|
|
989
987
|
});
|
|
990
988
|
const fileMatches = latestUserText.match(filePattern) ?? [];
|
|
@@ -41,7 +41,7 @@ export interface ThinkingCheckpointConfig {
|
|
|
41
41
|
* @returns Block result if thinking required, undefined otherwise
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
export function checkThinkingCheckpoint(
|
|
46
46
|
event: PluginHookBeforeToolCallEvent,
|
|
47
47
|
config: ThinkingCheckpointConfig,
|
package/src/index.ts
CHANGED
|
@@ -283,7 +283,7 @@ const plugin = {
|
|
|
283
283
|
|
|
284
284
|
if (shouldRecordShadow) {
|
|
285
285
|
const observation = recordShadowRouting(workspaceDir, {
|
|
286
|
-
checkpointId: decision.activeCheckpointId!,
|
|
286
|
+
checkpointId: decision.activeCheckpointId!,
|
|
287
287
|
workerProfile: agentId as WorkerProfile,
|
|
288
288
|
taskFingerprint: computeRuntimeShadowTaskFingerprint(event),
|
|
289
289
|
});
|
|
@@ -362,7 +362,7 @@ const plugin = {
|
|
|
362
362
|
|
|
363
363
|
// ── Slash Commands ──
|
|
364
364
|
// Register command with optional short alias
|
|
365
|
-
|
|
365
|
+
|
|
366
366
|
const registerCommandWithAlias = (name: string, alias: string | null, desc: string, handler: any, opts?: { acceptsArgs?: boolean }) => {
|
|
367
367
|
const base = {
|
|
368
368
|
name,
|
|
@@ -380,17 +380,17 @@ const plugin = {
|
|
|
380
380
|
}
|
|
381
381
|
};
|
|
382
382
|
|
|
383
|
-
|
|
383
|
+
|
|
384
384
|
registerCommandWithAlias('pd-init', 'pdi', getCommandDescription('pd-init', language), (ctx: any) => handleInitStrategy(ctx));
|
|
385
|
-
|
|
385
|
+
|
|
386
386
|
registerCommandWithAlias('pd-okr', 'pdk', getCommandDescription('pd-okr', language), (ctx: any) => handleManageOkr(ctx));
|
|
387
|
-
|
|
387
|
+
|
|
388
388
|
registerCommandWithAlias('pd-bootstrap', 'pdb', getCommandDescription('pd-bootstrap', language), (ctx: any) => handleBootstrapTools(ctx));
|
|
389
|
-
|
|
389
|
+
|
|
390
390
|
registerCommandWithAlias('pd-research', 'pdr', getCommandDescription('pd-research', language), (ctx: any) => handleResearchTools(ctx));
|
|
391
|
-
|
|
391
|
+
|
|
392
392
|
registerCommandWithAlias('pd-thinking', 'pdt', getCommandDescription('pd-thinking', language), (ctx: any) => handleThinkingOs(ctx), { acceptsArgs: true });
|
|
393
|
-
|
|
393
|
+
|
|
394
394
|
registerCommandWithAlias('pd-reflect', 'pdrl', getCommandDescription('pd-reflect', language), (ctx: any) => {
|
|
395
395
|
try {
|
|
396
396
|
// Resolve agentId from sessionKey (if available), fallback to 'main'
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import Database from 'better-sqlite3';
|
|
2
3
|
import fs from 'fs';
|
|
3
4
|
import path from 'path';
|
|
@@ -200,7 +201,7 @@ export class CentralDatabase {
|
|
|
200
201
|
/**
|
|
201
202
|
* Sync data from a single workspace into the central database
|
|
202
203
|
*/
|
|
203
|
-
|
|
204
|
+
|
|
204
205
|
syncWorkspace(workspaceName: string): number {
|
|
205
206
|
const workspace = this.workspaces.find(w => w.name === workspaceName);
|
|
206
207
|
if (!workspace) {
|
|
@@ -714,7 +715,7 @@ export class CentralDatabase {
|
|
|
714
715
|
syncEnabled: c.sync_enabled === 1,
|
|
715
716
|
}));
|
|
716
717
|
}
|
|
717
|
-
|
|
718
|
+
|
|
718
719
|
|
|
719
720
|
updateWorkspaceConfig(
|
|
720
721
|
workspaceName: string,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import { getCentralDatabase } from './central-database.js';
|
|
2
3
|
import { HealthQueryService } from './health-query-service.js';
|
|
3
4
|
|
|
@@ -18,7 +19,7 @@ export interface CentralHealthResponse {
|
|
|
18
19
|
*/
|
|
19
20
|
export class CentralHealthService {
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
getAllWorkspaceHealth(): CentralHealthResponse {
|
|
23
24
|
const centralDb = getCentralDatabase();
|
|
24
25
|
const workspaces: WorkspaceHealthEntry[] = [];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import { getCentralDatabase, type CentralDatabase } from './central-database.js';
|
|
2
3
|
import { getThinkingModelDefinitions } from '../core/thinking-models.js';
|
|
3
4
|
import type { OverviewResponse } from './control-ui-query-service.js';
|
|
@@ -24,7 +25,7 @@ export class CentralOverviewService {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
|
|
28
29
|
dispose(): void {
|
|
29
30
|
// Do NOT dispose centralDb — it's a singleton shared across all requests.
|
|
30
31
|
// Individual services that open per-request connections (e.g. HealthQueryService)
|
|
@@ -62,7 +63,7 @@ export class CentralOverviewService {
|
|
|
62
63
|
|
|
63
64
|
// D-06: sampleQueue.counters from aggregated_correction_samples GROUP BY review_status
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
|
|
66
67
|
let sampleCounters: Record<string, number> = {};
|
|
67
68
|
try {
|
|
68
69
|
sampleCounters = this.centralDb.getSampleCountersByStatus();
|
|
@@ -255,7 +255,7 @@ export class ControlUiQueryService {
|
|
|
255
255
|
this.uiDb.dispose();
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
|
|
259
259
|
getOverview(days = 30): OverviewResponse {
|
|
260
260
|
const stats = this.trajectory.getDataStats();
|
|
261
261
|
const regressionRows = this.uiDb.all<{
|
|
@@ -400,7 +400,7 @@ export class ControlUiQueryService {
|
|
|
400
400
|
};
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
|
|
404
404
|
listSamples(filters: SampleListFilters = {}): SamplesResponse {
|
|
405
405
|
const page = Math.max(1, Number(filters.page ?? 1));
|
|
406
406
|
const pageSize = clampPageSize(filters.pageSize);
|
|
@@ -137,7 +137,7 @@ function countAllHooks(filePath: string): Record<string, number> {
|
|
|
137
137
|
* @param openclawDir - Base OpenClaw directory (e.g., ~/.openclaw)
|
|
138
138
|
* @param expectedToolHooks - Hook names that should appear in the primary workspace
|
|
139
139
|
*/
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
export async function auditEventLogs(
|
|
142
142
|
openclawDir: string,
|
|
143
143
|
expectedToolHooks: string[] = ['before_tool_call', 'after_tool_call'],
|
|
@@ -210,7 +210,7 @@ export async function auditEventLogs(
|
|
|
210
210
|
/**
|
|
211
211
|
* Format audit report for display.
|
|
212
212
|
*/
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
export function formatAuditReport(report: AuditReport): string {
|
|
215
215
|
const lines: string[] = [];
|
|
216
216
|
|
|
@@ -155,7 +155,7 @@ export class EvolutionQueryService {
|
|
|
155
155
|
* 注意:不关闭 trajectory,因为它是单例由 TrajectoryRegistry 管理
|
|
156
156
|
*/
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
dispose(): void {
|
|
160
160
|
// EvolutionQueryService 不拥有 trajectory,所以不关闭它
|
|
161
161
|
// trajectory 是由 TrajectoryRegistry 管理的单例
|
|
@@ -349,13 +349,13 @@ export class EvolutionQueryService {
|
|
|
349
349
|
for (const task of recentTasks) {
|
|
350
350
|
const [createdDay] = task.createdAt.split('T');
|
|
351
351
|
if (activityByDay.has(createdDay)) {
|
|
352
|
-
|
|
352
|
+
|
|
353
353
|
activityByDay.get(createdDay)!.created++;
|
|
354
354
|
}
|
|
355
355
|
if (task.completedAt) {
|
|
356
356
|
const [completedDay] = task.completedAt.split('T');
|
|
357
357
|
if (activityByDay.has(completedDay)) {
|
|
358
|
-
|
|
358
|
+
|
|
359
359
|
activityByDay.get(completedDay)!.completed++;
|
|
360
360
|
}
|
|
361
361
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
1
3
|
/* global NodeJS */
|
|
2
4
|
|
|
3
5
|
import * as fs from 'fs';
|
|
@@ -231,8 +233,6 @@ function buildFallbackNocturnalSnapshot(
|
|
|
231
233
|
};
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
const PAIN_QUEUE_DEDUP_WINDOW_MS = 30 * 60 * 1000;
|
|
235
|
-
|
|
236
236
|
// Queue lock constants and requireQueueLock are imported from queue-io.ts
|
|
237
237
|
|
|
238
238
|
export function extractEvolutionTaskId(task: string): string | null {
|
|
@@ -282,13 +282,6 @@ export function purgeStaleFailedTasks(
|
|
|
282
282
|
return { purged: purged.length, remaining: queue.length, byReason };
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
function normalizePainDedupKey(source: string, preview: string, reason?: string): string {
|
|
286
|
-
// Include reason in dedup key to match createEvolutionTaskId() behavior
|
|
287
|
-
// Different reasons for the same source/preview should create different tasks
|
|
288
|
-
const normalizedReason = (reason || '').trim().toLowerCase();
|
|
289
|
-
return `${source.trim().toLowerCase()}::${preview.trim().toLowerCase()}::${normalizedReason}`;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
285
|
|
|
293
286
|
|
|
294
287
|
export function hasRecentDuplicateTask(queue: EvolutionQueueItem[], source: string, preview: string, now: number, reason?: string): boolean {
|
|
@@ -665,7 +658,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
665
658
|
workspaceDir: wctx.workspaceDir,
|
|
666
659
|
stateDir: wctx.stateDir,
|
|
667
660
|
logger: api?.logger || logger,
|
|
668
|
-
|
|
661
|
+
|
|
669
662
|
runtimeAdapter: new OpenClawTrinityRuntimeAdapter(api!),
|
|
670
663
|
subagent: api?.runtime?.subagent,
|
|
671
664
|
});
|
|
@@ -1183,7 +1176,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1183
1176
|
let snapshotData: NocturnalSessionSnapshot | undefined;
|
|
1184
1177
|
|
|
1185
1178
|
if (isPollingTask) {
|
|
1186
|
-
|
|
1179
|
+
|
|
1187
1180
|
workflowId = sleepTask.resultRef!;
|
|
1188
1181
|
} else {
|
|
1189
1182
|
// Phase 1: Build trajectory snapshot for Nocturnal pipeline
|
|
@@ -1335,15 +1328,15 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1335
1328
|
|
|
1336
1329
|
try {
|
|
1337
1330
|
payload = lastEvent?.payload ?? {};
|
|
1338
|
-
|
|
1331
|
+
|
|
1339
1332
|
if ((payload as any).skipReason) {
|
|
1340
|
-
|
|
1333
|
+
|
|
1341
1334
|
detailedError += ` (skipReason: ${(payload as any).skipReason})`;
|
|
1342
1335
|
|
|
1343
1336
|
}
|
|
1344
|
-
|
|
1337
|
+
|
|
1345
1338
|
if ((payload as any).failures && Array.isArray((payload as any).failures) && (payload as any).failures.length > 0) {
|
|
1346
|
-
|
|
1339
|
+
|
|
1347
1340
|
detailedError += ` | failures: ${((payload as any).failures as string[]).slice(0, 3).join(', ')}`;
|
|
1348
1341
|
}
|
|
1349
1342
|
} catch { /* ignore parse errors */ }
|
|
@@ -1359,7 +1352,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1359
1352
|
sleepOutcomes.push({ taskKind: 'sleep_reflection', succeeded: true });
|
|
1360
1353
|
|
|
1361
1354
|
logger?.warn?.(`[PD:EvolutionWorker] sleep_reflection task ${sleepTask.id} background runtime unavailable, using stub fallback: ${errorReason}`);
|
|
1362
|
-
|
|
1355
|
+
|
|
1363
1356
|
} else if ((payload as any).skipReason === 'no_violating_sessions') {
|
|
1364
1357
|
// #244: No meaningful violations found (thin filter) → skip without failure
|
|
1365
1358
|
sleepTask.status = 'completed';
|
|
@@ -1554,7 +1547,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1554
1547
|
const manager = new CorrectionObserverWorkflowManager({
|
|
1555
1548
|
workspaceDir: wctx.workspaceDir,
|
|
1556
1549
|
logger,
|
|
1557
|
-
subagent: api?.runtime?.subagent!,
|
|
1550
|
+
subagent: api?.runtime?.subagent!,
|
|
1558
1551
|
agentSession: api?.runtime?.agent?.session,
|
|
1559
1552
|
});
|
|
1560
1553
|
|
|
@@ -1568,7 +1561,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
1568
1561
|
workflowId = handle.workflowId;
|
|
1569
1562
|
koTask.resultRef = workflowId;
|
|
1570
1563
|
} else {
|
|
1571
|
-
workflowId = koTask.resultRef!;
|
|
1564
|
+
workflowId = koTask.resultRef!;
|
|
1572
1565
|
}
|
|
1573
1566
|
|
|
1574
1567
|
// Poll workflow state
|