sigma-agents 0.1.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.
@@ -0,0 +1,5 @@
1
+ export { SmartRouter } from './router';
2
+ export { ModelProfiler } from './profiles';
3
+ export { SubAgentManager } from './sub-agent';
4
+ export * from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.SubAgentManager = exports.ModelProfiler = exports.SmartRouter = void 0;
18
+ var router_1 = require("./router");
19
+ Object.defineProperty(exports, "SmartRouter", { enumerable: true, get: function () { return router_1.SmartRouter; } });
20
+ var profiles_1 = require("./profiles");
21
+ Object.defineProperty(exports, "ModelProfiler", { enumerable: true, get: function () { return profiles_1.ModelProfiler; } });
22
+ var sub_agent_1 = require("./sub-agent");
23
+ Object.defineProperty(exports, "SubAgentManager", { enumerable: true, get: function () { return sub_agent_1.SubAgentManager; } });
24
+ __exportStar(require("./types"), exports);
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AACpB,uCAA2C;AAAlC,yGAAA,aAAa,OAAA;AACtB,yCAA8C;AAArC,4GAAA,eAAe,OAAA;AACxB,0CAAwB"}
@@ -0,0 +1,29 @@
1
+ import { ModelProfile, TaskCategory } from './types';
2
+ export declare class ModelProfiler {
3
+ profiles: Map<string, ModelProfile>;
4
+ /**
5
+ * Charge les profiles depuis un fichier JSON
6
+ */
7
+ loadFromFile(path: string): Promise<void>;
8
+ /**
9
+ * Sauvegarde les profiles vers un fichier JSON
10
+ */
11
+ saveToFile(path: string): Promise<void>;
12
+ /**
13
+ * Ajoute un profile
14
+ */
15
+ addProfile(profile: ModelProfile): void;
16
+ /**
17
+ * Retourne le meilleur modèle pour une tâche donnée
18
+ */
19
+ getBestForTask(category: TaskCategory): ModelProfile | null;
20
+ /**
21
+ * Charge les profiles par défaut des modèles Alibaba
22
+ */
23
+ private loadDefaultProfiles;
24
+ /**
25
+ * Retourne les profiles par défaut des 8 modèles Alibaba
26
+ */
27
+ getDefaultProfiles(): ModelProfile[];
28
+ }
29
+ //# sourceMappingURL=profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGrD,qBAAa,aAAa;IACjB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAa;IAEvD;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB/C;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIvC;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI;IAqB3D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,kBAAkB,IAAI,YAAY,EAAE;CAoFrC"}
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModelProfiler = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ class ModelProfiler {
6
+ profiles = new Map();
7
+ /**
8
+ * Charge les profiles depuis un fichier JSON
9
+ */
10
+ async loadFromFile(path) {
11
+ try {
12
+ const content = await (0, promises_1.readFile)(path, 'utf8');
13
+ const data = JSON.parse(content);
14
+ if (Array.isArray(data.profiles)) {
15
+ this.profiles.clear();
16
+ for (const profile of data.profiles) {
17
+ this.profiles.set(profile.id, profile);
18
+ }
19
+ }
20
+ }
21
+ catch (error) {
22
+ // Si le fichier n'existe pas, on utilise les profiles par défaut
23
+ console.warn(`Could not load profiles from ${path}:`, error);
24
+ this.loadDefaultProfiles();
25
+ }
26
+ }
27
+ /**
28
+ * Sauvegarde les profiles vers un fichier JSON
29
+ */
30
+ async saveToFile(path) {
31
+ const data = {
32
+ profiles: Array.from(this.profiles.values())
33
+ };
34
+ await (0, promises_1.writeFile)(path, JSON.stringify(data, null, 2), 'utf8');
35
+ }
36
+ /**
37
+ * Ajoute un profile
38
+ */
39
+ addProfile(profile) {
40
+ this.profiles.set(profile.id, profile);
41
+ }
42
+ /**
43
+ * Retourne le meilleur modèle pour une tâche donnée
44
+ */
45
+ getBestForTask(category) {
46
+ const candidates = Array.from(this.profiles.values())
47
+ .filter(profile => profile.strengths.includes(category))
48
+ .sort((a, b) => {
49
+ // Priorité: quality > speed > cost
50
+ if (a.quality !== b.quality) {
51
+ const qualityOrder = { high: 3, medium: 2, low: 1 };
52
+ return qualityOrder[b.quality] - qualityOrder[a.quality];
53
+ }
54
+ if (a.speed !== b.speed) {
55
+ const speedOrder = { fast: 3, medium: 2, slow: 1 };
56
+ return speedOrder[b.speed] - speedOrder[a.speed];
57
+ }
58
+ return a.cost - b.cost; // Coût plus bas = mieux
59
+ });
60
+ return candidates[0] || null;
61
+ }
62
+ /**
63
+ * Charge les profiles par défaut des modèles Alibaba
64
+ */
65
+ loadDefaultProfiles() {
66
+ const defaultProfiles = this.getDefaultProfiles();
67
+ this.profiles.clear();
68
+ for (const profile of defaultProfiles) {
69
+ this.profiles.set(profile.id, profile);
70
+ }
71
+ }
72
+ /**
73
+ * Retourne les profiles par défaut des 8 modèles Alibaba
74
+ */
75
+ getDefaultProfiles() {
76
+ return [
77
+ {
78
+ id: 'qwen3.5-plus',
79
+ provider: 'alibaba',
80
+ cost: 0,
81
+ speed: 'medium',
82
+ quality: 'high',
83
+ strengths: ['code', 'debug', 'plan', 'review', 'general'],
84
+ maxTokens: 131072,
85
+ supportsTools: true
86
+ },
87
+ {
88
+ id: 'qwen3-max-2026-01-23',
89
+ provider: 'alibaba',
90
+ cost: 0,
91
+ speed: 'slow',
92
+ quality: 'high',
93
+ strengths: ['plan', 'debug', 'review'],
94
+ maxTokens: 131072,
95
+ supportsTools: true
96
+ },
97
+ {
98
+ id: 'qwen3-coder-plus',
99
+ provider: 'alibaba',
100
+ cost: 0,
101
+ speed: 'medium',
102
+ quality: 'high',
103
+ strengths: ['code', 'debug'],
104
+ maxTokens: 131072,
105
+ supportsTools: true
106
+ },
107
+ {
108
+ id: 'qwen3-coder-next',
109
+ provider: 'alibaba',
110
+ cost: 0,
111
+ speed: 'fast',
112
+ quality: 'high',
113
+ strengths: ['code'],
114
+ maxTokens: 131072,
115
+ supportsTools: true
116
+ },
117
+ {
118
+ id: 'kimi-k2.5',
119
+ provider: 'alibaba',
120
+ cost: 0,
121
+ speed: 'fast',
122
+ quality: 'medium',
123
+ strengths: ['explore', 'test', 'general'],
124
+ maxTokens: 131072,
125
+ supportsTools: true
126
+ },
127
+ {
128
+ id: 'glm-5',
129
+ provider: 'alibaba',
130
+ cost: 0,
131
+ speed: 'medium',
132
+ quality: 'medium',
133
+ strengths: ['general', 'code'],
134
+ maxTokens: 131072,
135
+ supportsTools: true
136
+ },
137
+ {
138
+ id: 'glm-4.7',
139
+ provider: 'alibaba',
140
+ cost: 0,
141
+ speed: 'fast',
142
+ quality: 'low',
143
+ strengths: ['explore', 'general'],
144
+ maxTokens: 131072,
145
+ supportsTools: true
146
+ },
147
+ {
148
+ id: 'MiniMax-M2.5',
149
+ provider: 'alibaba',
150
+ cost: 0,
151
+ speed: 'fast',
152
+ quality: 'medium',
153
+ strengths: ['general'],
154
+ maxTokens: 131072,
155
+ supportsTools: true
156
+ }
157
+ ];
158
+ }
159
+ }
160
+ exports.ModelProfiler = ModelProfiler;
161
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { RoutingConfig, TaskCategory } from './types';
2
+ export declare class SmartRouter {
3
+ private config;
4
+ constructor(config: RoutingConfig);
5
+ /**
6
+ * Analyse le prompt et retourne la catégorie de tâche
7
+ * Priorité : debug > code > plan > review > test > explore > general
8
+ */
9
+ classifyTask(prompt: string): TaskCategory;
10
+ /**
11
+ * Retourne le modèle et l'agent recommandés pour un prompt
12
+ */
13
+ getRecommendation(prompt: string): {
14
+ model: string;
15
+ agent: string | null;
16
+ category: TaskCategory;
17
+ };
18
+ /**
19
+ * Charge la configuration depuis un fichier JSON
20
+ */
21
+ static loadConfig(configPath: string): Promise<RoutingConfig>;
22
+ /**
23
+ * Configuration par défaut utilisant les modèles Alibaba Coding Plan
24
+ */
25
+ static defaultConfig(): RoutingConfig;
26
+ }
27
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGtD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAIjC;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IA+B1C;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE;IAmBlG;;OAEG;WACU,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAUnE;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,aAAa;CAoDtC"}
package/dist/router.js ADDED
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SmartRouter = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ class SmartRouter {
6
+ config;
7
+ constructor(config) {
8
+ this.config = config;
9
+ }
10
+ /**
11
+ * Analyse le prompt et retourne la catégorie de tâche
12
+ * Priorité : debug > code > plan > review > test > explore > general
13
+ */
14
+ classifyTask(prompt) {
15
+ const lowerPrompt = prompt.toLowerCase();
16
+ const categories = [];
17
+ // Vérifier chaque catégorie
18
+ for (const [category, route] of Object.entries(this.config.routes)) {
19
+ const hasKeyword = route.keywords.some(keyword => lowerPrompt.includes(keyword.toLowerCase()));
20
+ if (hasKeyword) {
21
+ categories.push(category);
22
+ }
23
+ }
24
+ if (categories.length === 0) {
25
+ return 'general';
26
+ }
27
+ // Appliquer les priorités
28
+ const priorityOrder = ['debug', 'code', 'plan', 'review', 'test', 'explore', 'general'];
29
+ for (const priority of priorityOrder) {
30
+ if (categories.includes(priority)) {
31
+ return priority;
32
+ }
33
+ }
34
+ return categories[0];
35
+ }
36
+ /**
37
+ * Retourne le modèle et l'agent recommandés pour un prompt
38
+ */
39
+ getRecommendation(prompt) {
40
+ const category = this.classifyTask(prompt);
41
+ const route = this.config.routes[category];
42
+ if (!route) {
43
+ return {
44
+ model: this.config.default.model,
45
+ agent: this.config.default.agent,
46
+ category
47
+ };
48
+ }
49
+ return {
50
+ model: route.preferredModel,
51
+ agent: route.agent,
52
+ category
53
+ };
54
+ }
55
+ /**
56
+ * Charge la configuration depuis un fichier JSON
57
+ */
58
+ static async loadConfig(configPath) {
59
+ try {
60
+ const content = await (0, promises_1.readFile)(configPath, 'utf8');
61
+ return JSON.parse(content);
62
+ }
63
+ catch (error) {
64
+ console.warn(`Could not load routing config from ${configPath}:`, error);
65
+ return SmartRouter.defaultConfig();
66
+ }
67
+ }
68
+ /**
69
+ * Configuration par défaut utilisant les modèles Alibaba Coding Plan
70
+ */
71
+ static defaultConfig() {
72
+ return {
73
+ routes: {
74
+ code: {
75
+ preferredModel: 'qwen3-coder-plus',
76
+ fallback: 'qwen3.5-plus',
77
+ agent: null,
78
+ keywords: ['code', 'implement', 'write', 'create', 'build', 'développer', 'coder', 'programmer', 'function', 'class', 'method']
79
+ },
80
+ debug: {
81
+ preferredModel: 'qwen3.5-plus',
82
+ fallback: 'qwen3-max-2026-01-23',
83
+ agent: null,
84
+ keywords: ['debug', 'fix', 'error', 'bug', 'broken', 'issue', 'problem', 'repair', 'correct', 'erreur', 'problème', 'réparer']
85
+ },
86
+ explore: {
87
+ preferredModel: 'kimi-k2.5',
88
+ fallback: 'glm-4.7',
89
+ agent: null,
90
+ keywords: ['explore', 'understand', 'analyze', 'examine', 'investigate', 'study', 'review', 'explorer', 'analyser', 'comprendre']
91
+ },
92
+ plan: {
93
+ preferredModel: 'qwen3-max-2026-01-23',
94
+ fallback: 'qwen3.5-plus',
95
+ agent: null,
96
+ keywords: ['plan', 'design', 'architecture', 'strategy', 'approach', 'structure', 'organize', 'concevoir', 'planifier', 'architecture']
97
+ },
98
+ test: {
99
+ preferredModel: 'kimi-k2.5',
100
+ fallback: 'qwen3-coder-next',
101
+ agent: null,
102
+ keywords: ['test', 'testing', 'unit', 'integration', 'verify', 'validate', 'check', 'tester', 'vérifier', 'valider']
103
+ },
104
+ review: {
105
+ preferredModel: 'qwen3.5-plus',
106
+ fallback: 'qwen3-max-2026-01-23',
107
+ agent: null,
108
+ keywords: ['review', 'audit', 'check', 'validate', 'quality', 'improve', 'optimize', 'réviser', 'améliorer', 'optimiser']
109
+ },
110
+ general: {
111
+ preferredModel: 'qwen3.5-plus',
112
+ fallback: 'glm-5',
113
+ agent: null,
114
+ keywords: ['help', 'explain', 'what', 'how', 'why', 'question', 'aide', 'expliquer', 'comment', 'pourquoi']
115
+ }
116
+ },
117
+ default: {
118
+ model: 'qwen3.5-plus',
119
+ agent: null
120
+ }
121
+ };
122
+ }
123
+ }
124
+ exports.SmartRouter = SmartRouter;
125
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { SubAgentConfig } from './types';
2
+ export declare class SubAgentManager {
3
+ private agents;
4
+ /**
5
+ * Charge les définitions d'agents depuis un répertoire
6
+ * Les fichiers .md doivent avoir un frontmatter YAML
7
+ */
8
+ loadAgentDefinitions(agentsDir: string): Promise<void>;
9
+ /**
10
+ * Retourne la liste des agents disponibles
11
+ */
12
+ getAvailableAgents(): SubAgentConfig[];
13
+ /**
14
+ * Construit la commande CLI pour spawner un sous-agent phi
15
+ */
16
+ createCommand(agent: SubAgentConfig, task: string): string[];
17
+ /**
18
+ * Parse un fichier markdown avec frontmatter YAML
19
+ * Format attendu :
20
+ * ---
21
+ * name: agent-name
22
+ * description: Agent description
23
+ * model: model-name
24
+ * tools: [tool1, tool2]
25
+ * maxTokens: 4096
26
+ * ---
27
+ *
28
+ * # System Prompt
29
+ *
30
+ * Le contenu après le frontmatter devient le system prompt...
31
+ */
32
+ parseAgentMarkdown(content: string): SubAgentConfig | null;
33
+ /**
34
+ * Récupère un agent par son nom
35
+ */
36
+ getAgent(name: string): SubAgentConfig | null;
37
+ /**
38
+ * Vérifie si un agent existe
39
+ */
40
+ hasAgent(name: string): boolean;
41
+ }
42
+ //# sourceMappingURL=sub-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent.d.ts","sourceRoot":"","sources":["../src/sub-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAIzC,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA0C;IAExD;;;OAGG;IACG,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB5D;;OAEG;IACH,kBAAkB,IAAI,cAAc,EAAE;IAItC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAa5D;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IA0E1D;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI7C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAGhC"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubAgentManager = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_path_1 = require("node:path");
6
+ class SubAgentManager {
7
+ agents = new Map();
8
+ /**
9
+ * Charge les définitions d'agents depuis un répertoire
10
+ * Les fichiers .md doivent avoir un frontmatter YAML
11
+ */
12
+ async loadAgentDefinitions(agentsDir) {
13
+ try {
14
+ const files = await (0, promises_1.readdir)(agentsDir);
15
+ const mdFiles = files.filter(file => file.endsWith('.md'));
16
+ this.agents.clear();
17
+ for (const file of mdFiles) {
18
+ try {
19
+ const filePath = (0, node_path_1.join)(agentsDir, file);
20
+ const content = await (0, promises_1.readFile)(filePath, 'utf8');
21
+ const agent = this.parseAgentMarkdown(content);
22
+ if (agent) {
23
+ this.agents.set(agent.name, agent);
24
+ }
25
+ }
26
+ catch (error) {
27
+ console.warn(`Could not parse agent file ${file}:`, error);
28
+ }
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.warn(`Could not load agent definitions from ${agentsDir}:`, error);
33
+ }
34
+ }
35
+ /**
36
+ * Retourne la liste des agents disponibles
37
+ */
38
+ getAvailableAgents() {
39
+ return Array.from(this.agents.values());
40
+ }
41
+ /**
42
+ * Construit la commande CLI pour spawner un sous-agent phi
43
+ */
44
+ createCommand(agent, task) {
45
+ return [
46
+ 'phi',
47
+ '--json',
48
+ '--model',
49
+ agent.model,
50
+ '--no-save',
51
+ '--system',
52
+ agent.systemPrompt,
53
+ task
54
+ ];
55
+ }
56
+ /**
57
+ * Parse un fichier markdown avec frontmatter YAML
58
+ * Format attendu :
59
+ * ---
60
+ * name: agent-name
61
+ * description: Agent description
62
+ * model: model-name
63
+ * tools: [tool1, tool2]
64
+ * maxTokens: 4096
65
+ * ---
66
+ *
67
+ * # System Prompt
68
+ *
69
+ * Le contenu après le frontmatter devient le system prompt...
70
+ */
71
+ parseAgentMarkdown(content) {
72
+ const lines = content.split('\n');
73
+ if (!lines[0]?.startsWith('---')) {
74
+ return null;
75
+ }
76
+ // Trouver la fin du frontmatter
77
+ let frontmatterEnd = -1;
78
+ for (let i = 1; i < lines.length; i++) {
79
+ if (lines[i] === '---') {
80
+ frontmatterEnd = i;
81
+ break;
82
+ }
83
+ }
84
+ if (frontmatterEnd === -1) {
85
+ return null;
86
+ }
87
+ // Extraire et parser le frontmatter YAML
88
+ const frontmatterLines = lines.slice(1, frontmatterEnd);
89
+ const frontmatter = {};
90
+ for (const line of frontmatterLines) {
91
+ const trimmed = line.trim();
92
+ if (!trimmed || trimmed.startsWith('#'))
93
+ continue;
94
+ const colonIndex = trimmed.indexOf(':');
95
+ if (colonIndex === -1)
96
+ continue;
97
+ const key = trimmed.substring(0, colonIndex).trim();
98
+ const valueStr = trimmed.substring(colonIndex + 1).trim();
99
+ // Parser la valeur
100
+ let value = valueStr;
101
+ // Arrays (format: [item1, item2])
102
+ if (valueStr.startsWith('[') && valueStr.endsWith(']')) {
103
+ const arrayContent = valueStr.slice(1, -1);
104
+ value = arrayContent.split(',').map(item => item.trim().replace(/['"]/g, ''));
105
+ }
106
+ // Numbers
107
+ else if (/^\d+$/.test(valueStr)) {
108
+ value = parseInt(valueStr, 10);
109
+ }
110
+ // Remove quotes from strings
111
+ else if ((valueStr.startsWith('"') && valueStr.endsWith('"')) ||
112
+ (valueStr.startsWith("'") && valueStr.endsWith("'"))) {
113
+ value = valueStr.slice(1, -1);
114
+ }
115
+ frontmatter[key] = value;
116
+ }
117
+ // Extraire le system prompt (contenu après le frontmatter)
118
+ const systemPromptLines = lines.slice(frontmatterEnd + 1);
119
+ const systemPrompt = systemPromptLines.join('\n').trim();
120
+ // Valider les champs requis
121
+ if (!frontmatter.name || !frontmatter.model || !systemPrompt) {
122
+ return null;
123
+ }
124
+ return {
125
+ name: frontmatter.name,
126
+ description: frontmatter.description || '',
127
+ model: frontmatter.model,
128
+ tools: Array.isArray(frontmatter.tools) ? frontmatter.tools : [],
129
+ systemPrompt,
130
+ maxTokens: frontmatter.maxTokens || undefined
131
+ };
132
+ }
133
+ /**
134
+ * Récupère un agent par son nom
135
+ */
136
+ getAgent(name) {
137
+ return this.agents.get(name) || null;
138
+ }
139
+ /**
140
+ * Vérifie si un agent existe
141
+ */
142
+ hasAgent(name) {
143
+ return this.agents.has(name);
144
+ }
145
+ }
146
+ exports.SubAgentManager = SubAgentManager;
147
+ //# sourceMappingURL=sub-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent.js","sourceRoot":"","sources":["../src/sub-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export type TaskCategory = 'code' | 'debug' | 'explore' | 'plan' | 'test' | 'review' | 'general';
2
+ export interface ModelProfile {
3
+ id: string;
4
+ provider: string;
5
+ cost: number;
6
+ speed: 'fast' | 'medium' | 'slow';
7
+ quality: 'high' | 'medium' | 'low';
8
+ strengths: TaskCategory[];
9
+ maxTokens: number;
10
+ supportsTools: boolean;
11
+ }
12
+ export interface RoutingConfig {
13
+ routes: Record<TaskCategory, {
14
+ preferredModel: string;
15
+ fallback: string;
16
+ agent: string | null;
17
+ keywords: string[];
18
+ }>;
19
+ default: {
20
+ model: string;
21
+ agent: string | null;
22
+ };
23
+ }
24
+ export interface SubAgentConfig {
25
+ name: string;
26
+ description: string;
27
+ model: string;
28
+ tools: string[];
29
+ systemPrompt: string;
30
+ maxTokens?: number;
31
+ }
32
+ export interface SubAgentResult {
33
+ agentName: string;
34
+ model: string;
35
+ output: string;
36
+ tokensUsed: number;
37
+ durationMs: number;
38
+ success: boolean;
39
+ error?: string;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjG,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC,CAAC;IACH,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAClD;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "sigma-agents",
3
+ "version": "0.1.0",
4
+ "description": "Intelligent sub-agent system with model routing for Phi Code",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "clean": "rm -rf dist"
10
+ },
11
+ "dependencies": {},
12
+ "devDependencies": {
13
+ "typescript": "^5.4.0"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/uglyswap/phi-code.git"
18
+ },
19
+ "homepage": "https://github.com/uglyswap/phi-code",
20
+ "keywords": ["agents", "routing", "typescript", "phi-code"],
21
+ "license": "MIT",
22
+ "files": ["dist", "src", "README.md"]
23
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { SmartRouter } from './router';
2
+ export { ModelProfiler } from './profiles';
3
+ export { SubAgentManager } from './sub-agent';
4
+ export * from './types';
@@ -0,0 +1,169 @@
1
+ import { ModelProfile, TaskCategory } from './types';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+
4
+ export class ModelProfiler {
5
+ public profiles: Map<string, ModelProfile> = new Map();
6
+
7
+ /**
8
+ * Charge les profiles depuis un fichier JSON
9
+ */
10
+ async loadFromFile(path: string): Promise<void> {
11
+ try {
12
+ const content = await readFile(path, 'utf8');
13
+ const data = JSON.parse(content);
14
+
15
+ if (Array.isArray(data.profiles)) {
16
+ this.profiles.clear();
17
+ for (const profile of data.profiles) {
18
+ this.profiles.set(profile.id, profile);
19
+ }
20
+ }
21
+ } catch (error) {
22
+ // Si le fichier n'existe pas, on utilise les profiles par défaut
23
+ console.warn(`Could not load profiles from ${path}:`, error);
24
+ this.loadDefaultProfiles();
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Sauvegarde les profiles vers un fichier JSON
30
+ */
31
+ async saveToFile(path: string): Promise<void> {
32
+ const data = {
33
+ profiles: Array.from(this.profiles.values())
34
+ };
35
+
36
+ await writeFile(path, JSON.stringify(data, null, 2), 'utf8');
37
+ }
38
+
39
+ /**
40
+ * Ajoute un profile
41
+ */
42
+ addProfile(profile: ModelProfile): void {
43
+ this.profiles.set(profile.id, profile);
44
+ }
45
+
46
+ /**
47
+ * Retourne le meilleur modèle pour une tâche donnée
48
+ */
49
+ getBestForTask(category: TaskCategory): ModelProfile | null {
50
+ const candidates = Array.from(this.profiles.values())
51
+ .filter(profile => profile.strengths.includes(category))
52
+ .sort((a, b) => {
53
+ // Priorité: quality > speed > cost
54
+ if (a.quality !== b.quality) {
55
+ const qualityOrder = { high: 3, medium: 2, low: 1 };
56
+ return qualityOrder[b.quality] - qualityOrder[a.quality];
57
+ }
58
+
59
+ if (a.speed !== b.speed) {
60
+ const speedOrder = { fast: 3, medium: 2, slow: 1 };
61
+ return speedOrder[b.speed] - speedOrder[a.speed];
62
+ }
63
+
64
+ return a.cost - b.cost; // Coût plus bas = mieux
65
+ });
66
+
67
+ return candidates[0] || null;
68
+ }
69
+
70
+ /**
71
+ * Charge les profiles par défaut des modèles Alibaba
72
+ */
73
+ private loadDefaultProfiles(): void {
74
+ const defaultProfiles = this.getDefaultProfiles();
75
+ this.profiles.clear();
76
+
77
+ for (const profile of defaultProfiles) {
78
+ this.profiles.set(profile.id, profile);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Retourne les profiles par défaut des 8 modèles Alibaba
84
+ */
85
+ getDefaultProfiles(): ModelProfile[] {
86
+ return [
87
+ {
88
+ id: 'qwen3.5-plus',
89
+ provider: 'alibaba',
90
+ cost: 0,
91
+ speed: 'medium',
92
+ quality: 'high',
93
+ strengths: ['code', 'debug', 'plan', 'review', 'general'],
94
+ maxTokens: 131072,
95
+ supportsTools: true
96
+ },
97
+ {
98
+ id: 'qwen3-max-2026-01-23',
99
+ provider: 'alibaba',
100
+ cost: 0,
101
+ speed: 'slow',
102
+ quality: 'high',
103
+ strengths: ['plan', 'debug', 'review'],
104
+ maxTokens: 131072,
105
+ supportsTools: true
106
+ },
107
+ {
108
+ id: 'qwen3-coder-plus',
109
+ provider: 'alibaba',
110
+ cost: 0,
111
+ speed: 'medium',
112
+ quality: 'high',
113
+ strengths: ['code', 'debug'],
114
+ maxTokens: 131072,
115
+ supportsTools: true
116
+ },
117
+ {
118
+ id: 'qwen3-coder-next',
119
+ provider: 'alibaba',
120
+ cost: 0,
121
+ speed: 'fast',
122
+ quality: 'high',
123
+ strengths: ['code'],
124
+ maxTokens: 131072,
125
+ supportsTools: true
126
+ },
127
+ {
128
+ id: 'kimi-k2.5',
129
+ provider: 'alibaba',
130
+ cost: 0,
131
+ speed: 'fast',
132
+ quality: 'medium',
133
+ strengths: ['explore', 'test', 'general'],
134
+ maxTokens: 131072,
135
+ supportsTools: true
136
+ },
137
+ {
138
+ id: 'glm-5',
139
+ provider: 'alibaba',
140
+ cost: 0,
141
+ speed: 'medium',
142
+ quality: 'medium',
143
+ strengths: ['general', 'code'],
144
+ maxTokens: 131072,
145
+ supportsTools: true
146
+ },
147
+ {
148
+ id: 'glm-4.7',
149
+ provider: 'alibaba',
150
+ cost: 0,
151
+ speed: 'fast',
152
+ quality: 'low',
153
+ strengths: ['explore', 'general'],
154
+ maxTokens: 131072,
155
+ supportsTools: true
156
+ },
157
+ {
158
+ id: 'MiniMax-M2.5',
159
+ provider: 'alibaba',
160
+ cost: 0,
161
+ speed: 'fast',
162
+ quality: 'medium',
163
+ strengths: ['general'],
164
+ maxTokens: 131072,
165
+ supportsTools: true
166
+ }
167
+ ];
168
+ }
169
+ }
package/src/router.ts ADDED
@@ -0,0 +1,136 @@
1
+ import { RoutingConfig, TaskCategory } from './types';
2
+ import { readFile } from 'node:fs/promises';
3
+
4
+ export class SmartRouter {
5
+ private config: RoutingConfig;
6
+
7
+ constructor(config: RoutingConfig) {
8
+ this.config = config;
9
+ }
10
+
11
+ /**
12
+ * Analyse le prompt et retourne la catégorie de tâche
13
+ * Priorité : debug > code > plan > review > test > explore > general
14
+ */
15
+ classifyTask(prompt: string): TaskCategory {
16
+ const lowerPrompt = prompt.toLowerCase();
17
+ const categories: TaskCategory[] = [];
18
+
19
+ // Vérifier chaque catégorie
20
+ for (const [category, route] of Object.entries(this.config.routes)) {
21
+ const hasKeyword = route.keywords.some(keyword =>
22
+ lowerPrompt.includes(keyword.toLowerCase())
23
+ );
24
+
25
+ if (hasKeyword) {
26
+ categories.push(category as TaskCategory);
27
+ }
28
+ }
29
+
30
+ if (categories.length === 0) {
31
+ return 'general';
32
+ }
33
+
34
+ // Appliquer les priorités
35
+ const priorityOrder: TaskCategory[] = ['debug', 'code', 'plan', 'review', 'test', 'explore', 'general'];
36
+
37
+ for (const priority of priorityOrder) {
38
+ if (categories.includes(priority)) {
39
+ return priority;
40
+ }
41
+ }
42
+
43
+ return categories[0];
44
+ }
45
+
46
+ /**
47
+ * Retourne le modèle et l'agent recommandés pour un prompt
48
+ */
49
+ getRecommendation(prompt: string): { model: string; agent: string | null; category: TaskCategory } {
50
+ const category = this.classifyTask(prompt);
51
+ const route = this.config.routes[category];
52
+
53
+ if (!route) {
54
+ return {
55
+ model: this.config.default.model,
56
+ agent: this.config.default.agent,
57
+ category
58
+ };
59
+ }
60
+
61
+ return {
62
+ model: route.preferredModel,
63
+ agent: route.agent,
64
+ category
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Charge la configuration depuis un fichier JSON
70
+ */
71
+ static async loadConfig(configPath: string): Promise<RoutingConfig> {
72
+ try {
73
+ const content = await readFile(configPath, 'utf8');
74
+ return JSON.parse(content);
75
+ } catch (error) {
76
+ console.warn(`Could not load routing config from ${configPath}:`, error);
77
+ return SmartRouter.defaultConfig();
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Configuration par défaut utilisant les modèles Alibaba Coding Plan
83
+ */
84
+ static defaultConfig(): RoutingConfig {
85
+ return {
86
+ routes: {
87
+ code: {
88
+ preferredModel: 'qwen3-coder-plus',
89
+ fallback: 'qwen3.5-plus',
90
+ agent: null,
91
+ keywords: ['code', 'implement', 'write', 'create', 'build', 'développer', 'coder', 'programmer', 'function', 'class', 'method']
92
+ },
93
+ debug: {
94
+ preferredModel: 'qwen3.5-plus',
95
+ fallback: 'qwen3-max-2026-01-23',
96
+ agent: null,
97
+ keywords: ['debug', 'fix', 'error', 'bug', 'broken', 'issue', 'problem', 'repair', 'correct', 'erreur', 'problème', 'réparer']
98
+ },
99
+ explore: {
100
+ preferredModel: 'kimi-k2.5',
101
+ fallback: 'glm-4.7',
102
+ agent: null,
103
+ keywords: ['explore', 'understand', 'analyze', 'examine', 'investigate', 'study', 'review', 'explorer', 'analyser', 'comprendre']
104
+ },
105
+ plan: {
106
+ preferredModel: 'qwen3-max-2026-01-23',
107
+ fallback: 'qwen3.5-plus',
108
+ agent: null,
109
+ keywords: ['plan', 'design', 'architecture', 'strategy', 'approach', 'structure', 'organize', 'concevoir', 'planifier', 'architecture']
110
+ },
111
+ test: {
112
+ preferredModel: 'kimi-k2.5',
113
+ fallback: 'qwen3-coder-next',
114
+ agent: null,
115
+ keywords: ['test', 'testing', 'unit', 'integration', 'verify', 'validate', 'check', 'tester', 'vérifier', 'valider']
116
+ },
117
+ review: {
118
+ preferredModel: 'qwen3.5-plus',
119
+ fallback: 'qwen3-max-2026-01-23',
120
+ agent: null,
121
+ keywords: ['review', 'audit', 'check', 'validate', 'quality', 'improve', 'optimize', 'réviser', 'améliorer', 'optimiser']
122
+ },
123
+ general: {
124
+ preferredModel: 'qwen3.5-plus',
125
+ fallback: 'glm-5',
126
+ agent: null,
127
+ keywords: ['help', 'explain', 'what', 'how', 'why', 'question', 'aide', 'expliquer', 'comment', 'pourquoi']
128
+ }
129
+ },
130
+ default: {
131
+ model: 'qwen3.5-plus',
132
+ agent: null
133
+ }
134
+ };
135
+ }
136
+ }
@@ -0,0 +1,162 @@
1
+ import { SubAgentConfig } from './types';
2
+ import { readdir, readFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+
5
+ export class SubAgentManager {
6
+ private agents: Map<string, SubAgentConfig> = new Map();
7
+
8
+ /**
9
+ * Charge les définitions d'agents depuis un répertoire
10
+ * Les fichiers .md doivent avoir un frontmatter YAML
11
+ */
12
+ async loadAgentDefinitions(agentsDir: string): Promise<void> {
13
+ try {
14
+ const files = await readdir(agentsDir);
15
+ const mdFiles = files.filter(file => file.endsWith('.md'));
16
+
17
+ this.agents.clear();
18
+
19
+ for (const file of mdFiles) {
20
+ try {
21
+ const filePath = join(agentsDir, file);
22
+ const content = await readFile(filePath, 'utf8');
23
+ const agent = this.parseAgentMarkdown(content);
24
+
25
+ if (agent) {
26
+ this.agents.set(agent.name, agent);
27
+ }
28
+ } catch (error) {
29
+ console.warn(`Could not parse agent file ${file}:`, error);
30
+ }
31
+ }
32
+ } catch (error) {
33
+ console.warn(`Could not load agent definitions from ${agentsDir}:`, error);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Retourne la liste des agents disponibles
39
+ */
40
+ getAvailableAgents(): SubAgentConfig[] {
41
+ return Array.from(this.agents.values());
42
+ }
43
+
44
+ /**
45
+ * Construit la commande CLI pour spawner un sous-agent phi
46
+ */
47
+ createCommand(agent: SubAgentConfig, task: string): string[] {
48
+ return [
49
+ 'phi',
50
+ '--json',
51
+ '--model',
52
+ agent.model,
53
+ '--no-save',
54
+ '--system',
55
+ agent.systemPrompt,
56
+ task
57
+ ];
58
+ }
59
+
60
+ /**
61
+ * Parse un fichier markdown avec frontmatter YAML
62
+ * Format attendu :
63
+ * ---
64
+ * name: agent-name
65
+ * description: Agent description
66
+ * model: model-name
67
+ * tools: [tool1, tool2]
68
+ * maxTokens: 4096
69
+ * ---
70
+ *
71
+ * # System Prompt
72
+ *
73
+ * Le contenu après le frontmatter devient le system prompt...
74
+ */
75
+ parseAgentMarkdown(content: string): SubAgentConfig | null {
76
+ const lines = content.split('\n');
77
+
78
+ if (!lines[0]?.startsWith('---')) {
79
+ return null;
80
+ }
81
+
82
+ // Trouver la fin du frontmatter
83
+ let frontmatterEnd = -1;
84
+ for (let i = 1; i < lines.length; i++) {
85
+ if (lines[i] === '---') {
86
+ frontmatterEnd = i;
87
+ break;
88
+ }
89
+ }
90
+
91
+ if (frontmatterEnd === -1) {
92
+ return null;
93
+ }
94
+
95
+ // Extraire et parser le frontmatter YAML
96
+ const frontmatterLines = lines.slice(1, frontmatterEnd);
97
+ const frontmatter: any = {};
98
+
99
+ for (const line of frontmatterLines) {
100
+ const trimmed = line.trim();
101
+ if (!trimmed || trimmed.startsWith('#')) continue;
102
+
103
+ const colonIndex = trimmed.indexOf(':');
104
+ if (colonIndex === -1) continue;
105
+
106
+ const key = trimmed.substring(0, colonIndex).trim();
107
+ const valueStr = trimmed.substring(colonIndex + 1).trim();
108
+
109
+ // Parser la valeur
110
+ let value: any = valueStr;
111
+
112
+ // Arrays (format: [item1, item2])
113
+ if (valueStr.startsWith('[') && valueStr.endsWith(']')) {
114
+ const arrayContent = valueStr.slice(1, -1);
115
+ value = arrayContent.split(',').map(item => item.trim().replace(/['"]/g, ''));
116
+ }
117
+ // Numbers
118
+ else if (/^\d+$/.test(valueStr)) {
119
+ value = parseInt(valueStr, 10);
120
+ }
121
+ // Remove quotes from strings
122
+ else if ((valueStr.startsWith('"') && valueStr.endsWith('"')) ||
123
+ (valueStr.startsWith("'") && valueStr.endsWith("'"))) {
124
+ value = valueStr.slice(1, -1);
125
+ }
126
+
127
+ frontmatter[key] = value;
128
+ }
129
+
130
+ // Extraire le system prompt (contenu après le frontmatter)
131
+ const systemPromptLines = lines.slice(frontmatterEnd + 1);
132
+ const systemPrompt = systemPromptLines.join('\n').trim();
133
+
134
+ // Valider les champs requis
135
+ if (!frontmatter.name || !frontmatter.model || !systemPrompt) {
136
+ return null;
137
+ }
138
+
139
+ return {
140
+ name: frontmatter.name,
141
+ description: frontmatter.description || '',
142
+ model: frontmatter.model,
143
+ tools: Array.isArray(frontmatter.tools) ? frontmatter.tools : [],
144
+ systemPrompt,
145
+ maxTokens: frontmatter.maxTokens || undefined
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Récupère un agent par son nom
151
+ */
152
+ getAgent(name: string): SubAgentConfig | null {
153
+ return this.agents.get(name) || null;
154
+ }
155
+
156
+ /**
157
+ * Vérifie si un agent existe
158
+ */
159
+ hasAgent(name: string): boolean {
160
+ return this.agents.has(name);
161
+ }
162
+ }
package/src/types.ts ADDED
@@ -0,0 +1,41 @@
1
+ export type TaskCategory = 'code' | 'debug' | 'explore' | 'plan' | 'test' | 'review' | 'general';
2
+
3
+ export interface ModelProfile {
4
+ id: string;
5
+ provider: string;
6
+ cost: number; // 0 = free
7
+ speed: 'fast' | 'medium' | 'slow';
8
+ quality: 'high' | 'medium' | 'low';
9
+ strengths: TaskCategory[];
10
+ maxTokens: number;
11
+ supportsTools: boolean;
12
+ }
13
+
14
+ export interface RoutingConfig {
15
+ routes: Record<TaskCategory, {
16
+ preferredModel: string;
17
+ fallback: string;
18
+ agent: string | null;
19
+ keywords: string[];
20
+ }>;
21
+ default: { model: string; agent: string | null };
22
+ }
23
+
24
+ export interface SubAgentConfig {
25
+ name: string;
26
+ description: string;
27
+ model: string;
28
+ tools: string[];
29
+ systemPrompt: string;
30
+ maxTokens?: number;
31
+ }
32
+
33
+ export interface SubAgentResult {
34
+ agentName: string;
35
+ model: string;
36
+ output: string;
37
+ tokensUsed: number;
38
+ durationMs: number;
39
+ success: boolean;
40
+ error?: string;
41
+ }