principles-disciple 1.5.4
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/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.js +73 -0
- package/dist/commands/evolver.d.ts +9 -0
- package/dist/commands/evolver.js +26 -0
- package/dist/commands/pain.d.ts +5 -0
- package/dist/commands/pain.js +114 -0
- package/dist/commands/strategy.d.ts +3 -0
- package/dist/commands/strategy.js +29 -0
- package/dist/commands/thinking-os.d.ts +2 -0
- package/dist/commands/thinking-os.js +162 -0
- package/dist/commands/trust.d.ts +4 -0
- package/dist/commands/trust.js +95 -0
- package/dist/core/agent-loader.d.ts +44 -0
- package/dist/core/agent-loader.js +147 -0
- package/dist/core/config-service.d.ts +15 -0
- package/dist/core/config-service.js +26 -0
- package/dist/core/config.d.ts +103 -0
- package/dist/core/config.js +186 -0
- package/dist/core/detection-funnel.d.ts +33 -0
- package/dist/core/detection-funnel.js +100 -0
- package/dist/core/detection-service.d.ts +15 -0
- package/dist/core/detection-service.js +28 -0
- package/dist/core/dictionary-service.d.ts +15 -0
- package/dist/core/dictionary-service.js +26 -0
- package/dist/core/dictionary.d.ts +36 -0
- package/dist/core/dictionary.js +136 -0
- package/dist/core/event-log.d.ts +53 -0
- package/dist/core/event-log.js +196 -0
- package/dist/core/evolution-engine.d.ts +119 -0
- package/dist/core/evolution-engine.js +542 -0
- package/dist/core/evolution-types.d.ts +126 -0
- package/dist/core/evolution-types.js +56 -0
- package/dist/core/hygiene/tracker.d.ts +22 -0
- package/dist/core/hygiene/tracker.js +106 -0
- package/dist/core/init.d.ts +12 -0
- package/dist/core/init.js +117 -0
- package/dist/core/migration.d.ts +6 -0
- package/dist/core/migration.js +90 -0
- package/dist/core/pain.d.ts +4 -0
- package/dist/core/pain.js +70 -0
- package/dist/core/path-resolver.d.ts +43 -0
- package/dist/core/path-resolver.js +259 -0
- package/dist/core/paths.d.ts +60 -0
- package/dist/core/paths.js +67 -0
- package/dist/core/profile.d.ts +62 -0
- package/dist/core/profile.js +210 -0
- package/dist/core/risk-calculator.d.ts +7 -0
- package/dist/core/risk-calculator.js +39 -0
- package/dist/core/session-tracker.d.ts +76 -0
- package/dist/core/session-tracker.js +286 -0
- package/dist/core/system-logger.d.ts +8 -0
- package/dist/core/system-logger.js +31 -0
- package/dist/core/trust-engine.d.ts +91 -0
- package/dist/core/trust-engine.js +284 -0
- package/dist/core/workspace-context.d.ts +64 -0
- package/dist/core/workspace-context.js +134 -0
- package/dist/hooks/gate.d.ts +6 -0
- package/dist/hooks/gate.js +487 -0
- package/dist/hooks/lifecycle.d.ts +5 -0
- package/dist/hooks/lifecycle.js +180 -0
- package/dist/hooks/llm.d.ts +4 -0
- package/dist/hooks/llm.js +153 -0
- package/dist/hooks/pain.d.ts +5 -0
- package/dist/hooks/pain.js +173 -0
- package/dist/hooks/prompt.d.ts +38 -0
- package/dist/hooks/prompt.js +285 -0
- package/dist/hooks/subagent.d.ts +2 -0
- package/dist/hooks/subagent.js +70 -0
- package/dist/i18n/commands.d.ts +26 -0
- package/dist/i18n/commands.js +88 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +204 -0
- package/dist/service/evolution-worker.d.ts +17 -0
- package/dist/service/evolution-worker.js +293 -0
- package/dist/tools/agent-spawn.d.ts +33 -0
- package/dist/tools/agent-spawn.js +170 -0
- package/dist/tools/critique-prompt.d.ts +14 -0
- package/dist/tools/critique-prompt.js +81 -0
- package/dist/tools/deep-reflect.d.ts +19 -0
- package/dist/tools/deep-reflect.js +174 -0
- package/dist/tools/model-index.d.ts +9 -0
- package/dist/tools/model-index.js +82 -0
- package/dist/types/event-types.d.ts +229 -0
- package/dist/types/event-types.js +73 -0
- package/dist/types/hygiene-types.d.ts +20 -0
- package/dist/types/hygiene-types.js +12 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/dist/utils/file-lock.d.ts +64 -0
- package/dist/utils/file-lock.js +270 -0
- package/dist/utils/glob-match.d.ts +28 -0
- package/dist/utils/glob-match.js +49 -0
- package/dist/utils/hashing.d.ts +9 -0
- package/dist/utils/hashing.js +25 -0
- package/dist/utils/io.d.ts +6 -0
- package/dist/utils/io.js +106 -0
- package/dist/utils/nlp.d.ts +9 -0
- package/dist/utils/nlp.js +59 -0
- package/dist/utils/plugin-logger.d.ts +39 -0
- package/dist/utils/plugin-logger.js +70 -0
- package/openclaw.plugin.json +46 -0
- package/package.json +63 -0
- package/templates/langs/en/core/AGENTS.md +206 -0
- package/templates/langs/en/core/BOOT.md +60 -0
- package/templates/langs/en/core/BOOTSTRAP.md +250 -0
- package/templates/langs/en/core/HEARTBEAT.md +74 -0
- package/templates/langs/en/core/IDENTITY.md +8 -0
- package/templates/langs/en/core/PRINCIPLES.md +10 -0
- package/templates/langs/en/core/SOUL.md +76 -0
- package/templates/langs/en/core/TOOLS.md +53 -0
- package/templates/langs/en/core/USER.md +10 -0
- package/templates/langs/en/pain/00_seed_samples.md +23 -0
- package/templates/langs/en/pain_dictionary.json +22 -0
- package/templates/langs/en/skills/admin/SKILL.md +40 -0
- package/templates/langs/en/skills/bootstrap-tools/SKILL.md +53 -0
- package/templates/langs/en/skills/deductive-audit/SKILL.md +36 -0
- package/templates/langs/en/skills/evolution-framework-update/SKILL.md +31 -0
- package/templates/langs/en/skills/evolve-system/SKILL.md +46 -0
- package/templates/langs/en/skills/evolve-task/SKILL.md +83 -0
- package/templates/langs/en/skills/feedback/SKILL.md +51 -0
- package/templates/langs/en/skills/init-strategy/SKILL.md +54 -0
- package/templates/langs/en/skills/inject-rule/SKILL.md +19 -0
- package/templates/langs/en/skills/manage-okr/SKILL.md +96 -0
- package/templates/langs/en/skills/pain/SKILL.md +19 -0
- package/templates/langs/en/skills/pd-daily/SKILL.md +199 -0
- package/templates/langs/en/skills/pd-grooming/SKILL.md +46 -0
- package/templates/langs/en/skills/pd-mentor/SKILL.md +230 -0
- package/templates/langs/en/skills/plan-script/SKILL.md +32 -0
- package/templates/langs/en/skills/profile/SKILL.md +24 -0
- package/templates/langs/en/skills/reflection/SKILL.md +40 -0
- package/templates/langs/en/skills/reflection-log/SKILL.md +37 -0
- package/templates/langs/en/skills/report/SKILL.md +13 -0
- package/templates/langs/en/skills/root-cause/SKILL.md +33 -0
- package/templates/langs/en/skills/triage/SKILL.md +29 -0
- package/templates/langs/en/skills/watch-evolution/SKILL.md +33 -0
- package/templates/langs/zh/core/AGENTS.md +207 -0
- package/templates/langs/zh/core/BOOT.md +60 -0
- package/templates/langs/zh/core/BOOTSTRAP.md +250 -0
- package/templates/langs/zh/core/HEARTBEAT.md +74 -0
- package/templates/langs/zh/core/IDENTITY.md +8 -0
- package/templates/langs/zh/core/SOUL.md +76 -0
- package/templates/langs/zh/core/TOOLS.md +53 -0
- package/templates/langs/zh/core/USER.md +10 -0
- package/templates/langs/zh/pain/00_seed_samples.md +24 -0
- package/templates/langs/zh/pain_dictionary.json +18 -0
- package/templates/langs/zh/skills/admin/SKILL.md +42 -0
- package/templates/langs/zh/skills/bootstrap-tools/SKILL.md +52 -0
- package/templates/langs/zh/skills/deductive-audit/SKILL.md +36 -0
- package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +31 -0
- package/templates/langs/zh/skills/evolve-system/SKILL.md +46 -0
- package/templates/langs/zh/skills/evolve-task/SKILL.md +83 -0
- package/templates/langs/zh/skills/feedback/SKILL.md +53 -0
- package/templates/langs/zh/skills/init-strategy/SKILL.md +54 -0
- package/templates/langs/zh/skills/inject-rule/SKILL.md +19 -0
- package/templates/langs/zh/skills/manage-okr/SKILL.md +109 -0
- package/templates/langs/zh/skills/pain/SKILL.md +19 -0
- package/templates/langs/zh/skills/pd-daily/SKILL.md +199 -0
- package/templates/langs/zh/skills/pd-grooming/SKILL.md +46 -0
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +230 -0
- package/templates/langs/zh/skills/plan-script/SKILL.md +32 -0
- package/templates/langs/zh/skills/profile/SKILL.md +24 -0
- package/templates/langs/zh/skills/reflection/SKILL.md +40 -0
- package/templates/langs/zh/skills/reflection-log/SKILL.md +37 -0
- package/templates/langs/zh/skills/report/SKILL.md +13 -0
- package/templates/langs/zh/skills/root-cause/SKILL.md +33 -0
- package/templates/langs/zh/skills/triage/SKILL.md +29 -0
- package/templates/langs/zh/skills/watch-evolution/SKILL.md +33 -0
- package/templates/pain_dictionary.json +36 -0
- package/templates/pain_settings.json +77 -0
- package/templates/workspace/.principles/00-kernel.md +51 -0
- package/templates/workspace/.principles/DECISION_POLICY.json +44 -0
- package/templates/workspace/.principles/PRINCIPLES.md +20 -0
- package/templates/workspace/.principles/PROFILE.json +52 -0
- package/templates/workspace/.principles/PROFILE.schema.json +56 -0
- package/templates/workspace/.principles/THINKING_OS.md +64 -0
- package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +7 -0
- package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +9 -0
- package/templates/workspace/.principles/models/_INDEX.md +27 -0
- package/templates/workspace/.principles/models/first_principles.md +62 -0
- package/templates/workspace/.principles/models/marketing_4p.md +52 -0
- package/templates/workspace/.principles/models/porter_five.md +63 -0
- package/templates/workspace/.principles/models/swot.md +60 -0
- package/templates/workspace/.principles/models/user_story_map.md +63 -0
- package/templates/workspace/.state/WORKBOARD.json +4 -0
- package/templates/workspace/AUDIT.md +15 -0
- package/templates/workspace/PLAN.md +2 -0
- package/templates/workspace/okr/RECOVERY_PROTOCOL.md +56 -0
- package/templates/workspace/okr/TASK_CHANGES.jsonl +6 -0
- package/templates/workspace/okr/WEEK_TASKS.json +6 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evolution Engine V2.0 - MVP
|
|
3
|
+
*
|
|
4
|
+
* 成长驱动的进化积分系统,替代惩罚驱动的 Trust Engine。
|
|
5
|
+
*
|
|
6
|
+
* 核心原则:
|
|
7
|
+
* 1. 起点0分,只能增加,不扣分
|
|
8
|
+
* 2. 失败记录教训,不扣分
|
|
9
|
+
* 3. 同类任务失败后首次成功 = 双倍奖励(1小时冷却)
|
|
10
|
+
* 4. 高等级做低级任务积分衰减
|
|
11
|
+
* 5. 原子写入防止并发损坏
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { resolvePdPath } from './paths.js';
|
|
16
|
+
// ===== 文件锁常量 =====
|
|
17
|
+
const LOCK_SUFFIX = '.lock';
|
|
18
|
+
const LOCK_MAX_RETRIES = 50;
|
|
19
|
+
const LOCK_RETRY_DELAY_MS = 50;
|
|
20
|
+
const LOCK_STALE_MS = 30_000; // 30秒视为死锁
|
|
21
|
+
import { EvolutionTier, DEFAULT_EVOLUTION_CONFIG, TIER_DEFINITIONS, TASK_DIFFICULTY_CONFIG, getTierDefinition, getTierByPoints, } from './evolution-types.js';
|
|
22
|
+
// ===== 工具分类(复用 Trust Engine 的分类) =====
|
|
23
|
+
const EXPLORATORY_TOOLS = new Set([
|
|
24
|
+
'read', 'read_file', 'read_many_files', 'image_read',
|
|
25
|
+
'search_file_content', 'grep', 'grep_search', 'list_directory', 'ls', 'glob',
|
|
26
|
+
'web_fetch', 'web_search',
|
|
27
|
+
'ask_user', 'ask_user_question',
|
|
28
|
+
'memory_recall', 'save_memory',
|
|
29
|
+
]);
|
|
30
|
+
const CONSTRUCTIVE_TOOLS = new Set([
|
|
31
|
+
'write', 'write_file', 'edit', 'edit_file', 'replace', 'apply_patch',
|
|
32
|
+
'insert', 'patch', 'delete_file', 'move_file', 'run_shell_command',
|
|
33
|
+
'pd_spawn_agent', 'sessions_spawn',
|
|
34
|
+
]);
|
|
35
|
+
// 高风险工具:需要 allowRiskPath 权限
|
|
36
|
+
// 注意:pd_spawn_agent 和 sessions_spawn 已从高风险中移出,它们由 allowSubagentSpawn 单独控制
|
|
37
|
+
const HIGH_RISK_TOOLS = new Set([
|
|
38
|
+
'run_shell_command', 'delete_file', 'move_file',
|
|
39
|
+
]);
|
|
40
|
+
// 内容行数限制仅适用于这些写操作工具
|
|
41
|
+
const CONTENT_LIMITED_TOOLS = new Set([
|
|
42
|
+
'write', 'write_file',
|
|
43
|
+
'edit', 'edit_file',
|
|
44
|
+
'replace', 'apply_patch',
|
|
45
|
+
'insert', 'patch',
|
|
46
|
+
]);
|
|
47
|
+
// ===== 主引擎 =====
|
|
48
|
+
export class EvolutionEngine {
|
|
49
|
+
scorecard;
|
|
50
|
+
workspaceDir;
|
|
51
|
+
stateDir;
|
|
52
|
+
config;
|
|
53
|
+
storagePath;
|
|
54
|
+
constructor(workspaceDir, config) {
|
|
55
|
+
this.workspaceDir = workspaceDir;
|
|
56
|
+
this.stateDir = resolvePdPath(workspaceDir, 'STATE_DIR');
|
|
57
|
+
this.config = { ...DEFAULT_EVOLUTION_CONFIG, ...config };
|
|
58
|
+
this.storagePath = path.join(this.stateDir, 'evolution-scorecard.json');
|
|
59
|
+
this.scorecard = this.loadOrCreateScorecard();
|
|
60
|
+
}
|
|
61
|
+
// ===== 公共 API =====
|
|
62
|
+
/** 获取当前积分 */
|
|
63
|
+
getPoints() {
|
|
64
|
+
return this.scorecard.totalPoints;
|
|
65
|
+
}
|
|
66
|
+
/** 获取可用积分 */
|
|
67
|
+
getAvailablePoints() {
|
|
68
|
+
return this.scorecard.availablePoints;
|
|
69
|
+
}
|
|
70
|
+
/** 获取当前等级 */
|
|
71
|
+
getTier() {
|
|
72
|
+
return this.scorecard.currentTier;
|
|
73
|
+
}
|
|
74
|
+
/** 获取当前等级定义 */
|
|
75
|
+
getTierDefinition() {
|
|
76
|
+
return getTierDefinition(this.scorecard.currentTier);
|
|
77
|
+
}
|
|
78
|
+
/** 获取完整积分卡 */
|
|
79
|
+
getScorecard() {
|
|
80
|
+
return { ...this.scorecard };
|
|
81
|
+
}
|
|
82
|
+
/** 获取统计信息 */
|
|
83
|
+
getStats() {
|
|
84
|
+
return { ...this.scorecard.stats };
|
|
85
|
+
}
|
|
86
|
+
/** 获取状态摘要 */
|
|
87
|
+
getStatusSummary() {
|
|
88
|
+
const tierDef = this.getTierDefinition();
|
|
89
|
+
const nextTierDef = TIER_DEFINITIONS[this.scorecard.currentTier]; // undefined if max
|
|
90
|
+
return {
|
|
91
|
+
tier: this.scorecard.currentTier,
|
|
92
|
+
tierName: tierDef.name,
|
|
93
|
+
totalPoints: this.scorecard.totalPoints,
|
|
94
|
+
availablePoints: this.scorecard.availablePoints,
|
|
95
|
+
permissions: tierDef.permissions,
|
|
96
|
+
stats: this.scorecard.stats,
|
|
97
|
+
nextTier: nextTierDef ? {
|
|
98
|
+
tier: nextTierDef.tier,
|
|
99
|
+
name: nextTierDef.name,
|
|
100
|
+
pointsNeeded: nextTierDef.requiredPoints - this.scorecard.totalPoints,
|
|
101
|
+
} : null,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// ===== 记录成功 =====
|
|
105
|
+
recordSuccess(toolName, options) {
|
|
106
|
+
// 探索性工具成功不给积分,只重置失败记录
|
|
107
|
+
if (EXPLORATORY_TOOLS.has(toolName)) {
|
|
108
|
+
const taskHash = this.computeTaskHash(toolName, options?.filePath);
|
|
109
|
+
this.scorecard.recentFailureHashes.delete(taskHash);
|
|
110
|
+
this.saveScorecard();
|
|
111
|
+
return { pointsAwarded: 0, isDoubleReward: false };
|
|
112
|
+
}
|
|
113
|
+
const difficulty = options?.difficulty || this.inferDifficulty(toolName);
|
|
114
|
+
const taskHash = this.computeTaskHash(toolName, options?.filePath);
|
|
115
|
+
// 计算积分
|
|
116
|
+
let points = this.calculatePoints(difficulty, taskHash);
|
|
117
|
+
const isDoubleReward = points > TASK_DIFFICULTY_CONFIG[difficulty].basePoints;
|
|
118
|
+
// 更新积分
|
|
119
|
+
this.scorecard.totalPoints += points;
|
|
120
|
+
this.scorecard.availablePoints += points;
|
|
121
|
+
// 更新统计
|
|
122
|
+
this.scorecard.stats.totalSuccesses++;
|
|
123
|
+
this.scorecard.stats.consecutiveSuccesses++;
|
|
124
|
+
this.scorecard.stats.consecutiveFailures = 0;
|
|
125
|
+
this.scorecard.stats.pointsByDifficulty[difficulty] += points;
|
|
126
|
+
if (isDoubleReward) {
|
|
127
|
+
this.scorecard.stats.doubleRewardsEarned++;
|
|
128
|
+
this.scorecard.lastDoubleRewardTime = new Date().toISOString();
|
|
129
|
+
}
|
|
130
|
+
// 清除失败记录
|
|
131
|
+
this.scorecard.recentFailureHashes.delete(taskHash);
|
|
132
|
+
// 记录事件
|
|
133
|
+
const event = this.createEvent('success', taskHash, difficulty, toolName, options?.filePath, options?.reason, points, isDoubleReward, options?.sessionId);
|
|
134
|
+
this.addEvent(event);
|
|
135
|
+
// 检查升级
|
|
136
|
+
const newTier = this.checkAndApplyPromotion();
|
|
137
|
+
this.saveScorecard();
|
|
138
|
+
return { pointsAwarded: points, isDoubleReward, newTier };
|
|
139
|
+
}
|
|
140
|
+
// ===== 记录失败 =====
|
|
141
|
+
recordFailure(toolName, options) {
|
|
142
|
+
// 探索性工具失败:记录但几乎不影响
|
|
143
|
+
if (EXPLORATORY_TOOLS.has(toolName)) {
|
|
144
|
+
const event = this.createEvent('failure', this.computeTaskHash(toolName, options?.filePath), 'trivial', toolName, options?.filePath, options?.reason, 0, false, options?.sessionId);
|
|
145
|
+
this.addEvent(event);
|
|
146
|
+
this.saveScorecard();
|
|
147
|
+
return { pointsAwarded: 0, lessonRecorded: true };
|
|
148
|
+
}
|
|
149
|
+
const difficulty = options?.difficulty || this.inferDifficulty(toolName);
|
|
150
|
+
const taskHash = this.computeTaskHash(toolName, options?.filePath);
|
|
151
|
+
// 失败不扣分,但记录教训(用于后续双倍奖励)
|
|
152
|
+
this.scorecard.recentFailureHashes.set(taskHash, new Date().toISOString());
|
|
153
|
+
// 更新统计
|
|
154
|
+
this.scorecard.stats.totalFailures++;
|
|
155
|
+
this.scorecard.stats.consecutiveFailures++;
|
|
156
|
+
this.scorecard.stats.consecutiveSuccesses = 0;
|
|
157
|
+
// 记录事件(0分)
|
|
158
|
+
const event = this.createEvent('failure', taskHash, difficulty, toolName, options?.filePath, options?.reason, 0, false, options?.sessionId);
|
|
159
|
+
this.addEvent(event);
|
|
160
|
+
this.saveScorecard();
|
|
161
|
+
return { pointsAwarded: 0, lessonRecorded: true };
|
|
162
|
+
}
|
|
163
|
+
// ===== Gate 集成 =====
|
|
164
|
+
/** 工具调用前检查 */
|
|
165
|
+
beforeToolCall(context) {
|
|
166
|
+
const tierDef = this.getTierDefinition();
|
|
167
|
+
const perms = tierDef.permissions;
|
|
168
|
+
// 行数检查(仅针对写操作工具)
|
|
169
|
+
if (CONTENT_LIMITED_TOOLS.has(context.toolName)) {
|
|
170
|
+
if (context.content) {
|
|
171
|
+
const lineCount = context.content.split('\n').length;
|
|
172
|
+
if (lineCount > perms.maxLinesPerWrite) {
|
|
173
|
+
return {
|
|
174
|
+
allowed: false,
|
|
175
|
+
reason: `Tier ${this.scorecard.currentTier} (${tierDef.name}) 限制: 最多 ${perms.maxLinesPerWrite} 行,当前 ${lineCount} 行`,
|
|
176
|
+
currentTier: this.scorecard.currentTier,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (context.lineCount && context.lineCount > perms.maxLinesPerWrite) {
|
|
181
|
+
return {
|
|
182
|
+
allowed: false,
|
|
183
|
+
reason: `Tier ${this.scorecard.currentTier} (${tierDef.name}) 限制: 最多 ${perms.maxLinesPerWrite} 行`,
|
|
184
|
+
currentTier: this.scorecard.currentTier,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// 风险路径检查
|
|
189
|
+
if (context.isRiskPath && !perms.allowRiskPath) {
|
|
190
|
+
return {
|
|
191
|
+
allowed: false,
|
|
192
|
+
reason: `Tier ${this.scorecard.currentTier} (${tierDef.name}) 未解锁风险路径权限`,
|
|
193
|
+
currentTier: this.scorecard.currentTier,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// 高风险工具检查(不包括子智能体,它们有单独控制)
|
|
197
|
+
if (HIGH_RISK_TOOLS.has(context.toolName) && !perms.allowRiskPath) {
|
|
198
|
+
return {
|
|
199
|
+
allowed: false,
|
|
200
|
+
reason: `Tier ${this.scorecard.currentTier} (${tierDef.name}) 未解锁高风险工具权限`,
|
|
201
|
+
currentTier: this.scorecard.currentTier,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// 子智能体检查
|
|
205
|
+
if ((context.toolName === 'pd_spawn_agent' || context.toolName === 'sessions_spawn') && !perms.allowSubagentSpawn) {
|
|
206
|
+
return {
|
|
207
|
+
allowed: false,
|
|
208
|
+
reason: `Tier ${this.scorecard.currentTier} (${tierDef.name}) 未解锁子智能体权限`,
|
|
209
|
+
currentTier: this.scorecard.currentTier,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return { allowed: true, currentTier: this.scorecard.currentTier };
|
|
213
|
+
}
|
|
214
|
+
// ===== 积分计算 =====
|
|
215
|
+
calculatePoints(difficulty, taskHash) {
|
|
216
|
+
const basePoints = TASK_DIFFICULTY_CONFIG[difficulty].basePoints;
|
|
217
|
+
// 难度衰减
|
|
218
|
+
const penalty = this.getDifficultyPenalty(difficulty);
|
|
219
|
+
let points = Math.max(1, Math.floor(basePoints * penalty));
|
|
220
|
+
// 双倍奖励检查
|
|
221
|
+
if (this.canReceiveDoubleReward(taskHash)) {
|
|
222
|
+
points *= 2;
|
|
223
|
+
}
|
|
224
|
+
return points;
|
|
225
|
+
}
|
|
226
|
+
getDifficultyPenalty(difficulty) {
|
|
227
|
+
const tier = this.scorecard.currentTier;
|
|
228
|
+
const dc = this.config.difficultyPenalty;
|
|
229
|
+
if (tier >= EvolutionTier.Tree) {
|
|
230
|
+
if (difficulty === 'trivial')
|
|
231
|
+
return dc.tier4Trivial;
|
|
232
|
+
if (difficulty === 'normal')
|
|
233
|
+
return dc.tier4Normal;
|
|
234
|
+
}
|
|
235
|
+
if (tier >= EvolutionTier.Forest) {
|
|
236
|
+
if (difficulty === 'trivial')
|
|
237
|
+
return dc.tier5Trivial;
|
|
238
|
+
if (difficulty === 'normal')
|
|
239
|
+
return dc.tier5Normal;
|
|
240
|
+
}
|
|
241
|
+
return 1.0;
|
|
242
|
+
}
|
|
243
|
+
canReceiveDoubleReward(taskHash) {
|
|
244
|
+
// 必须有该任务的失败记录
|
|
245
|
+
if (!this.scorecard.recentFailureHashes.has(taskHash)) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
// 冷却检查:1小时内最多1次双倍奖励
|
|
249
|
+
if (this.scorecard.lastDoubleRewardTime) {
|
|
250
|
+
const elapsed = Date.now() - new Date(this.scorecard.lastDoubleRewardTime).getTime();
|
|
251
|
+
if (elapsed < this.config.doubleRewardCooldownMs) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
// ===== 等级晋升 =====
|
|
258
|
+
checkAndApplyPromotion() {
|
|
259
|
+
const newTier = getTierByPoints(this.scorecard.totalPoints);
|
|
260
|
+
if (newTier > this.scorecard.currentTier) {
|
|
261
|
+
const previousTier = this.scorecard.currentTier;
|
|
262
|
+
this.scorecard.currentTier = newTier;
|
|
263
|
+
this.scorecard.stats.tierPromotions++;
|
|
264
|
+
// 记录升级事件
|
|
265
|
+
const promotionEvent = {
|
|
266
|
+
previousTier,
|
|
267
|
+
newTier,
|
|
268
|
+
totalPoints: this.scorecard.totalPoints,
|
|
269
|
+
timestamp: new Date().toISOString(),
|
|
270
|
+
newPermissions: getTierDefinition(newTier).permissions,
|
|
271
|
+
};
|
|
272
|
+
console.log(`[Evolution] 🎉 Tier promotion: ${previousTier} → ${newTier} (${getTierDefinition(newTier).name})`);
|
|
273
|
+
return newTier;
|
|
274
|
+
}
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
// ===== 任务难度推断 =====
|
|
278
|
+
inferDifficulty(toolName) {
|
|
279
|
+
if (HIGH_RISK_TOOLS.has(toolName))
|
|
280
|
+
return 'hard';
|
|
281
|
+
if (CONSTRUCTIVE_TOOLS.has(toolName))
|
|
282
|
+
return 'normal';
|
|
283
|
+
return 'trivial';
|
|
284
|
+
}
|
|
285
|
+
// ===== 任务哈希 =====
|
|
286
|
+
computeTaskHash(toolName, filePath) {
|
|
287
|
+
const normalizedPath = filePath ? path.normalize(filePath) : '_nofile';
|
|
288
|
+
return `${toolName}:${normalizedPath}`;
|
|
289
|
+
}
|
|
290
|
+
// ===== 事件管理 =====
|
|
291
|
+
createEvent(type, taskHash, difficulty, toolName, filePath, reason, points, isDoubleReward, sessionId) {
|
|
292
|
+
return {
|
|
293
|
+
id: this.generateId(),
|
|
294
|
+
timestamp: new Date().toISOString(),
|
|
295
|
+
type,
|
|
296
|
+
taskHash,
|
|
297
|
+
taskDifficulty: difficulty,
|
|
298
|
+
toolName,
|
|
299
|
+
filePath,
|
|
300
|
+
reason,
|
|
301
|
+
pointsAwarded: points,
|
|
302
|
+
isDoubleReward,
|
|
303
|
+
sessionId,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
addEvent(event) {
|
|
307
|
+
this.scorecard.recentEvents.push(event);
|
|
308
|
+
// 限制事件数量
|
|
309
|
+
if (this.scorecard.recentEvents.length > this.config.maxRecentEvents) {
|
|
310
|
+
this.scorecard.recentEvents.shift();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// ===== 存储 =====
|
|
314
|
+
loadOrCreateScorecard() {
|
|
315
|
+
// 尝试从文件加载
|
|
316
|
+
if (fs.existsSync(this.storagePath)) {
|
|
317
|
+
try {
|
|
318
|
+
const raw = fs.readFileSync(this.storagePath, 'utf8');
|
|
319
|
+
const data = JSON.parse(raw);
|
|
320
|
+
if (data.version === '2.0') {
|
|
321
|
+
// 恢复 Map 类型
|
|
322
|
+
if (data.recentFailureHashes && Array.isArray(data.recentFailureHashes)) {
|
|
323
|
+
data.recentFailureHashes = new Map(data.recentFailureHashes);
|
|
324
|
+
}
|
|
325
|
+
else if (!data.recentFailureHashes) {
|
|
326
|
+
data.recentFailureHashes = new Map();
|
|
327
|
+
}
|
|
328
|
+
return data;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
console.error(`[Evolution] Failed to parse scorecard at ${this.storagePath}. Creating new.`, e);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// 创建新的积分卡
|
|
336
|
+
return this.createNewScorecard();
|
|
337
|
+
}
|
|
338
|
+
createNewScorecard() {
|
|
339
|
+
const now = new Date().toISOString();
|
|
340
|
+
return {
|
|
341
|
+
version: '2.0',
|
|
342
|
+
agentId: 'default',
|
|
343
|
+
totalPoints: 0,
|
|
344
|
+
availablePoints: 0,
|
|
345
|
+
currentTier: EvolutionTier.Seed,
|
|
346
|
+
recentFailureHashes: new Map(),
|
|
347
|
+
stats: {
|
|
348
|
+
totalSuccesses: 0,
|
|
349
|
+
totalFailures: 0,
|
|
350
|
+
consecutiveSuccesses: 0,
|
|
351
|
+
consecutiveFailures: 0,
|
|
352
|
+
doubleRewardsEarned: 0,
|
|
353
|
+
tierPromotions: 0,
|
|
354
|
+
pointsByDifficulty: { trivial: 0, normal: 0, hard: 0 },
|
|
355
|
+
},
|
|
356
|
+
recentEvents: [],
|
|
357
|
+
lastUpdated: now,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
// ===== 文件锁与原子写入(P0 修复) =====
|
|
361
|
+
/** 获取文件锁,返回释放函数 */
|
|
362
|
+
acquireFileLock(resourcePath) {
|
|
363
|
+
const lockPath = resourcePath + LOCK_SUFFIX;
|
|
364
|
+
let retries = 0;
|
|
365
|
+
while (retries < LOCK_MAX_RETRIES) {
|
|
366
|
+
try {
|
|
367
|
+
// 'wx' = 写入+排他,文件已存在则抛 EEXIST
|
|
368
|
+
const fd = fs.openSync(lockPath, 'wx');
|
|
369
|
+
fs.writeSync(fd, `${process.pid}\n${Date.now()}`);
|
|
370
|
+
fs.closeSync(fd);
|
|
371
|
+
return () => {
|
|
372
|
+
try {
|
|
373
|
+
fs.unlinkSync(lockPath);
|
|
374
|
+
}
|
|
375
|
+
catch { /* ignore */ }
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
if (err.code === 'EEXIST') {
|
|
380
|
+
// 检测死锁:锁文件过旧则强制清理
|
|
381
|
+
if (this.isLockStale(lockPath)) {
|
|
382
|
+
try {
|
|
383
|
+
fs.unlinkSync(lockPath);
|
|
384
|
+
continue; // 立即重试
|
|
385
|
+
}
|
|
386
|
+
catch { /* 抢占失败,继续等待 */ }
|
|
387
|
+
}
|
|
388
|
+
retries++;
|
|
389
|
+
// busy wait(可改为指数退避)
|
|
390
|
+
const start = Date.now();
|
|
391
|
+
while (Date.now() - start < LOCK_RETRY_DELAY_MS) { /* spin */ }
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
throw err;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
throw new Error(`[Evolution] Lock acquisition failed after ${LOCK_MAX_RETRIES} retries: ${resourcePath}`);
|
|
398
|
+
}
|
|
399
|
+
/** 检查锁文件是否过期(死锁检测) */
|
|
400
|
+
isLockStale(lockPath) {
|
|
401
|
+
try {
|
|
402
|
+
const stat = fs.statSync(lockPath);
|
|
403
|
+
const mtimeMs = stat.mtimeMs;
|
|
404
|
+
// 读取 PID 检查进程是否存活
|
|
405
|
+
const content = fs.readFileSync(lockPath, 'utf8').trim();
|
|
406
|
+
const parts = content.split('\n');
|
|
407
|
+
const pid = parseInt(parts[0] || '0', 10);
|
|
408
|
+
// Unix: signal 0 仅检查进程存在性,Windows 也支持
|
|
409
|
+
if (pid > 0) {
|
|
410
|
+
try {
|
|
411
|
+
process.kill(pid, 0);
|
|
412
|
+
// 进程存活,检查时间
|
|
413
|
+
return Date.now() - mtimeMs > LOCK_STALE_MS;
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
if (e.code === 'ESRCH') {
|
|
417
|
+
// 进程不存在,锁已死
|
|
418
|
+
return true;
|
|
419
|
+
}
|
|
420
|
+
// 无法确定,按时间判断
|
|
421
|
+
return Date.now() - mtimeMs > LOCK_STALE_MS;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// 无有效 PID,按时间判断
|
|
425
|
+
return Date.now() - mtimeMs > LOCK_STALE_MS;
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/** 持久化评分卡(含锁保护) */
|
|
432
|
+
saveScorecard() {
|
|
433
|
+
this.scorecard.lastUpdated = new Date().toISOString();
|
|
434
|
+
// 确保目录存在
|
|
435
|
+
const dir = path.dirname(this.storagePath);
|
|
436
|
+
if (!fs.existsSync(dir)) {
|
|
437
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
438
|
+
}
|
|
439
|
+
// 序列化(Map 转 Array)
|
|
440
|
+
const serializable = {
|
|
441
|
+
...this.scorecard,
|
|
442
|
+
recentFailureHashes: Array.from(this.scorecard.recentFailureHashes.entries()),
|
|
443
|
+
};
|
|
444
|
+
const release = this.acquireFileLock(this.storagePath);
|
|
445
|
+
const tempPath = `${this.storagePath}.tmp.${Date.now()}.${process.pid}`;
|
|
446
|
+
try {
|
|
447
|
+
fs.writeFileSync(tempPath, JSON.stringify(serializable, null, 2), 'utf8');
|
|
448
|
+
// fsync 确保数据落盘
|
|
449
|
+
const fd = fs.openSync(tempPath, 'r+');
|
|
450
|
+
fs.fsyncSync(fd);
|
|
451
|
+
fs.closeSync(fd);
|
|
452
|
+
// 原子重命名
|
|
453
|
+
fs.renameSync(tempPath, this.storagePath);
|
|
454
|
+
}
|
|
455
|
+
catch (e) {
|
|
456
|
+
console.error(`[Evolution] Failed to save scorecard: ${String(e)}`);
|
|
457
|
+
try {
|
|
458
|
+
fs.unlinkSync(tempPath);
|
|
459
|
+
}
|
|
460
|
+
catch { }
|
|
461
|
+
throw e; // 重新抛出,让调用者知道保存失败
|
|
462
|
+
}
|
|
463
|
+
finally {
|
|
464
|
+
release();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/** 保存失败后的重试队列 */
|
|
468
|
+
static retryQueue = [];
|
|
469
|
+
static retryTimer = null;
|
|
470
|
+
/** 调度重试保存 */
|
|
471
|
+
static scheduleRetrySave(engine) {
|
|
472
|
+
// 每个引擎只保留最新数据
|
|
473
|
+
EvolutionEngine.retryQueue = EvolutionEngine.retryQueue.filter(item => item.engine !== engine);
|
|
474
|
+
EvolutionEngine.retryQueue.push({ engine, data: { ...engine.scorecard } });
|
|
475
|
+
// 启动重试定时器
|
|
476
|
+
if (!EvolutionEngine.retryTimer) {
|
|
477
|
+
EvolutionEngine.retryTimer = setTimeout(() => {
|
|
478
|
+
EvolutionEngine.processRetryQueue();
|
|
479
|
+
}, 1000);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/** 处理重试队列 */
|
|
483
|
+
static processRetryQueue() {
|
|
484
|
+
EvolutionEngine.retryTimer = null;
|
|
485
|
+
const latestByEngine = new Map();
|
|
486
|
+
for (const item of EvolutionEngine.retryQueue) {
|
|
487
|
+
latestByEngine.set(item.engine, item.data);
|
|
488
|
+
}
|
|
489
|
+
EvolutionEngine.retryQueue = [];
|
|
490
|
+
for (const [engine, data] of latestByEngine) {
|
|
491
|
+
try {
|
|
492
|
+
engine.saveScorecardImmediate(data);
|
|
493
|
+
console.log(`[Evolution] Retry save succeeded for ${engine.workspaceDir}`);
|
|
494
|
+
}
|
|
495
|
+
catch (e) {
|
|
496
|
+
console.error(`[Evolution] Retry save failed: ${String(e)}`);
|
|
497
|
+
EvolutionEngine.scheduleRetrySave(engine);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
/** 无锁快速保存(用于重试) */
|
|
502
|
+
saveScorecardImmediate(data) {
|
|
503
|
+
const serializable = {
|
|
504
|
+
...this.scorecard,
|
|
505
|
+
...data,
|
|
506
|
+
recentFailureHashes: Array.from(this.scorecard.recentFailureHashes.entries()),
|
|
507
|
+
};
|
|
508
|
+
const tempPath = `${this.storagePath}.tmp.retry.${Date.now()}.${process.pid}`;
|
|
509
|
+
fs.writeFileSync(tempPath, JSON.stringify(serializable, null, 2), 'utf8');
|
|
510
|
+
const fd = fs.openSync(tempPath, 'r');
|
|
511
|
+
fs.fsyncSync(fd);
|
|
512
|
+
fs.closeSync(fd);
|
|
513
|
+
fs.renameSync(tempPath, this.storagePath);
|
|
514
|
+
}
|
|
515
|
+
// ===== 工具方法 =====
|
|
516
|
+
generateId() {
|
|
517
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// ===== 便捷函数 =====
|
|
521
|
+
// 使用 Map 按 workspace 隔离实例,避免多 workspace 场景状态串扰
|
|
522
|
+
const _instances = new Map();
|
|
523
|
+
/** 获取指定 workspace 的引擎实例 */
|
|
524
|
+
export function getEvolutionEngine(workspaceDir) {
|
|
525
|
+
const resolved = path.resolve(workspaceDir);
|
|
526
|
+
if (!_instances.has(resolved)) {
|
|
527
|
+
_instances.set(resolved, new EvolutionEngine(resolved));
|
|
528
|
+
}
|
|
529
|
+
return _instances.get(resolved);
|
|
530
|
+
}
|
|
531
|
+
/** 记录成功(便捷函数) */
|
|
532
|
+
export function recordEvolutionSuccess(workspaceDir, toolName, options) {
|
|
533
|
+
return getEvolutionEngine(workspaceDir).recordSuccess(toolName, options);
|
|
534
|
+
}
|
|
535
|
+
/** 记录失败(便捷函数) */
|
|
536
|
+
export function recordEvolutionFailure(workspaceDir, toolName, options) {
|
|
537
|
+
return getEvolutionEngine(workspaceDir).recordFailure(toolName, options);
|
|
538
|
+
}
|
|
539
|
+
/** Gate 检查(便捷函数) */
|
|
540
|
+
export function checkEvolutionGate(workspaceDir, context) {
|
|
541
|
+
return getEvolutionEngine(workspaceDir).beforeToolCall(context);
|
|
542
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evolution Points System V2.0 - MVP
|
|
3
|
+
*
|
|
4
|
+
* Core Philosophy: Growth-driven替代Penalty-driven
|
|
5
|
+
* - 起点0分,只能增加,不扣分
|
|
6
|
+
* - 失败记录教训,不扣分
|
|
7
|
+
* - 同类任务失败后首次成功 = 双倍奖励(1小时冷却)
|
|
8
|
+
* - 5级成长路径:Seed → Forest
|
|
9
|
+
*/
|
|
10
|
+
export declare enum EvolutionTier {
|
|
11
|
+
Seed = 1,// 萌芽:只读 + 基础文档
|
|
12
|
+
Sprout = 2,// 新芽:单文件编辑 (<50行)
|
|
13
|
+
Sapling = 3,// 幼苗:多文件 + 测试 + 子智能体
|
|
14
|
+
Tree = 4,// 大树:重构 + 风险路径
|
|
15
|
+
Forest = 5
|
|
16
|
+
}
|
|
17
|
+
export interface TierPermissions {
|
|
18
|
+
maxLinesPerWrite: number;
|
|
19
|
+
maxFilesPerTask: number;
|
|
20
|
+
allowRiskPath: boolean;
|
|
21
|
+
allowSubagentSpawn: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface TierDefinition {
|
|
24
|
+
tier: EvolutionTier;
|
|
25
|
+
name: string;
|
|
26
|
+
requiredPoints: number;
|
|
27
|
+
permissions: TierPermissions;
|
|
28
|
+
}
|
|
29
|
+
export declare const TIER_DEFINITIONS: readonly TierDefinition[];
|
|
30
|
+
export declare function getTierDefinition(tier: EvolutionTier): TierDefinition;
|
|
31
|
+
export declare function getTierByPoints(totalPoints: number): EvolutionTier;
|
|
32
|
+
export type TaskDifficulty = 'trivial' | 'normal' | 'hard';
|
|
33
|
+
export interface TaskDifficultyConfig {
|
|
34
|
+
basePoints: number;
|
|
35
|
+
description: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const TASK_DIFFICULTY_CONFIG: Record<TaskDifficulty, TaskDifficultyConfig>;
|
|
38
|
+
export type EvolutionEventType = 'success' | 'failure';
|
|
39
|
+
export interface EvolutionEvent {
|
|
40
|
+
id: string;
|
|
41
|
+
timestamp: string;
|
|
42
|
+
type: EvolutionEventType;
|
|
43
|
+
taskHash: string;
|
|
44
|
+
taskDifficulty: TaskDifficulty;
|
|
45
|
+
toolName?: string;
|
|
46
|
+
filePath?: string;
|
|
47
|
+
reason?: string;
|
|
48
|
+
pointsAwarded: number;
|
|
49
|
+
isDoubleReward: boolean;
|
|
50
|
+
sessionId?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface EvolutionScorecard {
|
|
53
|
+
version: '2.0';
|
|
54
|
+
agentId: string;
|
|
55
|
+
totalPoints: number;
|
|
56
|
+
availablePoints: number;
|
|
57
|
+
currentTier: EvolutionTier;
|
|
58
|
+
lastDoubleRewardTime?: string;
|
|
59
|
+
recentFailureHashes: Map<string, string>;
|
|
60
|
+
stats: EvolutionStats;
|
|
61
|
+
recentEvents: EvolutionEvent[];
|
|
62
|
+
lastUpdated: string;
|
|
63
|
+
}
|
|
64
|
+
export interface EvolutionStats {
|
|
65
|
+
totalSuccesses: number;
|
|
66
|
+
totalFailures: number;
|
|
67
|
+
consecutiveSuccesses: number;
|
|
68
|
+
consecutiveFailures: number;
|
|
69
|
+
doubleRewardsEarned: number;
|
|
70
|
+
tierPromotions: number;
|
|
71
|
+
pointsByDifficulty: Record<TaskDifficulty, number>;
|
|
72
|
+
}
|
|
73
|
+
export interface EvolutionStorage {
|
|
74
|
+
scorecard: EvolutionScorecard;
|
|
75
|
+
archivedStats: {
|
|
76
|
+
totalEventsProcessed: number;
|
|
77
|
+
pointsFromTrivial: number;
|
|
78
|
+
pointsFromNormal: number;
|
|
79
|
+
pointsFromHard: number;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export interface EvolutionConfig {
|
|
83
|
+
/** 双倍奖励冷却时间(毫秒),默认1小时 */
|
|
84
|
+
doubleRewardCooldownMs: number;
|
|
85
|
+
/** 保存的最近事件数量,默认50 */
|
|
86
|
+
maxRecentEvents: number;
|
|
87
|
+
/** 高等级做低级任务的积分衰减系数 */
|
|
88
|
+
difficultyPenalty: {
|
|
89
|
+
tier4Trivial: number;
|
|
90
|
+
tier4Normal: number;
|
|
91
|
+
tier5Trivial: number;
|
|
92
|
+
tier5Normal: number;
|
|
93
|
+
};
|
|
94
|
+
/** 信任分系统双轨运行时的配置 */
|
|
95
|
+
dualTrack: {
|
|
96
|
+
enabled: boolean;
|
|
97
|
+
primarySystem: 'trust' | 'evolution';
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export declare const DEFAULT_EVOLUTION_CONFIG: EvolutionConfig;
|
|
101
|
+
export interface ArchivedEventStats {
|
|
102
|
+
totalEventsProcessed: number;
|
|
103
|
+
pointsFromTrivial: number;
|
|
104
|
+
pointsFromNormal: number;
|
|
105
|
+
pointsFromHard: number;
|
|
106
|
+
}
|
|
107
|
+
export interface GateDecision {
|
|
108
|
+
allowed: boolean;
|
|
109
|
+
reason?: string;
|
|
110
|
+
currentTier?: EvolutionTier;
|
|
111
|
+
requiredTier?: EvolutionTier;
|
|
112
|
+
}
|
|
113
|
+
export interface ToolCallContext {
|
|
114
|
+
toolName: string;
|
|
115
|
+
filePath?: string;
|
|
116
|
+
content?: string;
|
|
117
|
+
lineCount?: number;
|
|
118
|
+
isRiskPath?: boolean;
|
|
119
|
+
}
|
|
120
|
+
export interface TierPromotionEvent {
|
|
121
|
+
previousTier: EvolutionTier;
|
|
122
|
+
newTier: EvolutionTier;
|
|
123
|
+
totalPoints: number;
|
|
124
|
+
timestamp: string;
|
|
125
|
+
newPermissions: TierPermissions;
|
|
126
|
+
}
|