@avee1234/agent-kit 0.1.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/model/mock.ts","../src/model/openai-compatible.ts","../src/events.ts","../src/types.ts","../src/agent.ts","../src/tool.ts","../src/store/in-memory.ts","../src/store/sqlite.ts","../src/memory.ts"],"sourcesContent":["// Core\nexport { Agent } from './agent';\nexport type { AgentConfig } from './agent';\n\nexport { Tool } from './tool';\n\nexport { Memory } from './memory';\nexport type { MemoryConfig, MemoryContext } from './memory';\n\n// Model adapters\nexport type { ModelAdapter } from './model/adapter';\nexport { MockAdapter } from './model/mock';\nexport { OpenAICompatibleAdapter } from './model/openai-compatible';\nexport type { OpenAIAdapterConfig } from './model/openai-compatible';\n\n// Storage\nexport type { MemoryStore } from './store/interface';\nexport { InMemoryStore } from './store/in-memory';\nexport { SQLiteStore } from './store/sqlite';\n\n// Events\nexport { AgentEventEmitter } from './events';\n\n// Types\nexport type {\n Message,\n ToolCall,\n Summary,\n ModelConfig,\n ModelResponse,\n ModelChunk,\n ToolDefinition,\n ParameterDef,\n AgentEvent,\n} from './types';\nexport { createMessage, createSummary, isToolCallMessage } from './types';\n","// src/model/mock.ts\nimport type { ModelAdapter } from './adapter';\nimport type { Message, ModelResponse, ModelChunk, ToolDefinition } from '../types';\n\nexport class MockAdapter implements ModelAdapter {\n async chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse> {\n const lastUserMsg = [...messages].reverse().find((m) => m.role === 'user');\n const content = lastUserMsg?.content ?? '';\n\n // Check if this is a summarization request\n const systemMsg = messages.find((m) => m.role === 'system');\n if (systemMsg?.content.toLowerCase().includes('summarize')) {\n const conversationContent = messages\n .filter((m) => m.role !== 'system')\n .map((m) => m.content)\n .join(' ');\n return { content: `[Mock Summary] ${conversationContent.slice(0, 200)}` };\n }\n\n // Check if user message matches any tool\n if (tools?.length) {\n for (const tool of tools) {\n const toolNameWords = tool.name.replace(/_/g, ' ').split(' ');\n const matches = toolNameWords.some((word) =>\n content.toLowerCase().includes(word.toLowerCase()),\n );\n if (matches) {\n return {\n content: '',\n toolCalls: [\n {\n id: `mock-tc-${Date.now()}`,\n name: tool.name,\n arguments: JSON.stringify(\n Object.fromEntries(Object.keys(tool.parameters).map((key) => [key, content])),\n ),\n },\n ],\n };\n }\n }\n }\n\n return {\n content: `[Mock] Received: \"${content}\". Tools available: ${tools?.map((t) => t.name).join(', ') ?? 'none'}.`,\n };\n }\n\n async *stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk> {\n const response = await this.chat(messages, tools);\n const words = response.content.split(' ');\n for (let i = 0; i < words.length; i++) {\n yield {\n text: (i > 0 ? ' ' : '') + words[i],\n done: i === words.length - 1,\n ...(i === words.length - 1 && response.toolCalls ? { toolCalls: response.toolCalls } : {}),\n };\n }\n }\n}\n","// src/model/openai-compatible.ts\nimport type { ModelAdapter } from './adapter';\nimport type { Message, ModelResponse, ModelChunk, ToolDefinition } from '../types';\n\nexport interface OpenAIAdapterConfig {\n baseURL: string;\n model: string;\n apiKey?: string;\n}\n\nexport class OpenAICompatibleAdapter implements ModelAdapter {\n private config: OpenAIAdapterConfig;\n\n constructor(config: OpenAIAdapterConfig) {\n this.config = config;\n }\n\n async chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse> {\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages: messages.map((m) => this.toOpenAIMessage(m)),\n };\n if (tools?.length) {\n body.tools = tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters },\n },\n }));\n }\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n\n const response = await fetch(`${this.config.baseURL}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Model API error (${response.status}): ${errorText}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data: any = await response.json();\n const choice = data.choices[0].message;\n const result: ModelResponse = { content: choice.content ?? '' };\n if (choice.tool_calls?.length) {\n result.toolCalls = choice.tool_calls.map(\n (tc: { id: string; function: { name: string; arguments: string } }) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }),\n );\n }\n if (data.usage) {\n result.tokens = { input: data.usage.prompt_tokens, output: data.usage.completion_tokens };\n }\n return result;\n }\n\n async *stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages: messages.map((m) => this.toOpenAIMessage(m)),\n stream: true,\n };\n if (tools?.length) {\n body.tools = tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters },\n },\n }));\n }\n const response = await fetch(`${this.config.baseURL}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Model API error (${response.status}): ${errorText}`);\n }\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n const decoder = new TextDecoder();\n let buffer = '';\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n yield { text: '', done: true };\n return;\n }\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta;\n if (delta?.content) yield { text: delta.content, done: false };\n }\n }\n }\n\n private toOpenAIMessage(msg: Message): Record<string, unknown> {\n const result: Record<string, unknown> = { role: msg.role, content: msg.content };\n if (msg.toolCalls) {\n result.tool_calls = msg.toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: { name: tc.name, arguments: tc.arguments },\n }));\n }\n if (msg.toolCallId) result.tool_call_id = msg.toolCallId;\n return result;\n }\n}\n","// src/events.ts\nimport type { AgentEvent } from './types';\n\ntype EventHandler = (event: AgentEvent) => void;\n\nexport class AgentEventEmitter {\n private listeners = new Map<string, Set<EventHandler>>();\n\n on(type: string, handler: EventHandler): void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n }\n\n off(type: string, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n emit(event: AgentEvent): void {\n this.listeners.get(event.type)?.forEach((handler) => handler(event));\n if (event.type !== '*') {\n this.listeners.get('*')?.forEach((handler) => handler(event));\n }\n }\n}\n","// src/types.ts\n\n// --- Messages ---\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: string; // JSON string\n}\n\nexport interface Message {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n timestamp: number;\n toolCalls?: ToolCall[];\n toolCallId?: string; // for role: 'tool' — links to ToolCall.id\n}\n\nexport function createMessage(opts: Omit<Message, 'timestamp'> & { timestamp?: number }): Message {\n return {\n ...opts,\n timestamp: opts.timestamp ?? Date.now(),\n };\n}\n\nexport function isToolCallMessage(msg: Message): boolean {\n return Array.isArray(msg.toolCalls) && msg.toolCalls.length > 0;\n}\n\n// --- Summaries ---\n\nexport interface Summary {\n id: string;\n content: string;\n timestamp: number;\n messageRange: { from: number; to: number }; // timestamps of summarized messages\n}\n\nexport function createSummary(\n opts: Omit<Summary, 'id' | 'timestamp' | 'messageRange'> & {\n id?: string;\n timestamp?: number;\n messageRange?: { from: number; to: number };\n },\n): Summary {\n return {\n id: opts.id ?? crypto.randomUUID(),\n content: opts.content,\n timestamp: opts.timestamp ?? Date.now(),\n messageRange: opts.messageRange ?? { from: 0, to: 0 },\n };\n}\n\n// --- Model ---\n\nexport interface ModelConfig {\n provider?: 'ollama';\n baseURL?: string;\n apiKey?: string;\n model: string;\n}\n\nexport interface ModelResponse {\n content: string;\n toolCalls?: ToolCall[];\n tokens?: { input: number; output: number };\n}\n\nexport interface ModelChunk {\n text: string;\n toolCalls?: ToolCall[];\n done: boolean;\n}\n\n// --- Tools ---\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, ParameterDef>;\n}\n\nexport interface ParameterDef {\n type: string;\n description?: string;\n enum?: string[];\n required?: boolean;\n}\n\n// --- Events ---\n\nexport interface AgentEvent {\n type: string;\n timestamp: number;\n agentId: string;\n data: Record<string, unknown>;\n latencyMs?: number;\n tokens?: { input: number; output: number };\n}\n","// src/agent.ts\nimport type { ModelAdapter } from './model/adapter';\nimport { MockAdapter } from './model/mock';\nimport { OpenAICompatibleAdapter } from './model/openai-compatible';\nimport type { Memory } from './memory';\nimport type { Tool } from './tool';\nimport { AgentEventEmitter } from './events';\nimport { createMessage, isToolCallMessage } from './types';\nimport type { Message, ModelConfig, ModelResponse, ModelChunk, AgentEvent } from './types';\n\nexport interface AgentConfig {\n name: string;\n model?: ModelAdapter | ModelConfig;\n memory?: Memory;\n tools?: Tool[];\n system?: string;\n maxToolRounds?: number;\n}\n\nexport class Agent {\n private name: string;\n private model: ModelAdapter;\n private memory?: Memory;\n private tools: Tool[];\n private toolMap: Map<string, Tool>;\n private system?: string;\n private maxToolRounds: number;\n private emitter: AgentEventEmitter;\n\n constructor(config: AgentConfig) {\n this.name = config.name;\n this.memory = config.memory;\n this.tools = config.tools ?? [];\n this.system = config.system;\n this.maxToolRounds = config.maxToolRounds ?? 10;\n this.emitter = new AgentEventEmitter();\n\n // Build tool map for quick lookup\n this.toolMap = new Map(this.tools.map((t) => [t.name, t]));\n\n // Resolve model adapter\n if (!config.model) {\n this.model = new MockAdapter();\n } else if (this.isModelAdapter(config.model)) {\n this.model = config.model;\n } else {\n // ModelConfig object — create OpenAICompatibleAdapter\n const cfg = config.model as ModelConfig;\n const baseURL =\n cfg.provider === 'ollama'\n ? (cfg.baseURL ?? 'http://localhost:11434/v1')\n : (cfg.baseURL ?? 'http://localhost:11434/v1');\n this.model = new OpenAICompatibleAdapter({\n baseURL,\n model: cfg.model,\n apiKey: cfg.apiKey,\n });\n }\n\n // Wire memory model for summarization\n if (this.memory) {\n this.memory.setModel(this.model);\n }\n }\n\n private isModelAdapter(obj: ModelAdapter | ModelConfig): obj is ModelAdapter {\n return typeof (obj as ModelAdapter).chat === 'function';\n }\n\n on(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.on(type, handler);\n }\n\n off(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.off(type, handler);\n }\n\n private emit(type: string, data: Record<string, unknown>, extras?: Partial<AgentEvent>): void {\n this.emitter.emit({\n type,\n timestamp: Date.now(),\n agentId: this.name,\n data,\n ...extras,\n });\n }\n\n async chat(input: string): Promise<ModelResponse> {\n const toolDefs = this.tools.map((t) => t.definition);\n\n // Build initial messages\n const messages: Message[] = [];\n\n // Add system prompt\n if (this.system) {\n messages.push(createMessage({ role: 'system', content: this.system }));\n }\n\n // Add memory context (summaries + recent messages)\n if (this.memory) {\n const ctx = await this.memory.getContext(this.name, input);\n this.emit('memory:retrieve', {\n summaries: ctx.relevantSummaries.length,\n recentMessages: ctx.recentMessages.length,\n });\n\n // Add relevant summaries as system context\n for (const summary of ctx.relevantSummaries) {\n messages.push(\n createMessage({\n role: 'system',\n content: `[Previous conversation summary]: ${summary.content}`,\n timestamp: summary.timestamp,\n }),\n );\n }\n\n // Add recent messages\n messages.push(...ctx.recentMessages);\n }\n\n // Add current user message\n const userMessage = createMessage({ role: 'user', content: input });\n messages.push(userMessage);\n\n // Emit user message event\n this.emit('message', { role: 'user', content: input });\n\n // Main tool loop\n let response: ModelResponse = { content: '' };\n let toolRoundsUsed = 0;\n\n // First model call\n response = await this.model.chat(messages, toolDefs.length ? toolDefs : undefined);\n\n // Tool call loop\n while (\n isToolCallMessage({ ...response, role: 'assistant', timestamp: Date.now() }) &&\n toolRoundsUsed < this.maxToolRounds\n ) {\n // Append assistant's tool-calling message\n const assistantMsg = createMessage({\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n });\n messages.push(assistantMsg);\n\n // Execute each tool call\n for (const toolCall of response.toolCalls ?? []) {\n const tool = this.toolMap.get(toolCall.name);\n const startTime = Date.now();\n\n this.emit('tool:start', {\n toolName: toolCall.name,\n toolCallId: toolCall.id,\n arguments: toolCall.arguments,\n });\n\n let toolResult: string;\n if (!tool) {\n toolResult = `Error: tool \"${toolCall.name}\" not found`;\n this.emit('error', {\n message: `Tool not found: ${toolCall.name}`,\n toolCallId: toolCall.id,\n });\n } else {\n try {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(toolCall.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n const result = await tool.execute(parsedArgs);\n toolResult = typeof result === 'string' ? result : JSON.stringify(result);\n } catch (err) {\n const error = err as Error;\n toolResult = `Error: ${error.message}`;\n this.emit('error', {\n message: error.message,\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n });\n }\n }\n\n const latencyMs = Date.now() - startTime;\n this.emit('tool:end', {\n toolName: toolCall.name,\n toolCallId: toolCall.id,\n result: toolResult,\n latencyMs,\n });\n\n // Append tool result message\n messages.push(\n createMessage({\n role: 'tool',\n content: toolResult,\n toolCallId: toolCall.id,\n }),\n );\n }\n\n toolRoundsUsed++;\n\n // Call model again with tool results\n response = await this.model.chat(messages, toolDefs.length ? toolDefs : undefined);\n }\n\n // Emit final assistant message event\n this.emit('message', { role: 'assistant', content: response.content });\n\n // Save exchange to memory\n if (this.memory) {\n const exchangeMessages: Message[] = [\n userMessage,\n createMessage({\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }),\n ];\n await this.memory.saveExchange(this.name, exchangeMessages);\n }\n\n return response;\n }\n\n async *stream(input: string): AsyncIterable<ModelChunk> {\n const toolDefs = this.tools.map((t) => t.definition);\n\n // Build messages\n const messages: Message[] = [];\n\n if (this.system) {\n messages.push(createMessage({ role: 'system', content: this.system }));\n }\n\n if (this.memory) {\n const ctx = await this.memory.getContext(this.name, input);\n for (const summary of ctx.relevantSummaries) {\n messages.push(\n createMessage({\n role: 'system',\n content: `[Previous conversation summary]: ${summary.content}`,\n timestamp: summary.timestamp,\n }),\n );\n }\n messages.push(...ctx.recentMessages);\n }\n\n const userMessage = createMessage({ role: 'user', content: input });\n messages.push(userMessage);\n\n this.emit('message', { role: 'user', content: input });\n\n // Stream response\n let fullText = '';\n for await (const chunk of this.model.stream(messages, toolDefs.length ? toolDefs : undefined)) {\n fullText += chunk.text;\n yield chunk;\n }\n\n this.emit('message', { role: 'assistant', content: fullText });\n\n // Save to memory\n if (this.memory) {\n await this.memory.saveExchange(this.name, [\n userMessage,\n createMessage({ role: 'assistant', content: fullText }),\n ]);\n }\n }\n}\n","// src/tool.ts\nimport type { ToolDefinition, ParameterDef } from './types';\n\ninterface ToolConfig {\n name: string;\n description: string;\n parameters: Record<string, ParameterDef>;\n execute: (params: Record<string, unknown>) => Promise<unknown>;\n}\n\nexport class Tool {\n readonly name: string;\n readonly description: string;\n readonly definition: ToolDefinition;\n private executeFn: (params: Record<string, unknown>) => Promise<unknown>;\n\n private constructor(config: ToolConfig) {\n this.name = config.name;\n this.description = config.description;\n this.definition = {\n name: config.name,\n description: config.description,\n parameters: config.parameters,\n };\n this.executeFn = config.execute;\n }\n\n static create(config: ToolConfig): Tool {\n return new Tool(config);\n }\n\n async execute(params: Record<string, unknown>): Promise<unknown> {\n return this.executeFn(params);\n }\n}\n","// src/store/in-memory.ts\nimport type { Message, Summary } from '../types';\nimport type { MemoryStore } from './interface';\n\nexport class InMemoryStore implements MemoryStore {\n private messages = new Map<string, Message[]>();\n private summaries = new Map<string, Summary[]>();\n\n async saveMessages(agentId: string, messages: Message[]): Promise<void> {\n const existing = this.messages.get(agentId) ?? [];\n existing.push(...messages);\n this.messages.set(agentId, existing);\n }\n\n async getRecentMessages(agentId: string, limit: number): Promise<Message[]> {\n const all = this.messages.get(agentId) ?? [];\n return all.slice(-limit);\n }\n\n async saveSummary(agentId: string, summary: Summary): Promise<void> {\n const existing = this.summaries.get(agentId) ?? [];\n existing.push(summary);\n this.summaries.set(agentId, existing);\n }\n\n async searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]> {\n const all = this.summaries.get(agentId) ?? [];\n const queryLower = query.toLowerCase();\n const matches = all\n .filter((s) => s.content.toLowerCase().includes(queryLower))\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, limit);\n return matches;\n }\n}\n","// src/store/sqlite.ts\nimport { createRequire } from 'module';\nimport type { Message, Summary } from '../types';\nimport type { MemoryStore } from './interface';\n\nconst require = createRequire(import.meta.url);\n\nexport class SQLiteStore implements MemoryStore {\n private db: import('better-sqlite3').Database;\n\n constructor(path: string) {\n const Database = require('better-sqlite3');\n this.db = new Database(path);\n this.db.pragma('journal_mode = WAL');\n this.init();\n }\n\n private init(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n agent_id TEXT NOT NULL,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n tool_calls TEXT,\n tool_call_id TEXT\n );\n CREATE TABLE IF NOT EXISTS summaries (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n message_range_from INTEGER NOT NULL,\n message_range_to INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_messages_agent ON messages(agent_id);\n CREATE INDEX IF NOT EXISTS idx_summaries_agent ON summaries(agent_id);\n `);\n }\n\n async saveMessages(agentId: string, messages: Message[]): Promise<void> {\n const stmt = this.db.prepare(\n 'INSERT INTO messages (agent_id, role, content, timestamp, tool_calls, tool_call_id) VALUES (?, ?, ?, ?, ?, ?)',\n );\n const insertMany = this.db.transaction((msgs: Message[]) => {\n for (const msg of msgs) {\n stmt.run(\n agentId,\n msg.role,\n msg.content,\n msg.timestamp,\n msg.toolCalls ? JSON.stringify(msg.toolCalls) : null,\n msg.toolCallId ?? null,\n );\n }\n });\n insertMany(messages);\n }\n\n async getRecentMessages(agentId: string, limit: number): Promise<Message[]> {\n const rows = this.db\n .prepare(\n `SELECT role, content, timestamp, tool_calls, tool_call_id\n FROM messages WHERE agent_id = ?\n ORDER BY id DESC LIMIT ?`,\n )\n .all(agentId, limit) as Array<{\n role: Message['role'];\n content: string;\n timestamp: number;\n tool_calls: string | null;\n tool_call_id: string | null;\n }>;\n\n return rows.reverse().map((row) => ({\n role: row.role,\n content: row.content,\n timestamp: row.timestamp,\n ...(row.tool_calls ? { toolCalls: JSON.parse(row.tool_calls) } : {}),\n ...(row.tool_call_id ? { toolCallId: row.tool_call_id } : {}),\n }));\n }\n\n async saveSummary(agentId: string, summary: Summary): Promise<void> {\n this.db\n .prepare(\n 'INSERT INTO summaries (id, agent_id, content, timestamp, message_range_from, message_range_to) VALUES (?, ?, ?, ?, ?, ?)',\n )\n .run(\n summary.id,\n agentId,\n summary.content,\n summary.timestamp,\n summary.messageRange.from,\n summary.messageRange.to,\n );\n }\n\n async searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]> {\n const rows = this.db\n .prepare(\n `SELECT id, content, timestamp, message_range_from, message_range_to\n FROM summaries WHERE agent_id = ? AND content LIKE ?\n ORDER BY timestamp DESC LIMIT ?`,\n )\n .all(agentId, `%${query}%`, limit) as Array<{\n id: string;\n content: string;\n timestamp: number;\n message_range_from: number;\n message_range_to: number;\n }>;\n\n return rows.map((row) => ({\n id: row.id,\n content: row.content,\n timestamp: row.timestamp,\n messageRange: { from: row.message_range_from, to: row.message_range_to },\n }));\n }\n\n close(): void {\n this.db.close();\n }\n}\n","// src/memory.ts\nimport type { Message, Summary } from './types';\nimport { createSummary } from './types';\nimport type { MemoryStore } from './store/interface';\nimport { InMemoryStore } from './store/in-memory';\nimport { SQLiteStore } from './store/sqlite';\nimport type { ModelAdapter } from './model/adapter';\n\nexport interface MemoryConfig {\n store?: 'memory' | 'sqlite' | MemoryStore;\n path?: string;\n windowSize?: number;\n summarizeAfter?: number;\n}\n\nexport interface MemoryContext {\n recentMessages: Message[];\n relevantSummaries: Summary[];\n}\n\nexport class Memory {\n private store: MemoryStore;\n private windowSize: number;\n private summarizeAfter: number;\n private model?: ModelAdapter;\n private messageCount = new Map<string, number>();\n\n constructor(config: MemoryConfig = {}) {\n this.windowSize = config.windowSize ?? 20;\n this.summarizeAfter = config.summarizeAfter ?? 20;\n\n if (!config.store || config.store === 'memory') {\n this.store = new InMemoryStore();\n } else if (config.store === 'sqlite') {\n this.store = new SQLiteStore(config.path ?? './agent-memory.db');\n } else {\n this.store = config.store;\n }\n }\n\n setModel(model: ModelAdapter): void {\n this.model = model;\n }\n\n getStore(): MemoryStore {\n return this.store;\n }\n\n async saveExchange(agentId: string, messages: Message[]): Promise<void> {\n await this.store.saveMessages(agentId, messages);\n const count = (this.messageCount.get(agentId) ?? 0) + messages.length;\n this.messageCount.set(agentId, count);\n if (count >= this.summarizeAfter && this.model) {\n await this.summarize(agentId);\n this.messageCount.set(agentId, 0);\n }\n }\n\n async getContext(agentId: string, query: string): Promise<MemoryContext> {\n const recentMessages = await this.store.getRecentMessages(agentId, this.windowSize);\n const relevantSummaries = await this.store.searchSummaries(agentId, query, 3);\n return { recentMessages, relevantSummaries };\n }\n\n private async summarize(agentId: string): Promise<void> {\n if (!this.model) return;\n const allRecent = await this.store.getRecentMessages(agentId, this.summarizeAfter);\n if (allRecent.length === 0) return;\n const summaryResponse = await this.model.chat([\n {\n role: 'system',\n content:\n 'Summarize the following conversation concisely. Focus on key topics, decisions, and facts discussed.',\n timestamp: Date.now(),\n },\n ...allRecent,\n ]);\n const summary = createSummary({\n content: summaryResponse.content,\n messageRange: {\n from: allRecent[0].timestamp,\n to: allRecent[allRecent.length - 1].timestamp,\n },\n });\n await this.store.saveSummary(agentId, summary);\n }\n\n close(): void {\n if (\n 'close' in this.store &&\n typeof (this.store as { close: () => void }).close === 'function'\n ) {\n (this.store as { close: () => void }).close();\n }\n }\n}\n"],"mappings":"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","names":["require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/model/mock.ts","../src/model/openai-compatible.ts","../src/events.ts","../src/types.ts","../src/agent.ts","../src/strategy/sequential.ts","../src/strategy/parallel.ts","../src/strategy/debate.ts","../src/tool.ts","../src/strategy/hierarchical.ts","../src/team.ts","../src/store/cosine.ts","../src/store/in-memory.ts","../src/store/sqlite.ts","../src/memory.ts","../src/model/ollama-embedding.ts"],"sourcesContent":["// Core\nexport { Agent } from './agent';\nexport type { AgentConfig } from './agent';\n\nexport { Team } from './team';\nexport type { TeamConfig, TeamResult, AgentResponse } from './team';\n\nexport { Tool } from './tool';\n\nexport { Memory } from './memory';\nexport type { MemoryConfig, MemoryContext } from './memory';\n\n// Model adapters\nexport type { ModelAdapter } from './model/adapter';\nexport { MockAdapter } from './model/mock';\nexport { OpenAICompatibleAdapter } from './model/openai-compatible';\nexport type { OpenAIAdapterConfig } from './model/openai-compatible';\nexport type { EmbeddingAdapter } from './model/embedding-adapter';\nexport { OllamaEmbeddingAdapter } from './model/ollama-embedding';\nexport type { OllamaEmbeddingConfig } from './model/ollama-embedding';\n\n// Storage\nexport type { MemoryStore } from './store/interface';\nexport { InMemoryStore } from './store/in-memory';\nexport { SQLiteStore } from './store/sqlite';\n\n// Events\nexport { AgentEventEmitter } from './events';\n\n// Types\nexport type {\n Message,\n ToolCall,\n Summary,\n ModelConfig,\n ModelResponse,\n ModelChunk,\n ToolDefinition,\n ParameterDef,\n AgentEvent,\n} from './types';\nexport { createMessage, createSummary, isToolCallMessage } from './types';\n","// src/model/mock.ts\nimport type { ModelAdapter } from './adapter';\nimport type { Message, ModelResponse, ModelChunk, ToolDefinition } from '../types';\n\nexport class MockAdapter implements ModelAdapter {\n async chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse> {\n const lastUserMsg = [...messages].reverse().find((m) => m.role === 'user');\n const content = lastUserMsg?.content ?? '';\n\n // Check if this is a summarization request\n const systemMsg = messages.find((m) => m.role === 'system');\n if (systemMsg?.content.toLowerCase().includes('summarize')) {\n const conversationContent = messages\n .filter((m) => m.role !== 'system')\n .map((m) => m.content)\n .join(' ');\n return { content: `[Mock Summary] ${conversationContent.slice(0, 200)}` };\n }\n\n // Check if user message matches any tool\n if (tools?.length) {\n for (const tool of tools) {\n const toolNameWords = tool.name.replace(/_/g, ' ').split(' ');\n const matches = toolNameWords.some((word) =>\n content.toLowerCase().includes(word.toLowerCase()),\n );\n if (matches) {\n return {\n content: '',\n toolCalls: [\n {\n id: `mock-tc-${Date.now()}`,\n name: tool.name,\n arguments: JSON.stringify(\n Object.fromEntries(Object.keys(tool.parameters).map((key) => [key, content])),\n ),\n },\n ],\n };\n }\n }\n }\n\n return {\n content: `[Mock] Received: \"${content}\". Tools available: ${tools?.map((t) => t.name).join(', ') ?? 'none'}.`,\n };\n }\n\n async *stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk> {\n const response = await this.chat(messages, tools);\n const words = response.content.split(' ');\n for (let i = 0; i < words.length; i++) {\n yield {\n text: (i > 0 ? ' ' : '') + words[i],\n done: i === words.length - 1,\n ...(i === words.length - 1 && response.toolCalls ? { toolCalls: response.toolCalls } : {}),\n };\n }\n }\n}\n","// src/model/openai-compatible.ts\nimport type { ModelAdapter } from './adapter';\nimport type { Message, ModelResponse, ModelChunk, ToolDefinition } from '../types';\n\nexport interface OpenAIAdapterConfig {\n baseURL: string;\n model: string;\n apiKey?: string;\n}\n\nexport class OpenAICompatibleAdapter implements ModelAdapter {\n private config: OpenAIAdapterConfig;\n\n constructor(config: OpenAIAdapterConfig) {\n this.config = config;\n }\n\n async chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse> {\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages: messages.map((m) => this.toOpenAIMessage(m)),\n };\n if (tools?.length) {\n body.tools = tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters },\n },\n }));\n }\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n\n const response = await fetch(`${this.config.baseURL}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Model API error (${response.status}): ${errorText}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data: any = await response.json();\n const choice = data.choices[0].message;\n const result: ModelResponse = { content: choice.content ?? '' };\n if (choice.tool_calls?.length) {\n result.toolCalls = choice.tool_calls.map(\n (tc: { id: string; function: { name: string; arguments: string } }) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }),\n );\n }\n if (data.usage) {\n result.tokens = { input: data.usage.prompt_tokens, output: data.usage.completion_tokens };\n }\n return result;\n }\n\n async *stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages: messages.map((m) => this.toOpenAIMessage(m)),\n stream: true,\n };\n if (tools?.length) {\n body.tools = tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters },\n },\n }));\n }\n const response = await fetch(`${this.config.baseURL}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Model API error (${response.status}): ${errorText}`);\n }\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n const decoder = new TextDecoder();\n let buffer = '';\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n yield { text: '', done: true };\n return;\n }\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta;\n if (delta?.content) yield { text: delta.content, done: false };\n }\n }\n }\n\n private toOpenAIMessage(msg: Message): Record<string, unknown> {\n const result: Record<string, unknown> = { role: msg.role, content: msg.content };\n if (msg.toolCalls) {\n result.tool_calls = msg.toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: { name: tc.name, arguments: tc.arguments },\n }));\n }\n if (msg.toolCallId) result.tool_call_id = msg.toolCallId;\n return result;\n }\n}\n","// src/events.ts\nimport type { AgentEvent } from './types';\n\ntype EventHandler = (event: AgentEvent) => void;\n\nexport class AgentEventEmitter {\n private listeners = new Map<string, Set<EventHandler>>();\n\n on(type: string, handler: EventHandler): void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n }\n\n off(type: string, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n emit(event: AgentEvent): void {\n this.listeners.get(event.type)?.forEach((handler) => handler(event));\n if (event.type !== '*') {\n this.listeners.get('*')?.forEach((handler) => handler(event));\n }\n }\n}\n","// src/types.ts\n\n// --- Messages ---\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: string; // JSON string\n}\n\nexport interface Message {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n timestamp: number;\n toolCalls?: ToolCall[];\n toolCallId?: string; // for role: 'tool' — links to ToolCall.id\n}\n\nexport function createMessage(opts: Omit<Message, 'timestamp'> & { timestamp?: number }): Message {\n return {\n ...opts,\n timestamp: opts.timestamp ?? Date.now(),\n };\n}\n\nexport function isToolCallMessage(msg: Message): boolean {\n return Array.isArray(msg.toolCalls) && msg.toolCalls.length > 0;\n}\n\n// --- Summaries ---\n\nexport interface Summary {\n id: string;\n content: string;\n timestamp: number;\n messageRange: { from: number; to: number }; // timestamps of summarized messages\n}\n\nexport function createSummary(\n opts: Omit<Summary, 'id' | 'timestamp' | 'messageRange'> & {\n id?: string;\n timestamp?: number;\n messageRange?: { from: number; to: number };\n },\n): Summary {\n return {\n id: opts.id ?? crypto.randomUUID(),\n content: opts.content,\n timestamp: opts.timestamp ?? Date.now(),\n messageRange: opts.messageRange ?? { from: 0, to: 0 },\n };\n}\n\n// --- Model ---\n\nexport interface ModelConfig {\n provider?: 'ollama';\n baseURL?: string;\n apiKey?: string;\n model: string;\n}\n\nexport interface ModelResponse {\n content: string;\n toolCalls?: ToolCall[];\n tokens?: { input: number; output: number };\n}\n\nexport interface ModelChunk {\n text: string;\n toolCalls?: ToolCall[];\n done: boolean;\n}\n\n// --- Tools ---\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, ParameterDef>;\n}\n\nexport interface ParameterDef {\n type: string;\n description?: string;\n enum?: string[];\n required?: boolean;\n}\n\n// --- Events ---\n\nexport interface AgentEvent {\n type: string;\n timestamp: number;\n agentId: string;\n data: Record<string, unknown>;\n latencyMs?: number;\n tokens?: { input: number; output: number };\n}\n","// src/agent.ts\nimport type { ModelAdapter } from './model/adapter';\nimport { MockAdapter } from './model/mock';\nimport { OpenAICompatibleAdapter } from './model/openai-compatible';\nimport type { Memory } from './memory';\nimport type { Tool } from './tool';\nimport { AgentEventEmitter } from './events';\nimport { createMessage, isToolCallMessage } from './types';\nimport type { Message, ModelConfig, ModelResponse, ModelChunk, AgentEvent } from './types';\n\nexport interface AgentConfig {\n name: string;\n model?: ModelAdapter | ModelConfig;\n memory?: Memory;\n tools?: Tool[];\n system?: string;\n maxToolRounds?: number;\n}\n\nexport class Agent {\n readonly name: string;\n private model: ModelAdapter;\n private memory?: Memory;\n private tools: Tool[];\n private toolMap: Map<string, Tool>;\n private system?: string;\n private maxToolRounds: number;\n private emitter: AgentEventEmitter;\n\n constructor(config: AgentConfig) {\n this.name = config.name;\n this.memory = config.memory;\n this.tools = config.tools ?? [];\n this.system = config.system;\n this.maxToolRounds = config.maxToolRounds ?? 10;\n this.emitter = new AgentEventEmitter();\n\n // Build tool map for quick lookup\n this.toolMap = new Map(this.tools.map((t) => [t.name, t]));\n\n // Resolve model adapter\n if (!config.model) {\n this.model = new MockAdapter();\n } else if (this.isModelAdapter(config.model)) {\n this.model = config.model;\n } else {\n // ModelConfig object — create OpenAICompatibleAdapter\n const cfg = config.model as ModelConfig;\n const baseURL =\n cfg.provider === 'ollama'\n ? (cfg.baseURL ?? 'http://localhost:11434/v1')\n : (cfg.baseURL ?? 'http://localhost:11434/v1');\n this.model = new OpenAICompatibleAdapter({\n baseURL,\n model: cfg.model,\n apiKey: cfg.apiKey,\n });\n }\n\n // Wire memory model for summarization\n if (this.memory) {\n this.memory.setModel(this.model);\n }\n }\n\n private isModelAdapter(obj: ModelAdapter | ModelConfig): obj is ModelAdapter {\n return typeof (obj as ModelAdapter).chat === 'function';\n }\n\n getModel(): ModelAdapter {\n return this.model;\n }\n\n on(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.on(type, handler);\n }\n\n off(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.off(type, handler);\n }\n\n private emit(type: string, data: Record<string, unknown>, extras?: Partial<AgentEvent>): void {\n this.emitter.emit({\n type,\n timestamp: Date.now(),\n agentId: this.name,\n data,\n ...extras,\n });\n }\n\n async chat(input: string): Promise<ModelResponse> {\n const toolDefs = this.tools.map((t) => t.definition);\n\n // Build initial messages\n const messages: Message[] = [];\n\n // Add system prompt\n if (this.system) {\n messages.push(createMessage({ role: 'system', content: this.system }));\n }\n\n // Add memory context (summaries + recent messages)\n if (this.memory) {\n const ctx = await this.memory.getContext(this.name, input);\n this.emit('memory:retrieve', {\n summaries: ctx.relevantSummaries.length,\n recentMessages: ctx.recentMessages.length,\n });\n\n // Add relevant summaries as system context\n for (const summary of ctx.relevantSummaries) {\n messages.push(\n createMessage({\n role: 'system',\n content: `[Previous conversation summary]: ${summary.content}`,\n timestamp: summary.timestamp,\n }),\n );\n }\n\n // Add recent messages\n messages.push(...ctx.recentMessages);\n }\n\n // Add current user message\n const userMessage = createMessage({ role: 'user', content: input });\n messages.push(userMessage);\n\n // Emit user message event\n this.emit('message', { role: 'user', content: input });\n\n // Main tool loop\n let response: ModelResponse = { content: '' };\n let toolRoundsUsed = 0;\n\n // First model call\n response = await this.model.chat(messages, toolDefs.length ? toolDefs : undefined);\n\n // Tool call loop\n while (\n isToolCallMessage({ ...response, role: 'assistant', timestamp: Date.now() }) &&\n toolRoundsUsed < this.maxToolRounds\n ) {\n // Append assistant's tool-calling message\n const assistantMsg = createMessage({\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n });\n messages.push(assistantMsg);\n\n // Execute each tool call\n for (const toolCall of response.toolCalls ?? []) {\n const tool = this.toolMap.get(toolCall.name);\n const startTime = Date.now();\n\n this.emit('tool:start', {\n toolName: toolCall.name,\n toolCallId: toolCall.id,\n arguments: toolCall.arguments,\n });\n\n let toolResult: string;\n if (!tool) {\n toolResult = `Error: tool \"${toolCall.name}\" not found`;\n this.emit('error', {\n message: `Tool not found: ${toolCall.name}`,\n toolCallId: toolCall.id,\n });\n } else {\n try {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(toolCall.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n const result = await tool.execute(parsedArgs);\n toolResult = typeof result === 'string' ? result : JSON.stringify(result);\n } catch (err) {\n const error = err as Error;\n toolResult = `Error: ${error.message}`;\n this.emit('error', {\n message: error.message,\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n });\n }\n }\n\n const latencyMs = Date.now() - startTime;\n this.emit('tool:end', {\n toolName: toolCall.name,\n toolCallId: toolCall.id,\n result: toolResult,\n latencyMs,\n });\n\n // Append tool result message\n messages.push(\n createMessage({\n role: 'tool',\n content: toolResult,\n toolCallId: toolCall.id,\n }),\n );\n }\n\n toolRoundsUsed++;\n\n // Call model again with tool results\n response = await this.model.chat(messages, toolDefs.length ? toolDefs : undefined);\n }\n\n // Emit final assistant message event\n this.emit('message', { role: 'assistant', content: response.content });\n\n // Save exchange to memory\n if (this.memory) {\n const exchangeMessages: Message[] = [\n userMessage,\n createMessage({\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }),\n ];\n await this.memory.saveExchange(this.name, exchangeMessages);\n }\n\n return response;\n }\n\n async *stream(input: string): AsyncIterable<ModelChunk> {\n const toolDefs = this.tools.map((t) => t.definition);\n\n // Build messages\n const messages: Message[] = [];\n\n if (this.system) {\n messages.push(createMessage({ role: 'system', content: this.system }));\n }\n\n if (this.memory) {\n const ctx = await this.memory.getContext(this.name, input);\n for (const summary of ctx.relevantSummaries) {\n messages.push(\n createMessage({\n role: 'system',\n content: `[Previous conversation summary]: ${summary.content}`,\n timestamp: summary.timestamp,\n }),\n );\n }\n messages.push(...ctx.recentMessages);\n }\n\n const userMessage = createMessage({ role: 'user', content: input });\n messages.push(userMessage);\n\n this.emit('message', { role: 'user', content: input });\n\n // Stream response\n let fullText = '';\n for await (const chunk of this.model.stream(messages, toolDefs.length ? toolDefs : undefined)) {\n fullText += chunk.text;\n yield chunk;\n }\n\n this.emit('message', { role: 'assistant', content: fullText });\n\n // Save to memory\n if (this.memory) {\n await this.memory.saveExchange(this.name, [\n userMessage,\n createMessage({ role: 'assistant', content: fullText }),\n ]);\n }\n }\n}\n","// src/strategy/sequential.ts\nimport type { Agent } from '../agent';\nimport type { AgentEventEmitter } from '../events';\nimport type { Strategy, StrategyOptions, TeamResult, AgentResponse } from './interface';\n\nexport class SequentialStrategy implements Strategy {\n async execute(\n agents: Agent[],\n task: string,\n _options: StrategyOptions,\n emitter: AgentEventEmitter,\n ): Promise<TeamResult> {\n const responses: AgentResponse[] = [];\n let previousOutput: string | undefined;\n\n for (const agent of agents) {\n const input =\n previousOutput !== undefined\n ? `${task}\\n\\nPrevious agent output:\\n${previousOutput}`\n : task;\n\n emitter.emit({\n type: 'team:agent:start',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, input },\n });\n\n const startTime = Date.now();\n const result = await agent.chat(input);\n const latencyMs = Date.now() - startTime;\n\n emitter.emit({\n type: 'team:agent:end',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, output: result.content },\n latencyMs,\n });\n\n responses.push({ agent: agent.name, content: result.content });\n previousOutput = result.content;\n }\n\n return {\n content: responses[responses.length - 1]?.content ?? '',\n responses,\n };\n }\n}\n","// src/strategy/parallel.ts\nimport type { Agent } from '../agent';\nimport type { AgentEventEmitter } from '../events';\nimport type { Strategy, StrategyOptions, TeamResult, AgentResponse } from './interface';\n\nexport class ParallelStrategy implements Strategy {\n async execute(\n agents: Agent[],\n task: string,\n _options: StrategyOptions,\n emitter: AgentEventEmitter,\n ): Promise<TeamResult> {\n // Emit start events and launch all agent calls concurrently\n const agentPromises = agents.map(async (agent) => {\n emitter.emit({\n type: 'team:agent:start',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, input: task },\n });\n\n const startTime = Date.now();\n const result = await agent.chat(task);\n const latencyMs = Date.now() - startTime;\n\n emitter.emit({\n type: 'team:agent:end',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, output: result.content },\n latencyMs,\n });\n\n return { agent: agent.name, content: result.content } satisfies AgentResponse;\n });\n\n const responses = await Promise.all(agentPromises);\n\n const content = responses.map((r) => `[${r.agent}]: ${r.content}`).join('\\n\\n');\n\n return { content, responses };\n }\n}\n","// src/strategy/debate.ts\nimport type { Agent } from '../agent';\nimport type { AgentEventEmitter } from '../events';\nimport type { Strategy, StrategyOptions, TeamResult, AgentResponse } from './interface';\n\nexport class DebateStrategy implements Strategy {\n async execute(\n agents: Agent[],\n task: string,\n options: StrategyOptions,\n emitter: AgentEventEmitter,\n ): Promise<TeamResult> {\n const maxRounds = options.maxRounds ?? 3;\n const responses: AgentResponse[] = [];\n const priorOutputs: string[] = [];\n\n // Run debate rounds — each agent responds in turn, seeing all prior outputs\n for (let round = 1; round <= maxRounds; round++) {\n emitter.emit({\n type: 'team:round',\n timestamp: Date.now(),\n agentId: 'team',\n data: { round, totalRounds: maxRounds },\n });\n\n for (const agent of agents) {\n const context =\n priorOutputs.length > 0\n ? `${task}\\n\\nDebate so far:\\n${priorOutputs.join('\\n\\n')}\\n\\nYour turn (Round ${round}):`\n : `${task}\\n\\n(Round ${round}):`;\n\n emitter.emit({\n type: 'team:agent:start',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, round },\n });\n\n const startTime = Date.now();\n const result = await agent.chat(context);\n const latencyMs = Date.now() - startTime;\n\n emitter.emit({\n type: 'team:agent:end',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: agent.name, output: result.content, round },\n latencyMs,\n });\n\n const agentResponse: AgentResponse = {\n agent: agent.name,\n content: result.content,\n round,\n };\n responses.push(agentResponse);\n priorOutputs.push(`[${agent.name}, Round ${round}]: ${result.content}`);\n }\n }\n\n // Final answer: first agent synthesizes with all debate context\n const firstAgent = agents[0];\n const synthesisInput = `${task}\\n\\nDebate summary:\\n${priorOutputs.join('\\n\\n')}\\n\\nProvide your final answer:`;\n\n emitter.emit({\n type: 'team:agent:start',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: firstAgent.name, phase: 'final' },\n });\n\n const finalResult = await firstAgent.chat(synthesisInput);\n\n emitter.emit({\n type: 'team:agent:end',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName: firstAgent.name, output: finalResult.content, phase: 'final' },\n });\n\n return {\n content: finalResult.content,\n responses,\n };\n }\n}\n","// src/tool.ts\nimport type { ToolDefinition, ParameterDef } from './types';\n\ninterface ToolConfig {\n name: string;\n description: string;\n parameters: Record<string, ParameterDef>;\n execute: (params: Record<string, unknown>) => Promise<unknown>;\n}\n\nexport class Tool {\n readonly name: string;\n readonly description: string;\n readonly definition: ToolDefinition;\n private executeFn: (params: Record<string, unknown>) => Promise<unknown>;\n\n private constructor(config: ToolConfig) {\n this.name = config.name;\n this.description = config.description;\n this.definition = {\n name: config.name,\n description: config.description,\n parameters: config.parameters,\n };\n this.executeFn = config.execute;\n }\n\n static create(config: ToolConfig): Tool {\n return new Tool(config);\n }\n\n async execute(params: Record<string, unknown>): Promise<unknown> {\n return this.executeFn(params);\n }\n}\n","// src/strategy/hierarchical.ts\nimport { Agent } from '../agent';\nimport { Tool } from '../tool';\nimport type { AgentEventEmitter } from '../events';\nimport type { Strategy, StrategyOptions, TeamResult, AgentResponse } from './interface';\n\nexport class HierarchicalStrategy implements Strategy {\n async execute(\n agents: Agent[],\n task: string,\n options: StrategyOptions,\n emitter: AgentEventEmitter,\n ): Promise<TeamResult> {\n const { manager, maxDelegations = 10 } = options;\n\n if (!manager) {\n throw new Error('HierarchicalStrategy requires a manager agent');\n }\n\n // Build a lookup map from agent name to Agent instance\n const agentMap = new Map<string, Agent>(agents.map((a) => [a.name, a]));\n\n const responses: AgentResponse[] = [];\n\n // Create a delegate tool that calls worker agents\n const delegateTool = Tool.create({\n name: 'delegate',\n description: 'Delegate a sub-task to a specialist agent. Use this to assign work to workers.',\n parameters: {\n agentName: {\n type: 'string',\n description: 'The name of the agent to delegate to',\n required: true,\n },\n task: {\n type: 'string',\n description: 'The task to assign to the agent',\n required: true,\n },\n },\n execute: async (params) => {\n const agentName = params.agentName as string;\n const subTask = params.task as string;\n\n const worker = agentMap.get(agentName);\n if (!worker) {\n return `Error: No agent named \"${agentName}\" found. Available agents: ${[...agentMap.keys()].join(', ')}`;\n }\n\n emitter.emit({\n type: 'team:delegate',\n timestamp: Date.now(),\n agentId: 'team',\n data: { agentName, task: subTask },\n });\n\n const result = await worker.chat(subTask);\n\n const response: AgentResponse = { agent: agentName, content: result.content };\n responses.push(response);\n\n return result.content;\n },\n });\n\n // Create a fresh Agent with the manager's model adapter + the delegate tool\n // maxToolRounds caps how many delegations can happen\n const orchestratorAgent = new Agent({\n name: manager.name,\n model: manager.getModel(),\n tools: [delegateTool],\n system: `You are an orchestrating manager. You have access to specialist agents: ${[...agentMap.keys()].join(', ')}. Use the delegate tool to assign sub-tasks to them.`,\n maxToolRounds: maxDelegations,\n });\n\n const finalResult = await orchestratorAgent.chat(task);\n\n return {\n content: finalResult.content,\n responses,\n };\n }\n}\n","// src/team.ts\nimport type { Agent } from './agent';\nimport { AgentEventEmitter } from './events';\nimport { SequentialStrategy } from './strategy/sequential';\nimport { ParallelStrategy } from './strategy/parallel';\nimport { DebateStrategy } from './strategy/debate';\nimport { HierarchicalStrategy } from './strategy/hierarchical';\nimport type { TeamResult, AgentResponse } from './strategy/interface';\nimport type { AgentEvent } from './types';\n\nexport type { TeamResult, AgentResponse };\n\nexport interface TeamConfig {\n agents: Agent[];\n strategy: 'sequential' | 'parallel' | 'debate' | 'hierarchical';\n manager?: Agent;\n maxRounds?: number;\n maxDelegations?: number;\n}\n\nexport class Team {\n private agents: Agent[];\n private strategyName: TeamConfig['strategy'];\n private manager?: Agent;\n private maxRounds?: number;\n private maxDelegations?: number;\n private emitter: AgentEventEmitter;\n\n constructor(config: TeamConfig) {\n this.agents = config.agents;\n this.strategyName = config.strategy;\n this.manager = config.manager;\n this.maxRounds = config.maxRounds;\n this.maxDelegations = config.maxDelegations;\n this.emitter = new AgentEventEmitter();\n }\n\n on(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.on(type, handler);\n }\n\n off(type: string, handler: (event: AgentEvent) => void): void {\n this.emitter.off(type, handler);\n }\n\n async run(task: string): Promise<TeamResult> {\n this.emitter.emit({\n type: 'team:start',\n timestamp: Date.now(),\n agentId: 'team',\n data: {\n strategy: this.strategyName,\n agentCount: this.agents.length,\n task,\n },\n });\n\n const startTime = Date.now();\n\n const strategy = this.resolveStrategy();\n const result = await strategy.execute(\n this.agents,\n task,\n {\n maxRounds: this.maxRounds,\n maxDelegations: this.maxDelegations,\n manager: this.manager,\n },\n this.emitter,\n );\n\n const latencyMs = Date.now() - startTime;\n\n this.emitter.emit({\n type: 'team:end',\n timestamp: Date.now(),\n agentId: 'team',\n data: {\n strategy: this.strategyName,\n responseCount: result.responses.length,\n },\n latencyMs,\n });\n\n return result;\n }\n\n private resolveStrategy() {\n switch (this.strategyName) {\n case 'sequential':\n return new SequentialStrategy();\n case 'parallel':\n return new ParallelStrategy();\n case 'debate':\n return new DebateStrategy();\n case 'hierarchical':\n return new HierarchicalStrategy();\n }\n }\n}\n","// src/store/cosine.ts\n\n/**\n * Computes cosine similarity between two equal-length vectors.\n * Returns a value in [-1, 1] where 1 is identical direction.\n * Returns 0 if either vector has zero magnitude.\n */\nexport function cosineSimilarity(a: number[], b: number[]): number {\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n if (denom === 0) return 0;\n return dot / denom;\n}\n","// src/store/in-memory.ts\nimport type { Message, Summary } from '../types';\nimport type { MemoryStore } from './interface';\nimport { cosineSimilarity } from './cosine';\n\nexport class InMemoryStore implements MemoryStore {\n private messages = new Map<string, Message[]>();\n private summaries = new Map<string, Summary[]>();\n // agentId -> (summaryId -> embedding vector)\n private embeddings = new Map<string, Map<string, number[]>>();\n\n async saveMessages(agentId: string, messages: Message[]): Promise<void> {\n const existing = this.messages.get(agentId) ?? [];\n existing.push(...messages);\n this.messages.set(agentId, existing);\n }\n\n async getRecentMessages(agentId: string, limit: number): Promise<Message[]> {\n const all = this.messages.get(agentId) ?? [];\n return all.slice(-limit);\n }\n\n async saveSummary(agentId: string, summary: Summary): Promise<void> {\n const existing = this.summaries.get(agentId) ?? [];\n existing.push(summary);\n this.summaries.set(agentId, existing);\n }\n\n async searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]> {\n const all = this.summaries.get(agentId) ?? [];\n const queryLower = query.toLowerCase();\n const matches = all\n .filter((s) => s.content.toLowerCase().includes(queryLower))\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, limit);\n return matches;\n }\n\n async saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void> {\n let agentMap = this.embeddings.get(agentId);\n if (!agentMap) {\n agentMap = new Map();\n this.embeddings.set(agentId, agentMap);\n }\n agentMap.set(summaryId, embedding);\n }\n\n async searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]> {\n const agentMap = this.embeddings.get(agentId);\n if (!agentMap || agentMap.size === 0) return [];\n\n const summaries = this.summaries.get(agentId) ?? [];\n const summaryById = new Map(summaries.map((s) => [s.id, s]));\n\n const scored: Array<{ summary: Summary; score: number }> = [];\n for (const [summaryId, storedEmbedding] of agentMap) {\n const summary = summaryById.get(summaryId);\n if (!summary) continue;\n const score = cosineSimilarity(embedding, storedEmbedding);\n scored.push({ summary, score });\n }\n\n return scored\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n .map((entry) => entry.summary);\n }\n}\n","// src/store/sqlite.ts\nimport { createRequire } from 'module';\nimport type { Message, Summary } from '../types';\nimport type { MemoryStore } from './interface';\nimport { cosineSimilarity } from './cosine';\n\nconst require = createRequire(import.meta.url);\n\nexport class SQLiteStore implements MemoryStore {\n private db: import('better-sqlite3').Database;\n\n constructor(path: string) {\n const Database = require('better-sqlite3');\n this.db = new Database(path);\n this.db.pragma('journal_mode = WAL');\n this.init();\n }\n\n private init(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n agent_id TEXT NOT NULL,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n tool_calls TEXT,\n tool_call_id TEXT\n );\n CREATE TABLE IF NOT EXISTS summaries (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n message_range_from INTEGER NOT NULL,\n message_range_to INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS embeddings (\n summary_id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n embedding BLOB NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_messages_agent ON messages(agent_id);\n CREATE INDEX IF NOT EXISTS idx_summaries_agent ON summaries(agent_id);\n CREATE INDEX IF NOT EXISTS idx_embeddings_agent ON embeddings(agent_id);\n `);\n }\n\n async saveMessages(agentId: string, messages: Message[]): Promise<void> {\n const stmt = this.db.prepare(\n 'INSERT INTO messages (agent_id, role, content, timestamp, tool_calls, tool_call_id) VALUES (?, ?, ?, ?, ?, ?)',\n );\n const insertMany = this.db.transaction((msgs: Message[]) => {\n for (const msg of msgs) {\n stmt.run(\n agentId,\n msg.role,\n msg.content,\n msg.timestamp,\n msg.toolCalls ? JSON.stringify(msg.toolCalls) : null,\n msg.toolCallId ?? null,\n );\n }\n });\n insertMany(messages);\n }\n\n async getRecentMessages(agentId: string, limit: number): Promise<Message[]> {\n const rows = this.db\n .prepare(\n `SELECT role, content, timestamp, tool_calls, tool_call_id\n FROM messages WHERE agent_id = ?\n ORDER BY id DESC LIMIT ?`,\n )\n .all(agentId, limit) as Array<{\n role: Message['role'];\n content: string;\n timestamp: number;\n tool_calls: string | null;\n tool_call_id: string | null;\n }>;\n\n return rows.reverse().map((row) => ({\n role: row.role,\n content: row.content,\n timestamp: row.timestamp,\n ...(row.tool_calls ? { toolCalls: JSON.parse(row.tool_calls) } : {}),\n ...(row.tool_call_id ? { toolCallId: row.tool_call_id } : {}),\n }));\n }\n\n async saveSummary(agentId: string, summary: Summary): Promise<void> {\n this.db\n .prepare(\n 'INSERT INTO summaries (id, agent_id, content, timestamp, message_range_from, message_range_to) VALUES (?, ?, ?, ?, ?, ?)',\n )\n .run(\n summary.id,\n agentId,\n summary.content,\n summary.timestamp,\n summary.messageRange.from,\n summary.messageRange.to,\n );\n }\n\n async searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]> {\n const rows = this.db\n .prepare(\n `SELECT id, content, timestamp, message_range_from, message_range_to\n FROM summaries WHERE agent_id = ? AND content LIKE ?\n ORDER BY timestamp DESC LIMIT ?`,\n )\n .all(agentId, `%${query}%`, limit) as Array<{\n id: string;\n content: string;\n timestamp: number;\n message_range_from: number;\n message_range_to: number;\n }>;\n\n return rows.map((row) => ({\n id: row.id,\n content: row.content,\n timestamp: row.timestamp,\n messageRange: { from: row.message_range_from, to: row.message_range_to },\n }));\n }\n\n async saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void> {\n this.db\n .prepare(\n 'INSERT OR REPLACE INTO embeddings (summary_id, agent_id, embedding) VALUES (?, ?, ?)',\n )\n .run(summaryId, agentId, JSON.stringify(embedding));\n }\n\n async searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]> {\n const rows = this.db\n .prepare(\n `SELECT e.summary_id, s.content, s.timestamp, s.message_range_from, s.message_range_to, e.embedding\n FROM embeddings e\n JOIN summaries s ON e.summary_id = s.id\n WHERE e.agent_id = ?`,\n )\n .all(agentId) as Array<{\n summary_id: string;\n content: string;\n timestamp: number;\n message_range_from: number;\n message_range_to: number;\n embedding: string;\n }>;\n\n if (rows.length === 0) return [];\n\n const scored = rows.map((row) => {\n const storedEmbedding = JSON.parse(row.embedding) as number[];\n const score = cosineSimilarity(embedding, storedEmbedding);\n return {\n summary: {\n id: row.summary_id,\n content: row.content,\n timestamp: row.timestamp,\n messageRange: { from: row.message_range_from, to: row.message_range_to },\n } satisfies Summary,\n score,\n };\n });\n\n return scored\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n .map((entry) => entry.summary);\n }\n\n close(): void {\n this.db.close();\n }\n}\n","// src/memory.ts\nimport type { Message, Summary } from './types';\nimport { createSummary } from './types';\nimport type { MemoryStore } from './store/interface';\nimport { InMemoryStore } from './store/in-memory';\nimport { SQLiteStore } from './store/sqlite';\nimport type { ModelAdapter } from './model/adapter';\nimport type { EmbeddingAdapter } from './model/embedding-adapter';\n\nexport interface MemoryConfig {\n store?: 'memory' | 'sqlite' | MemoryStore;\n path?: string;\n windowSize?: number;\n summarizeAfter?: number;\n /** Optional embedding adapter for semantic (vector) search. Falls back to keyword search if not set. */\n embedding?: EmbeddingAdapter;\n}\n\nexport interface MemoryContext {\n recentMessages: Message[];\n relevantSummaries: Summary[];\n}\n\nexport class Memory {\n private store: MemoryStore;\n private windowSize: number;\n private summarizeAfter: number;\n private model?: ModelAdapter;\n private embeddingAdapter?: EmbeddingAdapter;\n private messageCount = new Map<string, number>();\n\n constructor(config: MemoryConfig = {}) {\n this.windowSize = config.windowSize ?? 20;\n this.summarizeAfter = config.summarizeAfter ?? 20;\n this.embeddingAdapter = config.embedding;\n\n if (!config.store || config.store === 'memory') {\n this.store = new InMemoryStore();\n } else if (config.store === 'sqlite') {\n this.store = new SQLiteStore(config.path ?? './agent-memory.db');\n } else {\n this.store = config.store;\n }\n }\n\n setModel(model: ModelAdapter): void {\n this.model = model;\n }\n\n getStore(): MemoryStore {\n return this.store;\n }\n\n async saveExchange(agentId: string, messages: Message[]): Promise<void> {\n await this.store.saveMessages(agentId, messages);\n const count = (this.messageCount.get(agentId) ?? 0) + messages.length;\n this.messageCount.set(agentId, count);\n if (count >= this.summarizeAfter && this.model) {\n await this.summarize(agentId);\n this.messageCount.set(agentId, 0);\n }\n }\n\n async getContext(agentId: string, query: string): Promise<MemoryContext> {\n const recentMessages = await this.store.getRecentMessages(agentId, this.windowSize);\n\n let relevantSummaries: Summary[];\n if (this.embeddingAdapter && this.store.searchByEmbedding) {\n const queryEmbedding = await this.embeddingAdapter.embed(query);\n relevantSummaries = await this.store.searchByEmbedding(agentId, queryEmbedding, 3);\n } else {\n relevantSummaries = await this.store.searchSummaries(agentId, query, 3);\n }\n\n return { recentMessages, relevantSummaries };\n }\n\n private async summarize(agentId: string): Promise<void> {\n if (!this.model) return;\n const allRecent = await this.store.getRecentMessages(agentId, this.summarizeAfter);\n if (allRecent.length === 0) return;\n const summaryResponse = await this.model.chat([\n {\n role: 'system',\n content:\n 'Summarize the following conversation concisely. Focus on key topics, decisions, and facts discussed.',\n timestamp: Date.now(),\n },\n ...allRecent,\n ]);\n const summary = createSummary({\n content: summaryResponse.content,\n messageRange: {\n from: allRecent[0].timestamp,\n to: allRecent[allRecent.length - 1].timestamp,\n },\n });\n await this.store.saveSummary(agentId, summary);\n\n // Generate and persist embedding when adapter + store both support it\n if (this.embeddingAdapter && this.store.saveEmbedding) {\n const embedding = await this.embeddingAdapter.embed(summary.content);\n await this.store.saveEmbedding(agentId, summary.id, embedding);\n }\n }\n\n close(): void {\n if (\n 'close' in this.store &&\n typeof (this.store as { close: () => void }).close === 'function'\n ) {\n (this.store as { close: () => void }).close();\n }\n }\n}\n","// src/model/ollama-embedding.ts\nimport type { EmbeddingAdapter } from './embedding-adapter';\n\nexport interface OllamaEmbeddingConfig {\n /** Ollama server base URL. Default: http://localhost:11434 */\n baseURL?: string;\n /** Embedding model name. Default: nomic-embed-text */\n model?: string;\n}\n\nexport class OllamaEmbeddingAdapter implements EmbeddingAdapter {\n private baseURL: string;\n private model: string;\n\n constructor(config: OllamaEmbeddingConfig = {}) {\n this.baseURL = config.baseURL ?? 'http://localhost:11434';\n this.model = config.model ?? 'nomic-embed-text';\n }\n\n async embed(text: string): Promise<number[]> {\n const [vector] = await this.request(text);\n return vector;\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n return this.request(texts);\n }\n\n private async request(input: string | string[]): Promise<number[][]> {\n const response = await fetch(`${this.baseURL}/api/embed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model: this.model, input }),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama embedding request failed: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as { embeddings: number[][] };\n return data.embeddings;\n }\n}\n"],"mappings":"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","names":["require"]}
package/dist/index.d.cts CHANGED
@@ -83,6 +83,13 @@ interface MemoryStore {
83
83
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
84
84
  saveSummary(agentId: string, summary: Summary): Promise<void>;
85
85
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
86
+ saveEmbedding?(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
87
+ searchByEmbedding?(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
88
+ }
89
+
90
+ interface EmbeddingAdapter {
91
+ embed(text: string): Promise<number[]>;
92
+ embedBatch(texts: string[]): Promise<number[][]>;
86
93
  }
87
94
 
88
95
  interface MemoryConfig {
@@ -90,6 +97,8 @@ interface MemoryConfig {
90
97
  path?: string;
91
98
  windowSize?: number;
92
99
  summarizeAfter?: number;
100
+ /** Optional embedding adapter for semantic (vector) search. Falls back to keyword search if not set. */
101
+ embedding?: EmbeddingAdapter;
93
102
  }
94
103
  interface MemoryContext {
95
104
  recentMessages: Message[];
@@ -100,6 +109,7 @@ declare class Memory {
100
109
  private windowSize;
101
110
  private summarizeAfter;
102
111
  private model?;
112
+ private embeddingAdapter?;
103
113
  private messageCount;
104
114
  constructor(config?: MemoryConfig);
105
115
  setModel(model: ModelAdapter): void;
@@ -135,7 +145,7 @@ interface AgentConfig {
135
145
  maxToolRounds?: number;
136
146
  }
137
147
  declare class Agent {
138
- private name;
148
+ readonly name: string;
139
149
  private model;
140
150
  private memory?;
141
151
  private tools;
@@ -145,6 +155,7 @@ declare class Agent {
145
155
  private emitter;
146
156
  constructor(config: AgentConfig);
147
157
  private isModelAdapter;
158
+ getModel(): ModelAdapter;
148
159
  on(type: string, handler: (event: AgentEvent) => void): void;
149
160
  off(type: string, handler: (event: AgentEvent) => void): void;
150
161
  private emit;
@@ -152,6 +163,45 @@ declare class Agent {
152
163
  stream(input: string): AsyncIterable<ModelChunk>;
153
164
  }
154
165
 
166
+ type EventHandler = (event: AgentEvent) => void;
167
+ declare class AgentEventEmitter {
168
+ private listeners;
169
+ on(type: string, handler: EventHandler): void;
170
+ off(type: string, handler: EventHandler): void;
171
+ emit(event: AgentEvent): void;
172
+ }
173
+
174
+ interface AgentResponse {
175
+ agent: string;
176
+ content: string;
177
+ round?: number;
178
+ }
179
+ interface TeamResult {
180
+ content: string;
181
+ responses: AgentResponse[];
182
+ }
183
+
184
+ interface TeamConfig {
185
+ agents: Agent[];
186
+ strategy: 'sequential' | 'parallel' | 'debate' | 'hierarchical';
187
+ manager?: Agent;
188
+ maxRounds?: number;
189
+ maxDelegations?: number;
190
+ }
191
+ declare class Team {
192
+ private agents;
193
+ private strategyName;
194
+ private manager?;
195
+ private maxRounds?;
196
+ private maxDelegations?;
197
+ private emitter;
198
+ constructor(config: TeamConfig);
199
+ on(type: string, handler: (event: AgentEvent) => void): void;
200
+ off(type: string, handler: (event: AgentEvent) => void): void;
201
+ run(task: string): Promise<TeamResult>;
202
+ private resolveStrategy;
203
+ }
204
+
155
205
  declare class MockAdapter implements ModelAdapter {
156
206
  chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse>;
157
207
  stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk>;
@@ -170,13 +220,31 @@ declare class OpenAICompatibleAdapter implements ModelAdapter {
170
220
  private toOpenAIMessage;
171
221
  }
172
222
 
223
+ interface OllamaEmbeddingConfig {
224
+ /** Ollama server base URL. Default: http://localhost:11434 */
225
+ baseURL?: string;
226
+ /** Embedding model name. Default: nomic-embed-text */
227
+ model?: string;
228
+ }
229
+ declare class OllamaEmbeddingAdapter implements EmbeddingAdapter {
230
+ private baseURL;
231
+ private model;
232
+ constructor(config?: OllamaEmbeddingConfig);
233
+ embed(text: string): Promise<number[]>;
234
+ embedBatch(texts: string[]): Promise<number[][]>;
235
+ private request;
236
+ }
237
+
173
238
  declare class InMemoryStore implements MemoryStore {
174
239
  private messages;
175
240
  private summaries;
241
+ private embeddings;
176
242
  saveMessages(agentId: string, messages: Message[]): Promise<void>;
177
243
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
178
244
  saveSummary(agentId: string, summary: Summary): Promise<void>;
179
245
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
246
+ saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
247
+ searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
180
248
  }
181
249
 
182
250
  declare class SQLiteStore implements MemoryStore {
@@ -187,15 +255,9 @@ declare class SQLiteStore implements MemoryStore {
187
255
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
188
256
  saveSummary(agentId: string, summary: Summary): Promise<void>;
189
257
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
258
+ saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
259
+ searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
190
260
  close(): void;
191
261
  }
192
262
 
193
- type EventHandler = (event: AgentEvent) => void;
194
- declare class AgentEventEmitter {
195
- private listeners;
196
- on(type: string, handler: EventHandler): void;
197
- off(type: string, handler: EventHandler): void;
198
- emit(event: AgentEvent): void;
199
- }
200
-
201
- export { Agent, type AgentConfig, type AgentEvent, AgentEventEmitter, InMemoryStore, Memory, type MemoryConfig, type MemoryContext, type MemoryStore, type Message, MockAdapter, type ModelAdapter, type ModelChunk, type ModelConfig, type ModelResponse, type OpenAIAdapterConfig, OpenAICompatibleAdapter, type ParameterDef, SQLiteStore, type Summary, Tool, type ToolCall, type ToolDefinition, createMessage, createSummary, isToolCallMessage };
263
+ export { Agent, type AgentConfig, type AgentEvent, AgentEventEmitter, type AgentResponse, type EmbeddingAdapter, InMemoryStore, Memory, type MemoryConfig, type MemoryContext, type MemoryStore, type Message, MockAdapter, type ModelAdapter, type ModelChunk, type ModelConfig, type ModelResponse, OllamaEmbeddingAdapter, type OllamaEmbeddingConfig, type OpenAIAdapterConfig, OpenAICompatibleAdapter, type ParameterDef, SQLiteStore, type Summary, Team, type TeamConfig, type TeamResult, Tool, type ToolCall, type ToolDefinition, createMessage, createSummary, isToolCallMessage };
package/dist/index.d.ts CHANGED
@@ -83,6 +83,13 @@ interface MemoryStore {
83
83
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
84
84
  saveSummary(agentId: string, summary: Summary): Promise<void>;
85
85
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
86
+ saveEmbedding?(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
87
+ searchByEmbedding?(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
88
+ }
89
+
90
+ interface EmbeddingAdapter {
91
+ embed(text: string): Promise<number[]>;
92
+ embedBatch(texts: string[]): Promise<number[][]>;
86
93
  }
87
94
 
88
95
  interface MemoryConfig {
@@ -90,6 +97,8 @@ interface MemoryConfig {
90
97
  path?: string;
91
98
  windowSize?: number;
92
99
  summarizeAfter?: number;
100
+ /** Optional embedding adapter for semantic (vector) search. Falls back to keyword search if not set. */
101
+ embedding?: EmbeddingAdapter;
93
102
  }
94
103
  interface MemoryContext {
95
104
  recentMessages: Message[];
@@ -100,6 +109,7 @@ declare class Memory {
100
109
  private windowSize;
101
110
  private summarizeAfter;
102
111
  private model?;
112
+ private embeddingAdapter?;
103
113
  private messageCount;
104
114
  constructor(config?: MemoryConfig);
105
115
  setModel(model: ModelAdapter): void;
@@ -135,7 +145,7 @@ interface AgentConfig {
135
145
  maxToolRounds?: number;
136
146
  }
137
147
  declare class Agent {
138
- private name;
148
+ readonly name: string;
139
149
  private model;
140
150
  private memory?;
141
151
  private tools;
@@ -145,6 +155,7 @@ declare class Agent {
145
155
  private emitter;
146
156
  constructor(config: AgentConfig);
147
157
  private isModelAdapter;
158
+ getModel(): ModelAdapter;
148
159
  on(type: string, handler: (event: AgentEvent) => void): void;
149
160
  off(type: string, handler: (event: AgentEvent) => void): void;
150
161
  private emit;
@@ -152,6 +163,45 @@ declare class Agent {
152
163
  stream(input: string): AsyncIterable<ModelChunk>;
153
164
  }
154
165
 
166
+ type EventHandler = (event: AgentEvent) => void;
167
+ declare class AgentEventEmitter {
168
+ private listeners;
169
+ on(type: string, handler: EventHandler): void;
170
+ off(type: string, handler: EventHandler): void;
171
+ emit(event: AgentEvent): void;
172
+ }
173
+
174
+ interface AgentResponse {
175
+ agent: string;
176
+ content: string;
177
+ round?: number;
178
+ }
179
+ interface TeamResult {
180
+ content: string;
181
+ responses: AgentResponse[];
182
+ }
183
+
184
+ interface TeamConfig {
185
+ agents: Agent[];
186
+ strategy: 'sequential' | 'parallel' | 'debate' | 'hierarchical';
187
+ manager?: Agent;
188
+ maxRounds?: number;
189
+ maxDelegations?: number;
190
+ }
191
+ declare class Team {
192
+ private agents;
193
+ private strategyName;
194
+ private manager?;
195
+ private maxRounds?;
196
+ private maxDelegations?;
197
+ private emitter;
198
+ constructor(config: TeamConfig);
199
+ on(type: string, handler: (event: AgentEvent) => void): void;
200
+ off(type: string, handler: (event: AgentEvent) => void): void;
201
+ run(task: string): Promise<TeamResult>;
202
+ private resolveStrategy;
203
+ }
204
+
155
205
  declare class MockAdapter implements ModelAdapter {
156
206
  chat(messages: Message[], tools?: ToolDefinition[]): Promise<ModelResponse>;
157
207
  stream(messages: Message[], tools?: ToolDefinition[]): AsyncIterable<ModelChunk>;
@@ -170,13 +220,31 @@ declare class OpenAICompatibleAdapter implements ModelAdapter {
170
220
  private toOpenAIMessage;
171
221
  }
172
222
 
223
+ interface OllamaEmbeddingConfig {
224
+ /** Ollama server base URL. Default: http://localhost:11434 */
225
+ baseURL?: string;
226
+ /** Embedding model name. Default: nomic-embed-text */
227
+ model?: string;
228
+ }
229
+ declare class OllamaEmbeddingAdapter implements EmbeddingAdapter {
230
+ private baseURL;
231
+ private model;
232
+ constructor(config?: OllamaEmbeddingConfig);
233
+ embed(text: string): Promise<number[]>;
234
+ embedBatch(texts: string[]): Promise<number[][]>;
235
+ private request;
236
+ }
237
+
173
238
  declare class InMemoryStore implements MemoryStore {
174
239
  private messages;
175
240
  private summaries;
241
+ private embeddings;
176
242
  saveMessages(agentId: string, messages: Message[]): Promise<void>;
177
243
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
178
244
  saveSummary(agentId: string, summary: Summary): Promise<void>;
179
245
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
246
+ saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
247
+ searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
180
248
  }
181
249
 
182
250
  declare class SQLiteStore implements MemoryStore {
@@ -187,15 +255,9 @@ declare class SQLiteStore implements MemoryStore {
187
255
  getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
188
256
  saveSummary(agentId: string, summary: Summary): Promise<void>;
189
257
  searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
258
+ saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
259
+ searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
190
260
  close(): void;
191
261
  }
192
262
 
193
- type EventHandler = (event: AgentEvent) => void;
194
- declare class AgentEventEmitter {
195
- private listeners;
196
- on(type: string, handler: EventHandler): void;
197
- off(type: string, handler: EventHandler): void;
198
- emit(event: AgentEvent): void;
199
- }
200
-
201
- export { Agent, type AgentConfig, type AgentEvent, AgentEventEmitter, InMemoryStore, Memory, type MemoryConfig, type MemoryContext, type MemoryStore, type Message, MockAdapter, type ModelAdapter, type ModelChunk, type ModelConfig, type ModelResponse, type OpenAIAdapterConfig, OpenAICompatibleAdapter, type ParameterDef, SQLiteStore, type Summary, Tool, type ToolCall, type ToolDefinition, createMessage, createSummary, isToolCallMessage };
263
+ export { Agent, type AgentConfig, type AgentEvent, AgentEventEmitter, type AgentResponse, type EmbeddingAdapter, InMemoryStore, Memory, type MemoryConfig, type MemoryContext, type MemoryStore, type Message, MockAdapter, type ModelAdapter, type ModelChunk, type ModelConfig, type ModelResponse, OllamaEmbeddingAdapter, type OllamaEmbeddingConfig, type OpenAIAdapterConfig, OpenAICompatibleAdapter, type ParameterDef, SQLiteStore, type Summary, Team, type TeamConfig, type TeamResult, Tool, type ToolCall, type ToolDefinition, createMessage, createSummary, isToolCallMessage };