@haoyiyin/workflow 0.2.11 → 0.3.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.
Files changed (164) hide show
  1. package/dist/src/agents/contracts/implementer.d.ts +29 -0
  2. package/dist/src/agents/contracts/implementer.d.ts.map +1 -0
  3. package/dist/src/agents/contracts/implementer.js +94 -0
  4. package/dist/src/agents/contracts/implementer.js.map +1 -0
  5. package/dist/src/agents/contracts/index.d.ts +11 -0
  6. package/dist/src/agents/contracts/index.d.ts.map +1 -0
  7. package/dist/src/agents/contracts/index.js +11 -0
  8. package/dist/src/agents/contracts/index.js.map +1 -0
  9. package/dist/src/agents/contracts/planner.d.ts +25 -0
  10. package/dist/src/agents/contracts/planner.d.ts.map +1 -0
  11. package/dist/src/agents/contracts/planner.js +107 -0
  12. package/dist/src/agents/contracts/planner.js.map +1 -0
  13. package/dist/src/agents/contracts/router.d.ts +24 -0
  14. package/dist/src/agents/contracts/router.d.ts.map +1 -0
  15. package/dist/src/agents/contracts/router.js +137 -0
  16. package/dist/src/agents/contracts/router.js.map +1 -0
  17. package/dist/src/agents/contracts/verifier.d.ts +27 -0
  18. package/dist/src/agents/contracts/verifier.d.ts.map +1 -0
  19. package/dist/src/agents/contracts/verifier.js +115 -0
  20. package/dist/src/agents/contracts/verifier.js.map +1 -0
  21. package/dist/src/agents/dispatcher.d.ts +94 -51
  22. package/dist/src/agents/dispatcher.d.ts.map +1 -1
  23. package/dist/src/agents/dispatcher.js +207 -164
  24. package/dist/src/agents/dispatcher.js.map +1 -1
  25. package/dist/src/persistence/index.d.ts +4 -2
  26. package/dist/src/persistence/index.d.ts.map +1 -1
  27. package/dist/src/persistence/index.js +4 -1
  28. package/dist/src/persistence/index.js.map +1 -1
  29. package/dist/src/persistence/plan-md.d.ts +3 -2
  30. package/dist/src/persistence/plan-md.d.ts.map +1 -1
  31. package/dist/src/persistence/plan-md.js +47 -15
  32. package/dist/src/persistence/plan-md.js.map +1 -1
  33. package/dist/src/persistence/state-md.d.ts +2 -0
  34. package/dist/src/persistence/state-md.d.ts.map +1 -1
  35. package/dist/src/persistence/state-md.js +40 -22
  36. package/dist/src/persistence/state-md.js.map +1 -1
  37. package/dist/src/persistence/types.d.ts +35 -39
  38. package/dist/src/persistence/types.d.ts.map +1 -1
  39. package/dist/src/router/namespace/core/intent-router.d.ts +24 -0
  40. package/dist/src/router/namespace/core/intent-router.d.ts.map +1 -0
  41. package/dist/src/router/namespace/core/intent-router.js +190 -0
  42. package/dist/src/router/namespace/core/intent-router.js.map +1 -0
  43. package/dist/src/router/namespace/core/lifecycle-router.d.ts +28 -0
  44. package/dist/src/router/namespace/core/lifecycle-router.d.ts.map +1 -0
  45. package/dist/src/router/namespace/core/lifecycle-router.js +132 -0
  46. package/dist/src/router/namespace/core/lifecycle-router.js.map +1 -0
  47. package/dist/src/router/namespace/core/state-router.d.ts +32 -0
  48. package/dist/src/router/namespace/core/state-router.d.ts.map +1 -0
  49. package/dist/src/router/namespace/core/state-router.js +157 -0
  50. package/dist/src/router/namespace/core/state-router.js.map +1 -0
  51. package/dist/src/router/namespace/domain/code-router.d.ts +26 -0
  52. package/dist/src/router/namespace/domain/code-router.d.ts.map +1 -0
  53. package/dist/src/router/namespace/domain/code-router.js +171 -0
  54. package/dist/src/router/namespace/domain/code-router.js.map +1 -0
  55. package/dist/src/router/namespace/domain/debug-router.d.ts +25 -0
  56. package/dist/src/router/namespace/domain/debug-router.d.ts.map +1 -0
  57. package/dist/src/router/namespace/domain/debug-router.js +139 -0
  58. package/dist/src/router/namespace/domain/debug-router.js.map +1 -0
  59. package/dist/src/router/namespace/domain/plan-router.d.ts +29 -0
  60. package/dist/src/router/namespace/domain/plan-router.d.ts.map +1 -0
  61. package/dist/src/router/namespace/domain/plan-router.js +160 -0
  62. package/dist/src/router/namespace/domain/plan-router.js.map +1 -0
  63. package/dist/src/router/namespace/domain/review-router.d.ts +24 -0
  64. package/dist/src/router/namespace/domain/review-router.d.ts.map +1 -0
  65. package/dist/src/router/namespace/domain/review-router.js +116 -0
  66. package/dist/src/router/namespace/domain/review-router.js.map +1 -0
  67. package/dist/src/router/namespace/index.d.ts +19 -0
  68. package/dist/src/router/namespace/index.d.ts.map +1 -0
  69. package/dist/src/router/namespace/index.js +22 -0
  70. package/dist/src/router/namespace/index.js.map +1 -0
  71. package/dist/src/router/namespace/registry.d.ts +67 -0
  72. package/dist/src/router/namespace/registry.d.ts.map +1 -0
  73. package/dist/src/router/namespace/registry.js +197 -0
  74. package/dist/src/router/namespace/registry.js.map +1 -0
  75. package/dist/src/router/namespace/types.d.ts +124 -0
  76. package/dist/src/router/namespace/types.d.ts.map +1 -0
  77. package/dist/src/router/namespace/types.js +20 -0
  78. package/dist/src/router/namespace/types.js.map +1 -0
  79. package/dist/src/router/namespace/utility/fallback-router.d.ts +28 -0
  80. package/dist/src/router/namespace/utility/fallback-router.d.ts.map +1 -0
  81. package/dist/src/router/namespace/utility/fallback-router.js +88 -0
  82. package/dist/src/router/namespace/utility/fallback-router.js.map +1 -0
  83. package/dist/src/router/namespace/utility/quick-task-router.d.ts +28 -0
  84. package/dist/src/router/namespace/utility/quick-task-router.d.ts.map +1 -0
  85. package/dist/src/router/namespace/utility/quick-task-router.js +99 -0
  86. package/dist/src/router/namespace/utility/quick-task-router.js.map +1 -0
  87. package/dist/src/router/namespace/utility/research-router.d.ts +24 -0
  88. package/dist/src/router/namespace/utility/research-router.d.ts.map +1 -0
  89. package/dist/src/router/namespace/utility/research-router.js +84 -0
  90. package/dist/src/router/namespace/utility/research-router.js.map +1 -0
  91. package/dist/src/skills/agents-md/index.js +2 -2
  92. package/dist/src/skills/agents-md/index.js.map +1 -1
  93. package/dist/src/skills/execute-plan/index.d.ts +45 -65
  94. package/dist/src/skills/execute-plan/index.d.ts.map +1 -1
  95. package/dist/src/skills/execute-plan/index.js +325 -551
  96. package/dist/src/skills/execute-plan/index.js.map +1 -1
  97. package/dist/src/skills/index.d.ts +1 -0
  98. package/dist/src/skills/index.d.ts.map +1 -1
  99. package/dist/src/skills/index.js +1 -0
  100. package/dist/src/skills/index.js.map +1 -1
  101. package/dist/src/skills/quick-task/index.d.ts +4 -4
  102. package/dist/src/skills/quick-task/index.js +1 -1
  103. package/dist/src/skills/quick-task/index.js.map +1 -1
  104. package/dist/src/skills/review-diff/index.d.ts +6 -6
  105. package/dist/src/skills/review-diff/index.js +1 -1
  106. package/dist/src/skills/review-diff/index.js.map +1 -1
  107. package/dist/src/skills/router/index.d.ts +101 -0
  108. package/dist/src/skills/router/index.d.ts.map +1 -0
  109. package/dist/src/skills/router/index.js +450 -0
  110. package/dist/src/skills/router/index.js.map +1 -0
  111. package/dist/src/skills/router/types.d.ts +79 -0
  112. package/dist/src/skills/router/types.d.ts.map +1 -0
  113. package/dist/src/skills/router/types.js +8 -0
  114. package/dist/src/skills/router/types.js.map +1 -0
  115. package/dist/src/skills/systematic-debugging/index.js +1 -1
  116. package/dist/src/skills/systematic-debugging/index.js.map +1 -1
  117. package/dist/src/skills/tdd/index.d.ts +14 -14
  118. package/dist/src/skills/tdd/index.js +1 -1
  119. package/dist/src/skills/tdd/index.js.map +1 -1
  120. package/dist/src/skills/to-plan/index-enhanced.d.ts +4 -4
  121. package/dist/src/skills/to-plan/index-enhanced.d.ts.map +1 -1
  122. package/dist/src/skills/to-plan/index-enhanced.js +3 -5
  123. package/dist/src/skills/to-plan/index-enhanced.js.map +1 -1
  124. package/dist/src/skills/to-plan/index.d.ts +24 -91
  125. package/dist/src/skills/to-plan/index.d.ts.map +1 -1
  126. package/dist/src/skills/to-plan/index.js +214 -409
  127. package/dist/src/skills/to-plan/index.js.map +1 -1
  128. package/package.json +3 -5
  129. package/src/agents/contracts/implementer.ts +122 -0
  130. package/src/agents/contracts/index.ts +27 -0
  131. package/src/agents/contracts/planner.ts +129 -0
  132. package/src/agents/contracts/router.ts +168 -0
  133. package/src/agents/contracts/verifier.ts +137 -0
  134. package/src/agents/dispatcher.ts +387 -362
  135. package/src/persistence/index.ts +10 -4
  136. package/src/persistence/plan-md.ts +52 -18
  137. package/src/persistence/state-md.ts +45 -23
  138. package/src/persistence/types.ts +37 -40
  139. package/src/router/namespace/README.md +127 -0
  140. package/src/router/namespace/core/intent-router.ts +221 -0
  141. package/src/router/namespace/core/lifecycle-router.ts +156 -0
  142. package/src/router/namespace/core/state-router.ts +192 -0
  143. package/src/router/namespace/domain/code-router.ts +202 -0
  144. package/src/router/namespace/domain/debug-router.ts +167 -0
  145. package/src/router/namespace/domain/plan-router.ts +196 -0
  146. package/src/router/namespace/domain/review-router.ts +142 -0
  147. package/src/router/namespace/index.ts +84 -0
  148. package/src/router/namespace/registry.ts +242 -0
  149. package/src/router/namespace/types.ts +182 -0
  150. package/src/router/namespace/utility/fallback-router.ts +107 -0
  151. package/src/router/namespace/utility/quick-task-router.ts +121 -0
  152. package/src/router/namespace/utility/research-router.ts +105 -0
  153. package/src/skills/agents-md/index.ts +2 -2
  154. package/src/skills/execute-plan/index.ts +419 -673
  155. package/src/skills/index.ts +1 -0
  156. package/src/skills/quick-task/index.ts +1 -1
  157. package/src/skills/review-diff/index.ts +1 -1
  158. package/src/skills/router/SKILL.md +181 -0
  159. package/src/skills/router/index.ts +577 -0
  160. package/src/skills/router/types.ts +90 -0
  161. package/src/skills/systematic-debugging/index.ts +1 -1
  162. package/src/skills/tdd/index.ts +1 -1
  163. package/src/skills/to-plan/index-enhanced.ts +3 -5
  164. package/src/skills/to-plan/index.ts +231 -502
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Intent Router - Core Layer
3
+ *
4
+ * 基于用户意图的分类进行路由决策
5
+ * 使用关键词和模式匹配提取意图
6
+ */
7
+
8
+ import type {
9
+ NamespaceRouter,
10
+ RoutingContext,
11
+ RouteDecision,
12
+ NamespaceHealth,
13
+ AlternativeRoute,
14
+ } from '../types.js'
15
+
16
+ // 意图定义
17
+ interface IntentPattern {
18
+ name: string
19
+ patterns: RegExp[]
20
+ targetSkill: string
21
+ confidence: number
22
+ complexity: 'low' | 'medium' | 'high'
23
+ }
24
+
25
+ const INTENTS: IntentPattern[] = [
26
+ {
27
+ name: 'plan',
28
+ patterns: [
29
+ /plan|设计|架构|方案/i,
30
+ /how to implement|如何实现/i,
31
+ /architecture|结构/i,
32
+ /strategy|策略/i,
33
+ ],
34
+ targetSkill: 'to-plan',
35
+ confidence: 0.85,
36
+ complexity: 'high',
37
+ },
38
+ {
39
+ name: 'execute',
40
+ patterns: [
41
+ /implement|实现|完成/i,
42
+ /build|创建|建立/i,
43
+ /develop|开发/i,
44
+ /execute|执行/i,
45
+ ],
46
+ targetSkill: 'execute-plan',
47
+ confidence: 0.8,
48
+ complexity: 'high',
49
+ },
50
+ {
51
+ name: 'fix',
52
+ patterns: [
53
+ /fix|修复|解决/i,
54
+ /correct|修正/i,
55
+ /update|更新.*(typo|typo|错误)/i,
56
+ ],
57
+ targetSkill: 'quick-task',
58
+ confidence: 0.75,
59
+ complexity: 'low',
60
+ },
61
+ {
62
+ name: 'debug',
63
+ patterns: [
64
+ /debug|调试/i,
65
+ /bug|错误|故障/i,
66
+ /error|异常/i,
67
+ /not working|不工作|失效/i,
68
+ /investigate|调查/i,
69
+ ],
70
+ targetSkill: 'systematic-debugging',
71
+ confidence: 0.85,
72
+ complexity: 'medium',
73
+ },
74
+ {
75
+ name: 'review',
76
+ patterns: [
77
+ /review|审查|检查/i,
78
+ /audit|审核/i,
79
+ /check.*quality|检查.*质量/i,
80
+ /code review|代码审查/i,
81
+ ],
82
+ targetSkill: 'review-diff',
83
+ confidence: 0.8,
84
+ complexity: 'medium',
85
+ },
86
+ {
87
+ name: 'test',
88
+ patterns: [
89
+ /test|测试/i,
90
+ /tdd|test.*driven/i,
91
+ /unit test|单元测试/i,
92
+ /coverage|覆盖率/i,
93
+ ],
94
+ targetSkill: 'tdd',
95
+ confidence: 0.85,
96
+ complexity: 'medium',
97
+ },
98
+ {
99
+ name: 'research',
100
+ patterns: [
101
+ /research|研究/i,
102
+ /explore|探索/i,
103
+ /find out|查找/i,
104
+ /learn about|了解/i,
105
+ /what is|什么是/i,
106
+ /how does|如何.*工作/i,
107
+ ],
108
+ targetSkill: 'research',
109
+ confidence: 0.7,
110
+ complexity: 'low',
111
+ },
112
+ {
113
+ name: 'docs',
114
+ patterns: [
115
+ /document|文档/i,
116
+ /claude\.md|agents\.md/i,
117
+ /readme|说明/i,
118
+ /update.*doc|更新.*文档/i,
119
+ ],
120
+ targetSkill: 'agents-md',
121
+ confidence: 0.75,
122
+ complexity: 'low',
123
+ },
124
+ ]
125
+
126
+ export class IntentRouter implements NamespaceRouter {
127
+ readonly name = 'intent'
128
+ readonly layer = 'core' as const
129
+ readonly priority = 80
130
+ readonly patterns = INTENTS.flatMap((i) => i.patterns)
131
+
132
+ private routeCount = 0
133
+ private successCount = 0
134
+ private totalLatency = 0
135
+
136
+ async canRoute(context: RoutingContext): Promise<boolean> {
137
+ // 检查是否能匹配到任何意图
138
+ const request = context.request.text.toLowerCase()
139
+ return INTENTS.some((intent) => intent.patterns.some((p) => p.test(request)))
140
+ }
141
+
142
+ async route(context: RoutingContext): Promise<RouteDecision> {
143
+ const startTime = Date.now()
144
+ const requestText = context.request.text.toLowerCase()
145
+
146
+ // 计算每个意图的匹配分数
147
+ const scored = INTENTS.map((intent) => {
148
+ let score = 0
149
+ for (const pattern of intent.patterns) {
150
+ if (pattern.test(requestText)) {
151
+ score += intent.confidence / intent.patterns.length
152
+ }
153
+ }
154
+ return { intent, score }
155
+ }).filter((s) => s.score > 0)
156
+
157
+ // 按分数排序
158
+ scored.sort((a, b) => b.score - a.score)
159
+
160
+ const best = scored[0]
161
+ const alternatives: AlternativeRoute[] = scored.slice(1, 4).map((s) => ({
162
+ skill: s.intent.targetSkill,
163
+ confidence: s.score,
164
+ reasoning: `Intent: ${s.intent.name}`,
165
+ }))
166
+
167
+ this.routeCount++
168
+ this.totalLatency += Date.now() - startTime
169
+
170
+ if (best) {
171
+ this.successCount++
172
+ return {
173
+ skill: best.intent.targetSkill,
174
+ confidence: Math.min(best.score, 1.0),
175
+ reasoning: `Intent matched: ${best.intent.name} (${best.intent.complexity} complexity)`,
176
+ namespace: this.name,
177
+ alternatives,
178
+ metadata: {
179
+ layer: this.layer,
180
+ processingTime: Date.now() - startTime,
181
+ hops: 1,
182
+ },
183
+ }
184
+ }
185
+
186
+ // 无匹配
187
+ return {
188
+ skill: 'quick-task',
189
+ confidence: 0.3,
190
+ reasoning: 'No clear intent matched',
191
+ namespace: this.name,
192
+ alternatives: [],
193
+ metadata: {
194
+ layer: this.layer,
195
+ processingTime: Date.now() - startTime,
196
+ hops: 1,
197
+ },
198
+ }
199
+ }
200
+
201
+ getSupportedSkills(): string[] {
202
+ return INTENTS.map((i) => i.targetSkill)
203
+ }
204
+
205
+ getHealth(): NamespaceHealth {
206
+ return {
207
+ name: this.name,
208
+ status: this.successRate() > 0.7 ? 'healthy' : 'degraded',
209
+ totalRoutes: this.routeCount,
210
+ successRate: this.successRate(),
211
+ avgLatency: this.routeCount > 0 ? this.totalLatency / this.routeCount : 0,
212
+ }
213
+ }
214
+
215
+ private successRate(): number {
216
+ return this.routeCount > 0 ? this.successCount / this.routeCount : 1.0
217
+ }
218
+ }
219
+
220
+ export const intentRouter = new IntentRouter()
221
+ export default intentRouter
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Lifecycle Router - Core Layer
3
+ *
4
+ * 基于项目生命周期阶段进行路由决策
5
+ * 生命周期: idle → planning → executing → verifying → completed
6
+ */
7
+
8
+ import type {
9
+ NamespaceRouter,
10
+ RoutingContext,
11
+ RouteDecision,
12
+ NamespaceHealth,
13
+ AlternativeRoute,
14
+ } from '../types.js'
15
+
16
+ // 各阶段可用的技能
17
+ const SKILLS_BY_PHASE: Record<string, string[]> = {
18
+ idle: ['to-plan', 'research', 'quick-task', 'agents-md'],
19
+ planning: ['to-plan', 'research', 'review-diff', 'agents-md'],
20
+ executing: ['execute-plan', 'quick-task', 'tdd', 'systematic-debugging'],
21
+ verifying: ['review-diff', 'systematic-debugging', 'execute-plan'],
22
+ completed: ['review-diff', 'agents-md', 'research'],
23
+ failed: ['systematic-debugging', 'to-plan', 'review-diff'],
24
+ }
25
+
26
+ export class LifecycleRouter implements NamespaceRouter {
27
+ readonly name = 'lifecycle'
28
+ readonly layer = 'core' as const
29
+ readonly priority = 90
30
+ readonly patterns = [
31
+ /plan|规划|设计/i,
32
+ /execute|执行|实现/i,
33
+ /debug|调试|fix/i,
34
+ /review|审查|review/i,
35
+ /complete|完成|结束/i,
36
+ ]
37
+
38
+ private routeCount = 0
39
+ private successCount = 0
40
+ private totalLatency = 0
41
+
42
+ async canRoute(context: RoutingContext): Promise<boolean> {
43
+ // 总是可以检查生命周期
44
+ return true
45
+ }
46
+
47
+ async route(context: RoutingContext): Promise<RouteDecision> {
48
+ const startTime = Date.now()
49
+ const phase = context.state.phase
50
+ const availableSkills = SKILLS_BY_PHASE[phase] || SKILLS_BY_PHASE.idle
51
+
52
+ // 基于请求内容匹配最佳技能
53
+ const requestText = context.request.text.toLowerCase()
54
+ let bestSkill: string | null = null
55
+ let bestScore = 0
56
+ const alternatives: AlternativeRoute[] = []
57
+
58
+ for (const skill of availableSkills) {
59
+ const score = this.calculateSkillScore(skill, requestText, phase)
60
+ if (score > bestScore) {
61
+ // 当前最佳变为备选
62
+ if (bestSkill) {
63
+ alternatives.push({
64
+ skill: bestSkill,
65
+ confidence: bestScore,
66
+ reasoning: `Matched lifecycle phase ${phase}`,
67
+ })
68
+ }
69
+ bestSkill = skill
70
+ bestScore = score
71
+ } else if (score > 0.3) {
72
+ alternatives.push({
73
+ skill,
74
+ confidence: score,
75
+ reasoning: `Alternative for ${phase} phase`,
76
+ })
77
+ }
78
+ }
79
+
80
+ this.routeCount++
81
+ this.totalLatency += Date.now() - startTime
82
+ if (bestSkill) this.successCount++
83
+
84
+ return {
85
+ skill: bestSkill || 'quick-task',
86
+ confidence: bestScore || 0.5,
87
+ reasoning: `Lifecycle phase: ${phase}. Available: ${availableSkills.join(', ')}`,
88
+ namespace: this.name,
89
+ alternatives: alternatives.slice(0, 3),
90
+ metadata: {
91
+ layer: this.layer,
92
+ processingTime: Date.now() - startTime,
93
+ hops: 1,
94
+ },
95
+ }
96
+ }
97
+
98
+ /**
99
+ * 计算技能匹配分数
100
+ */
101
+ private calculateSkillScore(skill: string, request: string, phase: string): number {
102
+ const keywordMap: Record<string, string[]> = {
103
+ 'to-plan': ['plan', 'design', 'architecture', '规划', '设计'],
104
+ 'execute-plan': ['implement', 'build', 'execute', '实现', '执行'],
105
+ 'quick-task': ['fix', 'typo', 'rename', 'small', '快速', '修复'],
106
+ 'review-diff': ['review', 'audit', 'check', '审查', '检查'],
107
+ 'systematic-debugging': ['debug', 'bug', 'error', '调试', '错误'],
108
+ 'tdd': ['test', 'tdd', '测试'],
109
+ 'research': ['research', 'explore', 'learn', '研究', '探索'],
110
+ 'agents-md': ['agent', 'claude.md', 'agents.md', '文档'],
111
+ }
112
+
113
+ const keywords = keywordMap[skill] || []
114
+ let score = 0
115
+
116
+ for (const keyword of keywords) {
117
+ if (request.includes(keyword.toLowerCase())) {
118
+ score += 0.2
119
+ }
120
+ }
121
+
122
+ // 根据生命周期阶段调整分数
123
+ const phaseBoost: Record<string, Record<string, number>> = {
124
+ planning: { 'to-plan': 0.3, 'research': 0.2 },
125
+ executing: { 'execute-plan': 0.3, 'tdd': 0.2, 'quick-task': 0.1 },
126
+ verifying: { 'review-diff': 0.3, 'systematic-debugging': 0.2 },
127
+ }
128
+
129
+ if (phaseBoost[phase]?.[skill]) {
130
+ score += phaseBoost[phase][skill]
131
+ }
132
+
133
+ return Math.min(score, 1.0)
134
+ }
135
+
136
+ getSupportedSkills(): string[] {
137
+ return Object.values(SKILLS_BY_PHASE).flat()
138
+ }
139
+
140
+ getHealth(): NamespaceHealth {
141
+ return {
142
+ name: this.name,
143
+ status: this.successRate() > 0.8 ? 'healthy' : 'degraded',
144
+ totalRoutes: this.routeCount,
145
+ successRate: this.successRate(),
146
+ avgLatency: this.routeCount > 0 ? this.totalLatency / this.routeCount : 0,
147
+ }
148
+ }
149
+
150
+ private successRate(): number {
151
+ return this.routeCount > 0 ? this.successCount / this.routeCount : 1.0
152
+ }
153
+ }
154
+
155
+ export const lifecycleRouter = new LifecycleRouter()
156
+ export default lifecycleRouter
@@ -0,0 +1,192 @@
1
+ /**
2
+ * State Router - Core Layer
3
+ *
4
+ * 基于 STATE.md 和 PLAN.md 的状态进行路由决策
5
+ * 优先使用状态信号而非关键词匹配
6
+ */
7
+
8
+ import type {
9
+ NamespaceRouter,
10
+ RoutingContext,
11
+ RouteDecision,
12
+ NamespaceHealth,
13
+ AlternativeRoute,
14
+ } from '../types.js'
15
+
16
+ export class StateRouter implements NamespaceRouter {
17
+ readonly name = 'state'
18
+ readonly layer = 'core' as const
19
+ readonly priority = 95 // 高于 lifecycle
20
+ readonly patterns = [
21
+ /state|状态/i,
22
+ /plan|计划/i,
23
+ /continue|继续/i,
24
+ /resume|恢复/i,
25
+ ]
26
+
27
+ private routeCount = 0
28
+ private successCount = 0
29
+ private totalLatency = 0
30
+
31
+ async canRoute(context: RoutingContext): Promise<boolean> {
32
+ // 如果有 plan 或 state 信息,可以路由
33
+ return context.plan !== null || context.state.phase !== 'idle'
34
+ }
35
+
36
+ async route(context: RoutingContext): Promise<RouteDecision> {
37
+ const startTime = Date.now()
38
+ const { state, plan, request } = context
39
+
40
+ // 基于状态的路由决策
41
+ const decision = this.makeStateBasedDecision(state, plan, request.text)
42
+
43
+ this.routeCount++
44
+ this.totalLatency += Date.now() - startTime
45
+ this.successCount++
46
+
47
+ return {
48
+ ...decision,
49
+ namespace: this.name,
50
+ metadata: {
51
+ layer: this.layer,
52
+ processingTime: Date.now() - startTime,
53
+ hops: 1,
54
+ },
55
+ }
56
+ }
57
+
58
+ /**
59
+ * 基于状态的路由决策
60
+ */
61
+ private makeStateBasedDecision(
62
+ state: RoutingContext['state'],
63
+ plan: RoutingContext['plan'],
64
+ requestText: string
65
+ ): Omit<RouteDecision, 'namespace' | 'metadata'> {
66
+ const alternatives: AlternativeRoute[] = []
67
+
68
+ // 规则1: 如果有 plan 且未完成,默认路由到 execute-plan
69
+ if (plan && state.phase === 'executing') {
70
+ const completedCount = state.completedTasks?.length || 0
71
+ const totalCount = plan.tasks?.length || 0
72
+ const progress = totalCount > 0 ? completedCount / totalCount : 0
73
+
74
+ // 检查是否继续执行
75
+ if (progress < 1.0) {
76
+ return {
77
+ skill: 'execute-plan',
78
+ confidence: 0.9,
79
+ reasoning: `Plan exists with ${completedCount}/${totalCount} tasks complete. Phase: ${state.phase}`,
80
+ alternatives: [
81
+ { skill: 'quick-task', confidence: 0.3, reasoning: 'Small task bypass' },
82
+ ],
83
+ }
84
+ }
85
+ }
86
+
87
+ // 规则2: 如果正在 verifying,路由到 review-diff
88
+ if (state.phase === 'verifying') {
89
+ return {
90
+ skill: 'review-diff',
91
+ confidence: 0.85,
92
+ reasoning: `Phase is ${state.phase}, need verification`,
93
+ alternatives: [
94
+ { skill: 'systematic-debugging', confidence: 0.4, reasoning: 'If verification fails' },
95
+ ],
96
+ }
97
+ }
98
+
99
+ // 规则3: 如果有 plan 但还没开始执行
100
+ if (plan && state.phase === 'planning') {
101
+ return {
102
+ skill: 'execute-plan',
103
+ confidence: 0.8,
104
+ reasoning: `Plan ready (${plan.tasks?.length || 0} tasks), waiting to execute`,
105
+ alternatives: [
106
+ { skill: 'to-plan', confidence: 0.3, reasoning: 'Revise plan' },
107
+ ],
108
+ }
109
+ }
110
+
111
+ // 规则4: 如果用户说 "continue" 或 "继续"
112
+ if (/^\s*(continue|resume|proceed|继续|恢复)/i.test(requestText)) {
113
+ if (plan) {
114
+ return {
115
+ skill: 'execute-plan',
116
+ confidence: 0.95,
117
+ reasoning: 'User requested to continue with existing plan',
118
+ alternatives: [],
119
+ }
120
+ }
121
+ }
122
+
123
+ // 规则5: 默认情况 - 检查是否需要创建 plan
124
+ if (!plan && state.phase === 'idle') {
125
+ // 请求复杂度检测
126
+ const isComplex = this.isComplexRequest(requestText)
127
+ if (isComplex) {
128
+ return {
129
+ skill: 'to-plan',
130
+ confidence: 0.75,
131
+ reasoning: 'No plan exists and request appears complex',
132
+ alternatives: [
133
+ { skill: 'quick-task', confidence: 0.4, reasoning: 'Simple approach' },
134
+ { skill: 'research', confidence: 0.3, reasoning: 'Need more info' },
135
+ ],
136
+ }
137
+ }
138
+ }
139
+
140
+ // 默认返回 low confidence
141
+ return {
142
+ skill: 'quick-task',
143
+ confidence: 0.3,
144
+ reasoning: `State-based routing default: ${state.phase}, no plan`,
145
+ alternatives: [],
146
+ }
147
+ }
148
+
149
+ /**
150
+ * 判断请求是否复杂(需要创建 plan)
151
+ */
152
+ private isComplexRequest(request: string): boolean {
153
+ const complexityIndicators = [
154
+ /implement|实现/i,
155
+ /feature|功能/i,
156
+ /refactor|重构/i,
157
+ /architecture|架构/i,
158
+ /design|设计/i,
159
+ /multiple|多个/i,
160
+ /steps?|步骤/i,
161
+ /phase|阶段/i,
162
+ ]
163
+
164
+ const indicatorCount = complexityIndicators.filter((pattern) =>
165
+ pattern.test(request)
166
+ ).length
167
+
168
+ // 如果匹配多个复杂度指标,认为是复杂请求
169
+ return indicatorCount >= 2 || request.length > 100
170
+ }
171
+
172
+ getSupportedSkills(): string[] {
173
+ return ['to-plan', 'execute-plan', 'quick-task', 'review-diff', 'systematic-debugging', 'research']
174
+ }
175
+
176
+ getHealth(): NamespaceHealth {
177
+ return {
178
+ name: this.name,
179
+ status: this.successRate() > 0.8 ? 'healthy' : 'degraded',
180
+ totalRoutes: this.routeCount,
181
+ successRate: this.successRate(),
182
+ avgLatency: this.routeCount > 0 ? this.totalLatency / this.routeCount : 0,
183
+ }
184
+ }
185
+
186
+ private successRate(): number {
187
+ return this.routeCount > 0 ? this.successCount / this.routeCount : 1.0
188
+ }
189
+ }
190
+
191
+ export const stateRouter = new StateRouter()
192
+ export default stateRouter