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.
Files changed (132) hide show
  1. package/.env.example +49 -0
  2. package/README.md +161 -0
  3. package/dist/cli/index.d.ts +3 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +336 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/config/index.d.ts +37 -0
  8. package/dist/config/index.d.ts.map +1 -0
  9. package/dist/config/index.js +68 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/config/models.d.ts +17 -0
  12. package/dist/config/models.d.ts.map +1 -0
  13. package/dist/config/models.js +128 -0
  14. package/dist/config/models.js.map +1 -0
  15. package/dist/core/agents/agent-factory.d.ts +31 -0
  16. package/dist/core/agents/agent-factory.d.ts.map +1 -0
  17. package/dist/core/agents/agent-factory.js +151 -0
  18. package/dist/core/agents/agent-factory.js.map +1 -0
  19. package/dist/core/agents/base-agent.d.ts +51 -0
  20. package/dist/core/agents/base-agent.d.ts.map +1 -0
  21. package/dist/core/agents/base-agent.js +245 -0
  22. package/dist/core/agents/base-agent.js.map +1 -0
  23. package/dist/core/agents/index.d.ts +8 -0
  24. package/dist/core/agents/index.d.ts.map +1 -0
  25. package/dist/core/agents/index.js +9 -0
  26. package/dist/core/agents/index.js.map +1 -0
  27. package/dist/core/agents/personalities/automation.d.ts +14 -0
  28. package/dist/core/agents/personalities/automation.d.ts.map +1 -0
  29. package/dist/core/agents/personalities/automation.js +146 -0
  30. package/dist/core/agents/personalities/automation.js.map +1 -0
  31. package/dist/core/agents/personalities/chat.d.ts +10 -0
  32. package/dist/core/agents/personalities/chat.d.ts.map +1 -0
  33. package/dist/core/agents/personalities/chat.js +132 -0
  34. package/dist/core/agents/personalities/chat.js.map +1 -0
  35. package/dist/core/agents/personalities/coding.d.ts +16 -0
  36. package/dist/core/agents/personalities/coding.d.ts.map +1 -0
  37. package/dist/core/agents/personalities/coding.js +166 -0
  38. package/dist/core/agents/personalities/coding.js.map +1 -0
  39. package/dist/core/agents/personalities/research.d.ts +13 -0
  40. package/dist/core/agents/personalities/research.d.ts.map +1 -0
  41. package/dist/core/agents/personalities/research.js +133 -0
  42. package/dist/core/agents/personalities/research.js.map +1 -0
  43. package/dist/core/agents/types.d.ts +102 -0
  44. package/dist/core/agents/types.d.ts.map +1 -0
  45. package/dist/core/agents/types.js +2 -0
  46. package/dist/core/agents/types.js.map +1 -0
  47. package/dist/core/orchestrator/graph.d.ts +118 -0
  48. package/dist/core/orchestrator/graph.d.ts.map +1 -0
  49. package/dist/core/orchestrator/graph.js +233 -0
  50. package/dist/core/orchestrator/graph.js.map +1 -0
  51. package/dist/database/client.d.ts +19 -0
  52. package/dist/database/client.d.ts.map +1 -0
  53. package/dist/database/client.js +95 -0
  54. package/dist/database/client.js.map +1 -0
  55. package/dist/index.d.ts +41 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +67 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/llm/openrouter-client.d.ts +45 -0
  60. package/dist/llm/openrouter-client.d.ts.map +1 -0
  61. package/dist/llm/openrouter-client.js +155 -0
  62. package/dist/llm/openrouter-client.js.map +1 -0
  63. package/dist/memory/conversation/index.d.ts +37 -0
  64. package/dist/memory/conversation/index.d.ts.map +1 -0
  65. package/dist/memory/conversation/index.js +196 -0
  66. package/dist/memory/conversation/index.js.map +1 -0
  67. package/dist/memory/index.d.ts +4 -0
  68. package/dist/memory/index.d.ts.map +1 -0
  69. package/dist/memory/index.js +5 -0
  70. package/dist/memory/index.js.map +1 -0
  71. package/dist/memory/knowledge-base/index.d.ts +51 -0
  72. package/dist/memory/knowledge-base/index.d.ts.map +1 -0
  73. package/dist/memory/knowledge-base/index.js +222 -0
  74. package/dist/memory/knowledge-base/index.js.map +1 -0
  75. package/dist/memory/longterm/vector-store.d.ts +44 -0
  76. package/dist/memory/longterm/vector-store.d.ts.map +1 -0
  77. package/dist/memory/longterm/vector-store.js +229 -0
  78. package/dist/memory/longterm/vector-store.js.map +1 -0
  79. package/dist/safety/audit-logger.d.ts +68 -0
  80. package/dist/safety/audit-logger.d.ts.map +1 -0
  81. package/dist/safety/audit-logger.js +215 -0
  82. package/dist/safety/audit-logger.js.map +1 -0
  83. package/dist/safety/guardrails/input-guardrail.d.ts +21 -0
  84. package/dist/safety/guardrails/input-guardrail.d.ts.map +1 -0
  85. package/dist/safety/guardrails/input-guardrail.js +145 -0
  86. package/dist/safety/guardrails/input-guardrail.js.map +1 -0
  87. package/dist/safety/guardrails/output-guardrail.d.ts +18 -0
  88. package/dist/safety/guardrails/output-guardrail.d.ts.map +1 -0
  89. package/dist/safety/guardrails/output-guardrail.js +125 -0
  90. package/dist/safety/guardrails/output-guardrail.js.map +1 -0
  91. package/dist/safety/index.d.ts +4 -0
  92. package/dist/safety/index.d.ts.map +1 -0
  93. package/dist/safety/index.js +5 -0
  94. package/dist/safety/index.js.map +1 -0
  95. package/dist/utils/errors.d.ts +36 -0
  96. package/dist/utils/errors.d.ts.map +1 -0
  97. package/dist/utils/errors.js +94 -0
  98. package/dist/utils/errors.js.map +1 -0
  99. package/dist/utils/logger.d.ts +8 -0
  100. package/dist/utils/logger.d.ts.map +1 -0
  101. package/dist/utils/logger.js +47 -0
  102. package/dist/utils/logger.js.map +1 -0
  103. package/docker/init-db.sql +149 -0
  104. package/docker/sandbox/Dockerfile.sandbox +29 -0
  105. package/docker-compose.yml +61 -0
  106. package/package.json +80 -0
  107. package/src/cli/index.ts +392 -0
  108. package/src/config/index.ts +85 -0
  109. package/src/config/models.ts +156 -0
  110. package/src/core/agents/agent-factory.ts +192 -0
  111. package/src/core/agents/base-agent.ts +333 -0
  112. package/src/core/agents/index.ts +27 -0
  113. package/src/core/agents/personalities/automation.ts +202 -0
  114. package/src/core/agents/personalities/chat.ts +159 -0
  115. package/src/core/agents/personalities/coding.ts +227 -0
  116. package/src/core/agents/personalities/research.ts +177 -0
  117. package/src/core/agents/types.ts +124 -0
  118. package/src/core/orchestrator/graph.ts +305 -0
  119. package/src/database/client.ts +109 -0
  120. package/src/index.ts +104 -0
  121. package/src/llm/openrouter-client.ts +218 -0
  122. package/src/memory/conversation/index.ts +313 -0
  123. package/src/memory/index.ts +23 -0
  124. package/src/memory/knowledge-base/index.ts +357 -0
  125. package/src/memory/longterm/vector-store.ts +364 -0
  126. package/src/safety/audit-logger.ts +357 -0
  127. package/src/safety/guardrails/input-guardrail.ts +191 -0
  128. package/src/safety/guardrails/output-guardrail.ts +160 -0
  129. package/src/safety/index.ts +21 -0
  130. package/src/utils/errors.ts +120 -0
  131. package/src/utils/logger.ts +74 -0
  132. package/tsconfig.json +37 -0
@@ -0,0 +1,192 @@
1
+ import type { StructuredTool } from '@langchain/core/tools';
2
+ import { nanoid } from 'nanoid';
3
+
4
+ import { BaseAgent } from './base-agent.js';
5
+ import { ChatAgent, createChatAgent } from './personalities/chat.js';
6
+ import { ResearchAgent, createResearchAgent } from './personalities/research.js';
7
+ import { CodingAgent, createCodingAgent } from './personalities/coding.js';
8
+ import { AutomationAgent, createAutomationAgent } from './personalities/automation.js';
9
+ import type { AgentRole, AgentIdentity } from './types.js';
10
+ import { createLogger } from '../../utils/logger.js';
11
+
12
+ const logger = createLogger('AgentFactory');
13
+
14
+ export interface AgentPoolConfig {
15
+ maxAgentsPerRole: number;
16
+ defaultTools: StructuredTool[];
17
+ }
18
+
19
+ const DEFAULT_POOL_CONFIG: AgentPoolConfig = {
20
+ maxAgentsPerRole: 3,
21
+ defaultTools: [],
22
+ };
23
+
24
+ export class AgentFactory {
25
+ private config: AgentPoolConfig;
26
+ private agentPool: Map<AgentRole, BaseAgent[]> = new Map();
27
+ private allAgents: Map<string, BaseAgent> = new Map();
28
+
29
+ constructor(config: Partial<AgentPoolConfig> = {}) {
30
+ this.config = { ...DEFAULT_POOL_CONFIG, ...config };
31
+ this.initializePools();
32
+ }
33
+
34
+ private initializePools(): void {
35
+ const roles: AgentRole[] = ['chat', 'research', 'coding', 'automation'];
36
+ for (const role of roles) {
37
+ this.agentPool.set(role, []);
38
+ }
39
+ }
40
+
41
+ // Create a new agent of specific type
42
+ createAgent(role: AgentRole, tools?: StructuredTool[]): BaseAgent {
43
+ const agentTools = tools ?? this.config.defaultTools;
44
+
45
+ let agent: BaseAgent;
46
+
47
+ switch (role) {
48
+ case 'chat':
49
+ agent = createChatAgent(agentTools);
50
+ break;
51
+ case 'research':
52
+ agent = createResearchAgent(agentTools);
53
+ break;
54
+ case 'coding':
55
+ agent = createCodingAgent(agentTools);
56
+ break;
57
+ case 'automation':
58
+ agent = createAutomationAgent(agentTools);
59
+ break;
60
+ default:
61
+ throw new Error(`Unknown agent role: ${role}`);
62
+ }
63
+
64
+ // Register agent
65
+ this.allAgents.set(agent.id, agent);
66
+
67
+ // Add to pool
68
+ const pool = this.agentPool.get(role) ?? [];
69
+ pool.push(agent);
70
+ this.agentPool.set(role, pool);
71
+
72
+ logger.info('Agent created', { agentId: agent.id, role });
73
+
74
+ return agent;
75
+ }
76
+
77
+ // Get or create an available agent
78
+ getAgent(role: AgentRole): BaseAgent {
79
+ const pool = this.agentPool.get(role) ?? [];
80
+
81
+ // Find an idle agent
82
+ const idleAgent = pool.find((a) => a.getStatus() === 'idle');
83
+ if (idleAgent) {
84
+ return idleAgent;
85
+ }
86
+
87
+ // Create new agent if under limit
88
+ if (pool.length < this.config.maxAgentsPerRole) {
89
+ return this.createAgent(role);
90
+ }
91
+
92
+ // Return least busy agent (waiting status preferred over executing)
93
+ const waitingAgent = pool.find((a) => a.getStatus() === 'waiting');
94
+ if (waitingAgent) {
95
+ return waitingAgent;
96
+ }
97
+
98
+ // Return first agent as fallback
99
+ logger.warn('All agents busy, returning first agent', { role });
100
+ return pool[0]!;
101
+ }
102
+
103
+ // Get agent by ID
104
+ getAgentById(id: string): BaseAgent | undefined {
105
+ return this.allAgents.get(id);
106
+ }
107
+
108
+ // Get all agents of a role
109
+ getAgentsByRole(role: AgentRole): BaseAgent[] {
110
+ return this.agentPool.get(role) ?? [];
111
+ }
112
+
113
+ // Get all active agent identities
114
+ getActiveAgentIdentities(): AgentIdentity[] {
115
+ return Array.from(this.allAgents.values()).map((a) => a.getInfo());
116
+ }
117
+
118
+ // Release/reset an agent
119
+ releaseAgent(agentId: string): void {
120
+ const agent = this.allAgents.get(agentId);
121
+ if (agent) {
122
+ agent.reset();
123
+ logger.debug('Agent released', { agentId });
124
+ }
125
+ }
126
+
127
+ // Remove agent from pool
128
+ removeAgent(agentId: string): boolean {
129
+ const agent = this.allAgents.get(agentId);
130
+ if (!agent) return false;
131
+
132
+ // Remove from role pool
133
+ const role = agent.role as AgentRole;
134
+ const pool = this.agentPool.get(role) ?? [];
135
+ const index = pool.findIndex((a) => a.id === agentId);
136
+ if (index > -1) {
137
+ pool.splice(index, 1);
138
+ this.agentPool.set(role, pool);
139
+ }
140
+
141
+ // Remove from all agents
142
+ this.allAgents.delete(agentId);
143
+
144
+ logger.info('Agent removed', { agentId, role });
145
+ return true;
146
+ }
147
+
148
+ // Get pool statistics
149
+ getPoolStats(): Record<AgentRole, { total: number; idle: number; busy: number }> {
150
+ const stats: Record<string, { total: number; idle: number; busy: number }> = {};
151
+
152
+ for (const [role, agents] of this.agentPool) {
153
+ const idle = agents.filter((a) => a.getStatus() === 'idle').length;
154
+ stats[role] = {
155
+ total: agents.length,
156
+ idle,
157
+ busy: agents.length - idle,
158
+ };
159
+ }
160
+
161
+ return stats as Record<AgentRole, { total: number; idle: number; busy: number }>;
162
+ }
163
+
164
+ // Clear all agents
165
+ clear(): void {
166
+ for (const agent of this.allAgents.values()) {
167
+ agent.reset();
168
+ }
169
+ this.allAgents.clear();
170
+ this.initializePools();
171
+ logger.info('Agent pool cleared');
172
+ }
173
+ }
174
+
175
+ // Singleton factory instance
176
+ let factoryInstance: AgentFactory | null = null;
177
+
178
+ export function getAgentFactory(config?: Partial<AgentPoolConfig>): AgentFactory {
179
+ if (!factoryInstance) {
180
+ factoryInstance = new AgentFactory(config);
181
+ }
182
+ return factoryInstance;
183
+ }
184
+
185
+ export function resetAgentFactory(): void {
186
+ if (factoryInstance) {
187
+ factoryInstance.clear();
188
+ factoryInstance = null;
189
+ }
190
+ }
191
+
192
+ export default AgentFactory;
@@ -0,0 +1,333 @@
1
+ import { ChatOpenAI } from '@langchain/openai';
2
+ import { createReactAgent } from '@langchain/langgraph/prebuilt';
3
+ import { SystemMessage, HumanMessage, AIMessage } from '@langchain/core/messages';
4
+ import type { BaseMessage } from '@langchain/core/messages';
5
+ import type { StructuredTool } from '@langchain/core/tools';
6
+ import { nanoid } from 'nanoid';
7
+
8
+ import { getOpenRouterClient } from '../../llm/openrouter-client.js';
9
+ import { createLogger, logAgentAction } from '../../utils/logger.js';
10
+ import { AgentError } from '../../utils/errors.js';
11
+ import type {
12
+ AgentConfig,
13
+ AgentIdentity,
14
+ AgentState,
15
+ AgentStatus,
16
+ AgentEvent,
17
+ TaskDefinition,
18
+ TaskResult,
19
+ RetrievedMemory,
20
+ HandoffDecision,
21
+ } from './types.js';
22
+
23
+ const logger = createLogger('BaseAgent');
24
+
25
+ export abstract class BaseAgent {
26
+ protected readonly identity: AgentIdentity;
27
+ protected readonly model: ChatOpenAI;
28
+ protected readonly systemPrompt: string;
29
+ protected readonly tools: StructuredTool[];
30
+ protected readonly maxIterations: number;
31
+ protected readonly timeout: number;
32
+
33
+ protected status: AgentStatus = 'idle';
34
+ protected currentTask: TaskDefinition | null = null;
35
+ protected iterationCount = 0;
36
+
37
+ private eventListeners: ((event: AgentEvent) => void)[] = [];
38
+
39
+ constructor(config: AgentConfig) {
40
+ this.identity = config.identity;
41
+ this.systemPrompt = config.systemPrompt;
42
+ this.tools = config.tools;
43
+ this.maxIterations = config.maxIterations ?? 10;
44
+ this.timeout = config.timeout ?? 120000; // 2 minutes default
45
+
46
+ // Get model from OpenRouter
47
+ const client = getOpenRouterClient();
48
+ this.model = client.getChatModelForAgent({
49
+ model: config.model,
50
+ temperature: config.temperature ?? 0.7,
51
+ maxTokens: config.maxTokens,
52
+ });
53
+ }
54
+
55
+ // Identity getters
56
+ get id(): string {
57
+ return this.identity.id;
58
+ }
59
+
60
+ get name(): string {
61
+ return this.identity.name;
62
+ }
63
+
64
+ get role(): string {
65
+ return this.identity.role;
66
+ }
67
+
68
+ get capabilities(): string[] {
69
+ return this.identity.capabilities;
70
+ }
71
+
72
+ getStatus(): AgentStatus {
73
+ return this.status;
74
+ }
75
+
76
+ // Abstract methods that subclasses must implement
77
+ protected abstract buildSystemPrompt(
78
+ context: Record<string, unknown>,
79
+ memories: RetrievedMemory[]
80
+ ): string;
81
+
82
+ protected abstract shouldHandoff(
83
+ state: AgentState,
84
+ result: TaskResult
85
+ ): Promise<HandoffDecision>;
86
+
87
+ // Create the LangGraph agent
88
+ protected createAgent() {
89
+ return createReactAgent({
90
+ llm: this.model,
91
+ tools: this.tools,
92
+ });
93
+ }
94
+
95
+ // Main execution method
96
+ async execute(
97
+ input: string,
98
+ context: Record<string, unknown> = {},
99
+ memories: RetrievedMemory[] = []
100
+ ): Promise<TaskResult> {
101
+ const taskId = nanoid();
102
+ const startTime = Date.now();
103
+
104
+ this.status = 'thinking';
105
+ this.iterationCount = 0;
106
+
107
+ this.emitEvent('started', { taskId, input });
108
+
109
+ try {
110
+ // Build the full system prompt with context and memories
111
+ const fullSystemPrompt = this.buildSystemPrompt(context, memories);
112
+
113
+ // Create messages
114
+ const messages: BaseMessage[] = [
115
+ new SystemMessage(fullSystemPrompt),
116
+ new HumanMessage(input),
117
+ ];
118
+
119
+ // Create and invoke the agent
120
+ const agent = this.createAgent();
121
+
122
+ this.status = 'executing';
123
+ this.emitEvent('thinking', { taskId });
124
+
125
+ const result = await this.invokeWithTimeout(agent, messages);
126
+
127
+ const executionTime = Date.now() - startTime;
128
+ this.status = 'completed';
129
+
130
+ const taskResult: TaskResult = {
131
+ taskId,
132
+ agentId: this.id,
133
+ status: 'success',
134
+ output: this.extractOutput(result),
135
+ executionTimeMs: executionTime,
136
+ metadata: {
137
+ iterations: this.iterationCount,
138
+ model: this.model.modelName,
139
+ },
140
+ };
141
+
142
+ this.emitEvent('completed', { taskId, result: taskResult });
143
+ logAgentAction(this.id, 'execute', {
144
+ taskId,
145
+ success: true,
146
+ duration: executionTime,
147
+ });
148
+
149
+ return taskResult;
150
+ } catch (error) {
151
+ const executionTime = Date.now() - startTime;
152
+ this.status = 'error';
153
+
154
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
155
+
156
+ const taskResult: TaskResult = {
157
+ taskId,
158
+ agentId: this.id,
159
+ status: 'failed',
160
+ output: null,
161
+ error: errorMessage,
162
+ executionTimeMs: executionTime,
163
+ };
164
+
165
+ this.emitEvent('error', { taskId, error: errorMessage });
166
+ logAgentAction(this.id, 'execute', {
167
+ taskId,
168
+ success: false,
169
+ error: errorMessage,
170
+ duration: executionTime,
171
+ });
172
+
173
+ throw new AgentError(
174
+ `Agent execution failed: ${errorMessage}`,
175
+ this.id,
176
+ { taskId, originalError: errorMessage }
177
+ );
178
+ } finally {
179
+ this.currentTask = null;
180
+ this.iterationCount = 0;
181
+ }
182
+ }
183
+
184
+ // Execute with timeout
185
+ private async invokeWithTimeout(
186
+ agent: ReturnType<typeof createReactAgent>,
187
+ messages: BaseMessage[]
188
+ ): Promise<unknown> {
189
+ const timeoutPromise = new Promise((_, reject) => {
190
+ setTimeout(() => {
191
+ reject(new AgentError('Agent execution timed out', this.id));
192
+ }, this.timeout);
193
+ });
194
+
195
+ const executionPromise = agent.invoke({
196
+ messages,
197
+ });
198
+
199
+ return Promise.race([executionPromise, timeoutPromise]);
200
+ }
201
+
202
+ // Extract output from agent result
203
+ protected extractOutput(result: unknown): string {
204
+ if (!result || typeof result !== 'object') {
205
+ return String(result);
206
+ }
207
+
208
+ const agentResult = result as Record<string, unknown>;
209
+
210
+ if (Array.isArray(agentResult.messages)) {
211
+ const lastMessage = agentResult.messages[agentResult.messages.length - 1];
212
+ if (lastMessage && typeof lastMessage === 'object' && 'content' in lastMessage) {
213
+ const content = (lastMessage as AIMessage).content;
214
+ return typeof content === 'string' ? content : JSON.stringify(content);
215
+ }
216
+ }
217
+
218
+ return JSON.stringify(result);
219
+ }
220
+
221
+ // Event handling
222
+ onEvent(listener: (event: AgentEvent) => void): () => void {
223
+ this.eventListeners.push(listener);
224
+ return () => {
225
+ const index = this.eventListeners.indexOf(listener);
226
+ if (index > -1) {
227
+ this.eventListeners.splice(index, 1);
228
+ }
229
+ };
230
+ }
231
+
232
+ protected emitEvent(type: AgentEvent['type'], data: Record<string, unknown>): void {
233
+ const event: AgentEvent = {
234
+ type,
235
+ agentId: this.id,
236
+ timestamp: new Date(),
237
+ data,
238
+ };
239
+
240
+ for (const listener of this.eventListeners) {
241
+ try {
242
+ listener(event);
243
+ } catch (error) {
244
+ logger.error('Event listener error', { error });
245
+ }
246
+ }
247
+ }
248
+
249
+ // Stream execution for real-time output
250
+ async *stream(
251
+ input: string,
252
+ context: Record<string, unknown> = {},
253
+ memories: RetrievedMemory[] = []
254
+ ): AsyncGenerator<string, TaskResult, unknown> {
255
+ const taskId = nanoid();
256
+ const startTime = Date.now();
257
+
258
+ this.status = 'thinking';
259
+ this.emitEvent('started', { taskId, input });
260
+
261
+ try {
262
+ const fullSystemPrompt = this.buildSystemPrompt(context, memories);
263
+ const messages: BaseMessage[] = [
264
+ new SystemMessage(fullSystemPrompt),
265
+ new HumanMessage(input),
266
+ ];
267
+
268
+ const agent = this.createAgent();
269
+ this.status = 'executing';
270
+
271
+ let fullOutput = '';
272
+
273
+ const stream = await agent.stream({
274
+ messages,
275
+ });
276
+
277
+ for await (const chunk of stream) {
278
+ if (chunk && typeof chunk === 'object') {
279
+ const chunkData = chunk as Record<string, unknown>;
280
+ if (Array.isArray(chunkData.messages)) {
281
+ const lastMsg = chunkData.messages[chunkData.messages.length - 1];
282
+ if (lastMsg && typeof lastMsg === 'object' && 'content' in lastMsg) {
283
+ const content = (lastMsg as AIMessage).content;
284
+ if (typeof content === 'string') {
285
+ fullOutput = content;
286
+ yield content;
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+
293
+ const executionTime = Date.now() - startTime;
294
+ this.status = 'completed';
295
+
296
+ const taskResult: TaskResult = {
297
+ taskId,
298
+ agentId: this.id,
299
+ status: 'success',
300
+ output: fullOutput,
301
+ executionTimeMs: executionTime,
302
+ };
303
+
304
+ this.emitEvent('completed', { taskId, result: taskResult });
305
+ return taskResult;
306
+ } catch (error) {
307
+ this.status = 'error';
308
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
309
+ this.emitEvent('error', { taskId, error: errorMessage });
310
+ throw new AgentError(`Stream execution failed: ${errorMessage}`, this.id);
311
+ }
312
+ }
313
+
314
+ // Check if agent can handle a task
315
+ canHandle(task: TaskDefinition): boolean {
316
+ const requiredCaps = task.requiredCapabilities || [];
317
+ return requiredCaps.every((cap) => this.capabilities.includes(cap));
318
+ }
319
+
320
+ // Reset agent state
321
+ reset(): void {
322
+ this.status = 'idle';
323
+ this.currentTask = null;
324
+ this.iterationCount = 0;
325
+ }
326
+
327
+ // Get agent info for display
328
+ getInfo(): AgentIdentity {
329
+ return { ...this.identity };
330
+ }
331
+ }
332
+
333
+ export default BaseAgent;
@@ -0,0 +1,27 @@
1
+ // Agent exports
2
+ export { BaseAgent } from './base-agent.js';
3
+ export { AgentFactory, getAgentFactory, resetAgentFactory } from './agent-factory.js';
4
+
5
+ // Personalities
6
+ export { ChatAgent, createChatAgent } from './personalities/chat.js';
7
+ export { ResearchAgent, createResearchAgent } from './personalities/research.js';
8
+ export { CodingAgent, createCodingAgent } from './personalities/coding.js';
9
+ export { AutomationAgent, createAutomationAgent } from './personalities/automation.js';
10
+
11
+ // Types
12
+ export type {
13
+ AgentRole,
14
+ AgentStatus,
15
+ AgentIdentity,
16
+ AgentConfig,
17
+ AgentState,
18
+ TaskDefinition,
19
+ TaskResult,
20
+ RetrievedMemory,
21
+ AgentMessage,
22
+ HandoffDecision,
23
+ RoutingDecision,
24
+ ToolResult,
25
+ AgentEventType,
26
+ AgentEvent,
27
+ } from './types.js';