digital-workers 2.1.1 → 2.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.
- package/CHANGELOG.md +23 -0
- package/README.md +136 -180
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +34 -21
- package/dist/actions.js.map +1 -1
- package/dist/agent-comms.d.ts +438 -0
- package/dist/agent-comms.d.ts.map +1 -0
- package/dist/agent-comms.js +677 -0
- package/dist/agent-comms.js.map +1 -0
- package/dist/approve.d.ts +40 -8
- package/dist/approve.d.ts.map +1 -1
- package/dist/approve.js +86 -20
- package/dist/approve.js.map +1 -1
- package/dist/ask.d.ts +38 -7
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +85 -25
- package/dist/ask.js.map +1 -1
- package/dist/browse.d.ts +223 -0
- package/dist/browse.d.ts.map +1 -0
- package/dist/browse.js +392 -0
- package/dist/browse.js.map +1 -0
- package/dist/capability-tiers.d.ts +230 -0
- package/dist/capability-tiers.d.ts.map +1 -0
- package/dist/capability-tiers.js +388 -0
- package/dist/capability-tiers.js.map +1 -0
- package/dist/cascade-context.d.ts +523 -0
- package/dist/cascade-context.d.ts.map +1 -0
- package/dist/cascade-context.js +494 -0
- package/dist/cascade-context.js.map +1 -0
- package/dist/client.d.ts +162 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +64 -0
- package/dist/client.js.map +1 -0
- package/dist/decide.d.ts +42 -6
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +54 -11
- package/dist/decide.js.map +1 -1
- package/dist/do.d.ts +36 -7
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +82 -39
- package/dist/do.js.map +1 -1
- package/dist/error-escalation.d.ts +416 -0
- package/dist/error-escalation.d.ts.map +1 -0
- package/dist/error-escalation.js +656 -0
- package/dist/error-escalation.js.map +1 -0
- package/dist/generate.d.ts +48 -7
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +49 -8
- package/dist/generate.js.map +1 -1
- package/dist/goals.d.ts +10 -9
- package/dist/goals.d.ts.map +1 -1
- package/dist/goals.js +30 -24
- package/dist/goals.js.map +1 -1
- package/dist/image.d.ts +189 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +528 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +59 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -2
- package/dist/index.js.map +1 -1
- package/dist/is.d.ts +45 -10
- package/dist/is.d.ts.map +1 -1
- package/dist/is.js +56 -21
- package/dist/is.js.map +1 -1
- package/dist/kpis.d.ts +24 -15
- package/dist/kpis.d.ts.map +1 -1
- package/dist/kpis.js +16 -14
- package/dist/kpis.js.map +1 -1
- package/dist/load-balancing.d.ts +395 -0
- package/dist/load-balancing.d.ts.map +1 -0
- package/dist/load-balancing.js +991 -0
- package/dist/load-balancing.js.map +1 -0
- package/dist/logger.d.ts +76 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +39 -0
- package/dist/logger.js.map +1 -0
- package/dist/notify.d.ts +38 -9
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +72 -17
- package/dist/notify.js.map +1 -1
- package/dist/role.d.ts +5 -4
- package/dist/role.d.ts.map +1 -1
- package/dist/role.js +13 -10
- package/dist/role.js.map +1 -1
- package/dist/runtime.d.ts +310 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +510 -0
- package/dist/runtime.js.map +1 -0
- package/dist/team.d.ts +11 -6
- package/dist/team.d.ts.map +1 -1
- package/dist/team.js +22 -15
- package/dist/team.js.map +1 -1
- package/dist/transports/email.d.ts +318 -0
- package/dist/transports/email.d.ts.map +1 -0
- package/dist/transports/email.js +779 -0
- package/dist/transports/email.js.map +1 -0
- package/dist/transports/slack.d.ts +515 -0
- package/dist/transports/slack.d.ts.map +1 -0
- package/dist/transports/slack.js +844 -0
- package/dist/transports/slack.js.map +1 -0
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +44 -25
- package/dist/transports.js.map +1 -1
- package/dist/types.d.ts +149 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/id.d.ts +19 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +21 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/video.d.ts +203 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +528 -0
- package/dist/video.js.map +1 -0
- package/dist/worker.d.ts +343 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +698 -0
- package/dist/worker.js.map +1 -0
- package/package.json +24 -5
- package/src/actions.ts +48 -38
- package/src/agent-comms.ts +1200 -0
- package/src/approve.ts +91 -20
- package/src/ask.ts +99 -25
- package/src/browse.ts +627 -0
- package/src/capability-tiers.ts +545 -0
- package/src/cascade-context.ts +648 -0
- package/src/client.ts +221 -0
- package/src/decide.ts +81 -35
- package/src/do.ts +98 -52
- package/src/error-escalation.ts +1123 -0
- package/src/generate.ts +52 -18
- package/src/goals.ts +36 -27
- package/src/image.ts +816 -0
- package/src/index.ts +410 -2
- package/src/is.ts +59 -25
- package/src/kpis.ts +41 -36
- package/src/load-balancing.ts +1467 -0
- package/src/logger.ts +93 -0
- package/src/notify.ts +78 -17
- package/src/role.ts +30 -20
- package/src/runtime.ts +796 -0
- package/src/team.ts +24 -19
- package/src/transports/email.ts +1160 -0
- package/src/transports/slack.ts +1320 -0
- package/src/transports.ts +58 -43
- package/src/types.ts +182 -46
- package/src/utils/id.ts +21 -0
- package/src/video.ts +906 -0
- package/src/worker.ts +1007 -0
- package/test/agent-comms.test.ts +1397 -0
- package/test/approve.test.ts +305 -0
- package/test/ask.test.ts +274 -0
- package/test/browse.test.ts +361 -0
- package/test/capability-tiers.test.ts +631 -0
- package/test/cascade-context.test.ts +692 -0
- package/test/decide.test.ts +252 -0
- package/test/do.test.ts +144 -0
- package/test/error-escalation.test.ts +1205 -0
- package/test/error-logging.test.ts +357 -0
- package/test/generate.test.ts +319 -0
- package/test/image.test.ts +398 -0
- package/test/is.test.ts +287 -0
- package/test/load-balancing-safety.test.ts +404 -0
- package/test/load-balancing-thread-safety.test.ts +464 -0
- package/test/load-balancing.test.ts +1145 -0
- package/test/notify.test.ts +434 -0
- package/test/primitives.test.ts +320 -0
- package/test/runtime-integration.test.ts +892 -0
- package/test/transports/crypto.test.ts +230 -0
- package/test/transports/email.test.ts +866 -0
- package/test/transports/id-generation.test.ts +91 -0
- package/test/transports/slack.test.ts +760 -0
- package/test/type-safety.test.ts +834 -0
- package/test/types.test.ts +95 -2
- package/test/video.test.ts +530 -0
- package/test/worker.test.ts +1433 -0
- package/tsconfig.json +4 -1
- package/vitest.config.ts +42 -0
- package/wrangler.jsonc +36 -0
- package/.turbo/turbo-build.log +0 -5
- package/src/actions.js +0 -436
- package/src/approve.js +0 -234
- package/src/ask.js +0 -226
- package/src/decide.js +0 -244
- package/src/do.js +0 -227
- package/src/generate.js +0 -298
- package/src/goals.js +0 -205
- package/src/index.js +0 -68
- package/src/is.js +0 -317
- package/src/kpis.js +0 -270
- package/src/notify.js +0 -219
- package/src/role.js +0 -110
- package/src/team.js +0 -130
- package/src/transports.js +0 -357
- package/src/types.js +0 -71
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Tiers
|
|
3
|
+
*
|
|
4
|
+
* Agent capability tiers with complexity levels and toolsets.
|
|
5
|
+
* Follows the cascade pattern: code < generative < agentic < human
|
|
6
|
+
*
|
|
7
|
+
* ## Tier Hierarchy
|
|
8
|
+
*
|
|
9
|
+
* 1. **Code** (complexity 1-2): Deterministic, pure functions
|
|
10
|
+
* - Tools: calculate, lookup, validate, transform
|
|
11
|
+
* - No AI, predictable outputs
|
|
12
|
+
*
|
|
13
|
+
* 2. **Generative** (complexity 3-5): LLM-powered generation
|
|
14
|
+
* - Tools: generate, summarize, analyze, classify
|
|
15
|
+
* - Uses AI but no autonomous actions
|
|
16
|
+
*
|
|
17
|
+
* 3. **Agentic** (complexity 6-8): Autonomous AI agents
|
|
18
|
+
* - Tools: browse, execute, plan, delegate
|
|
19
|
+
* - Can take actions, make decisions
|
|
20
|
+
*
|
|
21
|
+
* 4. **Human** (complexity 9-10): Human-in-the-loop
|
|
22
|
+
* - Tools: approve, review, decide, escalate
|
|
23
|
+
* - Requires human judgment
|
|
24
|
+
*
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Type Definitions
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Capability tier levels following cascade pattern
|
|
34
|
+
*/
|
|
35
|
+
export type CapabilityTier = 'code' | 'generative' | 'agentic' | 'human'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Task complexity rating (1-10 scale)
|
|
39
|
+
*/
|
|
40
|
+
export type TaskComplexity = number
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Capability profile defining an agent's abilities
|
|
44
|
+
*/
|
|
45
|
+
export interface CapabilityProfile {
|
|
46
|
+
/** Unique profile name */
|
|
47
|
+
name: string
|
|
48
|
+
/** Tier level */
|
|
49
|
+
tier: CapabilityTier
|
|
50
|
+
/** Complexity rating this profile can handle (1-10) */
|
|
51
|
+
complexityRating: number
|
|
52
|
+
/** Available tools for this profile */
|
|
53
|
+
tools: string[]
|
|
54
|
+
/** Optional description */
|
|
55
|
+
description?: string
|
|
56
|
+
/** Optional constraints */
|
|
57
|
+
constraints?: ProfileConstraints
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Profile constraints
|
|
62
|
+
*/
|
|
63
|
+
export interface ProfileConstraints {
|
|
64
|
+
maxTokens?: number
|
|
65
|
+
allowedDomains?: string[]
|
|
66
|
+
requiresApproval?: boolean
|
|
67
|
+
timeout?: number
|
|
68
|
+
maxRetries?: number
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Tier configuration
|
|
73
|
+
*/
|
|
74
|
+
export interface TierConfig {
|
|
75
|
+
tier: CapabilityTier
|
|
76
|
+
minComplexity: number
|
|
77
|
+
maxComplexity: number
|
|
78
|
+
description: string
|
|
79
|
+
allowedTools: string[]
|
|
80
|
+
defaultTimeout: number
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Toolset for a tier
|
|
85
|
+
*/
|
|
86
|
+
export interface TierToolset {
|
|
87
|
+
tier: CapabilityTier
|
|
88
|
+
tools: string[]
|
|
89
|
+
includesLowerTiers: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Result of matching a tier to complexity
|
|
94
|
+
*/
|
|
95
|
+
export interface TierMatchResult {
|
|
96
|
+
tier: CapabilityTier
|
|
97
|
+
confidence: number
|
|
98
|
+
suggestedTools: string[]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Tier escalation request
|
|
103
|
+
*/
|
|
104
|
+
export interface TierEscalation {
|
|
105
|
+
fromTier: CapabilityTier
|
|
106
|
+
toTier: CapabilityTier
|
|
107
|
+
reason: string
|
|
108
|
+
skipJustification?: string
|
|
109
|
+
allowDeescalation?: boolean
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Escalation validation result
|
|
114
|
+
*/
|
|
115
|
+
export interface EscalationValidationResult {
|
|
116
|
+
valid: boolean
|
|
117
|
+
error?: string
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Constants
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* All capability tiers in order
|
|
126
|
+
*/
|
|
127
|
+
export const CAPABILITY_TIERS: readonly CapabilityTier[] = [
|
|
128
|
+
'code',
|
|
129
|
+
'generative',
|
|
130
|
+
'agentic',
|
|
131
|
+
'human',
|
|
132
|
+
] as const
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Tier order for comparison
|
|
136
|
+
*/
|
|
137
|
+
export const TIER_ORDER: Record<CapabilityTier, number> = {
|
|
138
|
+
code: 0,
|
|
139
|
+
generative: 1,
|
|
140
|
+
agentic: 2,
|
|
141
|
+
human: 3,
|
|
142
|
+
} as const
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Tools specific to each tier (not including inherited tools)
|
|
146
|
+
*/
|
|
147
|
+
const TIER_SPECIFIC_TOOLS: Record<CapabilityTier, string[]> = {
|
|
148
|
+
code: ['calculate', 'lookup', 'validate', 'transform'],
|
|
149
|
+
generative: ['generate', 'summarize', 'analyze', 'classify'],
|
|
150
|
+
agentic: ['browse', 'execute', 'plan', 'delegate'],
|
|
151
|
+
human: ['approve', 'review', 'decide', 'escalate'],
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Tier configurations
|
|
156
|
+
*/
|
|
157
|
+
const TIER_CONFIGS: Record<CapabilityTier, TierConfig> = {
|
|
158
|
+
code: {
|
|
159
|
+
tier: 'code',
|
|
160
|
+
minComplexity: 1,
|
|
161
|
+
maxComplexity: 2,
|
|
162
|
+
description: 'Deterministic code execution with predictable outputs',
|
|
163
|
+
allowedTools: TIER_SPECIFIC_TOOLS.code,
|
|
164
|
+
defaultTimeout: 5000, // 5 seconds
|
|
165
|
+
},
|
|
166
|
+
generative: {
|
|
167
|
+
tier: 'generative',
|
|
168
|
+
minComplexity: 3,
|
|
169
|
+
maxComplexity: 5,
|
|
170
|
+
description: 'LLM-powered generation and analysis without autonomous actions',
|
|
171
|
+
allowedTools: [...TIER_SPECIFIC_TOOLS.code, ...TIER_SPECIFIC_TOOLS.generative],
|
|
172
|
+
defaultTimeout: 30000, // 30 seconds
|
|
173
|
+
},
|
|
174
|
+
agentic: {
|
|
175
|
+
tier: 'agentic',
|
|
176
|
+
minComplexity: 6,
|
|
177
|
+
maxComplexity: 8,
|
|
178
|
+
description: 'Autonomous AI agents that can take actions and make decisions',
|
|
179
|
+
allowedTools: [
|
|
180
|
+
...TIER_SPECIFIC_TOOLS.code,
|
|
181
|
+
...TIER_SPECIFIC_TOOLS.generative,
|
|
182
|
+
...TIER_SPECIFIC_TOOLS.agentic,
|
|
183
|
+
],
|
|
184
|
+
defaultTimeout: 300000, // 5 minutes
|
|
185
|
+
},
|
|
186
|
+
human: {
|
|
187
|
+
tier: 'human',
|
|
188
|
+
minComplexity: 9,
|
|
189
|
+
maxComplexity: 10,
|
|
190
|
+
description: 'Human-in-the-loop for tasks requiring human judgment',
|
|
191
|
+
allowedTools: [
|
|
192
|
+
...TIER_SPECIFIC_TOOLS.code,
|
|
193
|
+
...TIER_SPECIFIC_TOOLS.generative,
|
|
194
|
+
...TIER_SPECIFIC_TOOLS.agentic,
|
|
195
|
+
...TIER_SPECIFIC_TOOLS.human,
|
|
196
|
+
],
|
|
197
|
+
defaultTimeout: 86400000, // 24 hours
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// Tier Comparison Functions
|
|
203
|
+
// ============================================================================
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Compare two tiers
|
|
207
|
+
* @returns negative if a < b, positive if a > b, 0 if equal
|
|
208
|
+
*/
|
|
209
|
+
export function compareTiers(a: CapabilityTier, b: CapabilityTier): number {
|
|
210
|
+
return TIER_ORDER[a] - TIER_ORDER[b]
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check if tier A is higher than tier B
|
|
215
|
+
*/
|
|
216
|
+
export function isHigherTier(a: CapabilityTier, b: CapabilityTier): boolean {
|
|
217
|
+
return TIER_ORDER[a] > TIER_ORDER[b]
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Check if tier A is lower than tier B
|
|
222
|
+
*/
|
|
223
|
+
export function isLowerTier(a: CapabilityTier, b: CapabilityTier): boolean {
|
|
224
|
+
return TIER_ORDER[a] < TIER_ORDER[b]
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get the next tier in escalation order
|
|
229
|
+
* @returns next tier or null if at highest tier
|
|
230
|
+
*/
|
|
231
|
+
export function getNextTier(tier: CapabilityTier): CapabilityTier | null {
|
|
232
|
+
const index = TIER_ORDER[tier]
|
|
233
|
+
if (index >= CAPABILITY_TIERS.length - 1) {
|
|
234
|
+
return null
|
|
235
|
+
}
|
|
236
|
+
return CAPABILITY_TIERS[index + 1] ?? null
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get the previous tier in de-escalation order
|
|
241
|
+
* @returns previous tier or null if at lowest tier
|
|
242
|
+
*/
|
|
243
|
+
export function getPreviousTier(tier: CapabilityTier): CapabilityTier | null {
|
|
244
|
+
const index = TIER_ORDER[tier]
|
|
245
|
+
if (index <= 0) {
|
|
246
|
+
return null
|
|
247
|
+
}
|
|
248
|
+
return CAPABILITY_TIERS[index - 1] ?? null
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Tier Configuration Functions
|
|
253
|
+
// ============================================================================
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Get configuration for a tier
|
|
257
|
+
*/
|
|
258
|
+
export function getTierConfig(tier: CapabilityTier): TierConfig {
|
|
259
|
+
return TIER_CONFIGS[tier]
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get tools available for a tier (includes inherited tools from lower tiers)
|
|
264
|
+
*/
|
|
265
|
+
export function getToolsForTier(tier: CapabilityTier): string[] {
|
|
266
|
+
return TIER_CONFIGS[tier].allowedTools
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ============================================================================
|
|
270
|
+
// Complexity Matching Functions
|
|
271
|
+
// ============================================================================
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Match a complexity rating to the appropriate tier
|
|
275
|
+
*/
|
|
276
|
+
export function matchTierToComplexity(complexity: TaskComplexity): TierMatchResult {
|
|
277
|
+
// Validate complexity is in range
|
|
278
|
+
const clampedComplexity = Math.max(1, Math.min(10, complexity))
|
|
279
|
+
|
|
280
|
+
// Find the matching tier
|
|
281
|
+
for (const tier of CAPABILITY_TIERS) {
|
|
282
|
+
const config = TIER_CONFIGS[tier]
|
|
283
|
+
if (clampedComplexity >= config.minComplexity && clampedComplexity <= config.maxComplexity) {
|
|
284
|
+
// Calculate confidence based on how centered in the range
|
|
285
|
+
const range = config.maxComplexity - config.minComplexity
|
|
286
|
+
const center = config.minComplexity + range / 2
|
|
287
|
+
const distance = Math.abs(clampedComplexity - center)
|
|
288
|
+
const confidence = 1 - (distance / (range + 1)) * 0.2 // 0.8-1.0 range
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
tier,
|
|
292
|
+
confidence,
|
|
293
|
+
suggestedTools: config.allowedTools,
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Handle boundary cases (between tiers)
|
|
299
|
+
// Find which tier is closest
|
|
300
|
+
let bestTier: CapabilityTier = 'code'
|
|
301
|
+
let bestDistance = Infinity
|
|
302
|
+
|
|
303
|
+
for (const tier of CAPABILITY_TIERS) {
|
|
304
|
+
const config = TIER_CONFIGS[tier]
|
|
305
|
+
const center = (config.minComplexity + config.maxComplexity) / 2
|
|
306
|
+
const distance = Math.abs(clampedComplexity - center)
|
|
307
|
+
if (distance < bestDistance) {
|
|
308
|
+
bestDistance = distance
|
|
309
|
+
bestTier = tier
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
tier: bestTier,
|
|
315
|
+
confidence: 0.7, // Lower confidence for boundary cases
|
|
316
|
+
suggestedTools: TIER_CONFIGS[bestTier].allowedTools,
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Check if a tier can execute a task of given complexity
|
|
322
|
+
*/
|
|
323
|
+
export function canExecuteAtTier(tier: CapabilityTier, complexity: TaskComplexity): boolean {
|
|
324
|
+
const config = TIER_CONFIGS[tier]
|
|
325
|
+
// A tier can handle its own complexity range or any lower complexity
|
|
326
|
+
return complexity <= config.maxComplexity
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ============================================================================
|
|
330
|
+
// Escalation Functions
|
|
331
|
+
// ============================================================================
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Validate a tier escalation request
|
|
335
|
+
*/
|
|
336
|
+
export function validateTierEscalation(escalation: TierEscalation): EscalationValidationResult {
|
|
337
|
+
const { fromTier, toTier, reason, skipJustification, allowDeescalation } = escalation
|
|
338
|
+
|
|
339
|
+
// Require a reason
|
|
340
|
+
if (!reason || reason.trim() === '') {
|
|
341
|
+
return {
|
|
342
|
+
valid: false,
|
|
343
|
+
error: 'Escalation reason is required',
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const fromOrder = TIER_ORDER[fromTier]
|
|
348
|
+
const toOrder = TIER_ORDER[toTier]
|
|
349
|
+
|
|
350
|
+
// Check for de-escalation
|
|
351
|
+
if (toOrder < fromOrder) {
|
|
352
|
+
if (!allowDeescalation) {
|
|
353
|
+
return {
|
|
354
|
+
valid: false,
|
|
355
|
+
error: 'de-escalation not allowed without explicit allowDeescalation flag',
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return { valid: true }
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Check for same tier (no-op)
|
|
362
|
+
if (fromOrder === toOrder) {
|
|
363
|
+
return { valid: true }
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Check for multi-level escalation (skipping tiers)
|
|
367
|
+
const tierDifference = toOrder - fromOrder
|
|
368
|
+
if (tierDifference > 1) {
|
|
369
|
+
if (!skipJustification || skipJustification.trim() === '') {
|
|
370
|
+
return {
|
|
371
|
+
valid: false,
|
|
372
|
+
error: 'skipJustification is required when skipping tiers',
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return { valid: true }
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ============================================================================
|
|
381
|
+
// Profile Creation and Validation
|
|
382
|
+
// ============================================================================
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Create a capability profile with validation
|
|
386
|
+
*/
|
|
387
|
+
export function createCapabilityProfile(input: {
|
|
388
|
+
name: string
|
|
389
|
+
tier: CapabilityTier
|
|
390
|
+
complexityRating: number
|
|
391
|
+
tools: string[]
|
|
392
|
+
description?: string
|
|
393
|
+
constraints?: ProfileConstraints
|
|
394
|
+
}): CapabilityProfile {
|
|
395
|
+
const { name, tier, complexityRating, tools, description, constraints } = input
|
|
396
|
+
const config = TIER_CONFIGS[tier]
|
|
397
|
+
|
|
398
|
+
// Validate complexity rating is within tier bounds
|
|
399
|
+
if (complexityRating < config.minComplexity || complexityRating > config.maxComplexity) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
`Complexity rating ${complexityRating} is outside bounds for ${tier} tier ` +
|
|
402
|
+
`(${config.minComplexity}-${config.maxComplexity})`
|
|
403
|
+
)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Validate tools are appropriate for tier
|
|
407
|
+
const allowedTools = new Set(config.allowedTools)
|
|
408
|
+
for (const tool of tools) {
|
|
409
|
+
if (!allowedTools.has(tool)) {
|
|
410
|
+
throw new Error(
|
|
411
|
+
`Tool '${tool}' is not allowed at ${tier} tier. ` +
|
|
412
|
+
`Allowed tools: ${config.allowedTools.join(', ')}`
|
|
413
|
+
)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
name,
|
|
419
|
+
tier,
|
|
420
|
+
complexityRating,
|
|
421
|
+
tools,
|
|
422
|
+
...(description !== undefined && { description }),
|
|
423
|
+
...(constraints !== undefined && { constraints }),
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// ============================================================================
|
|
428
|
+
// Tier Registry
|
|
429
|
+
// ============================================================================
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Registry for managing capability profiles
|
|
433
|
+
*/
|
|
434
|
+
export class TierRegistry {
|
|
435
|
+
private profiles: Map<string, CapabilityProfile> = new Map()
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Register a capability profile
|
|
439
|
+
*/
|
|
440
|
+
register(input: {
|
|
441
|
+
name: string
|
|
442
|
+
tier: CapabilityTier
|
|
443
|
+
complexityRating: number
|
|
444
|
+
tools: string[]
|
|
445
|
+
description?: string
|
|
446
|
+
constraints?: ProfileConstraints
|
|
447
|
+
}): void {
|
|
448
|
+
if (this.profiles.has(input.name)) {
|
|
449
|
+
throw new Error(`Profile '${input.name}' is already registered`)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const profile = createCapabilityProfile(input)
|
|
453
|
+
this.profiles.set(profile.name, profile)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Get a profile by name
|
|
458
|
+
*/
|
|
459
|
+
get(name: string): CapabilityProfile | undefined {
|
|
460
|
+
return this.profiles.get(name)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Unregister a profile
|
|
465
|
+
*/
|
|
466
|
+
unregister(name: string): boolean {
|
|
467
|
+
return this.profiles.delete(name)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* List all profiles for a tier
|
|
472
|
+
*/
|
|
473
|
+
listByTier(tier: CapabilityTier): CapabilityProfile[] {
|
|
474
|
+
const result: CapabilityProfile[] = []
|
|
475
|
+
for (const profile of this.profiles.values()) {
|
|
476
|
+
if (profile.tier === tier) {
|
|
477
|
+
result.push(profile)
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return result
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Find profiles that can handle a given complexity
|
|
485
|
+
*/
|
|
486
|
+
findByComplexity(complexity: TaskComplexity): CapabilityProfile[] {
|
|
487
|
+
const result: CapabilityProfile[] = []
|
|
488
|
+
for (const profile of this.profiles.values()) {
|
|
489
|
+
if (canExecuteAtTier(profile.tier, complexity)) {
|
|
490
|
+
result.push(profile)
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return result
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Find profiles with the required tools
|
|
498
|
+
*/
|
|
499
|
+
findByTools(requiredTools: string[]): CapabilityProfile[] {
|
|
500
|
+
const result: CapabilityProfile[] = []
|
|
501
|
+
for (const profile of this.profiles.values()) {
|
|
502
|
+
const profileTools = new Set(profile.tools)
|
|
503
|
+
const hasAllTools = requiredTools.every((tool) => profileTools.has(tool))
|
|
504
|
+
if (hasAllTools) {
|
|
505
|
+
result.push(profile)
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return result
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* List all registered profiles
|
|
513
|
+
*/
|
|
514
|
+
listAll(): CapabilityProfile[] {
|
|
515
|
+
return Array.from(this.profiles.values())
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Clear all profiles
|
|
520
|
+
*/
|
|
521
|
+
clear(): void {
|
|
522
|
+
this.profiles.clear()
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// ============================================================================
|
|
527
|
+
// Default Export
|
|
528
|
+
// ============================================================================
|
|
529
|
+
|
|
530
|
+
export default {
|
|
531
|
+
CAPABILITY_TIERS,
|
|
532
|
+
TIER_ORDER,
|
|
533
|
+
compareTiers,
|
|
534
|
+
isHigherTier,
|
|
535
|
+
isLowerTier,
|
|
536
|
+
getNextTier,
|
|
537
|
+
getPreviousTier,
|
|
538
|
+
getTierConfig,
|
|
539
|
+
getToolsForTier,
|
|
540
|
+
matchTierToComplexity,
|
|
541
|
+
canExecuteAtTier,
|
|
542
|
+
validateTierEscalation,
|
|
543
|
+
createCapabilityProfile,
|
|
544
|
+
TierRegistry,
|
|
545
|
+
}
|