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.
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/profiles.d.ts +29 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +161 -0
- package/dist/profiles.js.map +1 -0
- package/dist/router.d.ts +27 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +125 -0
- package/dist/router.js.map +1 -0
- package/dist/sub-agent.d.ts +42 -0
- package/dist/sub-agent.d.ts.map +1 -0
- package/dist/sub-agent.js +147 -0
- package/dist/sub-agent.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +23 -0
- package/src/index.ts +4 -0
- package/src/profiles.ts +169 -0
- package/src/router.ts +136 -0
- package/src/sub-agent.ts +162 -0
- package/src/types.ts +41 -0
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/profiles.js
ADDED
|
@@ -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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"}
|
package/dist/router.d.ts
ADDED
|
@@ -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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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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 @@
|
|
|
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
package/src/profiles.ts
ADDED
|
@@ -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
|
+
}
|
package/src/sub-agent.ts
ADDED
|
@@ -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
|
+
}
|