create-byan-agent 2.2.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/install/bin/create-byan-agent-v2.js +24 -0
- package/install/lib/platforms/claude-code.js +115 -5
- package/install/lib/yanstaller/agent-launcher.js +348 -0
- package/install/lib/yanstaller/index.js +56 -10
- package/install/lib/yanstaller/platform-selector.js +328 -0
- package/install/package.json +2 -2
- package/install/templates/.github/agents/bmad-agent-claude.md +48 -0
- package/install/templates/.github/agents/bmad-agent-codex.md +48 -0
- package/install/templates/_byan/bmb/agents/claude.md +502 -0
- package/install/templates/_byan/bmb/agents/codex.md +407 -0
- package/install/templates/_byan/workers/launchers/README.md +308 -0
- package/install/templates/_byan/workers/launchers/launch-yanstaller-claude.md +204 -0
- package/install/templates/_byan/workers/launchers/launch-yanstaller-codex.md +209 -0
- package/install/templates/_byan/workers/launchers/launch-yanstaller-copilot.md +173 -0
- package/install/templates/_byan/workers.md +343 -1126
- package/install/templates/workers/README.md +148 -0
- package/install/templates/workers/cost-optimizer.js +169 -0
- package/package.json +5 -2
|
@@ -1,1283 +1,500 @@
|
|
|
1
|
-
# BYAN v2 Workers
|
|
2
|
-
|
|
3
|
-
Documentation complète des 6 workers (modules fonctionnels) de BYAN v2.
|
|
1
|
+
# BYAN v2 Workers - Lightweight LLM Agents
|
|
4
2
|
|
|
5
3
|
**Version:** 2.0.0
|
|
6
|
-
**Last Updated:** 2026-02-
|
|
4
|
+
**Last Updated:** 2026-02-10
|
|
5
|
+
**Status:** ✅ Production Ready
|
|
7
6
|
|
|
8
7
|
---
|
|
9
8
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
1. [Vue d'ensemble](#vue-densemble)
|
|
13
|
-
2. [Context Worker](#1-context-worker)
|
|
14
|
-
3. [Dispatcher Worker](#2-dispatcher-worker)
|
|
15
|
-
4. [Generation Worker](#3-generation-worker)
|
|
16
|
-
5. [Orchestrator Worker](#4-orchestrator-worker)
|
|
17
|
-
6. [Observability Worker](#5-observability-worker)
|
|
18
|
-
7. [Integration Worker](#6-integration-worker)
|
|
19
|
-
8. [Architecture & Communication](#architecture--communication)
|
|
9
|
+
## ⚠️ IMPORTANT: Worker vs Module
|
|
20
10
|
|
|
21
|
-
|
|
11
|
+
**WORKERS** = Petits agents LLM légers (Haiku, gpt-5-mini)
|
|
12
|
+
**MODULES** = Code technique (Context, Dispatcher, Generation, etc.)
|
|
22
13
|
|
|
23
|
-
|
|
14
|
+
**Ne confondez pas les deux !**
|
|
24
15
|
|
|
25
|
-
|
|
16
|
+
---
|
|
26
17
|
|
|
27
|
-
|
|
18
|
+
## Qu'est-ce qu'un Worker ?
|
|
28
19
|
|
|
29
|
-
|
|
30
|
-
2. **Loose Coupling** - Workers communiquent via interfaces définies
|
|
31
|
-
3. **High Cohesion** - Fonctionnalités liées regroupées dans même worker
|
|
32
|
-
4. **Testability** - Chaque worker est testable indépendamment
|
|
33
|
-
5. **Observability** - Tous les workers loggent et émettent des métriques
|
|
20
|
+
Un **Worker** est un **petit agent LLM** optimisé pour des tâches simples et répétitives.
|
|
34
21
|
|
|
35
|
-
###
|
|
22
|
+
### Caractéristiques
|
|
36
23
|
|
|
37
24
|
```
|
|
38
|
-
|
|
39
|
-
│
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
│
|
|
43
|
-
|
|
44
|
-
│
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
│ DISPATCHER │
|
|
50
|
-
│ Task Router │
|
|
51
|
-
└───────┬────────┘
|
|
52
|
-
│
|
|
53
|
-
┌──────────┼──────────┐
|
|
54
|
-
│ │ │
|
|
55
|
-
┌───▼───┐ ┌──▼───┐ ┌───▼─────┐
|
|
56
|
-
│ GENER │ │ INTEG│ │ OBSERV │
|
|
57
|
-
│ ATION │ │RATION│ │ ABILITY │
|
|
58
|
-
└───────┘ └──────┘ └─────────┘
|
|
25
|
+
┌────────────────────┬──────────────┬──────────────┐
|
|
26
|
+
│ Feature │ Worker │ Agent │
|
|
27
|
+
├────────────────────┼──────────────┼──────────────┤
|
|
28
|
+
│ Model │ Haiku/Mini │ Sonnet/Opus │
|
|
29
|
+
│ Cost │ 0.0003$/call │ 0.003$/call │
|
|
30
|
+
│ Complexity Score │ < 30 │ ≥ 60 │
|
|
31
|
+
│ Task Type │ Simple │ Complex │
|
|
32
|
+
│ Context Window │ Small │ Large │
|
|
33
|
+
│ Response Time │ Fast │ Slower │
|
|
34
|
+
│ Intelligence │ Low │ High │
|
|
35
|
+
└────────────────────┴──────────────┴──────────────┘
|
|
59
36
|
```
|
|
60
37
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## 1. Context Worker
|
|
64
|
-
|
|
65
|
-
**Location:** `src/byan-v2/context/`
|
|
38
|
+
### Économie
|
|
66
39
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
```javascript
|
|
41
|
+
// Scénario : 100 tâches/semaine
|
|
42
|
+
// 100% Agent (Sonnet) = 100 × 0.003$ = 0.30$
|
|
43
|
+
// 60% Worker + 40% Agent = (60 × 0.0003$) + (40 × 0.003$) = 0.138$
|
|
44
|
+
//
|
|
45
|
+
// Économie : 54% réduction de coût
|
|
46
|
+
```
|
|
70
47
|
|
|
71
|
-
|
|
48
|
+
---
|
|
72
49
|
|
|
73
|
-
|
|
50
|
+
## Architecture BYAN v2
|
|
74
51
|
|
|
75
|
-
|
|
76
|
-
- Détecte environnement d'exécution (CLI, standalone, CI)
|
|
77
|
-
- Collecte metadata session (user, repo, branch)
|
|
78
|
-
- Fournit contexte aux autres workers
|
|
52
|
+
### Dispatcher Rule-Based
|
|
79
53
|
|
|
80
|
-
**
|
|
54
|
+
Le **Dispatcher** (module technique, PAS un worker) analyse la complexité de chaque tâche et route :
|
|
81
55
|
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
* Get full context snapshot
|
|
106
|
-
* @returns {Object} Complete context
|
|
107
|
-
*/
|
|
108
|
-
getSnapshot(): Object;
|
|
109
|
-
}
|
|
56
|
+
```
|
|
57
|
+
┌─────────────────────────────────────────────────┐
|
|
58
|
+
│ TASK ARRIVES │
|
|
59
|
+
└────────────────┬────────────────────────────────┘
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
┌─────────────────────────────────────────────────┐
|
|
63
|
+
│ DISPATCHER (Code Module) │
|
|
64
|
+
│ Analyse complexité → Score 0-100 │
|
|
65
|
+
└────────────────┬────────────────────────────────┘
|
|
66
|
+
│
|
|
67
|
+
┌────────┴────────┐
|
|
68
|
+
│ │
|
|
69
|
+
▼ ▼
|
|
70
|
+
┌──────────────┐ ┌──────────────┐
|
|
71
|
+
│ Score < 30 │ │ Score ≥ 60 │
|
|
72
|
+
│ │ │ │
|
|
73
|
+
│ WORKER │ │ AGENT │
|
|
74
|
+
│ (Cheap) │ │ (Expensive) │
|
|
75
|
+
│ │ │ │
|
|
76
|
+
│ gpt-5-mini │ │ claude-sonnet│
|
|
77
|
+
│ 0.0003$ │ │ 0.003$ │
|
|
78
|
+
└──────────────┘ └──────────────┘
|
|
110
79
|
```
|
|
111
80
|
|
|
112
|
-
|
|
81
|
+
### Worker Pool
|
|
113
82
|
|
|
114
83
|
```javascript
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const repoCtx = context.getRepoContext();
|
|
120
|
-
console.log('Repo:', repoCtx.repo);
|
|
84
|
+
// Pool de 2 workers LLM
|
|
85
|
+
WorkerPool (size=2)
|
|
86
|
+
├── Worker #0 (idle/busy) → Model: gpt-5-mini
|
|
87
|
+
└── Worker #1 (idle/busy) → Model: gpt-5-mini
|
|
121
88
|
```
|
|
122
89
|
|
|
123
|
-
|
|
90
|
+
**Gestion automatique :**
|
|
91
|
+
- Allocation du worker disponible
|
|
92
|
+
- File d'attente si tous occupés
|
|
93
|
+
- Fallback vers Agent si worker échoue
|
|
94
|
+
- Retry logic avec backoff
|
|
124
95
|
|
|
125
|
-
|
|
96
|
+
---
|
|
126
97
|
|
|
127
|
-
|
|
128
|
-
- Persiste questions et réponses
|
|
129
|
-
- Stocke metadata de session
|
|
130
|
-
- Gère historique et backups
|
|
131
|
-
- Thread-safe pour concurrence
|
|
98
|
+
## Types de Workers
|
|
132
99
|
|
|
133
|
-
|
|
100
|
+
### 1. Task Workers (Dans Worker Pool)
|
|
134
101
|
|
|
135
|
-
|
|
136
|
-
class SessionState {
|
|
137
|
-
constructor(sessionId?: string);
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Initialize new session
|
|
141
|
-
* @returns {string} Session ID
|
|
142
|
-
*/
|
|
143
|
-
initialize(): string;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Add question to session
|
|
147
|
-
* @param {string} question
|
|
148
|
-
*/
|
|
149
|
-
addQuestion(question: string): void;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Add response to last question
|
|
153
|
-
* @param {string} questionId
|
|
154
|
-
* @param {string} response
|
|
155
|
-
*/
|
|
156
|
-
addResponse(questionId: string, response: string): void;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Get all questions and responses
|
|
160
|
-
* @returns {Array} Interview history
|
|
161
|
-
*/
|
|
162
|
-
getHistory(): Array;
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Get session metadata
|
|
166
|
-
* @returns {Object} Metadata
|
|
167
|
-
*/
|
|
168
|
-
getMetadata(): Object;
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Save session to disk
|
|
172
|
-
* @param {string} path - Output path
|
|
173
|
-
*/
|
|
174
|
-
save(path: string): Promise<void>;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Load session from disk
|
|
178
|
-
* @param {string} sessionId
|
|
179
|
-
*/
|
|
180
|
-
static load(sessionId: string): Promise<SessionState>;
|
|
181
|
-
}
|
|
182
|
-
```
|
|
102
|
+
**Utilisation :** Tâches génériques simples
|
|
183
103
|
|
|
184
|
-
**
|
|
104
|
+
**Exemples :**
|
|
105
|
+
- Format JSON
|
|
106
|
+
- Extraire données structurées
|
|
107
|
+
- Valider format
|
|
108
|
+
- Traductions simples
|
|
109
|
+
- Résumés courts
|
|
185
110
|
|
|
111
|
+
**Routing :**
|
|
186
112
|
```javascript
|
|
187
|
-
//
|
|
188
|
-
{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
user: {...},
|
|
193
|
-
repo: {...},
|
|
194
|
-
interview: {
|
|
195
|
-
questions: [
|
|
196
|
-
{ id: "q1", text: "...", timestamp: 123 },
|
|
197
|
-
{ id: "q2", text: "...", timestamp: 456 }
|
|
198
|
-
],
|
|
199
|
-
responses: [
|
|
200
|
-
{ questionId: "q1", response: "...", timestamp: 234 },
|
|
201
|
-
{ questionId: "q2", response: "...", timestamp: 567 }
|
|
202
|
-
]
|
|
203
|
-
},
|
|
204
|
-
metadata: {
|
|
205
|
-
currentPhase: "BUSINESS",
|
|
206
|
-
questionsAsked: 6,
|
|
207
|
-
completed: false
|
|
208
|
-
}
|
|
113
|
+
// Dispatcher analyse complexité
|
|
114
|
+
if (complexityScore < 30) {
|
|
115
|
+
executeWithWorker(task);
|
|
116
|
+
} else {
|
|
117
|
+
executeWithAgent(task);
|
|
209
118
|
}
|
|
210
119
|
```
|
|
211
120
|
|
|
212
|
-
**Usage:**
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
const session = new SessionState();
|
|
216
|
-
session.initialize();
|
|
217
|
-
|
|
218
|
-
session.addQuestion('What is your project domain?');
|
|
219
|
-
session.addResponse('q1', 'E-commerce platform');
|
|
220
|
-
|
|
221
|
-
await session.save('_byan/memory/session-abc123.json');
|
|
222
|
-
```
|
|
223
|
-
|
|
224
121
|
---
|
|
225
122
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
**Location:** `src/byan-v2/dispatcher/`
|
|
229
|
-
|
|
230
|
-
**Responsabilité:** Routage intelligent des tâches vers workers appropriés
|
|
123
|
+
### 2. Launcher Workers (Platform-Specific)
|
|
231
124
|
|
|
232
|
-
|
|
125
|
+
**Utilisation :** Lancer yanstaller sur chaque plateforme
|
|
233
126
|
|
|
234
|
-
|
|
127
|
+
**Fichiers :**
|
|
128
|
+
- `_byan/workers/launchers/launch-yanstaller-copilot.md`
|
|
129
|
+
- `_byan/workers/launchers/launch-yanstaller-claude.md`
|
|
130
|
+
- `_byan/workers/launchers/launch-yanstaller-codex.md`
|
|
235
131
|
|
|
236
|
-
**
|
|
132
|
+
**Caractéristiques :**
|
|
133
|
+
- Single task (execute `npx create-byan-agent`)
|
|
134
|
+
- No LLM call (just shell command)
|
|
135
|
+
- Ultra-light (< 5 KB)
|
|
136
|
+
- Idempotent
|
|
137
|
+
- Platform hints via env vars
|
|
237
138
|
|
|
238
|
-
**
|
|
239
|
-
- Analyse sémantique du texte
|
|
240
|
-
- Calcule score de complexité (0.0 - 1.0)
|
|
241
|
-
- Identifie patterns de tâches complexes
|
|
242
|
-
|
|
243
|
-
**Algorithme:**
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
// Complexity factors
|
|
247
|
-
const factors = {
|
|
248
|
-
length: responseLength / 1000, // Longer = more complex
|
|
249
|
-
keywords: countComplexKeywords(text), // Technical terms
|
|
250
|
-
ambiguity: detectAmbiguity(text), // Unclear requirements
|
|
251
|
-
multiDomain: detectMultipleDomains(text) // Cross-domain knowledge
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
// Weighted score
|
|
255
|
-
const score =
|
|
256
|
-
factors.length * 0.2 +
|
|
257
|
-
factors.keywords * 0.3 +
|
|
258
|
-
factors.ambiguity * 0.3 +
|
|
259
|
-
factors.multiDomain * 0.2;
|
|
139
|
+
**Architecture :**
|
|
260
140
|
```
|
|
261
|
-
|
|
262
|
-
**API:**
|
|
263
|
-
|
|
264
|
-
```javascript
|
|
265
|
-
class ComplexityScorer {
|
|
266
|
-
/**
|
|
267
|
-
* Calculate complexity score
|
|
268
|
-
* @param {string} text - Text to analyze
|
|
269
|
-
* @returns {number} Score 0.0-1.0
|
|
270
|
-
*/
|
|
271
|
-
score(text: string): number;
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Get complexity level
|
|
275
|
-
* @param {string} text
|
|
276
|
-
* @returns {string} 'low' | 'medium' | 'high'
|
|
277
|
-
*/
|
|
278
|
-
getComplexityLevel(text: string): string;
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Explain complexity factors
|
|
282
|
-
* @param {string} text
|
|
283
|
-
* @returns {Object} Breakdown
|
|
284
|
-
*/
|
|
285
|
-
explain(text: string): Object;
|
|
286
|
-
}
|
|
141
|
+
User → Stub Agent → Launcher Worker → Yanstaller Agent
|
|
287
142
|
```
|
|
288
143
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
```javascript
|
|
292
|
-
const scorer = new ComplexityScorer();
|
|
293
|
-
|
|
294
|
-
const text = "Build a microservices architecture with event sourcing...";
|
|
295
|
-
const score = scorer.score(text); // 0.82
|
|
296
|
-
|
|
297
|
-
const level = scorer.getComplexityLevel(text); // "high"
|
|
298
|
-
```
|
|
144
|
+
---
|
|
299
145
|
|
|
300
|
-
|
|
146
|
+
## Worker Pool Implementation
|
|
301
147
|
|
|
302
|
-
|
|
148
|
+
### Code Location
|
|
303
149
|
|
|
304
|
-
|
|
305
|
-
- Décide local execution vs task tool delegation
|
|
306
|
-
- Sélectionne agent type pour délégation (explore, task, general-purpose)
|
|
307
|
-
- Gère fallback si délégation échoue
|
|
150
|
+
`src/core/worker-pool/worker-pool.js`
|
|
308
151
|
|
|
309
|
-
|
|
152
|
+
### API
|
|
310
153
|
|
|
311
154
|
```javascript
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
155
|
+
class WorkerPool {
|
|
156
|
+
/**
|
|
157
|
+
* @param {number} size - Number of workers (default: 2)
|
|
158
|
+
* @param {Object} options
|
|
159
|
+
* @param {string} options.model - LLM model (default: 'gpt-5-mini')
|
|
160
|
+
* @param {number} options.timeout - Timeout in ms (default: 30000)
|
|
161
|
+
*/
|
|
162
|
+
constructor(size = 2, options = {}) {
|
|
163
|
+
this.size = size;
|
|
164
|
+
this.model = options.model || 'gpt-5-mini';
|
|
165
|
+
this.workers = [];
|
|
166
|
+
this.queue = [];
|
|
167
|
+
this.stats = {
|
|
168
|
+
total: 0,
|
|
169
|
+
success: 0,
|
|
170
|
+
failed: 0,
|
|
171
|
+
fallbackToAgent: 0
|
|
172
|
+
};
|
|
173
|
+
}
|
|
327
174
|
|
|
328
|
-
```javascript
|
|
329
|
-
class TaskRouter {
|
|
330
|
-
constructor(config);
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Route task to appropriate executor
|
|
334
|
-
* @param {Object} task
|
|
335
|
-
* @returns {Promise<Object>} Result
|
|
336
|
-
*/
|
|
337
|
-
async route(task: Object): Promise<Object>;
|
|
338
|
-
|
|
339
175
|
/**
|
|
340
|
-
*
|
|
176
|
+
* Execute task with next available worker
|
|
341
177
|
* @param {Object} task
|
|
342
|
-
* @returns {Object}
|
|
343
|
-
*/
|
|
344
|
-
decideRoute(task: Object): Object;
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Get routing statistics
|
|
348
|
-
* @returns {Object} Stats
|
|
178
|
+
* @returns {Promise<Object>}
|
|
349
179
|
*/
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
**Rôle:** Exécution locale des tâches simples sans délégation
|
|
368
|
-
|
|
369
|
-
**Capabilities:**
|
|
370
|
-
- Template rendering
|
|
371
|
-
- Simple text transformations
|
|
372
|
-
- Basic validation
|
|
373
|
-
- File I/O operations
|
|
374
|
-
|
|
375
|
-
**API:**
|
|
180
|
+
async executeTask(task) {
|
|
181
|
+
const worker = await this.getAvailableWorker();
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const result = await worker.execute(task);
|
|
185
|
+
this.stats.success++;
|
|
186
|
+
return result;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
// Fallback to Agent if configured
|
|
189
|
+
if (task.fallbackToAgent) {
|
|
190
|
+
return await this.fallbackToAgent(task);
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
} finally {
|
|
194
|
+
worker.release();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
376
197
|
|
|
377
|
-
```javascript
|
|
378
|
-
class LocalExecutor {
|
|
379
198
|
/**
|
|
380
|
-
*
|
|
381
|
-
* @
|
|
382
|
-
* @returns {Promise<Object>} Result
|
|
199
|
+
* Get next available worker
|
|
200
|
+
* @returns {Promise<Worker>}
|
|
383
201
|
*/
|
|
384
|
-
async
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
**Capabilities:**
|
|
393
|
-
- Invoke explore agent
|
|
394
|
-
- Invoke task agent
|
|
395
|
-
- Invoke general-purpose agent
|
|
396
|
-
- Parse results
|
|
202
|
+
async getAvailableWorker() {
|
|
203
|
+
// Check for idle worker
|
|
204
|
+
const idle = this.workers.find(w => w.isIdle());
|
|
205
|
+
if (idle) {
|
|
206
|
+
idle.markBusy();
|
|
207
|
+
return idle;
|
|
208
|
+
}
|
|
397
209
|
|
|
398
|
-
|
|
210
|
+
// Queue if all busy
|
|
211
|
+
return new Promise((resolve) => {
|
|
212
|
+
this.queue.push(resolve);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
399
215
|
|
|
400
|
-
```javascript
|
|
401
|
-
class TaskToolInterface {
|
|
402
216
|
/**
|
|
403
|
-
*
|
|
404
|
-
* @param {string} agentType - 'explore' | 'task' | 'general-purpose'
|
|
217
|
+
* Fallback to Agent for complex tasks
|
|
405
218
|
* @param {Object} task
|
|
406
|
-
* @returns {Promise<Object>}
|
|
219
|
+
* @returns {Promise<Object>}
|
|
407
220
|
*/
|
|
408
|
-
async
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
221
|
+
async fallbackToAgent(task) {
|
|
222
|
+
console.log(`Worker failed, falling back to Agent for task ${task.id}`);
|
|
223
|
+
this.stats.fallbackToAgent++;
|
|
224
|
+
|
|
225
|
+
// Use more powerful model
|
|
226
|
+
const agent = new Agent({ model: 'claude-sonnet-4' });
|
|
227
|
+
return await agent.execute(task);
|
|
228
|
+
}
|
|
415
229
|
}
|
|
416
230
|
```
|
|
417
231
|
|
|
418
|
-
**Usage:**
|
|
419
|
-
|
|
420
|
-
```javascript
|
|
421
|
-
const router = new TaskRouter();
|
|
422
|
-
|
|
423
|
-
const task = {
|
|
424
|
-
type: 'analyze_codebase',
|
|
425
|
-
description: 'Find all authentication patterns',
|
|
426
|
-
context: {...}
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
const result = await router.route(task);
|
|
430
|
-
```
|
|
431
|
-
|
|
432
232
|
---
|
|
433
233
|
|
|
434
|
-
##
|
|
435
|
-
|
|
436
|
-
**Location:** `src/byan-v2/generation/`
|
|
437
|
-
|
|
438
|
-
**Responsabilité:** Génération et validation des profils d'agents
|
|
439
|
-
|
|
440
|
-
### Modules
|
|
441
|
-
|
|
442
|
-
#### 3.1 ProfileTemplate (`profile-template.js`)
|
|
443
|
-
|
|
444
|
-
**Rôle:** Gestion des templates markdown pour agents
|
|
445
|
-
|
|
446
|
-
**Capabilities:**
|
|
447
|
-
- Load templates from filesystem
|
|
448
|
-
- Render templates avec placeholders
|
|
449
|
-
- Support multiple template types
|
|
450
|
-
- Validation syntaxe markdown
|
|
451
|
-
|
|
452
|
-
**Template Format:**
|
|
453
|
-
|
|
454
|
-
```markdown
|
|
455
|
-
---
|
|
456
|
-
name: {{agent_name}}
|
|
457
|
-
description: "{{agent_description}}"
|
|
458
|
-
version: "{{agent_version}}"
|
|
459
|
-
---
|
|
460
|
-
|
|
461
|
-
# {{agent_title}}
|
|
462
|
-
|
|
463
|
-
## Persona
|
|
464
|
-
|
|
465
|
-
{{agent_persona}}
|
|
466
|
-
|
|
467
|
-
## Capabilities
|
|
234
|
+
## Complexity Scoring
|
|
468
235
|
|
|
469
|
-
|
|
470
|
-
- {{this}}
|
|
471
|
-
{{/each}}
|
|
472
|
-
|
|
473
|
-
## Knowledge Base
|
|
474
|
-
|
|
475
|
-
{{agent_knowledge}}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
**API:**
|
|
236
|
+
### Algorithm
|
|
479
237
|
|
|
480
238
|
```javascript
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Load template from file
|
|
486
|
-
* @param {string} templateName
|
|
487
|
-
*/
|
|
488
|
-
loadTemplate(templateName: string): void;
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Render template with data
|
|
492
|
-
* @param {Object} data
|
|
493
|
-
* @returns {string} Rendered markdown
|
|
494
|
-
*/
|
|
495
|
-
render(data: Object): string;
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* List available templates
|
|
499
|
-
* @returns {Array<string>}
|
|
500
|
-
*/
|
|
501
|
-
listTemplates(): Array<string>;
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Validate template syntax
|
|
505
|
-
* @returns {boolean}
|
|
506
|
-
*/
|
|
507
|
-
validate(): boolean;
|
|
508
|
-
}
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
**Usage:**
|
|
239
|
+
function calculateComplexity(task) {
|
|
240
|
+
let score = 0;
|
|
512
241
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const profile = template.render({
|
|
518
|
-
agent_name: 'code-reviewer',
|
|
519
|
-
agent_description: 'Code review assistant',
|
|
520
|
-
agent_version: '1.0.0',
|
|
521
|
-
capabilities: ['Review JS', 'Security checks'],
|
|
522
|
-
agent_knowledge: 'OWASP Top 10, ES2024'
|
|
523
|
-
});
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
#### 3.2 AgentProfileValidator (`agent-profile-validator.js`)
|
|
242
|
+
// Input length
|
|
243
|
+
if (task.input.length > 1000) score += 20;
|
|
244
|
+
else if (task.input.length > 500) score += 10;
|
|
527
245
|
|
|
528
|
-
|
|
246
|
+
// Task type
|
|
247
|
+
const complexTypes = ['analysis', 'reasoning', 'creation'];
|
|
248
|
+
if (complexTypes.includes(task.type)) score += 30;
|
|
529
249
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
- Check required fields
|
|
533
|
-
- Enforce naming conventions
|
|
534
|
-
- Detect emoji pollution (Mantra IA-23)
|
|
535
|
-
- SDK compliance verification
|
|
250
|
+
// Context required
|
|
251
|
+
if (task.contextSize > 5000) score += 20;
|
|
536
252
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
```javascript
|
|
540
|
-
const rules = {
|
|
541
|
-
frontmatter: {
|
|
542
|
-
required: ['name', 'description', 'version'],
|
|
543
|
-
optional: ['icon', 'tags', 'dependencies']
|
|
544
|
-
},
|
|
545
|
-
name: {
|
|
546
|
-
pattern: /^[a-z][a-z0-9-]*[a-z0-9]$/,
|
|
547
|
-
minLength: 3,
|
|
548
|
-
maxLength: 50
|
|
549
|
-
},
|
|
550
|
-
description: {
|
|
551
|
-
minLength: 20,
|
|
552
|
-
maxLength: 200
|
|
553
|
-
},
|
|
554
|
-
version: {
|
|
555
|
-
pattern: /^\d+\.\d+\.\d+$/
|
|
556
|
-
},
|
|
557
|
-
emojiPollution: {
|
|
558
|
-
allowedSections: ['user_docs'], // Only in user-facing docs
|
|
559
|
-
technicalSections: ['yaml', 'code', 'metadata'] // Zero tolerance
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
```
|
|
253
|
+
// Multi-step
|
|
254
|
+
if (task.steps && task.steps.length > 3) score += 15;
|
|
563
255
|
|
|
564
|
-
|
|
256
|
+
// Output structure
|
|
257
|
+
if (task.outputFormat === 'complex') score += 15;
|
|
565
258
|
|
|
566
|
-
|
|
567
|
-
class AgentProfileValidator {
|
|
568
|
-
/**
|
|
569
|
-
* Validate complete profile
|
|
570
|
-
* @param {string} profilePath
|
|
571
|
-
* @returns {Promise<Object>} Validation result
|
|
572
|
-
*/
|
|
573
|
-
async validateProfile(profilePath: string): Promise<Object>;
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* Validate frontmatter only
|
|
577
|
-
* @param {Object} frontmatter
|
|
578
|
-
* @returns {Object} Result
|
|
579
|
-
*/
|
|
580
|
-
validateFrontmatter(frontmatter: Object): Object;
|
|
581
|
-
|
|
582
|
-
/**
|
|
583
|
-
* Check emoji pollution (Mantra IA-23)
|
|
584
|
-
* @param {string} content
|
|
585
|
-
* @returns {Array} Violations
|
|
586
|
-
*/
|
|
587
|
-
detectEmojiPollution(content: string): Array;
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Verify SDK compliance
|
|
591
|
-
* @param {string} profile
|
|
592
|
-
* @returns {boolean}
|
|
593
|
-
*/
|
|
594
|
-
verifySdkCompliance(profile: string): boolean;
|
|
259
|
+
return score;
|
|
595
260
|
}
|
|
596
261
|
```
|
|
597
262
|
|
|
598
|
-
|
|
263
|
+
### Routing Logic
|
|
599
264
|
|
|
600
265
|
```javascript
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
266
|
+
const score = calculateComplexity(task);
|
|
267
|
+
|
|
268
|
+
if (score < 30) {
|
|
269
|
+
// Simple task → Worker (gpt-5-mini)
|
|
270
|
+
await workerPool.executeTask(task);
|
|
271
|
+
} else if (score < 60) {
|
|
272
|
+
// Medium task → Worker with Agent fallback
|
|
273
|
+
await workerPool.executeTask({
|
|
274
|
+
...task,
|
|
275
|
+
fallbackToAgent: true
|
|
276
|
+
});
|
|
607
277
|
} else {
|
|
608
|
-
|
|
609
|
-
|
|
278
|
+
// Complex task → Agent directly (claude-sonnet)
|
|
279
|
+
await agent.execute(task);
|
|
610
280
|
}
|
|
611
281
|
```
|
|
612
282
|
|
|
613
283
|
---
|
|
614
284
|
|
|
615
|
-
##
|
|
616
|
-
|
|
617
|
-
**Location:** `src/byan-v2/orchestrator/`
|
|
618
|
-
|
|
619
|
-
**Responsabilité:** Orchestration des états et workflow BYAN
|
|
285
|
+
## Worker Lifecycle
|
|
620
286
|
|
|
621
|
-
###
|
|
287
|
+
### States
|
|
622
288
|
|
|
623
|
-
#### 4.1 StateMachine (`state-machine.js`)
|
|
624
|
-
|
|
625
|
-
**Rôle:** Machine à états pour workflow BYAN
|
|
626
|
-
|
|
627
|
-
**States:**
|
|
628
289
|
```
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
290
|
+
IDLE → BUSY → IDLE (success)
|
|
291
|
+
↓
|
|
292
|
+
FAILED → RETRY → IDLE (success)
|
|
293
|
+
↓
|
|
294
|
+
FALLBACK_TO_AGENT
|
|
632
295
|
```
|
|
633
296
|
|
|
634
|
-
|
|
297
|
+
### Flow
|
|
635
298
|
|
|
636
299
|
```javascript
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
INTERVIEW: ['ANALYSIS', 'ERROR'],
|
|
640
|
-
ANALYSIS: ['GENERATION', 'ERROR'],
|
|
641
|
-
GENERATION: ['COMPLETED', 'ERROR'],
|
|
642
|
-
COMPLETED: [],
|
|
643
|
-
ERROR: ['INIT'] // Restart
|
|
644
|
-
};
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
**API:**
|
|
648
|
-
|
|
649
|
-
```javascript
|
|
650
|
-
class StateMachine {
|
|
651
|
-
constructor(initialState?: string);
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* Get current state
|
|
655
|
-
* @returns {string}
|
|
656
|
-
*/
|
|
657
|
-
getCurrentState(): string;
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* Transition to new state
|
|
661
|
-
* @param {string} newState
|
|
662
|
-
* @throws {Error} If transition invalid
|
|
663
|
-
*/
|
|
664
|
-
transition(newState: string): void;
|
|
665
|
-
|
|
666
|
-
/**
|
|
667
|
-
* Check if transition valid
|
|
668
|
-
* @param {string} targetState
|
|
669
|
-
* @returns {boolean}
|
|
670
|
-
*/
|
|
671
|
-
canTransition(targetState: string): boolean;
|
|
672
|
-
|
|
673
|
-
/**
|
|
674
|
-
* Get state history
|
|
675
|
-
* @returns {Array}
|
|
676
|
-
*/
|
|
677
|
-
getHistory(): Array;
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* Reset to initial state
|
|
681
|
-
*/
|
|
682
|
-
reset(): void;
|
|
683
|
-
}
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
**Usage:**
|
|
687
|
-
|
|
688
|
-
```javascript
|
|
689
|
-
const sm = new StateMachine('INIT');
|
|
690
|
-
|
|
691
|
-
sm.transition('INTERVIEW'); // Valid
|
|
692
|
-
console.log(sm.getCurrentState()); // 'INTERVIEW'
|
|
300
|
+
// 1. Worker allocated from pool
|
|
301
|
+
const worker = await pool.getAvailableWorker();
|
|
693
302
|
|
|
694
|
-
|
|
695
|
-
|
|
303
|
+
// 2. Worker executes task
|
|
304
|
+
worker.markBusy();
|
|
305
|
+
const result = await worker.callLLM(task);
|
|
696
306
|
|
|
697
|
-
|
|
307
|
+
// 3. Worker released back to pool
|
|
308
|
+
worker.markIdle();
|
|
309
|
+
pool.releaseWorker(worker);
|
|
698
310
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
2. BUSINESS (Q4-Q6)
|
|
704
|
-
3. AGENT_NEEDS (Q7-Q9)
|
|
705
|
-
4. VALIDATION (Q10-Q12)
|
|
706
|
-
|
|
707
|
-
**API:**
|
|
708
|
-
|
|
709
|
-
```javascript
|
|
710
|
-
class InterviewState {
|
|
711
|
-
constructor(sessionState);
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Ask next question
|
|
715
|
-
* @returns {Object|null} Question or null if complete
|
|
716
|
-
*/
|
|
717
|
-
askNextQuestion(): Object|null;
|
|
718
|
-
|
|
719
|
-
/**
|
|
720
|
-
* Process user response
|
|
721
|
-
* @param {string} response
|
|
722
|
-
* @returns {boolean} Interview complete?
|
|
723
|
-
*/
|
|
724
|
-
processResponse(response: string): boolean;
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* Check if phase complete
|
|
728
|
-
* @param {string} phase
|
|
729
|
-
* @returns {boolean}
|
|
730
|
-
*/
|
|
731
|
-
isPhaseComplete(phase: string): boolean;
|
|
732
|
-
|
|
733
|
-
/**
|
|
734
|
-
* Check if can transition to ANALYSIS
|
|
735
|
-
* @returns {boolean}
|
|
736
|
-
*/
|
|
737
|
-
canTransitionToAnalysis(): boolean;
|
|
738
|
-
|
|
739
|
-
/**
|
|
740
|
-
* Get all responses
|
|
741
|
-
* @returns {Object} Responses by phase
|
|
742
|
-
*/
|
|
743
|
-
getAllResponses(): Object;
|
|
311
|
+
// 4. If failed and fallback enabled
|
|
312
|
+
if (failed && task.fallbackToAgent) {
|
|
313
|
+
const agent = new Agent();
|
|
314
|
+
return await agent.execute(task);
|
|
744
315
|
}
|
|
745
316
|
```
|
|
746
317
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
#### 4.3 AnalysisState (`analysis-state.js`)
|
|
750
|
-
|
|
751
|
-
**Rôle:** Analyse des réponses interview pour extraire concepts
|
|
318
|
+
---
|
|
752
319
|
|
|
753
|
-
|
|
754
|
-
- Extract key concepts from responses
|
|
755
|
-
- Identify agent type (code-review, test-automation, etc.)
|
|
756
|
-
- Detect knowledge domains
|
|
757
|
-
- Map capabilities to implementations
|
|
758
|
-
- Identify gaps in requirements
|
|
320
|
+
## Monitoring & Observability
|
|
759
321
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
```javascript
|
|
763
|
-
class AnalysisState {
|
|
764
|
-
constructor(interviewResponses);
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* Analyze interview responses
|
|
768
|
-
* @returns {Promise<Object>} Analysis result
|
|
769
|
-
*/
|
|
770
|
-
async analyze(): Promise<Object>;
|
|
771
|
-
|
|
772
|
-
/**
|
|
773
|
-
* Extract concepts from text
|
|
774
|
-
* @param {string} text
|
|
775
|
-
* @returns {Array<string>}
|
|
776
|
-
*/
|
|
777
|
-
extractConcepts(text: string): Array<string>;
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* Identify agent type
|
|
781
|
-
* @returns {string} Agent type
|
|
782
|
-
*/
|
|
783
|
-
identifyAgentType(): string;
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* Identify gaps in requirements
|
|
787
|
-
* @returns {Array<string>}
|
|
788
|
-
*/
|
|
789
|
-
identifyGaps(): Array<string>;
|
|
790
|
-
|
|
791
|
-
/**
|
|
792
|
-
* Generate recommendations
|
|
793
|
-
* @returns {Array<Object>}
|
|
794
|
-
*/
|
|
795
|
-
recommend(): Array<Object>;
|
|
796
|
-
}
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
**Analysis Output:**
|
|
322
|
+
### Metrics Tracked
|
|
800
323
|
|
|
801
324
|
```javascript
|
|
802
325
|
{
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
],
|
|
811
|
-
gaps: ['No mention of automated testing'],
|
|
812
|
-
recommendations: [
|
|
813
|
-
{ type: 'add_capability', value: 'integrate-with-ci' },
|
|
814
|
-
{ type: 'add_knowledge', value: 'WCAG-accessibility' }
|
|
815
|
-
]
|
|
326
|
+
total: 1000, // Total tasks
|
|
327
|
+
success: 850, // Successful
|
|
328
|
+
failed: 50, // Failed
|
|
329
|
+
fallbackToAgent: 100, // Escalated to agent
|
|
330
|
+
avgDuration: 1200, // Average ms
|
|
331
|
+
totalCost: 0.255, // Total $
|
|
332
|
+
avgCostPerTask: 0.000255 // Average $/task
|
|
816
333
|
}
|
|
817
334
|
```
|
|
818
335
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
**Rôle:** Génération du profil agent final
|
|
822
|
-
|
|
823
|
-
**Capabilities:**
|
|
824
|
-
- Map analysis to template data
|
|
825
|
-
- Select appropriate template
|
|
826
|
-
- Render profile
|
|
827
|
-
- Validate generated profile
|
|
828
|
-
- Save to filesystem
|
|
829
|
-
|
|
830
|
-
**API:**
|
|
336
|
+
### Cost Breakdown
|
|
831
337
|
|
|
832
338
|
```javascript
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
/**
|
|
837
|
-
* Generate agent profile
|
|
838
|
-
* @returns {Promise<string>} Generated profile content
|
|
839
|
-
*/
|
|
840
|
-
async generateProfile(): Promise<string>;
|
|
841
|
-
|
|
842
|
-
/**
|
|
843
|
-
* Select template based on analysis
|
|
844
|
-
* @returns {string} Template name
|
|
845
|
-
*/
|
|
846
|
-
selectTemplate(): string;
|
|
847
|
-
|
|
848
|
-
/**
|
|
849
|
-
* Map analysis to template data
|
|
850
|
-
* @returns {Object} Template variables
|
|
851
|
-
*/
|
|
852
|
-
mapToTemplateData(): Object;
|
|
853
|
-
|
|
854
|
-
/**
|
|
855
|
-
* Save profile to file
|
|
856
|
-
* @param {string} content
|
|
857
|
-
* @returns {Promise<string>} File path
|
|
858
|
-
*/
|
|
859
|
-
async saveProfile(content: string): Promise<string>;
|
|
860
|
-
}
|
|
861
|
-
```
|
|
339
|
+
// Worker calls
|
|
340
|
+
workerCalls = 850;
|
|
341
|
+
workerCost = 850 × 0.0003$ = 0.255$;
|
|
862
342
|
|
|
863
|
-
|
|
343
|
+
// Agent fallback calls
|
|
344
|
+
agentCalls = 100;
|
|
345
|
+
agentCost = 100 × 0.003$ = 0.30$;
|
|
864
346
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
const genState = new GenerationState(analysisResult, config);
|
|
868
|
-
const profile = await genState.generateProfile();
|
|
347
|
+
// Total
|
|
348
|
+
totalCost = 0.255$ + 0.30$ = 0.555$;
|
|
869
349
|
|
|
870
|
-
//
|
|
871
|
-
|
|
350
|
+
// vs All Agent approach
|
|
351
|
+
allAgentCost = 950 × 0.003$ = 2.85$;
|
|
352
|
+
|
|
353
|
+
// Savings
|
|
354
|
+
savings = (2.85$ - 0.555$) / 2.85$ = 80.5%
|
|
872
355
|
```
|
|
873
356
|
|
|
874
357
|
---
|
|
875
358
|
|
|
876
|
-
##
|
|
877
|
-
|
|
878
|
-
**Location:** `src/byan-v2/observability/`
|
|
879
|
-
|
|
880
|
-
**Responsabilité:** Logging, métriques, error tracking
|
|
881
|
-
|
|
882
|
-
### Modules
|
|
883
|
-
|
|
884
|
-
#### 5.1 Logger (`logger.js`)
|
|
885
|
-
|
|
886
|
-
**Rôle:** Structured logging for all workers
|
|
887
|
-
|
|
888
|
-
**Levels:** DEBUG, INFO, WARN, ERROR
|
|
359
|
+
## Configuration
|
|
889
360
|
|
|
890
|
-
|
|
361
|
+
### Worker Pool Config
|
|
891
362
|
|
|
892
|
-
```
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
363
|
+
```yaml
|
|
364
|
+
# config/worker-pool.yaml
|
|
365
|
+
workerPool:
|
|
366
|
+
size: 2
|
|
367
|
+
model: gpt-5-mini
|
|
368
|
+
timeout: 30000
|
|
369
|
+
maxRetries: 3
|
|
370
|
+
retryDelay: 1000
|
|
900
371
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
setLevel(level: string): void;
|
|
906
|
-
}
|
|
372
|
+
fallback:
|
|
373
|
+
enabled: true
|
|
374
|
+
model: claude-sonnet-4
|
|
375
|
+
threshold: 2 # Fallback after 2 failures
|
|
907
376
|
```
|
|
908
377
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
```json
|
|
912
|
-
{
|
|
913
|
-
"timestamp": "2026-02-07T12:00:00.000Z",
|
|
914
|
-
"level": "INFO",
|
|
915
|
-
"namespace": "orchestrator.interview",
|
|
916
|
-
"message": "Question asked",
|
|
917
|
-
"context": {
|
|
918
|
-
"phase": "CONTEXT",
|
|
919
|
-
"questionNumber": 1
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
```
|
|
923
|
-
|
|
924
|
-
#### 5.2 MetricsCollector (`metrics-collector.js`)
|
|
925
|
-
|
|
926
|
-
**Rôle:** Collecte et agrégation de métriques
|
|
927
|
-
|
|
928
|
-
**Metrics:**
|
|
929
|
-
- Session count
|
|
930
|
-
- Average questions per session
|
|
931
|
-
- Success rate
|
|
932
|
-
- Delegation rate
|
|
933
|
-
- Average duration
|
|
934
|
-
|
|
935
|
-
**API:**
|
|
378
|
+
### Model Selection
|
|
936
379
|
|
|
937
380
|
```javascript
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
*/
|
|
952
|
-
increment(name: string, tags?: Object): void;
|
|
953
|
-
|
|
954
|
-
/**
|
|
955
|
-
* Get metric summary
|
|
956
|
-
* @param {string} name
|
|
957
|
-
* @returns {Object} Stats
|
|
958
|
-
*/
|
|
959
|
-
getSummary(name: string): Object;
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
* Export all metrics
|
|
963
|
-
* @returns {Object}
|
|
964
|
-
*/
|
|
965
|
-
export(): Object;
|
|
966
|
-
}
|
|
967
|
-
```
|
|
968
|
-
|
|
969
|
-
#### 5.3 ErrorTracker (`error-tracker.js`)
|
|
970
|
-
|
|
971
|
-
**Rôle:** Track and analyze errors
|
|
972
|
-
|
|
973
|
-
**API:**
|
|
381
|
+
// Available models for workers
|
|
382
|
+
const WORKER_MODELS = {
|
|
383
|
+
'gpt-5-mini': {
|
|
384
|
+
cost: 0.0003,
|
|
385
|
+
contextWindow: 128000,
|
|
386
|
+
speed: 'fast'
|
|
387
|
+
},
|
|
388
|
+
'claude-haiku': {
|
|
389
|
+
cost: 0.0005,
|
|
390
|
+
contextWindow: 200000,
|
|
391
|
+
speed: 'fast'
|
|
392
|
+
}
|
|
393
|
+
};
|
|
974
394
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
getStats(): Object;
|
|
989
|
-
|
|
990
|
-
/**
|
|
991
|
-
* Get recent errors
|
|
992
|
-
* @param {number} limit
|
|
993
|
-
* @returns {Array}
|
|
994
|
-
*/
|
|
995
|
-
getRecent(limit: number): Array;
|
|
996
|
-
}
|
|
395
|
+
// Available models for agents
|
|
396
|
+
const AGENT_MODELS = {
|
|
397
|
+
'claude-sonnet-4': {
|
|
398
|
+
cost: 0.003,
|
|
399
|
+
contextWindow: 200000,
|
|
400
|
+
speed: 'medium'
|
|
401
|
+
},
|
|
402
|
+
'claude-opus-4': {
|
|
403
|
+
cost: 0.015,
|
|
404
|
+
contextWindow: 200000,
|
|
405
|
+
speed: 'slow'
|
|
406
|
+
}
|
|
407
|
+
};
|
|
997
408
|
```
|
|
998
409
|
|
|
999
410
|
---
|
|
1000
411
|
|
|
1001
|
-
##
|
|
1002
|
-
|
|
1003
|
-
**Location:** `src/byan-v2/integration/`
|
|
1004
|
-
|
|
1005
|
-
**Responsabilité:** Intégrations avec systèmes externes
|
|
1006
|
-
|
|
1007
|
-
**Status:** Module présent, implémentations futures
|
|
1008
|
-
|
|
1009
|
-
**Planned Integrations:**
|
|
1010
|
-
- GitHub API (import agents from repos)
|
|
1011
|
-
- NPM registry (import from packages)
|
|
1012
|
-
- Claude/OpenAI (advanced analysis)
|
|
1013
|
-
- Vector DB (knowledge base)
|
|
412
|
+
## Best Practices
|
|
1014
413
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
## Architecture & Communication
|
|
414
|
+
### When to Use Workers
|
|
1018
415
|
|
|
1019
|
-
|
|
416
|
+
✅ **Use Workers for:**
|
|
417
|
+
- Format validation
|
|
418
|
+
- Data extraction
|
|
419
|
+
- Simple transformations
|
|
420
|
+
- JSON parsing/generation
|
|
421
|
+
- String operations
|
|
422
|
+
- Template filling
|
|
1020
423
|
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
this.stateMachine = new StateMachine('INIT');
|
|
1029
|
-
this.logger = new Logger('byan-v2');
|
|
1030
|
-
this.metrics = new MetricsCollector();
|
|
1031
|
-
|
|
1032
|
-
// Orchestrator workers
|
|
1033
|
-
this.interviewState = new InterviewState(this.sessionState);
|
|
1034
|
-
this.analysisState = new AnalysisState();
|
|
1035
|
-
this.generationState = new GenerationState();
|
|
1036
|
-
|
|
1037
|
-
// Dispatcher workers
|
|
1038
|
-
this.taskRouter = new TaskRouter(config);
|
|
1039
|
-
|
|
1040
|
-
// Generation workers
|
|
1041
|
-
this.profileTemplate = new ProfileTemplate();
|
|
1042
|
-
this.validator = new AgentProfileValidator();
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
async startSession() {
|
|
1046
|
-
// 1. Context: Initialize session
|
|
1047
|
-
this.sessionState.initialize();
|
|
1048
|
-
|
|
1049
|
-
// 2. Orchestrator: Transition to INTERVIEW
|
|
1050
|
-
this.stateMachine.transition('INTERVIEW');
|
|
1051
|
-
|
|
1052
|
-
// 3. Observability: Log & metrics
|
|
1053
|
-
this.logger.info('Session started');
|
|
1054
|
-
this.metrics.increment('sessions_started');
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
async getNextQuestion() {
|
|
1058
|
-
// Orchestrator: Ask question
|
|
1059
|
-
const question = this.interviewState.askNextQuestion();
|
|
1060
|
-
|
|
1061
|
-
// Observability: Log
|
|
1062
|
-
this.logger.debug('Question asked', { question });
|
|
1063
|
-
|
|
1064
|
-
return question;
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
async submitResponse(response) {
|
|
1068
|
-
// Context: Store response
|
|
1069
|
-
this.sessionState.addResponse(response);
|
|
1070
|
-
|
|
1071
|
-
// Dispatcher: Route if complex
|
|
1072
|
-
if (this.taskRouter.shouldDelegate(response)) {
|
|
1073
|
-
response = await this.taskRouter.route(response);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
// Orchestrator: Process response
|
|
1077
|
-
const complete = this.interviewState.processResponse(response);
|
|
1078
|
-
|
|
1079
|
-
// Transition if complete
|
|
1080
|
-
if (complete) {
|
|
1081
|
-
this.stateMachine.transition('ANALYSIS');
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
async generateProfile() {
|
|
1086
|
-
// Orchestrator: Analyze
|
|
1087
|
-
this.stateMachine.transition('ANALYSIS');
|
|
1088
|
-
const analysis = await this.analysisState.analyze(
|
|
1089
|
-
this.interviewState.getAllResponses()
|
|
1090
|
-
);
|
|
1091
|
-
|
|
1092
|
-
// Orchestrator: Generate
|
|
1093
|
-
this.stateMachine.transition('GENERATION');
|
|
1094
|
-
this.generationState = new GenerationState(analysis);
|
|
1095
|
-
const profile = await this.generationState.generateProfile();
|
|
1096
|
-
|
|
1097
|
-
// Generation: Validate
|
|
1098
|
-
const validation = await this.validator.validateProfile(profile);
|
|
1099
|
-
if (!validation.valid) {
|
|
1100
|
-
throw new Error('Invalid profile generated');
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
// Context: Save
|
|
1104
|
-
await this.sessionState.save();
|
|
1105
|
-
|
|
1106
|
-
// Orchestrator: Complete
|
|
1107
|
-
this.stateMachine.transition('COMPLETED');
|
|
1108
|
-
|
|
1109
|
-
// Observability: Metrics
|
|
1110
|
-
this.metrics.increment('profiles_generated');
|
|
1111
|
-
|
|
1112
|
-
return profile;
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
```
|
|
424
|
+
❌ **Don't Use Workers for:**
|
|
425
|
+
- Complex reasoning
|
|
426
|
+
- Multi-step analysis
|
|
427
|
+
- Code generation
|
|
428
|
+
- Architecture design
|
|
429
|
+
- Creative writing
|
|
430
|
+
- Decision making
|
|
1116
431
|
|
|
1117
|
-
###
|
|
432
|
+
### Optimization Tips
|
|
1118
433
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
ComplexityScorer (Dispatcher) → Analyze
|
|
1125
|
-
↓
|
|
1126
|
-
TaskRouter (Dispatcher) → Route
|
|
1127
|
-
↓
|
|
1128
|
-
LocalExecutor | TaskTool → Execute
|
|
1129
|
-
↓
|
|
1130
|
-
InterviewState (Orchestrator) → Process
|
|
1131
|
-
↓
|
|
1132
|
-
[Repeat until interview complete]
|
|
1133
|
-
↓
|
|
1134
|
-
AnalysisState (Orchestrator) → Extract concepts
|
|
1135
|
-
↓
|
|
1136
|
-
GenerationState (Orchestrator) → Select template
|
|
1137
|
-
↓
|
|
1138
|
-
ProfileTemplate (Generation) → Render
|
|
1139
|
-
↓
|
|
1140
|
-
AgentProfileValidator (Generation) → Validate
|
|
1141
|
-
↓
|
|
1142
|
-
SessionState (Context) → Save
|
|
1143
|
-
↓
|
|
1144
|
-
Logger/Metrics (Observability) → Track
|
|
1145
|
-
↓
|
|
1146
|
-
Agent Profile Output
|
|
1147
|
-
```
|
|
434
|
+
1. **Tune complexity thresholds** based on your use cases
|
|
435
|
+
2. **Monitor fallback rate** - high rate means threshold too low
|
|
436
|
+
3. **Batch simple tasks** to maximize worker utilization
|
|
437
|
+
4. **Cache common results** to avoid redundant calls
|
|
438
|
+
5. **Use async/await** properly to avoid blocking
|
|
1148
439
|
|
|
1149
440
|
---
|
|
1150
441
|
|
|
1151
|
-
##
|
|
442
|
+
## File Structure
|
|
1152
443
|
|
|
1153
|
-
Chaque worker a sa suite de tests:
|
|
1154
|
-
|
|
1155
|
-
```
|
|
1156
|
-
__tests__/byan-v2/
|
|
1157
|
-
├── context/
|
|
1158
|
-
│ ├── copilot-context.test.js
|
|
1159
|
-
│ └── session-state.test.js
|
|
1160
|
-
├── dispatcher/
|
|
1161
|
-
│ ├── complexity-scorer.test.js
|
|
1162
|
-
│ ├── task-router.test.js
|
|
1163
|
-
│ └── local-executor.test.js
|
|
1164
|
-
├── generation/
|
|
1165
|
-
│ ├── profile-template.test.js
|
|
1166
|
-
│ └── agent-profile-validator.test.js
|
|
1167
|
-
├── orchestrator/
|
|
1168
|
-
│ ├── state-machine.test.js
|
|
1169
|
-
│ ├── interview-state.test.js
|
|
1170
|
-
│ ├── analysis-state.test.js
|
|
1171
|
-
│ └── generation-state.test.js
|
|
1172
|
-
├── observability/
|
|
1173
|
-
│ ├── logger.test.js
|
|
1174
|
-
│ ├── metrics-collector.test.js
|
|
1175
|
-
│ └── error-tracker.test.js
|
|
1176
|
-
└── integration/
|
|
1177
|
-
└── full-flow.test.js
|
|
1178
444
|
```
|
|
445
|
+
_byan/
|
|
446
|
+
├── workers.md (this file)
|
|
447
|
+
└── workers/
|
|
448
|
+
└── launchers/
|
|
449
|
+
├── README.md
|
|
450
|
+
├── launch-yanstaller-copilot.md
|
|
451
|
+
├── launch-yanstaller-claude.md
|
|
452
|
+
└── launch-yanstaller-codex.md
|
|
1179
453
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
**File:** `_byan/config.yaml`
|
|
1187
|
-
|
|
1188
|
-
```yaml
|
|
1189
|
-
# Context Worker
|
|
1190
|
-
context:
|
|
1191
|
-
session_timeout: 1800 # 30 minutes
|
|
1192
|
-
auto_save: true
|
|
1193
|
-
backup_retention: 10
|
|
1194
|
-
|
|
1195
|
-
# Dispatcher Worker
|
|
1196
|
-
dispatcher:
|
|
1197
|
-
complexity_thresholds:
|
|
1198
|
-
low: 0.3
|
|
1199
|
-
medium: 0.6
|
|
1200
|
-
enable_delegation: true
|
|
1201
|
-
fallback_strategy: local
|
|
1202
|
-
|
|
1203
|
-
# Generation Worker
|
|
1204
|
-
generation:
|
|
1205
|
-
default_template: default-agent
|
|
1206
|
-
output_dir: _byan-output
|
|
1207
|
-
validate_on_generate: true
|
|
1208
|
-
|
|
1209
|
-
# Observability Worker
|
|
1210
|
-
observability:
|
|
1211
|
-
log_level: info # debug | info | warn | error
|
|
1212
|
-
metrics_enabled: true
|
|
1213
|
-
error_tracking: true
|
|
454
|
+
src/
|
|
455
|
+
└── core/
|
|
456
|
+
└── worker-pool/
|
|
457
|
+
├── worker-pool.js
|
|
458
|
+
├── worker.js
|
|
459
|
+
└── complexity-scorer.js
|
|
1214
460
|
```
|
|
1215
461
|
|
|
1216
462
|
---
|
|
1217
463
|
|
|
1218
|
-
##
|
|
464
|
+
## Related Documentation
|
|
1219
465
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
| Context | < 10ms | 50ms |
|
|
1225
|
-
| Dispatcher | < 100ms | 500ms |
|
|
1226
|
-
| Generation | < 200ms | 1s |
|
|
1227
|
-
| Orchestrator | < 50ms | 200ms |
|
|
1228
|
-
| Observability | < 1ms | 10ms |
|
|
1229
|
-
|
|
1230
|
-
**Total interview flow:** ~2 seconds (12 questions automated)
|
|
466
|
+
- **Worker Pool Implementation:** `src/core/worker-pool/worker-pool.js`
|
|
467
|
+
- **Dispatcher Logic:** `src/byan-v2/dispatcher/`
|
|
468
|
+
- **Launcher Workers:** `_byan/workers/launchers/README.md`
|
|
469
|
+
- **Architecture:** `_bmad-output/conception/01-vision-et-principes.md`
|
|
1231
470
|
|
|
1232
471
|
---
|
|
1233
472
|
|
|
1234
|
-
##
|
|
1235
|
-
|
|
1236
|
-
### Planned Enhancements
|
|
1237
|
-
|
|
1238
|
-
**Context Worker:**
|
|
1239
|
-
- [ ] Multi-user session support
|
|
1240
|
-
- [ ] Distributed session storage (Redis)
|
|
1241
|
-
- [ ] Session replay for debugging
|
|
1242
|
-
|
|
1243
|
-
**Dispatcher Worker:**
|
|
1244
|
-
- [ ] ML-based complexity scoring
|
|
1245
|
-
- [ ] Adaptive routing based on feedback
|
|
1246
|
-
- [ ] Parallel task execution
|
|
1247
|
-
|
|
1248
|
-
**Generation Worker:**
|
|
1249
|
-
- [ ] Multi-language templates (FR, ES, DE)
|
|
1250
|
-
- [ ] Custom template creation wizard
|
|
1251
|
-
- [ ] Agent versioning system
|
|
473
|
+
## Summary
|
|
1252
474
|
|
|
1253
|
-
**
|
|
1254
|
-
- [ ] Workflow branching (conditional paths)
|
|
1255
|
-
- [ ] Resume interrupted sessions
|
|
1256
|
-
- [ ] Collaborative interviews
|
|
475
|
+
**Workers = Lightweight LLM agents for simple tasks**
|
|
1257
476
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
477
|
+
```
|
|
478
|
+
┌─────────────────────────────────────────────────┐
|
|
479
|
+
│ BYAN v2 Task Execution │
|
|
480
|
+
│ │
|
|
481
|
+
│ Simple Task (score < 30) │
|
|
482
|
+
│ → Worker Pool (gpt-5-mini, 0.0003$) │
|
|
483
|
+
│ │
|
|
484
|
+
│ Medium Task (30 ≤ score < 60) │
|
|
485
|
+
│ → Worker Pool with Agent fallback │
|
|
486
|
+
│ │
|
|
487
|
+
│ Complex Task (score ≥ 60) │
|
|
488
|
+
│ → Agent directly (claude-sonnet, 0.003$) │
|
|
489
|
+
│ │
|
|
490
|
+
│ Result: 54-80% cost reduction │
|
|
491
|
+
└─────────────────────────────────────────────────┘
|
|
492
|
+
```
|
|
1271
493
|
|
|
1272
|
-
|
|
1273
|
-
- Workflows: `_byan/workflows/`
|
|
1274
|
-
- Tests: `__tests__/byan-v2/`
|
|
1275
|
-
- Config: `_byan/config.yaml`
|
|
494
|
+
**Key Principle:** Right model for right task = optimal cost/performance
|
|
1276
495
|
|
|
1277
496
|
---
|
|
1278
497
|
|
|
1279
|
-
**
|
|
1280
|
-
**Test Coverage:** 881/881 (100%)
|
|
498
|
+
**Maintainer:** BYAN Core Team
|
|
1281
499
|
**Version:** 2.0.0
|
|
1282
|
-
**
|
|
1283
|
-
**Maintainer:** BYAN v2 Team
|
|
500
|
+
**Status:** ✅ Production Ready
|