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/src/sub-agent.ts CHANGED
@@ -1,162 +1,155 @@
1
- import { SubAgentConfig } from './types.js';
2
- import { readdir, readFile } from 'node:fs/promises';
3
- import { join } from 'node:path';
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
- 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
- '--print',
51
- '--model',
52
- agent.model,
53
- '--no-session',
54
- '--system-prompt',
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
- // Extract system prompt (content after 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
- }
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 = 'code' | 'debug' | 'explore' | 'plan' | 'test' | 'review' | 'general';
1
+ export type TaskCategory = "code" | "debug" | "explore" | "plan" | "test" | "review" | "general";
2
2
 
3
3
  export interface ModelProfile {
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;
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
- routes: Record<TaskCategory, {
15
- preferredModel: string;
16
- fallback: string;
17
- agent: string | null;
18
- keywords: string[];
19
- }>;
20
- default: { model: string; agent: string | null };
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
- name: string;
25
- description: string;
26
- model: string;
27
- tools: string[];
28
- systemPrompt: string;
29
- maxTokens?: number;
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
- agentName: string;
34
- model: string;
35
- output: string;
36
- tokensUsed: number;
37
- durationMs: number;
38
- success: boolean;
39
- error?: string;
40
- }
36
+ agentName: string;
37
+ model: string;
38
+ output: string;
39
+ tokensUsed: number;
40
+ durationMs: number;
41
+ success: boolean;
42
+ error?: string;
43
+ }