sigma-agents 0.1.7 → 0.1.8
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 +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/profiles.d.ts +7 -1
- package/dist/profiles.d.ts.map +1 -1
- package/dist/profiles.js +38 -4
- package/dist/profiles.js.map +1 -1
- package/dist/router.d.ts +6 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +163 -32
- package/dist/router.js.map +1 -1
- package/dist/sub-agent.d.ts +1 -1
- package/dist/sub-agent.d.ts.map +1 -1
- package/dist/sub-agent.js +13 -22
- package/dist/sub-agent.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/index.ts +4 -4
- package/src/profiles.ts +126 -88
- package/src/router.ts +275 -136
- package/src/sub-agent.ts +153 -160
- package/src/types.ts +32 -29
package/src/sub-agent.ts
CHANGED
|
@@ -1,162 +1,155 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { SubAgentConfig } from "./types.js";
|
|
4
4
|
|
|
5
5
|
export class SubAgentManager {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Vérifie si un agent existe
|
|
158
|
-
*/
|
|
159
|
-
hasAgent(name: string): boolean {
|
|
160
|
-
return this.agents.has(name);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
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 ["phi", "--print", "--model", agent.model, "--no-session", "--system-prompt", agent.systemPrompt, task];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Parse un fichier markdown avec frontmatter YAML
|
|
53
|
+
* Format attendu :
|
|
54
|
+
* ---
|
|
55
|
+
* name: agent-name
|
|
56
|
+
* description: Agent description
|
|
57
|
+
* model: model-name
|
|
58
|
+
* tools: [tool1, tool2]
|
|
59
|
+
* maxTokens: 4096
|
|
60
|
+
* ---
|
|
61
|
+
*
|
|
62
|
+
* # System Prompt
|
|
63
|
+
*
|
|
64
|
+
* Le contenu après le frontmatter devient le system prompt...
|
|
65
|
+
*/
|
|
66
|
+
parseAgentMarkdown(content: string): SubAgentConfig | null {
|
|
67
|
+
const lines = content.split("\n");
|
|
68
|
+
|
|
69
|
+
if (!lines[0]?.startsWith("---")) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Trouver la fin du frontmatter
|
|
74
|
+
let frontmatterEnd = -1;
|
|
75
|
+
for (let i = 1; i < lines.length; i++) {
|
|
76
|
+
if (lines[i] === "---") {
|
|
77
|
+
frontmatterEnd = i;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (frontmatterEnd === -1) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Extraire et parser le frontmatter YAML
|
|
87
|
+
const frontmatterLines = lines.slice(1, frontmatterEnd);
|
|
88
|
+
const frontmatter: any = {};
|
|
89
|
+
|
|
90
|
+
for (const line of frontmatterLines) {
|
|
91
|
+
const trimmed = line.trim();
|
|
92
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
93
|
+
|
|
94
|
+
const colonIndex = trimmed.indexOf(":");
|
|
95
|
+
if (colonIndex === -1) continue;
|
|
96
|
+
|
|
97
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
98
|
+
const valueStr = trimmed.substring(colonIndex + 1).trim();
|
|
99
|
+
|
|
100
|
+
// Parser la valeur
|
|
101
|
+
let value: any = valueStr;
|
|
102
|
+
|
|
103
|
+
// Arrays (format: [item1, item2])
|
|
104
|
+
if (valueStr.startsWith("[") && valueStr.endsWith("]")) {
|
|
105
|
+
const arrayContent = valueStr.slice(1, -1);
|
|
106
|
+
value = arrayContent.split(",").map((item) => item.trim().replace(/['"]/g, ""));
|
|
107
|
+
}
|
|
108
|
+
// Numbers
|
|
109
|
+
else if (/^\d+$/.test(valueStr)) {
|
|
110
|
+
value = parseInt(valueStr, 10);
|
|
111
|
+
}
|
|
112
|
+
// Remove quotes from strings
|
|
113
|
+
else if (
|
|
114
|
+
(valueStr.startsWith('"') && valueStr.endsWith('"')) ||
|
|
115
|
+
(valueStr.startsWith("'") && valueStr.endsWith("'"))
|
|
116
|
+
) {
|
|
117
|
+
value = valueStr.slice(1, -1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
frontmatter[key] = value;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Extract system prompt (content after frontmatter)
|
|
124
|
+
const systemPromptLines = lines.slice(frontmatterEnd + 1);
|
|
125
|
+
const systemPrompt = systemPromptLines.join("\n").trim();
|
|
126
|
+
|
|
127
|
+
// Valider les champs requis
|
|
128
|
+
if (!frontmatter.name || !frontmatter.model || !systemPrompt) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
name: frontmatter.name,
|
|
134
|
+
description: frontmatter.description || "",
|
|
135
|
+
model: frontmatter.model,
|
|
136
|
+
tools: Array.isArray(frontmatter.tools) ? frontmatter.tools : [],
|
|
137
|
+
systemPrompt,
|
|
138
|
+
maxTokens: frontmatter.maxTokens || undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Récupère un agent par son nom
|
|
144
|
+
*/
|
|
145
|
+
getAgent(name: string): SubAgentConfig | null {
|
|
146
|
+
return this.agents.get(name) || null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Vérifie si un agent existe
|
|
151
|
+
*/
|
|
152
|
+
hasAgent(name: string): boolean {
|
|
153
|
+
return this.agents.has(name);
|
|
154
|
+
}
|
|
155
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,40 +1,43 @@
|
|
|
1
|
-
export type TaskCategory =
|
|
1
|
+
export type TaskCategory = "code" | "debug" | "explore" | "plan" | "test" | "review" | "general";
|
|
2
2
|
|
|
3
3
|
export interface ModelProfile {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
id: string;
|
|
5
|
+
provider: string;
|
|
6
|
+
speed: "fast" | "medium" | "slow";
|
|
7
|
+
quality: "high" | "medium" | "low";
|
|
8
|
+
strengths: TaskCategory[];
|
|
9
|
+
maxTokens: number;
|
|
10
|
+
supportsTools: boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface RoutingConfig {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
routes: Record<
|
|
15
|
+
TaskCategory,
|
|
16
|
+
{
|
|
17
|
+
preferredModel: string;
|
|
18
|
+
fallback: string;
|
|
19
|
+
agent: string | null;
|
|
20
|
+
keywords: string[];
|
|
21
|
+
}
|
|
22
|
+
>;
|
|
23
|
+
default: { model: string; agent: string | null };
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export interface SubAgentConfig {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
model: string;
|
|
30
|
+
tools: string[];
|
|
31
|
+
systemPrompt: string;
|
|
32
|
+
maxTokens?: number;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export interface SubAgentResult {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
36
|
+
agentName: string;
|
|
37
|
+
model: string;
|
|
38
|
+
output: string;
|
|
39
|
+
tokensUsed: number;
|
|
40
|
+
durationMs: number;
|
|
41
|
+
success: boolean;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|