principles-disciple 1.5.4 → 1.7.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/dist/commands/context.d.ts +5 -0
- package/dist/commands/context.js +312 -0
- package/dist/commands/evolution-status.d.ts +4 -0
- package/dist/commands/evolution-status.js +138 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +45 -0
- package/dist/commands/focus.d.ts +14 -0
- package/dist/commands/focus.js +582 -0
- package/dist/commands/pain.js +143 -6
- package/dist/commands/principle-rollback.d.ts +4 -0
- package/dist/commands/principle-rollback.js +22 -0
- package/dist/commands/rollback.d.ts +19 -0
- package/dist/commands/rollback.js +119 -0
- package/dist/commands/samples.d.ts +2 -0
- package/dist/commands/samples.js +55 -0
- package/dist/core/config.d.ts +37 -0
- package/dist/core/config.js +47 -0
- package/dist/core/control-ui-db.d.ts +68 -0
- package/dist/core/control-ui-db.js +274 -0
- package/dist/core/detection-funnel.d.ts +1 -1
- package/dist/core/detection-funnel.js +4 -0
- package/dist/core/dictionary.d.ts +2 -0
- package/dist/core/dictionary.js +13 -0
- package/dist/core/event-log.d.ts +22 -1
- package/dist/core/event-log.js +319 -0
- package/dist/core/evolution-engine.d.ts +5 -5
- package/dist/core/evolution-engine.js +18 -18
- package/dist/core/evolution-migration.d.ts +5 -0
- package/dist/core/evolution-migration.js +65 -0
- package/dist/core/evolution-reducer.d.ts +69 -0
- package/dist/core/evolution-reducer.js +369 -0
- package/dist/core/evolution-types.d.ts +103 -0
- package/dist/core/focus-history.d.ts +65 -0
- package/dist/core/focus-history.js +266 -0
- package/dist/core/init.js +30 -7
- package/dist/core/migration.js +0 -2
- package/dist/core/path-resolver.d.ts +3 -0
- package/dist/core/path-resolver.js +90 -31
- package/dist/core/paths.d.ts +7 -8
- package/dist/core/paths.js +48 -40
- package/dist/core/profile.js +1 -1
- package/dist/core/session-tracker.d.ts +4 -0
- package/dist/core/session-tracker.js +15 -0
- package/dist/core/thinking-models.d.ts +38 -0
- package/dist/core/thinking-models.js +170 -0
- package/dist/core/trajectory.d.ts +184 -0
- package/dist/core/trajectory.js +817 -0
- package/dist/core/trust-engine.d.ts +2 -0
- package/dist/core/trust-engine.js +30 -4
- package/dist/core/workspace-context.d.ts +13 -0
- package/dist/core/workspace-context.js +50 -7
- package/dist/hooks/gate.js +301 -30
- package/dist/hooks/llm.d.ts +8 -0
- package/dist/hooks/llm.js +347 -69
- package/dist/hooks/message-sanitize.d.ts +3 -0
- package/dist/hooks/message-sanitize.js +37 -0
- package/dist/hooks/pain.js +105 -5
- package/dist/hooks/prompt.d.ts +20 -11
- package/dist/hooks/prompt.js +558 -158
- package/dist/hooks/subagent.d.ts +9 -2
- package/dist/hooks/subagent.js +40 -3
- package/dist/http/principles-console-route.d.ts +2 -0
- package/dist/http/principles-console-route.js +257 -0
- package/dist/i18n/commands.js +48 -20
- package/dist/index.js +264 -8
- package/dist/service/control-ui-query-service.d.ts +217 -0
- package/dist/service/control-ui-query-service.js +537 -0
- package/dist/service/empathy-observer-manager.d.ts +42 -0
- package/dist/service/empathy-observer-manager.js +147 -0
- package/dist/service/evolution-worker.d.ts +10 -0
- package/dist/service/evolution-worker.js +156 -24
- package/dist/service/trajectory-service.d.ts +2 -0
- package/dist/service/trajectory-service.js +15 -0
- package/dist/tools/agent-spawn.d.ts +27 -6
- package/dist/tools/agent-spawn.js +339 -87
- package/dist/tools/deep-reflect.d.ts +27 -7
- package/dist/tools/deep-reflect.js +282 -113
- package/dist/types/event-types.d.ts +84 -2
- package/dist/types/event-types.js +33 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.js +24 -1
- package/openclaw.plugin.json +43 -11
- package/package.json +16 -6
- package/templates/langs/zh/core/HEARTBEAT.md +28 -4
- package/templates/langs/zh/skills/pd-daily/SKILL.md +97 -13
- package/templates/pain_settings.json +54 -2
- package/templates/workspace/.principles/PROFILE.json +2 -0
- package/templates/workspace/okr/CURRENT_FOCUS.md +57 -0
package/dist/core/paths.js
CHANGED
|
@@ -1,67 +1,75 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
|
+
const posixJoin = (...parts) => path.posix.join(...parts);
|
|
3
|
+
function isWindowsPath(input) {
|
|
4
|
+
return /^[A-Za-z]:[\\/]/.test(input) || input.startsWith('\\\\');
|
|
5
|
+
}
|
|
6
|
+
function joinWorkspacePath(workspaceDir, relativePath) {
|
|
7
|
+
if (isWindowsPath(workspaceDir)) {
|
|
8
|
+
return path.win32.join(workspaceDir, relativePath);
|
|
9
|
+
}
|
|
10
|
+
if (workspaceDir.startsWith('/')) {
|
|
11
|
+
return path.posix.join(workspaceDir, relativePath);
|
|
12
|
+
}
|
|
13
|
+
return path.join(workspaceDir, relativePath);
|
|
14
|
+
}
|
|
2
15
|
/**
|
|
3
16
|
* Principles Disciple Directory Constants
|
|
4
17
|
* Establishing a logical separation between Identity, State, and Memory.
|
|
5
18
|
*/
|
|
6
19
|
export const PD_DIRS = {
|
|
7
|
-
/** 🧬 Core configuration, identity, and kernel rules (hidden) */
|
|
8
20
|
IDENTITY: '.principles',
|
|
9
|
-
|
|
10
|
-
MODELS: path.join('.principles', 'models'),
|
|
11
|
-
/** ⚡ Volatile operational data, queues, and task status (hidden) */
|
|
21
|
+
MODELS: posixJoin('.principles', 'models'),
|
|
12
22
|
STATE: '.state',
|
|
13
|
-
/** 💾 Historical records, logs, and long-term memory */
|
|
14
23
|
MEMORY: 'memory',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
SESSIONS: path.join('.state', 'sessions'),
|
|
21
|
-
/** 🩹 Semantic pain samples for L3 retrieval */
|
|
22
|
-
PAIN_SAMPLES: path.join('memory', 'pain'),
|
|
24
|
+
OKR: posixJoin('memory', 'okr'),
|
|
25
|
+
LOGS: posixJoin('memory', 'logs'),
|
|
26
|
+
SESSIONS: posixJoin('.state', 'sessions'),
|
|
27
|
+
PAIN_SAMPLES: posixJoin('memory', 'pain'),
|
|
28
|
+
LOCKS: posixJoin('memory', '.locks'),
|
|
23
29
|
};
|
|
24
30
|
/**
|
|
25
31
|
* Standard File Path Mappings
|
|
26
32
|
*/
|
|
27
33
|
export const PD_FILES = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
DECISION_POLICY: path.join(PD_DIRS.IDENTITY, 'DECISION_POLICY.json'),
|
|
34
|
+
PROFILE: posixJoin(PD_DIRS.IDENTITY, 'PROFILE.json'),
|
|
35
|
+
PRINCIPLES: posixJoin(PD_DIRS.IDENTITY, 'PRINCIPLES.md'),
|
|
36
|
+
THINKING_OS: posixJoin(PD_DIRS.IDENTITY, 'THINKING_OS.md'),
|
|
37
|
+
KERNEL: posixJoin(PD_DIRS.IDENTITY, '00-kernel.md'),
|
|
38
|
+
DECISION_POLICY: posixJoin(PD_DIRS.IDENTITY, 'DECISION_POLICY.json'),
|
|
34
39
|
MODELS_DIR: PD_DIRS.MODELS,
|
|
35
|
-
// State Layer
|
|
36
40
|
STATE_DIR: PD_DIRS.STATE,
|
|
37
|
-
EVOLUTION_QUEUE:
|
|
38
|
-
EVOLUTION_DIRECTIVE:
|
|
39
|
-
WORKBOARD:
|
|
40
|
-
AGENT_SCORECARD:
|
|
41
|
-
PAIN_FLAG:
|
|
42
|
-
SYSTEM_CAPABILITIES:
|
|
43
|
-
PAIN_SETTINGS:
|
|
44
|
-
PAIN_CANDIDATES:
|
|
45
|
-
THINKING_OS_USAGE:
|
|
41
|
+
EVOLUTION_QUEUE: posixJoin(PD_DIRS.STATE, 'evolution_queue.json'),
|
|
42
|
+
EVOLUTION_DIRECTIVE: posixJoin(PD_DIRS.STATE, 'evolution_directive.json'),
|
|
43
|
+
WORKBOARD: posixJoin(PD_DIRS.STATE, 'WORKBOARD.json'),
|
|
44
|
+
AGENT_SCORECARD: posixJoin(PD_DIRS.STATE, 'AGENT_SCORECARD.json'),
|
|
45
|
+
PAIN_FLAG: posixJoin(PD_DIRS.STATE, '.pain_flag'),
|
|
46
|
+
SYSTEM_CAPABILITIES: posixJoin(PD_DIRS.STATE, 'SYSTEM_CAPABILITIES.json'),
|
|
47
|
+
PAIN_SETTINGS: posixJoin(PD_DIRS.STATE, 'pain_settings.json'),
|
|
48
|
+
PAIN_CANDIDATES: posixJoin(PD_DIRS.STATE, 'pain_candidates.json'),
|
|
49
|
+
THINKING_OS_USAGE: posixJoin(PD_DIRS.STATE, 'thinking_os_usage.json'),
|
|
50
|
+
TRAJECTORY_DB: posixJoin(PD_DIRS.STATE, 'trajectory.db'),
|
|
51
|
+
TRAJECTORY_BLOBS_DIR: posixJoin(PD_DIRS.STATE, 'blobs'),
|
|
52
|
+
EXPORTS_DIR: posixJoin(PD_DIRS.STATE, 'exports'),
|
|
46
53
|
SESSION_DIR: PD_DIRS.SESSIONS,
|
|
47
|
-
DICTIONARY:
|
|
48
|
-
|
|
54
|
+
DICTIONARY: posixJoin(PD_DIRS.STATE, 'pain_dictionary.json'),
|
|
55
|
+
PRINCIPLE_BLACKLIST: posixJoin(PD_DIRS.STATE, 'principle_blacklist.json'),
|
|
49
56
|
PLAN: 'PLAN.md',
|
|
50
57
|
MEMORY_MD: 'MEMORY.md',
|
|
51
58
|
HEARTBEAT: 'HEARTBEAT.md',
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
USER_CONTEXT: path.join(PD_DIRS.MEMORY, 'USER_CONTEXT.md'),
|
|
59
|
+
SYSTEM_LOG: posixJoin(PD_DIRS.LOGS, 'SYSTEM.log'),
|
|
60
|
+
REFLECTION_LOG: posixJoin(PD_DIRS.MEMORY, 'reflection-log.md'),
|
|
61
|
+
USER_CONTEXT: posixJoin(PD_DIRS.MEMORY, 'USER_CONTEXT.md'),
|
|
56
62
|
OKR_DIR: PD_DIRS.OKR,
|
|
57
|
-
CURRENT_FOCUS:
|
|
58
|
-
WEEK_STATE:
|
|
59
|
-
THINKING_OS_CANDIDATES:
|
|
60
|
-
SEMANTIC_PAIN:
|
|
63
|
+
CURRENT_FOCUS: posixJoin(PD_DIRS.OKR, 'CURRENT_FOCUS.md'),
|
|
64
|
+
WEEK_STATE: posixJoin(PD_DIRS.OKR, 'WEEK_STATE.json'),
|
|
65
|
+
THINKING_OS_CANDIDATES: posixJoin(PD_DIRS.MEMORY, 'THINKING_OS_CANDIDATES.md'),
|
|
66
|
+
SEMANTIC_PAIN: posixJoin(PD_DIRS.PAIN_SAMPLES, 'confusion_samples.md'),
|
|
67
|
+
EVOLUTION_STREAM: posixJoin(PD_DIRS.MEMORY, 'evolution.jsonl'),
|
|
68
|
+
EVOLUTION_LOCK: posixJoin(PD_DIRS.LOCKS, 'evolution'),
|
|
61
69
|
};
|
|
62
70
|
/**
|
|
63
71
|
* Resolves a PD file path within a given workspace.
|
|
64
72
|
*/
|
|
65
73
|
export function resolvePdPath(workspaceDir, fileKey) {
|
|
66
|
-
return
|
|
74
|
+
return joinWorkspacePath(workspaceDir, PD_FILES[fileKey]);
|
|
67
75
|
}
|
package/dist/core/profile.js
CHANGED
|
@@ -51,7 +51,7 @@ export const PROFILE_DEFAULTS = {
|
|
|
51
51
|
thinking_checkpoint: {
|
|
52
52
|
enabled: false, // Default OFF to avoid blocking new users
|
|
53
53
|
window_ms: 5 * 60 * 1000, // 5 minute window
|
|
54
|
-
high_risk_tools: ['run_shell_command', 'delete_file', 'move_file', '
|
|
54
|
+
high_risk_tools: ['run_shell_command', 'delete_file', 'move_file', 'pd_run_worker'],
|
|
55
55
|
},
|
|
56
56
|
custom_guards: [],
|
|
57
57
|
};
|
|
@@ -25,6 +25,7 @@ export interface SessionState {
|
|
|
25
25
|
dailyPainSignals: number;
|
|
26
26
|
dailyGfiPeak: number;
|
|
27
27
|
lastThinkingTimestamp: number;
|
|
28
|
+
injectedProbationIds?: string[];
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
31
|
* Initialize persistence for session state.
|
|
@@ -58,6 +59,9 @@ export declare function recordThinkingCheckpoint(sessionId: string, workspaceDir
|
|
|
58
59
|
*/
|
|
59
60
|
export declare function hasRecentThinking(sessionId: string, windowMs?: number): boolean;
|
|
60
61
|
export declare function trackBlock(sessionId: string): SessionState;
|
|
62
|
+
export declare function setInjectedProbationIds(sessionId: string, ids: string[], workspaceDir?: string): SessionState;
|
|
63
|
+
export declare function getInjectedProbationIds(sessionId: string, workspaceDir?: string): string[];
|
|
64
|
+
export declare function clearInjectedProbationIds(sessionId: string, workspaceDir?: string): SessionState;
|
|
61
65
|
export declare function getSession(sessionId: string): SessionState | undefined;
|
|
62
66
|
export declare function clearSession(sessionId: string): void;
|
|
63
67
|
export declare function garbageCollectSessions(): void;
|
|
@@ -115,6 +115,7 @@ function getOrCreateSession(sessionId, workspaceDir) {
|
|
|
115
115
|
dailyPainSignals: 0,
|
|
116
116
|
dailyGfiPeak: 0,
|
|
117
117
|
lastThinkingTimestamp: 0,
|
|
118
|
+
injectedProbationIds: [],
|
|
118
119
|
};
|
|
119
120
|
sessions.set(sessionId, state);
|
|
120
121
|
}
|
|
@@ -230,6 +231,20 @@ export function trackBlock(sessionId) {
|
|
|
230
231
|
state.lastActivityAt = Date.now();
|
|
231
232
|
return state;
|
|
232
233
|
}
|
|
234
|
+
export function setInjectedProbationIds(sessionId, ids, workspaceDir) {
|
|
235
|
+
const state = getOrCreateSession(sessionId, workspaceDir);
|
|
236
|
+
state.injectedProbationIds = [...ids];
|
|
237
|
+
state.lastActivityAt = Date.now();
|
|
238
|
+
schedulePersistence(state);
|
|
239
|
+
return state;
|
|
240
|
+
}
|
|
241
|
+
export function getInjectedProbationIds(sessionId, workspaceDir) {
|
|
242
|
+
const state = getOrCreateSession(sessionId, workspaceDir);
|
|
243
|
+
return [...(state.injectedProbationIds || [])];
|
|
244
|
+
}
|
|
245
|
+
export function clearInjectedProbationIds(sessionId, workspaceDir) {
|
|
246
|
+
return setInjectedProbationIds(sessionId, [], workspaceDir);
|
|
247
|
+
}
|
|
233
248
|
export function getSession(sessionId) {
|
|
234
249
|
return sessions.get(sessionId);
|
|
235
250
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface ThinkingModelDefinition {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
patterns: RegExp[];
|
|
6
|
+
baselineScenarios: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ThinkingModelMatch {
|
|
9
|
+
modelId: string;
|
|
10
|
+
matchedPattern: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ThinkingScenarioContext {
|
|
13
|
+
recentToolCalls?: Array<{
|
|
14
|
+
toolName: string;
|
|
15
|
+
outcome: 'success' | 'failure' | 'blocked';
|
|
16
|
+
errorType?: string | null;
|
|
17
|
+
}>;
|
|
18
|
+
recentPainEvents?: Array<{
|
|
19
|
+
source: string;
|
|
20
|
+
score: number;
|
|
21
|
+
}>;
|
|
22
|
+
recentGateBlocks?: Array<{
|
|
23
|
+
toolName: string;
|
|
24
|
+
reason: string;
|
|
25
|
+
}>;
|
|
26
|
+
recentUserCorrections?: Array<{
|
|
27
|
+
correctionCue?: string | null;
|
|
28
|
+
}>;
|
|
29
|
+
recentPrincipleEvents?: Array<{
|
|
30
|
+
eventType: string;
|
|
31
|
+
principleId?: string | null;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export declare const THINKING_MODEL_MAP: Map<string, ThinkingModelDefinition>;
|
|
35
|
+
export declare function listThinkingModels(): ThinkingModelDefinition[];
|
|
36
|
+
export declare function getThinkingModel(modelId: string): ThinkingModelDefinition | undefined;
|
|
37
|
+
export declare function detectThinkingModelMatches(text: string): ThinkingModelMatch[];
|
|
38
|
+
export declare function deriveThinkingScenarios(modelId: string, context: ThinkingScenarioContext): string[];
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
const THINKING_MODELS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'T-01',
|
|
4
|
+
name: 'Survey Before Acting',
|
|
5
|
+
description: 'Understand the structure first before making changes.',
|
|
6
|
+
baselineScenarios: ['exploration', 'discovery'],
|
|
7
|
+
patterns: [
|
|
8
|
+
/let me (first )?(understand|map|outline|survey|review the (structure|architecture|dependencies))/i,
|
|
9
|
+
/before (changing|editing|touching) anything/i,
|
|
10
|
+
/让我先(梳理|理解|看看|盘点).*(结构|架构|依赖|全貌)/i,
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 'T-02',
|
|
15
|
+
name: 'Respect Constraints',
|
|
16
|
+
description: 'Explicitly reason about contracts, tests, schemas, and requirements.',
|
|
17
|
+
baselineScenarios: ['constraint-check', 'contract-verification'],
|
|
18
|
+
patterns: [
|
|
19
|
+
/(type|test|contract|schema|interface) (constraint|requirement|check|validation)/i,
|
|
20
|
+
/we (must|need to) (respect|follow|adhere to) the/i,
|
|
21
|
+
/(必须|需要).*(遵守|符合|满足).*(类型|测试|契约|接口|规范)/i,
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'T-03',
|
|
26
|
+
name: 'Evidence Over Assumption',
|
|
27
|
+
description: 'Use logs, code, and outputs before inferring causes.',
|
|
28
|
+
baselineScenarios: ['evidence-gathering', 'verification'],
|
|
29
|
+
patterns: [
|
|
30
|
+
/based on (the |this )?(evidence|logs?|output|error|stack trace|test result)/i,
|
|
31
|
+
/let me (check|verify|confirm|read|look at) (the |)(actual|source|code|file|log)/i,
|
|
32
|
+
/根据(日志|证据|输出|报错|堆栈|测试结果)/i,
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'T-04',
|
|
37
|
+
name: 'Reversible First',
|
|
38
|
+
description: 'Prefer changes that are safe to roll back when risk is high.',
|
|
39
|
+
baselineScenarios: ['risk-management', 'reversibility'],
|
|
40
|
+
patterns: [
|
|
41
|
+
/this (is|would be) (irreversible|destructive|permanent|not easily undone)/i,
|
|
42
|
+
/(reversible|can be undone|safely roll back)/i,
|
|
43
|
+
/(不可逆|破坏性|无法回滚|可以回滚|安全撤销)/i,
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'T-05',
|
|
48
|
+
name: 'Safety Rails',
|
|
49
|
+
description: 'Call out guardrails, prohibitions, and failure-prevention constraints.',
|
|
50
|
+
baselineScenarios: ['guardrails', 'safety-rails'],
|
|
51
|
+
patterns: [
|
|
52
|
+
/we (must|should) (not|never|avoid|prevent|ensure we don't)/i,
|
|
53
|
+
/(critical|important) (not to|that we don't|to avoid)/i,
|
|
54
|
+
/(绝不能|必须避免|不可|禁止|确保不会)/i,
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'T-06',
|
|
59
|
+
name: 'Simplicity First',
|
|
60
|
+
description: 'Prefer the smallest understandable solution over over-engineering.',
|
|
61
|
+
baselineScenarios: ['simplification', 'pragmatism'],
|
|
62
|
+
patterns: [
|
|
63
|
+
/(simpl(er|est|ify)|minimal|straightforward|lean) (approach|solution|fix|implementation)/i,
|
|
64
|
+
/(simple is better|keep it simple|no need to over)/i,
|
|
65
|
+
/(最简|更简单|精简|没必要过度设计)/i,
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'T-07',
|
|
70
|
+
name: 'Minimal Change Surface',
|
|
71
|
+
description: 'Limit the blast radius and touch only what is necessary.',
|
|
72
|
+
baselineScenarios: ['minimal-diff', 'blast-radius-control'],
|
|
73
|
+
patterns: [
|
|
74
|
+
/(minimal|smallest|narrowest|least) (change|diff|modification|impact)/i,
|
|
75
|
+
/only (change|modify|touch|edit) (the |what)/i,
|
|
76
|
+
/(最小改动|最小变更|只改|只动必要部分)/i,
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'T-08',
|
|
81
|
+
name: 'Pain As Signal',
|
|
82
|
+
description: 'Treat failures and friction as clues to step back and rethink.',
|
|
83
|
+
baselineScenarios: ['reflection', 'pain-response'],
|
|
84
|
+
patterns: [
|
|
85
|
+
/this (error|failure|issue) (tells us|indicates|signals|suggests|means)/i,
|
|
86
|
+
/let me (stop|pause|step back|reconsider|rethink)/i,
|
|
87
|
+
/这个(错误|失败|问题).*(说明|意味着|提示)/i,
|
|
88
|
+
/让我(停下|暂停|退一步|重新考虑|重新审视)/i,
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'T-09',
|
|
93
|
+
name: 'Divide And Conquer',
|
|
94
|
+
description: 'Split the task into smaller phases before execution.',
|
|
95
|
+
baselineScenarios: ['decomposition', 'phased-execution'],
|
|
96
|
+
patterns: [
|
|
97
|
+
/(break|split|decompose|divide) (this |the task |it )?(into|down)/i,
|
|
98
|
+
/(step 1|first,? (we|i|let's)|phase 1)/i,
|
|
99
|
+
/(拆分|分解|分步|分阶段|第一步)/i,
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
export const THINKING_MODEL_MAP = new Map(THINKING_MODELS.map((model) => [model.id, model]));
|
|
104
|
+
export function listThinkingModels() {
|
|
105
|
+
return THINKING_MODELS.slice();
|
|
106
|
+
}
|
|
107
|
+
export function getThinkingModel(modelId) {
|
|
108
|
+
return THINKING_MODEL_MAP.get(modelId);
|
|
109
|
+
}
|
|
110
|
+
export function detectThinkingModelMatches(text) {
|
|
111
|
+
if (!text)
|
|
112
|
+
return [];
|
|
113
|
+
const matches = [];
|
|
114
|
+
for (const model of THINKING_MODELS) {
|
|
115
|
+
for (const pattern of model.patterns) {
|
|
116
|
+
if (pattern.test(text)) {
|
|
117
|
+
matches.push({
|
|
118
|
+
modelId: model.id,
|
|
119
|
+
matchedPattern: pattern.source,
|
|
120
|
+
});
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return matches;
|
|
126
|
+
}
|
|
127
|
+
export function deriveThinkingScenarios(modelId, context) {
|
|
128
|
+
const scenarios = new Set(getThinkingModel(modelId)?.baselineScenarios ?? []);
|
|
129
|
+
if ((context.recentToolCalls ?? []).some((call) => call.outcome === 'failure')) {
|
|
130
|
+
scenarios.add('after-tool-failure');
|
|
131
|
+
}
|
|
132
|
+
// after-recovery: success that follows a failure (not just any success)
|
|
133
|
+
const calls = context.recentToolCalls ?? [];
|
|
134
|
+
const hasFailure = calls.some((call) => call.outcome === 'failure');
|
|
135
|
+
const hasSuccess = calls.some((call) => call.outcome === 'success');
|
|
136
|
+
if (hasFailure && hasSuccess) {
|
|
137
|
+
scenarios.add('after-recovery');
|
|
138
|
+
}
|
|
139
|
+
if ((context.recentToolCalls ?? []).some((call) => call.outcome === 'blocked')) {
|
|
140
|
+
scenarios.add('blocked-execution');
|
|
141
|
+
}
|
|
142
|
+
if ((context.recentToolCalls ?? []).some((call) => Boolean(call.errorType))) {
|
|
143
|
+
scenarios.add('incident-response');
|
|
144
|
+
}
|
|
145
|
+
if ((context.recentPainEvents ?? []).length > 0) {
|
|
146
|
+
scenarios.add('user-friction');
|
|
147
|
+
}
|
|
148
|
+
if ((context.recentGateBlocks ?? []).length > 0) {
|
|
149
|
+
scenarios.add('gate-block');
|
|
150
|
+
}
|
|
151
|
+
if ((context.recentUserCorrections ?? []).length > 0) {
|
|
152
|
+
scenarios.add('user-correction');
|
|
153
|
+
}
|
|
154
|
+
if ((context.recentPrincipleEvents ?? []).length > 0) {
|
|
155
|
+
scenarios.add('principle-feedback');
|
|
156
|
+
}
|
|
157
|
+
if (modelId === 'T-03') {
|
|
158
|
+
scenarios.add('root-cause-analysis');
|
|
159
|
+
}
|
|
160
|
+
if (modelId === 'T-04' || modelId === 'T-05') {
|
|
161
|
+
scenarios.add('risk-review');
|
|
162
|
+
}
|
|
163
|
+
if (modelId === 'T-08') {
|
|
164
|
+
scenarios.add('reflection-loop');
|
|
165
|
+
}
|
|
166
|
+
if (modelId === 'T-09') {
|
|
167
|
+
scenarios.add('task-planning');
|
|
168
|
+
}
|
|
169
|
+
return Array.from(scenarios);
|
|
170
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
export type CorrectionSampleReviewStatus = 'pending' | 'approved' | 'rejected';
|
|
2
|
+
export type CorrectionExportMode = 'raw' | 'redacted';
|
|
3
|
+
export interface TrajectoryDataStats {
|
|
4
|
+
dbPath: string;
|
|
5
|
+
dbSizeBytes: number;
|
|
6
|
+
assistantTurns: number;
|
|
7
|
+
userTurns: number;
|
|
8
|
+
toolCalls: number;
|
|
9
|
+
painEvents: number;
|
|
10
|
+
pendingSamples: number;
|
|
11
|
+
approvedSamples: number;
|
|
12
|
+
blobBytes: number;
|
|
13
|
+
lastIngestAt: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface TrajectoryAssistantTurnInput {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
runId: string;
|
|
18
|
+
provider: string;
|
|
19
|
+
model: string;
|
|
20
|
+
rawText: string;
|
|
21
|
+
sanitizedText: string;
|
|
22
|
+
usageJson: unknown;
|
|
23
|
+
empathySignalJson: unknown;
|
|
24
|
+
createdAt?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface TrajectoryUserTurnInput {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
turnIndex: number;
|
|
29
|
+
rawText: string;
|
|
30
|
+
correctionDetected: boolean;
|
|
31
|
+
correctionCue?: string | null;
|
|
32
|
+
referencesAssistantTurnId?: number | null;
|
|
33
|
+
createdAt?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface TrajectoryToolCallInput {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
outcome: 'success' | 'failure' | 'blocked';
|
|
39
|
+
durationMs?: number | null;
|
|
40
|
+
exitCode?: number | null;
|
|
41
|
+
errorType?: string | null;
|
|
42
|
+
errorMessage?: string | null;
|
|
43
|
+
gfiBefore?: number | null;
|
|
44
|
+
gfiAfter?: number | null;
|
|
45
|
+
paramsJson?: unknown;
|
|
46
|
+
createdAt?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface TrajectoryPainEventInput {
|
|
49
|
+
sessionId: string;
|
|
50
|
+
source: string;
|
|
51
|
+
score: number;
|
|
52
|
+
reason?: string | null;
|
|
53
|
+
severity?: string | null;
|
|
54
|
+
origin?: string | null;
|
|
55
|
+
confidence?: number | null;
|
|
56
|
+
createdAt?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface TrajectoryGateBlockInput {
|
|
59
|
+
sessionId?: string | null;
|
|
60
|
+
toolName: string;
|
|
61
|
+
filePath?: string | null;
|
|
62
|
+
reason: string;
|
|
63
|
+
planStatus?: string | null;
|
|
64
|
+
createdAt?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface TrajectoryTrustChangeInput {
|
|
67
|
+
sessionId?: string | null;
|
|
68
|
+
previousScore: number;
|
|
69
|
+
newScore: number;
|
|
70
|
+
delta: number;
|
|
71
|
+
reason: string;
|
|
72
|
+
createdAt?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface TrajectoryPrincipleEventInput {
|
|
75
|
+
principleId?: string | null;
|
|
76
|
+
eventType: string;
|
|
77
|
+
payload: unknown;
|
|
78
|
+
createdAt?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface TrajectoryTaskOutcomeInput {
|
|
81
|
+
sessionId: string;
|
|
82
|
+
taskId?: string | null;
|
|
83
|
+
outcome: string;
|
|
84
|
+
summary?: string | null;
|
|
85
|
+
principleIdsJson?: unknown;
|
|
86
|
+
createdAt?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface TrajectorySessionInput {
|
|
89
|
+
sessionId: string;
|
|
90
|
+
startedAt?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface AssistantTurnRecord {
|
|
93
|
+
id: number;
|
|
94
|
+
sessionId: string;
|
|
95
|
+
runId: string;
|
|
96
|
+
provider: string;
|
|
97
|
+
model: string;
|
|
98
|
+
rawText: string;
|
|
99
|
+
sanitizedText: string;
|
|
100
|
+
blobRef: string | null;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
}
|
|
103
|
+
export interface CorrectionSampleRecord {
|
|
104
|
+
sampleId: string;
|
|
105
|
+
sessionId: string;
|
|
106
|
+
badAssistantTurnId: number;
|
|
107
|
+
userCorrectionTurnId: number;
|
|
108
|
+
recoveryToolSpanJson: string;
|
|
109
|
+
diffExcerpt: string;
|
|
110
|
+
principleIdsJson: string;
|
|
111
|
+
qualityScore: number;
|
|
112
|
+
reviewStatus: CorrectionSampleReviewStatus;
|
|
113
|
+
exportMode: CorrectionExportMode;
|
|
114
|
+
createdAt: string;
|
|
115
|
+
updatedAt: string;
|
|
116
|
+
}
|
|
117
|
+
export interface TrajectoryExportResult {
|
|
118
|
+
filePath: string;
|
|
119
|
+
count: number;
|
|
120
|
+
mode?: CorrectionExportMode;
|
|
121
|
+
}
|
|
122
|
+
export interface TrajectoryDatabaseOptions {
|
|
123
|
+
workspaceDir: string;
|
|
124
|
+
blobInlineThresholdBytes?: number;
|
|
125
|
+
busyTimeoutMs?: number;
|
|
126
|
+
orphanBlobGraceDays?: number;
|
|
127
|
+
}
|
|
128
|
+
export declare class TrajectoryDatabase {
|
|
129
|
+
private readonly workspaceDir;
|
|
130
|
+
private readonly stateDir;
|
|
131
|
+
private readonly dbPath;
|
|
132
|
+
private readonly blobDir;
|
|
133
|
+
private readonly exportDir;
|
|
134
|
+
private readonly blobInlineThresholdBytes;
|
|
135
|
+
private readonly orphanBlobGraceMs;
|
|
136
|
+
private readonly db;
|
|
137
|
+
constructor(opts: TrajectoryDatabaseOptions);
|
|
138
|
+
dispose(): void;
|
|
139
|
+
recordSession(input: TrajectorySessionInput): void;
|
|
140
|
+
recordAssistantTurn(input: TrajectoryAssistantTurnInput): number;
|
|
141
|
+
recordUserTurn(input: TrajectoryUserTurnInput): number;
|
|
142
|
+
recordToolCall(input: TrajectoryToolCallInput): number;
|
|
143
|
+
recordPainEvent(input: TrajectoryPainEventInput): void;
|
|
144
|
+
recordGateBlock(input: TrajectoryGateBlockInput): void;
|
|
145
|
+
recordTrustChange(input: TrajectoryTrustChangeInput): void;
|
|
146
|
+
recordPrincipleEvent(input: TrajectoryPrincipleEventInput): void;
|
|
147
|
+
recordTaskOutcome(input: TrajectoryTaskOutcomeInput): void;
|
|
148
|
+
listAssistantTurns(sessionId: string): AssistantTurnRecord[];
|
|
149
|
+
listCorrectionSamples(status?: CorrectionSampleReviewStatus): CorrectionSampleRecord[];
|
|
150
|
+
reviewCorrectionSample(sampleId: string, status: Exclude<CorrectionSampleReviewStatus, 'pending'>, note?: string): CorrectionSampleRecord;
|
|
151
|
+
exportCorrections(opts: {
|
|
152
|
+
mode: CorrectionExportMode;
|
|
153
|
+
approvedOnly: boolean;
|
|
154
|
+
}): TrajectoryExportResult;
|
|
155
|
+
exportAnalytics(): TrajectoryExportResult;
|
|
156
|
+
getDataStats(): TrajectoryDataStats;
|
|
157
|
+
cleanupBlobStorage(): {
|
|
158
|
+
removedFiles: number;
|
|
159
|
+
reclaimedBytes: number;
|
|
160
|
+
};
|
|
161
|
+
private initSchema;
|
|
162
|
+
private importLegacyArtifacts;
|
|
163
|
+
private migrateSchema;
|
|
164
|
+
private dailyMetrics;
|
|
165
|
+
private importLegacySessions;
|
|
166
|
+
private importLegacyEvents;
|
|
167
|
+
private importLegacyEvolution;
|
|
168
|
+
private markImported;
|
|
169
|
+
private isImported;
|
|
170
|
+
private maybeCreateCorrectionSample;
|
|
171
|
+
private recordExportAudit;
|
|
172
|
+
private storeRawText;
|
|
173
|
+
private restoreRawText;
|
|
174
|
+
private computeBlobBytes;
|
|
175
|
+
private pruneUnreferencedBlobs;
|
|
176
|
+
private withWrite;
|
|
177
|
+
}
|
|
178
|
+
export declare class TrajectoryRegistry {
|
|
179
|
+
private static instances;
|
|
180
|
+
static get(workspaceDir: string, opts?: Omit<TrajectoryDatabaseOptions, 'workspaceDir'>): TrajectoryDatabase;
|
|
181
|
+
static dispose(workspaceDir: string): void;
|
|
182
|
+
static clear(): void;
|
|
183
|
+
static use<T>(workspaceDir: string, fn: (db: TrajectoryDatabase) => T, opts?: Omit<TrajectoryDatabaseOptions, 'workspaceDir'>): T;
|
|
184
|
+
}
|