family-ai-agent 1.0.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/.env.example +49 -0
- package/README.md +161 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +336 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/index.d.ts +37 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +68 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/models.d.ts +17 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +128 -0
- package/dist/config/models.js.map +1 -0
- package/dist/core/agents/agent-factory.d.ts +31 -0
- package/dist/core/agents/agent-factory.d.ts.map +1 -0
- package/dist/core/agents/agent-factory.js +151 -0
- package/dist/core/agents/agent-factory.js.map +1 -0
- package/dist/core/agents/base-agent.d.ts +51 -0
- package/dist/core/agents/base-agent.d.ts.map +1 -0
- package/dist/core/agents/base-agent.js +245 -0
- package/dist/core/agents/base-agent.js.map +1 -0
- package/dist/core/agents/index.d.ts +8 -0
- package/dist/core/agents/index.d.ts.map +1 -0
- package/dist/core/agents/index.js +9 -0
- package/dist/core/agents/index.js.map +1 -0
- package/dist/core/agents/personalities/automation.d.ts +14 -0
- package/dist/core/agents/personalities/automation.d.ts.map +1 -0
- package/dist/core/agents/personalities/automation.js +146 -0
- package/dist/core/agents/personalities/automation.js.map +1 -0
- package/dist/core/agents/personalities/chat.d.ts +10 -0
- package/dist/core/agents/personalities/chat.d.ts.map +1 -0
- package/dist/core/agents/personalities/chat.js +132 -0
- package/dist/core/agents/personalities/chat.js.map +1 -0
- package/dist/core/agents/personalities/coding.d.ts +16 -0
- package/dist/core/agents/personalities/coding.d.ts.map +1 -0
- package/dist/core/agents/personalities/coding.js +166 -0
- package/dist/core/agents/personalities/coding.js.map +1 -0
- package/dist/core/agents/personalities/research.d.ts +13 -0
- package/dist/core/agents/personalities/research.d.ts.map +1 -0
- package/dist/core/agents/personalities/research.js +133 -0
- package/dist/core/agents/personalities/research.js.map +1 -0
- package/dist/core/agents/types.d.ts +102 -0
- package/dist/core/agents/types.d.ts.map +1 -0
- package/dist/core/agents/types.js +2 -0
- package/dist/core/agents/types.js.map +1 -0
- package/dist/core/orchestrator/graph.d.ts +118 -0
- package/dist/core/orchestrator/graph.d.ts.map +1 -0
- package/dist/core/orchestrator/graph.js +233 -0
- package/dist/core/orchestrator/graph.js.map +1 -0
- package/dist/database/client.d.ts +19 -0
- package/dist/database/client.d.ts.map +1 -0
- package/dist/database/client.js +95 -0
- package/dist/database/client.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/openrouter-client.d.ts +45 -0
- package/dist/llm/openrouter-client.d.ts.map +1 -0
- package/dist/llm/openrouter-client.js +155 -0
- package/dist/llm/openrouter-client.js.map +1 -0
- package/dist/memory/conversation/index.d.ts +37 -0
- package/dist/memory/conversation/index.d.ts.map +1 -0
- package/dist/memory/conversation/index.js +196 -0
- package/dist/memory/conversation/index.js.map +1 -0
- package/dist/memory/index.d.ts +4 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +5 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/knowledge-base/index.d.ts +51 -0
- package/dist/memory/knowledge-base/index.d.ts.map +1 -0
- package/dist/memory/knowledge-base/index.js +222 -0
- package/dist/memory/knowledge-base/index.js.map +1 -0
- package/dist/memory/longterm/vector-store.d.ts +44 -0
- package/dist/memory/longterm/vector-store.d.ts.map +1 -0
- package/dist/memory/longterm/vector-store.js +229 -0
- package/dist/memory/longterm/vector-store.js.map +1 -0
- package/dist/safety/audit-logger.d.ts +68 -0
- package/dist/safety/audit-logger.d.ts.map +1 -0
- package/dist/safety/audit-logger.js +215 -0
- package/dist/safety/audit-logger.js.map +1 -0
- package/dist/safety/guardrails/input-guardrail.d.ts +21 -0
- package/dist/safety/guardrails/input-guardrail.d.ts.map +1 -0
- package/dist/safety/guardrails/input-guardrail.js +145 -0
- package/dist/safety/guardrails/input-guardrail.js.map +1 -0
- package/dist/safety/guardrails/output-guardrail.d.ts +18 -0
- package/dist/safety/guardrails/output-guardrail.d.ts.map +1 -0
- package/dist/safety/guardrails/output-guardrail.js +125 -0
- package/dist/safety/guardrails/output-guardrail.js.map +1 -0
- package/dist/safety/index.d.ts +4 -0
- package/dist/safety/index.d.ts.map +1 -0
- package/dist/safety/index.js +5 -0
- package/dist/safety/index.js.map +1 -0
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +94 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/logger.js.map +1 -0
- package/docker/init-db.sql +149 -0
- package/docker/sandbox/Dockerfile.sandbox +29 -0
- package/docker-compose.yml +61 -0
- package/package.json +80 -0
- package/src/cli/index.ts +392 -0
- package/src/config/index.ts +85 -0
- package/src/config/models.ts +156 -0
- package/src/core/agents/agent-factory.ts +192 -0
- package/src/core/agents/base-agent.ts +333 -0
- package/src/core/agents/index.ts +27 -0
- package/src/core/agents/personalities/automation.ts +202 -0
- package/src/core/agents/personalities/chat.ts +159 -0
- package/src/core/agents/personalities/coding.ts +227 -0
- package/src/core/agents/personalities/research.ts +177 -0
- package/src/core/agents/types.ts +124 -0
- package/src/core/orchestrator/graph.ts +305 -0
- package/src/database/client.ts +109 -0
- package/src/index.ts +104 -0
- package/src/llm/openrouter-client.ts +218 -0
- package/src/memory/conversation/index.ts +313 -0
- package/src/memory/index.ts +23 -0
- package/src/memory/knowledge-base/index.ts +357 -0
- package/src/memory/longterm/vector-store.ts +364 -0
- package/src/safety/audit-logger.ts +357 -0
- package/src/safety/guardrails/input-guardrail.ts +191 -0
- package/src/safety/guardrails/output-guardrail.ts +160 -0
- package/src/safety/index.ts +21 -0
- package/src/utils/errors.ts +120 -0
- package/src/utils/logger.ts +74 -0
- package/tsconfig.json +37 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { BaseAgent } from '../base-agent.js';
|
|
3
|
+
import type {
|
|
4
|
+
AgentConfig,
|
|
5
|
+
AgentState,
|
|
6
|
+
TaskResult,
|
|
7
|
+
RetrievedMemory,
|
|
8
|
+
HandoffDecision,
|
|
9
|
+
} from '../types.js';
|
|
10
|
+
import { getRecommendedModel } from '../../../config/models.js';
|
|
11
|
+
|
|
12
|
+
const AUTOMATION_SYSTEM_PROMPT = `You are an expert Automation Agent in the Family AI Agent system, specializing in task automation and workflow management.
|
|
13
|
+
|
|
14
|
+
Your identity: Automation Specialist
|
|
15
|
+
Your personality:
|
|
16
|
+
- Systematic and organized
|
|
17
|
+
- Efficient and reliable
|
|
18
|
+
- Detail-oriented for error prevention
|
|
19
|
+
- Proactive in identifying automation opportunities
|
|
20
|
+
|
|
21
|
+
Your capabilities:
|
|
22
|
+
- Creating automated workflows
|
|
23
|
+
- Scheduling recurring tasks
|
|
24
|
+
- Managing task queues
|
|
25
|
+
- Batch processing operations
|
|
26
|
+
- Setting up notifications and alerts
|
|
27
|
+
- Integrating different tools and systems
|
|
28
|
+
- Monitoring task execution
|
|
29
|
+
|
|
30
|
+
Automation principles:
|
|
31
|
+
1. Reliability over speed
|
|
32
|
+
2. Clear error handling and recovery
|
|
33
|
+
3. Proper logging and monitoring
|
|
34
|
+
4. Minimal human intervention needed
|
|
35
|
+
5. Graceful degradation on failures
|
|
36
|
+
6. Clear status reporting
|
|
37
|
+
|
|
38
|
+
When designing automation:
|
|
39
|
+
- Understand the full workflow requirements
|
|
40
|
+
- Identify potential failure points
|
|
41
|
+
- Plan error handling strategies
|
|
42
|
+
- Consider resource constraints
|
|
43
|
+
- Design for maintainability
|
|
44
|
+
|
|
45
|
+
Task categories you handle:
|
|
46
|
+
- Scheduled jobs (cron-like)
|
|
47
|
+
- Event-triggered workflows
|
|
48
|
+
- Batch processing
|
|
49
|
+
- Data pipelines
|
|
50
|
+
- File operations
|
|
51
|
+
- System maintenance
|
|
52
|
+
|
|
53
|
+
Output format for automation tasks:
|
|
54
|
+
1. Task definition (what to automate)
|
|
55
|
+
2. Schedule/trigger conditions
|
|
56
|
+
3. Required resources
|
|
57
|
+
4. Error handling plan
|
|
58
|
+
5. Success criteria
|
|
59
|
+
6. Monitoring/alerting setup`;
|
|
60
|
+
|
|
61
|
+
export class AutomationAgent extends BaseAgent {
|
|
62
|
+
constructor(tools: AgentConfig['tools'] = []) {
|
|
63
|
+
super({
|
|
64
|
+
identity: {
|
|
65
|
+
id: `automation-${nanoid(8)}`,
|
|
66
|
+
name: 'Automator',
|
|
67
|
+
role: 'automation',
|
|
68
|
+
description: 'Task automation and workflow management agent',
|
|
69
|
+
capabilities: [
|
|
70
|
+
'task_scheduling',
|
|
71
|
+
'workflow_creation',
|
|
72
|
+
'batch_processing',
|
|
73
|
+
'monitoring',
|
|
74
|
+
'alerting',
|
|
75
|
+
'file_operations',
|
|
76
|
+
'system_integration',
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
model: getRecommendedModel('automation'),
|
|
80
|
+
temperature: 0.3, // Low temperature for reliable automation
|
|
81
|
+
systemPrompt: AUTOMATION_SYSTEM_PROMPT,
|
|
82
|
+
tools,
|
|
83
|
+
maxIterations: 8,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected buildSystemPrompt(
|
|
88
|
+
context: Record<string, unknown>,
|
|
89
|
+
memories: RetrievedMemory[]
|
|
90
|
+
): string {
|
|
91
|
+
let prompt = this.systemPrompt;
|
|
92
|
+
|
|
93
|
+
// Add workflow memories
|
|
94
|
+
const workflowMemories = memories.filter(
|
|
95
|
+
(m) => m.type === 'procedural' || m.metadata?.category === 'workflow'
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
if (workflowMemories.length > 0) {
|
|
99
|
+
prompt += '\n\n## Known Workflows/Automations\n';
|
|
100
|
+
for (const memory of workflowMemories) {
|
|
101
|
+
prompt += `- ${memory.content}\n`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Add active tasks context
|
|
106
|
+
if (context.activeTasks) {
|
|
107
|
+
prompt += '\n\n## Currently Active Tasks\n';
|
|
108
|
+
prompt += JSON.stringify(context.activeTasks, null, 2);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Add schedule context
|
|
112
|
+
if (context.schedule) {
|
|
113
|
+
prompt += '\n\n## Existing Schedules\n';
|
|
114
|
+
prompt += JSON.stringify(context.schedule, null, 2);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return prompt;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected async shouldHandoff(
|
|
121
|
+
state: AgentState,
|
|
122
|
+
result: TaskResult
|
|
123
|
+
): Promise<HandoffDecision> {
|
|
124
|
+
const output = String(result.output).toLowerCase();
|
|
125
|
+
|
|
126
|
+
// Check if coding is needed
|
|
127
|
+
if (
|
|
128
|
+
output.includes('write a script') ||
|
|
129
|
+
output.includes('create a program') ||
|
|
130
|
+
output.includes('implement code')
|
|
131
|
+
) {
|
|
132
|
+
return {
|
|
133
|
+
shouldHandoff: true,
|
|
134
|
+
targetAgent: 'coding',
|
|
135
|
+
reason: 'Need code implementation for automation',
|
|
136
|
+
context: {
|
|
137
|
+
automationSpec: result.output,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check if research is needed
|
|
143
|
+
if (
|
|
144
|
+
output.includes('need to investigate') ||
|
|
145
|
+
output.includes('research required')
|
|
146
|
+
) {
|
|
147
|
+
return {
|
|
148
|
+
shouldHandoff: true,
|
|
149
|
+
targetAgent: 'research',
|
|
150
|
+
reason: 'Need research before automation setup',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
shouldHandoff: false,
|
|
156
|
+
reason: 'Automation task complete',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Additional automation-specific methods
|
|
161
|
+
async scheduleTask(
|
|
162
|
+
taskDescription: string,
|
|
163
|
+
schedule: string
|
|
164
|
+
): Promise<TaskResult> {
|
|
165
|
+
return this.execute(
|
|
166
|
+
`Create a scheduled task:\n\nTask: ${taskDescription}\nSchedule: ${schedule}`,
|
|
167
|
+
{ task: 'scheduling' }
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async createWorkflow(steps: string[]): Promise<TaskResult> {
|
|
172
|
+
return this.execute(
|
|
173
|
+
`Create an automated workflow with these steps:\n\n${steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}`,
|
|
174
|
+
{ task: 'workflow_creation' }
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async batchProcess(
|
|
179
|
+
items: string[],
|
|
180
|
+
operation: string
|
|
181
|
+
): Promise<TaskResult> {
|
|
182
|
+
return this.execute(
|
|
183
|
+
`Set up batch processing:\n\nOperation: ${operation}\nItems: ${items.length} items to process`,
|
|
184
|
+
{ task: 'batch_processing', itemCount: items.length }
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async setupMonitoring(target: string, conditions: string): Promise<TaskResult> {
|
|
189
|
+
return this.execute(
|
|
190
|
+
`Set up monitoring:\n\nTarget: ${target}\nAlert conditions: ${conditions}`,
|
|
191
|
+
{ task: 'monitoring' }
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function createAutomationAgent(
|
|
197
|
+
tools: AgentConfig['tools'] = []
|
|
198
|
+
): AutomationAgent {
|
|
199
|
+
return new AutomationAgent(tools);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export default AutomationAgent;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { BaseAgent } from '../base-agent.js';
|
|
3
|
+
import type {
|
|
4
|
+
AgentConfig,
|
|
5
|
+
AgentState,
|
|
6
|
+
TaskResult,
|
|
7
|
+
RetrievedMemory,
|
|
8
|
+
HandoffDecision,
|
|
9
|
+
} from '../types.js';
|
|
10
|
+
import { getRecommendedModel } from '../../../config/models.js';
|
|
11
|
+
|
|
12
|
+
const CHAT_SYSTEM_PROMPT = `You are a friendly and helpful AI assistant named "Kakak" (Elder Sibling) from the Family AI Agent system.
|
|
13
|
+
|
|
14
|
+
Your personality:
|
|
15
|
+
- Warm, supportive, and patient
|
|
16
|
+
- Clear and concise in explanations
|
|
17
|
+
- Proactive in offering help
|
|
18
|
+
- Respectful and professional
|
|
19
|
+
|
|
20
|
+
Your capabilities:
|
|
21
|
+
- General conversation and Q&A
|
|
22
|
+
- Explaining concepts in simple terms
|
|
23
|
+
- Providing thoughtful advice
|
|
24
|
+
- Creative writing and brainstorming
|
|
25
|
+
- Summarizing information
|
|
26
|
+
|
|
27
|
+
Guidelines:
|
|
28
|
+
1. Be helpful and accurate in your responses
|
|
29
|
+
2. If you don't know something, say so honestly
|
|
30
|
+
3. For complex technical tasks (coding, research), suggest delegating to specialized agents
|
|
31
|
+
4. Remember context from the conversation
|
|
32
|
+
5. Use the user's language preference when possible
|
|
33
|
+
|
|
34
|
+
When you encounter tasks better suited for other agents:
|
|
35
|
+
- Research/information gathering → Research Agent
|
|
36
|
+
- Code writing/debugging → Coding Agent
|
|
37
|
+
- Task automation/scheduling → Automation Agent`;
|
|
38
|
+
|
|
39
|
+
export class ChatAgent extends BaseAgent {
|
|
40
|
+
constructor(tools: AgentConfig['tools'] = []) {
|
|
41
|
+
super({
|
|
42
|
+
identity: {
|
|
43
|
+
id: `chat-${nanoid(8)}`,
|
|
44
|
+
name: 'Kakak',
|
|
45
|
+
role: 'chat',
|
|
46
|
+
description: 'Friendly general-purpose chat assistant',
|
|
47
|
+
capabilities: [
|
|
48
|
+
'conversation',
|
|
49
|
+
'explanation',
|
|
50
|
+
'advice',
|
|
51
|
+
'creative_writing',
|
|
52
|
+
'summarization',
|
|
53
|
+
'translation',
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
model: getRecommendedModel('chat'),
|
|
57
|
+
temperature: 0.7,
|
|
58
|
+
systemPrompt: CHAT_SYSTEM_PROMPT,
|
|
59
|
+
tools,
|
|
60
|
+
maxIterations: 5,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected buildSystemPrompt(
|
|
65
|
+
context: Record<string, unknown>,
|
|
66
|
+
memories: RetrievedMemory[]
|
|
67
|
+
): string {
|
|
68
|
+
let prompt = this.systemPrompt;
|
|
69
|
+
|
|
70
|
+
// Add relevant memories
|
|
71
|
+
if (memories.length > 0) {
|
|
72
|
+
prompt += '\n\n## Relevant Memories\n';
|
|
73
|
+
for (const memory of memories) {
|
|
74
|
+
prompt += `- [${memory.type}] ${memory.content}\n`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Add context
|
|
79
|
+
if (Object.keys(context).length > 0) {
|
|
80
|
+
prompt += '\n\n## Current Context\n';
|
|
81
|
+
prompt += JSON.stringify(context, null, 2);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Add user preferences if available
|
|
85
|
+
if (context.userPreferences) {
|
|
86
|
+
prompt += '\n\n## User Preferences\n';
|
|
87
|
+
prompt += JSON.stringify(context.userPreferences, null, 2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return prompt;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected async shouldHandoff(
|
|
94
|
+
state: AgentState,
|
|
95
|
+
result: TaskResult
|
|
96
|
+
): Promise<HandoffDecision> {
|
|
97
|
+
// Check if the task requires specialized handling
|
|
98
|
+
const output = String(result.output).toLowerCase();
|
|
99
|
+
|
|
100
|
+
// Patterns that suggest handoff to other agents
|
|
101
|
+
const codingPatterns = [
|
|
102
|
+
'write code',
|
|
103
|
+
'debug',
|
|
104
|
+
'fix bug',
|
|
105
|
+
'implement',
|
|
106
|
+
'refactor',
|
|
107
|
+
'programming',
|
|
108
|
+
];
|
|
109
|
+
const researchPatterns = [
|
|
110
|
+
'search for',
|
|
111
|
+
'find information',
|
|
112
|
+
'research',
|
|
113
|
+
'look up',
|
|
114
|
+
'investigate',
|
|
115
|
+
];
|
|
116
|
+
const automationPatterns = [
|
|
117
|
+
'schedule',
|
|
118
|
+
'automate',
|
|
119
|
+
'repeat task',
|
|
120
|
+
'run every',
|
|
121
|
+
'batch process',
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
if (codingPatterns.some((p) => output.includes(p))) {
|
|
125
|
+
return {
|
|
126
|
+
shouldHandoff: true,
|
|
127
|
+
targetAgent: 'coding',
|
|
128
|
+
reason: 'Task requires code-related capabilities',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (researchPatterns.some((p) => output.includes(p))) {
|
|
133
|
+
return {
|
|
134
|
+
shouldHandoff: true,
|
|
135
|
+
targetAgent: 'research',
|
|
136
|
+
reason: 'Task requires web research capabilities',
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (automationPatterns.some((p) => output.includes(p))) {
|
|
141
|
+
return {
|
|
142
|
+
shouldHandoff: true,
|
|
143
|
+
targetAgent: 'automation',
|
|
144
|
+
reason: 'Task requires automation capabilities',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
shouldHandoff: false,
|
|
150
|
+
reason: 'Task can be handled by chat agent',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function createChatAgent(tools: AgentConfig['tools'] = []): ChatAgent {
|
|
156
|
+
return new ChatAgent(tools);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export default ChatAgent;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { BaseAgent } from '../base-agent.js';
|
|
3
|
+
import type {
|
|
4
|
+
AgentConfig,
|
|
5
|
+
AgentState,
|
|
6
|
+
TaskResult,
|
|
7
|
+
RetrievedMemory,
|
|
8
|
+
HandoffDecision,
|
|
9
|
+
} from '../types.js';
|
|
10
|
+
import { getRecommendedModel } from '../../../config/models.js';
|
|
11
|
+
|
|
12
|
+
const CODING_SYSTEM_PROMPT = `You are an expert Coding Agent in the Family AI Agent system, specializing in software development.
|
|
13
|
+
|
|
14
|
+
Your identity: "Adik" (Younger Sibling) - The brilliant coder
|
|
15
|
+
Your personality:
|
|
16
|
+
- Highly skilled and confident
|
|
17
|
+
- Detail-oriented and precise
|
|
18
|
+
- Creative problem solver
|
|
19
|
+
- Efficient and pragmatic
|
|
20
|
+
|
|
21
|
+
Your capabilities:
|
|
22
|
+
- Writing clean, efficient code in multiple languages
|
|
23
|
+
- Debugging and fixing errors
|
|
24
|
+
- Code review and optimization
|
|
25
|
+
- Explaining code and concepts
|
|
26
|
+
- Refactoring and improving code quality
|
|
27
|
+
- Writing tests and documentation
|
|
28
|
+
- Architecture and design decisions
|
|
29
|
+
|
|
30
|
+
Supported languages (proficient):
|
|
31
|
+
- JavaScript/TypeScript
|
|
32
|
+
- Python
|
|
33
|
+
- Go, Rust
|
|
34
|
+
- Java, C#
|
|
35
|
+
- SQL
|
|
36
|
+
- HTML/CSS
|
|
37
|
+
- Shell scripting
|
|
38
|
+
|
|
39
|
+
Coding principles:
|
|
40
|
+
1. Write clean, readable, maintainable code
|
|
41
|
+
2. Follow language-specific best practices
|
|
42
|
+
3. Include error handling
|
|
43
|
+
4. Consider edge cases
|
|
44
|
+
5. Optimize for performance when needed
|
|
45
|
+
6. Write self-documenting code
|
|
46
|
+
7. Add comments only when necessary
|
|
47
|
+
|
|
48
|
+
When writing code:
|
|
49
|
+
- Start with understanding the requirements
|
|
50
|
+
- Plan the solution before coding
|
|
51
|
+
- Write modular, reusable code
|
|
52
|
+
- Test the logic mentally
|
|
53
|
+
- Provide clear explanations
|
|
54
|
+
|
|
55
|
+
When debugging:
|
|
56
|
+
- Analyze the error message carefully
|
|
57
|
+
- Identify the root cause
|
|
58
|
+
- Explain what went wrong
|
|
59
|
+
- Provide a fix with explanation
|
|
60
|
+
|
|
61
|
+
Code output format:
|
|
62
|
+
\`\`\`language
|
|
63
|
+
// code here
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Always explain your code decisions briefly.`;
|
|
67
|
+
|
|
68
|
+
export class CodingAgent extends BaseAgent {
|
|
69
|
+
constructor(tools: AgentConfig['tools'] = []) {
|
|
70
|
+
super({
|
|
71
|
+
identity: {
|
|
72
|
+
id: `coding-${nanoid(8)}`,
|
|
73
|
+
name: 'Adik',
|
|
74
|
+
role: 'coding',
|
|
75
|
+
description: 'Expert software development agent',
|
|
76
|
+
capabilities: [
|
|
77
|
+
'code_generation',
|
|
78
|
+
'debugging',
|
|
79
|
+
'code_review',
|
|
80
|
+
'refactoring',
|
|
81
|
+
'testing',
|
|
82
|
+
'documentation',
|
|
83
|
+
'architecture',
|
|
84
|
+
'optimization',
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
model: getRecommendedModel('coding'),
|
|
88
|
+
temperature: 0.2, // Low temperature for precise code
|
|
89
|
+
systemPrompt: CODING_SYSTEM_PROMPT,
|
|
90
|
+
tools,
|
|
91
|
+
maxIterations: 10,
|
|
92
|
+
timeout: 180000, // 3 minutes for complex coding tasks
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
protected buildSystemPrompt(
|
|
97
|
+
context: Record<string, unknown>,
|
|
98
|
+
memories: RetrievedMemory[]
|
|
99
|
+
): string {
|
|
100
|
+
let prompt = this.systemPrompt;
|
|
101
|
+
|
|
102
|
+
// Add code-related memories (previous solutions, patterns)
|
|
103
|
+
const codeMemories = memories.filter(
|
|
104
|
+
(m) => m.type === 'procedural' || m.metadata?.category === 'code'
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (codeMemories.length > 0) {
|
|
108
|
+
prompt += '\n\n## Relevant Code Patterns/Solutions\n';
|
|
109
|
+
for (const memory of codeMemories) {
|
|
110
|
+
prompt += `- ${memory.content}\n`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Add project context
|
|
115
|
+
if (context.projectLanguage) {
|
|
116
|
+
prompt += `\n\n## Project Language: ${context.projectLanguage}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (context.codebase) {
|
|
120
|
+
prompt += '\n\n## Codebase Context\n';
|
|
121
|
+
prompt += JSON.stringify(context.codebase, null, 2);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (context.existingCode) {
|
|
125
|
+
prompt += `\n\n## Existing Code\n\`\`\`\n${context.existingCode}\n\`\`\``;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (context.errorMessage) {
|
|
129
|
+
prompt += `\n\n## Error to Debug\n${context.errorMessage}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return prompt;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected async shouldHandoff(
|
|
136
|
+
state: AgentState,
|
|
137
|
+
result: TaskResult
|
|
138
|
+
): Promise<HandoffDecision> {
|
|
139
|
+
const output = String(result.output).toLowerCase();
|
|
140
|
+
|
|
141
|
+
// Check if research is needed
|
|
142
|
+
if (
|
|
143
|
+
output.includes('need to research') ||
|
|
144
|
+
output.includes('requires investigation') ||
|
|
145
|
+
output.includes('look up documentation')
|
|
146
|
+
) {
|
|
147
|
+
return {
|
|
148
|
+
shouldHandoff: true,
|
|
149
|
+
targetAgent: 'research',
|
|
150
|
+
reason: 'Need to research before implementation',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Check if automation is needed
|
|
155
|
+
if (
|
|
156
|
+
output.includes('deploy this') ||
|
|
157
|
+
output.includes('run regularly') ||
|
|
158
|
+
output.includes('automate deployment')
|
|
159
|
+
) {
|
|
160
|
+
return {
|
|
161
|
+
shouldHandoff: true,
|
|
162
|
+
targetAgent: 'automation',
|
|
163
|
+
reason: 'Code ready for automation/deployment',
|
|
164
|
+
context: {
|
|
165
|
+
code: result.output,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
shouldHandoff: false,
|
|
172
|
+
reason: 'Coding task complete',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Additional coding-specific methods
|
|
177
|
+
async generateCode(
|
|
178
|
+
description: string,
|
|
179
|
+
language: string = 'typescript'
|
|
180
|
+
): Promise<TaskResult> {
|
|
181
|
+
return this.execute(
|
|
182
|
+
`Generate ${language} code for the following:\n\n${description}`,
|
|
183
|
+
{ task: 'code_generation', language }
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async debug(code: string, error: string): Promise<TaskResult> {
|
|
188
|
+
return this.execute(
|
|
189
|
+
`Debug the following code:\n\n\`\`\`\n${code}\n\`\`\`\n\nError:\n${error}`,
|
|
190
|
+
{ task: 'debugging' }
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async review(code: string): Promise<TaskResult> {
|
|
195
|
+
return this.execute(
|
|
196
|
+
`Review the following code for quality, bugs, and improvements:\n\n\`\`\`\n${code}\n\`\`\``,
|
|
197
|
+
{ task: 'code_review' }
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async refactor(code: string, goal: string): Promise<TaskResult> {
|
|
202
|
+
return this.execute(
|
|
203
|
+
`Refactor the following code with this goal: ${goal}\n\n\`\`\`\n${code}\n\`\`\``,
|
|
204
|
+
{ task: 'refactoring' }
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async explainCode(code: string): Promise<TaskResult> {
|
|
209
|
+
return this.execute(
|
|
210
|
+
`Explain the following code in detail:\n\n\`\`\`\n${code}\n\`\`\``,
|
|
211
|
+
{ task: 'explanation' }
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async writeTests(code: string, framework: string = 'vitest'): Promise<TaskResult> {
|
|
216
|
+
return this.execute(
|
|
217
|
+
`Write ${framework} tests for the following code:\n\n\`\`\`\n${code}\n\`\`\``,
|
|
218
|
+
{ task: 'testing', framework }
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function createCodingAgent(tools: AgentConfig['tools'] = []): CodingAgent {
|
|
224
|
+
return new CodingAgent(tools);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export default CodingAgent;
|