@haoyiyin/workflow 0.2.10 → 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,84 @@
1
+ /**
2
+ * Namespace Router System - 分层命名空间路由
3
+ *
4
+ * 导出所有命名空间路由相关模块
5
+ */
6
+
7
+ // Types
8
+ export type {
9
+ UserRequest,
10
+ ConversationHistory,
11
+ RouterConfig,
12
+ RoutingContext,
13
+ AlternativeRoute,
14
+ RouteDecision,
15
+ RouteResult,
16
+ NamespaceRouter,
17
+ NamespaceHealth,
18
+ SubagentRouteRequest,
19
+ SubagentRouteResponse,
20
+ NamespaceRegistry,
21
+ NamespaceConfig,
22
+ } from './types.js'
23
+
24
+ export { DEFAULT_NAMESPACE_CONFIG } from './types.js'
25
+
26
+ // Registry
27
+ export {
28
+ NamespaceRouterRegistry,
29
+ getNamespaceRegistry,
30
+ resetNamespaceRegistry,
31
+ } from './registry.js'
32
+
33
+ // Core Layer Routers
34
+ export {
35
+ lifecycleRouter,
36
+ LifecycleRouter,
37
+ } from './core/lifecycle-router.js'
38
+
39
+ export {
40
+ stateRouter,
41
+ StateRouter,
42
+ } from './core/state-router.js'
43
+
44
+ export {
45
+ intentRouter,
46
+ IntentRouter,
47
+ } from './core/intent-router.js'
48
+
49
+ // Domain Layer Routers
50
+ export {
51
+ planRouter,
52
+ PlanRouter,
53
+ } from './domain/plan-router.js'
54
+
55
+ export {
56
+ codeRouter,
57
+ CodeRouter,
58
+ } from './domain/code-router.js'
59
+
60
+ export {
61
+ debugRouter,
62
+ DebugRouter,
63
+ } from './domain/debug-router.js'
64
+
65
+ export {
66
+ reviewRouter,
67
+ ReviewRouter,
68
+ } from './domain/review-router.js'
69
+
70
+ // Utility Layer Routers
71
+ export {
72
+ quickTaskRouter,
73
+ QuickTaskRouter,
74
+ } from './utility/quick-task-router.js'
75
+
76
+ export {
77
+ researchRouter,
78
+ ResearchRouter,
79
+ } from './utility/research-router.js'
80
+
81
+ export {
82
+ fallbackRouter,
83
+ FallbackRouter,
84
+ } from './utility/fallback-router.js'
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Namespace Router Registry
3
+ *
4
+ * 管理和协调所有命名空间路由
5
+ * 实现分层路由决策流程
6
+ */
7
+
8
+ import type {
9
+ NamespaceRouter,
10
+ NamespaceRegistry,
11
+ RoutingContext,
12
+ RouteDecision,
13
+ NamespaceConfig,
14
+ } from './types.js'
15
+ import { DEFAULT_NAMESPACE_CONFIG } from './types.js'
16
+
17
+ // 导入核心层路由
18
+ import { lifecycleRouter } from './core/lifecycle-router.js'
19
+ import { stateRouter } from './core/state-router.js'
20
+ import { intentRouter } from './core/intent-router.js'
21
+
22
+ // 导入领域层路由
23
+ import { planRouter } from './domain/plan-router.js'
24
+ import { codeRouter } from './domain/code-router.js'
25
+ import { debugRouter } from './domain/debug-router.js'
26
+ import { reviewRouter } from './domain/review-router.js'
27
+
28
+ // 导入工具层路由
29
+ import { quickTaskRouter } from './utility/quick-task-router.js'
30
+ import { researchRouter } from './utility/research-router.js'
31
+ import { fallbackRouter } from './utility/fallback-router.js'
32
+
33
+ // ---------------------------------------------------------------------------
34
+ // Default Routers
35
+ // ---------------------------------------------------------------------------
36
+
37
+ const DEFAULT_ROUTERS: NamespaceRouter[] = [
38
+ // Core Layer (高优先级)
39
+ stateRouter, // priority 95 - 基于状态
40
+ lifecycleRouter, // priority 90 - 基于生命周期
41
+ intentRouter, // priority 80 - 基于意图
42
+
43
+ // Domain Layer (中优先级)
44
+ planRouter, // priority 70 - 计划相关
45
+ debugRouter, // priority 70 - 调试相关
46
+ codeRouter, // priority 65 - 代码相关
47
+ reviewRouter, // priority 65 - 审查相关
48
+
49
+ // Utility Layer (低优先级)
50
+ quickTaskRouter, // priority 50 - 快速任务
51
+ researchRouter, // priority 45 - 研究探索
52
+ fallbackRouter, // priority 0 - 最终降级
53
+ ]
54
+
55
+ // ---------------------------------------------------------------------------
56
+ // Registry Implementation
57
+ // ---------------------------------------------------------------------------
58
+
59
+ export class NamespaceRouterRegistry implements NamespaceRegistry {
60
+ private routers: Map<string, NamespaceRouter> = new Map()
61
+ private config: NamespaceConfig
62
+
63
+ constructor(config: Partial<NamespaceConfig> = {}) {
64
+ this.config = this.mergeConfig(config)
65
+ this.registerDefaults()
66
+ }
67
+
68
+ /**
69
+ * 注册默认路由
70
+ */
71
+ private registerDefaults(): void {
72
+ for (const router of DEFAULT_ROUTERS) {
73
+ if (this.isLayerEnabled(router.layer)) {
74
+ this.register(router)
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * 合并配置
81
+ */
82
+ private mergeConfig(config: Partial<NamespaceConfig>): NamespaceConfig {
83
+ return {
84
+ core: { ...DEFAULT_NAMESPACE_CONFIG.core, ...config.core },
85
+ domain: { ...DEFAULT_NAMESPACE_CONFIG.domain, ...config.domain },
86
+ utility: { ...DEFAULT_NAMESPACE_CONFIG.utility, ...config.utility },
87
+ }
88
+ }
89
+
90
+ /**
91
+ * 检查某层是否启用
92
+ */
93
+ private isLayerEnabled(layer: 'core' | 'domain' | 'utility'): boolean {
94
+ return this.config[layer]?.enabled ?? true
95
+ }
96
+
97
+ // -----------------------------------------------------------------------
98
+ // Registry API
99
+ // -----------------------------------------------------------------------
100
+
101
+ register(router: NamespaceRouter): void {
102
+ if (this.routers.has(router.name)) {
103
+ console.warn(`[NamespaceRegistry] Router ${router.name} already exists, overwriting`)
104
+ }
105
+ this.routers.set(router.name, router)
106
+ }
107
+
108
+ unregister(name: string): void {
109
+ this.routers.delete(name)
110
+ }
111
+
112
+ get(name: string): NamespaceRouter | undefined {
113
+ return this.routers.get(name)
114
+ }
115
+
116
+ list(): NamespaceRouter[] {
117
+ return Array.from(this.routers.values())
118
+ }
119
+
120
+ listByLayer(layer: 'core' | 'domain' | 'utility'): NamespaceRouter[] {
121
+ return this.list().filter((r) => r.layer === layer)
122
+ }
123
+
124
+ /**
125
+ * 执行分层路由决策
126
+ *
127
+ * 流程:
128
+ * 1. 按优先级排序所有启用的路由
129
+ * 2. 从高优先级开始调用 canRoute
130
+ * 3. 第一个返回 true 的路由执行 route
131
+ * 4. 如果没有匹配,使用 fallback
132
+ */
133
+ async resolve(context: RoutingContext): Promise<RouteDecision> {
134
+ const candidates: RouteDecision[] = []
135
+
136
+ // 按优先级排序
137
+ const sorted = this.list().sort((a, b) => b.priority - a.priority)
138
+
139
+ for (const router of sorted) {
140
+ try {
141
+ const canHandle = await router.canRoute(context)
142
+ if (canHandle) {
143
+ const decision = await router.route(context)
144
+ candidates.push(decision)
145
+
146
+ // 如果置信度足够高,直接返回
147
+ if (decision.confidence >= 0.85) {
148
+ return {
149
+ ...decision,
150
+ metadata: {
151
+ layer: decision.metadata?.layer || router.layer,
152
+ processingTime: decision.metadata?.processingTime || 0,
153
+ hops: candidates.length,
154
+ },
155
+ }
156
+ }
157
+ }
158
+ } catch (error) {
159
+ console.error(`[NamespaceRegistry] Router ${router.name} failed:`, error)
160
+ }
161
+ }
162
+
163
+ // 如果没有候选,使用 fallback
164
+ if (candidates.length === 0) {
165
+ return await fallbackRouter.route(context)
166
+ }
167
+
168
+ // 返回最佳候选(按置信度排序)
169
+ candidates.sort((a, b) => b.confidence - a.confidence)
170
+ const best = candidates[0]
171
+
172
+ return {
173
+ ...best,
174
+ alternatives: candidates.slice(1, 4).map((c) => ({
175
+ skill: c.skill,
176
+ confidence: c.confidence,
177
+ reasoning: `From ${c.namespace}: ${c.reasoning}`,
178
+ })),
179
+ metadata: {
180
+ layer: best.metadata?.layer || 'utility',
181
+ processingTime: best.metadata?.processingTime || 0,
182
+ hops: candidates.length,
183
+ },
184
+ }
185
+ }
186
+
187
+ /**
188
+ * 获取所有路由的健康状态
189
+ */
190
+ getHealthReport(): Array<ReturnType<NamespaceRouter['getHealth']>> {
191
+ return this.list().map((r) => r.getHealth())
192
+ }
193
+
194
+ /**
195
+ * 获取路由统计
196
+ */
197
+ getStats(): {
198
+ total: number
199
+ byLayer: Record<'core' | 'domain' | 'utility', number>
200
+ avgSuccessRate: number
201
+ } {
202
+ const routers = this.list()
203
+ const health = routers.map((r) => r.getHealth())
204
+
205
+ return {
206
+ total: routers.length,
207
+ byLayer: {
208
+ core: this.listByLayer('core').length,
209
+ domain: this.listByLayer('domain').length,
210
+ utility: this.listByLayer('utility').length,
211
+ },
212
+ avgSuccessRate: health.length > 0
213
+ ? health.reduce((sum, h) => sum + h.successRate, 0) / health.length
214
+ : 1.0,
215
+ }
216
+ }
217
+ }
218
+
219
+ // ---------------------------------------------------------------------------
220
+ // Singleton
221
+ // ---------------------------------------------------------------------------
222
+
223
+ let globalRegistry: NamespaceRouterRegistry | null = null
224
+
225
+ export function getNamespaceRegistry(config?: Partial<NamespaceConfig>): NamespaceRouterRegistry {
226
+ if (!globalRegistry) {
227
+ globalRegistry = new NamespaceRouterRegistry(config)
228
+ }
229
+ return globalRegistry
230
+ }
231
+
232
+ export function resetNamespaceRegistry(): void {
233
+ globalRegistry = null
234
+ }
235
+
236
+ // ---------------------------------------------------------------------------
237
+ // Convenience exports
238
+ // ---------------------------------------------------------------------------
239
+
240
+ export { lifecycleRouter, stateRouter, intentRouter }
241
+ export { planRouter, codeRouter, debugRouter, reviewRouter }
242
+ export { quickTaskRouter, researchRouter, fallbackRouter }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Namespace Router Types - 分层命名空间路由系统
3
+ *
4
+ * 提供模块化的路由架构,将路由决策分散到多个命名空间中
5
+ */
6
+
7
+ import type { WorkflowState, Plan } from '../../persistence/types.js'
8
+ import type { SubagentConfig, SubagentContract } from '../../agents/types.js'
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Core Types
12
+ // ---------------------------------------------------------------------------
13
+
14
+ export interface UserRequest {
15
+ text: string
16
+ timestamp: number
17
+ metadata?: Record<string, unknown>
18
+ }
19
+
20
+ export interface ConversationHistory {
21
+ role: 'user' | 'assistant'
22
+ content: string
23
+ timestamp?: number
24
+ }
25
+
26
+ export interface RouterConfig {
27
+ defaultModel: string
28
+ confidenceThreshold: number
29
+ maxHops: number
30
+ enableLogging: boolean
31
+ }
32
+
33
+ export interface RoutingContext {
34
+ request: UserRequest
35
+ state: WorkflowState
36
+ plan: Plan | null
37
+ history: ConversationHistory[]
38
+ config: RouterConfig
39
+ metadata?: Record<string, unknown>
40
+ }
41
+
42
+ // ---------------------------------------------------------------------------
43
+ // Route Decision
44
+ // ---------------------------------------------------------------------------
45
+
46
+ export interface AlternativeRoute {
47
+ skill: string
48
+ confidence: number
49
+ reasoning: string
50
+ }
51
+
52
+ export interface RouteDecision {
53
+ skill: string
54
+ confidence: number
55
+ reasoning: string
56
+ namespace: string
57
+ alternatives: AlternativeRoute[]
58
+ metadata?: {
59
+ layer: 'core' | 'domain' | 'utility'
60
+ processingTime: number
61
+ hops: number
62
+ }
63
+ }
64
+
65
+ export interface RouteResult {
66
+ decision: RouteDecision
67
+ executedNamespace: string
68
+ allCandidates: RouteDecision[]
69
+ }
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // Namespace Router Interface
73
+ // ---------------------------------------------------------------------------
74
+
75
+ export interface NamespaceRouter {
76
+ /** 命名空间名称 */
77
+ readonly name: string
78
+
79
+ /** 命名空间所属层 */
80
+ readonly layer: 'core' | 'domain' | 'utility'
81
+
82
+ /** 优先级,越高越先匹配 (0-100) */
83
+ readonly priority: number
84
+
85
+ /** 匹配模式(关键词正则) */
86
+ readonly patterns: RegExp[]
87
+
88
+ /**
89
+ * 检查此命名空间是否可以处理该请求
90
+ * 快速检查,不需要完整路由逻辑
91
+ */
92
+ canRoute(context: RoutingContext): boolean | Promise<boolean>
93
+
94
+ /**
95
+ * 执行路由决策
96
+ * 返回此命名空间的推荐路由
97
+ */
98
+ route(context: RoutingContext): RouteDecision | Promise<RouteDecision>
99
+
100
+ /**
101
+ * 获取此命名空间支持的所有技能
102
+ */
103
+ getSupportedSkills(): string[]
104
+
105
+ /**
106
+ * 获取健康状态
107
+ */
108
+ getHealth(): NamespaceHealth
109
+ }
110
+
111
+ export interface NamespaceHealth {
112
+ name: string
113
+ status: 'healthy' | 'degraded' | 'unhealthy'
114
+ totalRoutes: number
115
+ successRate: number
116
+ avgLatency: number
117
+ }
118
+
119
+ // ---------------------------------------------------------------------------
120
+ // Subagent Dispatch
121
+ // ---------------------------------------------------------------------------
122
+
123
+ export interface SubagentRouteRequest {
124
+ role: SubagentConfig['role']
125
+ prompt: string
126
+ expectedOutput: string
127
+ timeout?: number
128
+ }
129
+
130
+ export interface SubagentRouteResponse {
131
+ skill: string
132
+ confidence: number
133
+ reasoning: string
134
+ alternatives?: AlternativeRoute[]
135
+ }
136
+
137
+ // ---------------------------------------------------------------------------
138
+ // Namespace Registry
139
+ // ---------------------------------------------------------------------------
140
+
141
+ export interface NamespaceRegistry {
142
+ register(router: NamespaceRouter): void
143
+ unregister(name: string): void
144
+ get(name: string): NamespaceRouter | undefined
145
+ list(): NamespaceRouter[]
146
+ listByLayer(layer: 'core' | 'domain' | 'utility'): NamespaceRouter[]
147
+ resolve(context: RoutingContext): Promise<RouteDecision>
148
+ }
149
+
150
+ // ---------------------------------------------------------------------------
151
+ // Configuration
152
+ // ---------------------------------------------------------------------------
153
+
154
+ export interface NamespaceConfig {
155
+ core: {
156
+ enabled: boolean
157
+ routers: string[]
158
+ }
159
+ domain: {
160
+ enabled: boolean
161
+ routers: string[]
162
+ }
163
+ utility: {
164
+ enabled: boolean
165
+ routers: string[]
166
+ }
167
+ }
168
+
169
+ export const DEFAULT_NAMESPACE_CONFIG: NamespaceConfig = {
170
+ core: {
171
+ enabled: true,
172
+ routers: ['lifecycle', 'state', 'intent'],
173
+ },
174
+ domain: {
175
+ enabled: true,
176
+ routers: ['plan', 'code', 'debug', 'review'],
177
+ },
178
+ utility: {
179
+ enabled: true,
180
+ routers: ['quick-task', 'research', 'fallback'],
181
+ },
182
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Fallback Router - Utility 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
+ export class FallbackRouter implements NamespaceRouter {
17
+ readonly name = 'fallback'
18
+ readonly layer = 'utility' as const
19
+ readonly priority = 0 // 最低优先级
20
+ readonly patterns = [/.*/s] // 匹配所有
21
+
22
+ private routeCount = 0
23
+ private successCount = 0
24
+ private totalLatency = 0
25
+
26
+ async canRoute(context: RoutingContext): Promise<boolean> {
27
+ // 总是可以路由
28
+ return true
29
+ }
30
+
31
+ async route(context: RoutingContext): Promise<RouteDecision> {
32
+ const startTime = Date.now()
33
+ const { state, request } = context
34
+
35
+ this.routeCount++
36
+ this.totalLatency += Date.now() - startTime
37
+ this.successCount++
38
+
39
+ // 基于状态选择最合适的降级技能
40
+ const fallbackSkill = this.selectFallbackSkill(state, request.text)
41
+
42
+ return {
43
+ skill: fallbackSkill,
44
+ confidence: 0.4, // 低置信度
45
+ reasoning: `Fallback decision: ambiguous request, defaulting to ${fallbackSkill} based on phase ${state.phase}`,
46
+ namespace: this.name,
47
+ alternatives: [
48
+ { skill: 'quick-task', confidence: 0.3, reasoning: 'Quick approach' },
49
+ { skill: 'to-plan', confidence: 0.2, reasoning: 'Conservative approach' },
50
+ ],
51
+ metadata: {
52
+ layer: this.layer,
53
+ processingTime: Date.now() - startTime,
54
+ hops: 1,
55
+ },
56
+ }
57
+ }
58
+
59
+ /**
60
+ * 选择最合适的降级技能
61
+ */
62
+ private selectFallbackSkill(state: RoutingContext['state'], requestText: string): string {
63
+ // 基于生命周期阶段选择
64
+ switch (state.phase) {
65
+ case 'planning':
66
+ return 'to-plan'
67
+ case 'executing':
68
+ return 'execute-plan'
69
+ case 'verifying':
70
+ return 'review-diff'
71
+ case 'completed':
72
+ return 'quick-task'
73
+ case 'failed':
74
+ return 'systematic-debugging'
75
+ default:
76
+ // 基于请求内容启发式选择
77
+ if (requestText.length > 100) {
78
+ return 'to-plan' // 复杂请求需要规划
79
+ }
80
+ if (/fix|error|bug|fail/i.test(requestText)) {
81
+ return 'systematic-debugging' // 可能是错误
82
+ }
83
+ return 'quick-task' // 默认快速任务
84
+ }
85
+ }
86
+
87
+ getSupportedSkills(): string[] {
88
+ return ['quick-task', 'to-plan', 'execute-plan', 'systematic-debugging', 'review-diff']
89
+ }
90
+
91
+ getHealth(): NamespaceHealth {
92
+ return {
93
+ name: this.name,
94
+ status: 'healthy', // fallback 总是健康
95
+ totalRoutes: this.routeCount,
96
+ successRate: this.successRate(),
97
+ avgLatency: this.routeCount > 0 ? this.totalLatency / this.routeCount : 0,
98
+ }
99
+ }
100
+
101
+ private successRate(): number {
102
+ return this.routeCount > 0 ? this.successCount / this.routeCount : 1.0
103
+ }
104
+ }
105
+
106
+ export const fallbackRouter = new FallbackRouter()
107
+ export default fallbackRouter