sigma-agents 0.1.9 → 0.1.10
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/router.d.ts +11 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +42 -16
- package/dist/router.js.map +1 -1
- package/package.json +2 -2
- package/src/router.ts +44 -19
package/dist/router.d.ts
CHANGED
|
@@ -3,8 +3,17 @@ export declare class SmartRouter {
|
|
|
3
3
|
private config;
|
|
4
4
|
constructor(config: RoutingConfig);
|
|
5
5
|
/**
|
|
6
|
-
* Analyse le prompt et retourne la catégorie de tâche
|
|
7
|
-
*
|
|
6
|
+
* Analyse le prompt et retourne la catégorie de tâche.
|
|
7
|
+
*
|
|
8
|
+
* Scoring: whole-word keyword matches per category (naive plural folding,
|
|
9
|
+
* multi-word keywords match as substrings). Best score wins. Ties break by
|
|
10
|
+
* intent priority — categories whose keywords are strong action verbs
|
|
11
|
+
* (debug, test, explore, review) beat categories that also match on generic
|
|
12
|
+
* nouns like "code" or "structure" (code, plan):
|
|
13
|
+
* debug > test > explore > review > code > plan > general.
|
|
14
|
+
*
|
|
15
|
+
* Whole-word matching matters: the previous substring match classified
|
|
16
|
+
* "functionality" as code (contains "function") and "codebase" as code.
|
|
8
17
|
*/
|
|
9
18
|
classifyTask(prompt: string): TaskCategory;
|
|
10
19
|
/**
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9D,qBAAa,WAAW;IACvB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAIjC
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9D,qBAAa,WAAW;IACvB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAIjC;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAoD1C;;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;IAmBnE;;;OAGG;IACH,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,aAAa;IA2CtE;;;;OAIG;IACH,MAAM,CAAC,aAAa,IAAI,aAAa;CAkIrC"}
|
package/dist/router.js
CHANGED
|
@@ -8,35 +8,63 @@ class SmartRouter {
|
|
|
8
8
|
this.config = config;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Analyse le prompt et retourne la catégorie de tâche
|
|
12
|
-
*
|
|
11
|
+
* Analyse le prompt et retourne la catégorie de tâche.
|
|
12
|
+
*
|
|
13
|
+
* Scoring: whole-word keyword matches per category (naive plural folding,
|
|
14
|
+
* multi-word keywords match as substrings). Best score wins. Ties break by
|
|
15
|
+
* intent priority — categories whose keywords are strong action verbs
|
|
16
|
+
* (debug, test, explore, review) beat categories that also match on generic
|
|
17
|
+
* nouns like "code" or "structure" (code, plan):
|
|
18
|
+
* debug > test > explore > review > code > plan > general.
|
|
19
|
+
*
|
|
20
|
+
* Whole-word matching matters: the previous substring match classified
|
|
21
|
+
* "functionality" as code (contains "function") and "codebase" as code.
|
|
13
22
|
*/
|
|
14
23
|
classifyTask(prompt) {
|
|
15
24
|
const lowerPrompt = prompt.toLowerCase();
|
|
16
|
-
const categories = [];
|
|
17
25
|
if (!this.config?.routes) {
|
|
18
26
|
return "general";
|
|
19
27
|
}
|
|
20
|
-
//
|
|
28
|
+
// Tokenize into whole words, folding naive plurals ("tests" -> "test").
|
|
29
|
+
const words = new Set();
|
|
30
|
+
for (const word of lowerPrompt.match(/[\p{L}\p{N}]+/gu) ?? []) {
|
|
31
|
+
words.add(word);
|
|
32
|
+
if (word.length > 3 && word.endsWith("s")) {
|
|
33
|
+
words.add(word.slice(0, -1));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const scores = new Map();
|
|
21
37
|
for (const [category, route] of Object.entries(this.config.routes)) {
|
|
22
38
|
if (!Array.isArray(route?.keywords))
|
|
23
39
|
continue;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
let score = 0;
|
|
41
|
+
// Dedupe so a keyword listed twice in a config cannot double-count.
|
|
42
|
+
for (const needle of new Set(route.keywords.map((k) => k.toLowerCase()))) {
|
|
43
|
+
const matched = needle.includes(" ") ? lowerPrompt.includes(needle) : words.has(needle);
|
|
44
|
+
if (matched)
|
|
45
|
+
score++;
|
|
46
|
+
}
|
|
47
|
+
if (score > 0) {
|
|
48
|
+
scores.set(category, score);
|
|
27
49
|
}
|
|
28
50
|
}
|
|
29
|
-
if (
|
|
51
|
+
if (scores.size === 0) {
|
|
30
52
|
return "general";
|
|
31
53
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
const priorityOrder = ["debug", "test", "explore", "review", "code", "plan", "general"];
|
|
55
|
+
let best;
|
|
56
|
+
let bestScore = 0;
|
|
57
|
+
for (const [category, score] of scores) {
|
|
58
|
+
if (score > bestScore ||
|
|
59
|
+
(score === bestScore &&
|
|
60
|
+
best !== undefined &&
|
|
61
|
+
priorityOrder.indexOf(category) !== -1 &&
|
|
62
|
+
priorityOrder.indexOf(category) < priorityOrder.indexOf(best))) {
|
|
63
|
+
best = category;
|
|
64
|
+
bestScore = score;
|
|
37
65
|
}
|
|
38
66
|
}
|
|
39
|
-
return
|
|
67
|
+
return best ?? "general";
|
|
40
68
|
}
|
|
41
69
|
/**
|
|
42
70
|
* Retourne le modèle et l'agent recommandés pour un prompt
|
|
@@ -172,7 +200,6 @@ class SmartRouter {
|
|
|
172
200
|
"examine",
|
|
173
201
|
"investigate",
|
|
174
202
|
"study",
|
|
175
|
-
"review",
|
|
176
203
|
"explorer",
|
|
177
204
|
"analyser",
|
|
178
205
|
"comprendre",
|
|
@@ -192,7 +219,6 @@ class SmartRouter {
|
|
|
192
219
|
"organize",
|
|
193
220
|
"concevoir",
|
|
194
221
|
"planifier",
|
|
195
|
-
"architecture",
|
|
196
222
|
],
|
|
197
223
|
},
|
|
198
224
|
test: {
|
package/dist/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":";;;AAAA,+CAA4C;AAG5C,MAAa,WAAW;IACf,MAAM,CAAgB;IAE9B,YAAY,MAAqB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigma-agents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Intelligent sub-agent system with model routing for Phi Code",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"clean": "shx rm -rf dist",
|
|
10
10
|
"prepublishOnly": "npm run clean && npm run build",
|
|
11
|
-
"test": "
|
|
11
|
+
"test": "tsx --test test/*.test.ts"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {},
|
|
14
14
|
"devDependencies": {
|
package/src/router.ts
CHANGED
|
@@ -9,41 +9,68 @@ export class SmartRouter {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Analyse le prompt et retourne la catégorie de tâche
|
|
13
|
-
*
|
|
12
|
+
* Analyse le prompt et retourne la catégorie de tâche.
|
|
13
|
+
*
|
|
14
|
+
* Scoring: whole-word keyword matches per category (naive plural folding,
|
|
15
|
+
* multi-word keywords match as substrings). Best score wins. Ties break by
|
|
16
|
+
* intent priority — categories whose keywords are strong action verbs
|
|
17
|
+
* (debug, test, explore, review) beat categories that also match on generic
|
|
18
|
+
* nouns like "code" or "structure" (code, plan):
|
|
19
|
+
* debug > test > explore > review > code > plan > general.
|
|
20
|
+
*
|
|
21
|
+
* Whole-word matching matters: the previous substring match classified
|
|
22
|
+
* "functionality" as code (contains "function") and "codebase" as code.
|
|
14
23
|
*/
|
|
15
24
|
classifyTask(prompt: string): TaskCategory {
|
|
16
25
|
const lowerPrompt = prompt.toLowerCase();
|
|
17
|
-
const categories: TaskCategory[] = [];
|
|
18
|
-
|
|
19
26
|
if (!this.config?.routes) {
|
|
20
27
|
return "general";
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
//
|
|
30
|
+
// Tokenize into whole words, folding naive plurals ("tests" -> "test").
|
|
31
|
+
const words = new Set<string>();
|
|
32
|
+
for (const word of lowerPrompt.match(/[\p{L}\p{N}]+/gu) ?? []) {
|
|
33
|
+
words.add(word);
|
|
34
|
+
if (word.length > 3 && word.endsWith("s")) {
|
|
35
|
+
words.add(word.slice(0, -1));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const scores = new Map<TaskCategory, number>();
|
|
24
40
|
for (const [category, route] of Object.entries(this.config.routes)) {
|
|
25
41
|
if (!Array.isArray(route?.keywords)) continue;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
let score = 0;
|
|
43
|
+
// Dedupe so a keyword listed twice in a config cannot double-count.
|
|
44
|
+
for (const needle of new Set(route.keywords.map((k) => k.toLowerCase()))) {
|
|
45
|
+
const matched = needle.includes(" ") ? lowerPrompt.includes(needle) : words.has(needle);
|
|
46
|
+
if (matched) score++;
|
|
47
|
+
}
|
|
48
|
+
if (score > 0) {
|
|
49
|
+
scores.set(category as TaskCategory, score);
|
|
30
50
|
}
|
|
31
51
|
}
|
|
32
52
|
|
|
33
|
-
if (
|
|
53
|
+
if (scores.size === 0) {
|
|
34
54
|
return "general";
|
|
35
55
|
}
|
|
36
56
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
for (const
|
|
41
|
-
if (
|
|
42
|
-
|
|
57
|
+
const priorityOrder: TaskCategory[] = ["debug", "test", "explore", "review", "code", "plan", "general"];
|
|
58
|
+
let best: TaskCategory | undefined;
|
|
59
|
+
let bestScore = 0;
|
|
60
|
+
for (const [category, score] of scores) {
|
|
61
|
+
if (
|
|
62
|
+
score > bestScore ||
|
|
63
|
+
(score === bestScore &&
|
|
64
|
+
best !== undefined &&
|
|
65
|
+
priorityOrder.indexOf(category) !== -1 &&
|
|
66
|
+
priorityOrder.indexOf(category) < priorityOrder.indexOf(best))
|
|
67
|
+
) {
|
|
68
|
+
best = category;
|
|
69
|
+
bestScore = score;
|
|
43
70
|
}
|
|
44
71
|
}
|
|
45
72
|
|
|
46
|
-
return
|
|
73
|
+
return best ?? "general";
|
|
47
74
|
}
|
|
48
75
|
|
|
49
76
|
/**
|
|
@@ -193,7 +220,6 @@ export class SmartRouter {
|
|
|
193
220
|
"examine",
|
|
194
221
|
"investigate",
|
|
195
222
|
"study",
|
|
196
|
-
"review",
|
|
197
223
|
"explorer",
|
|
198
224
|
"analyser",
|
|
199
225
|
"comprendre",
|
|
@@ -213,7 +239,6 @@ export class SmartRouter {
|
|
|
213
239
|
"organize",
|
|
214
240
|
"concevoir",
|
|
215
241
|
"planifier",
|
|
216
|
-
"architecture",
|
|
217
242
|
],
|
|
218
243
|
},
|
|
219
244
|
test: {
|