@avee1234/agent-kit 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  MockAdapter: () => MockAdapter,
28
28
  OllamaEmbeddingAdapter: () => OllamaEmbeddingAdapter,
29
29
  OpenAICompatibleAdapter: () => OpenAICompatibleAdapter,
30
+ PostgresStore: () => PostgresStore,
30
31
  SQLiteStore: () => SQLiteStore,
31
32
  Team: () => Team,
32
33
  Tool: () => Tool,
@@ -102,7 +103,15 @@ var OpenAICompatibleAdapter = class {
102
103
  function: {
103
104
  name: t.name,
104
105
  description: t.description,
105
- parameters: { type: "object", properties: t.parameters }
106
+ parameters: {
107
+ type: "object",
108
+ properties: Object.fromEntries(
109
+ Object.entries(t.parameters).map(([key, val]) => {
110
+ const { required: _req, ...rest } = val;
111
+ return [key, rest];
112
+ })
113
+ )
114
+ }
106
115
  }
107
116
  }));
108
117
  }
@@ -148,7 +157,15 @@ var OpenAICompatibleAdapter = class {
148
157
  function: {
149
158
  name: t.name,
150
159
  description: t.description,
151
- parameters: { type: "object", properties: t.parameters }
160
+ parameters: {
161
+ type: "object",
162
+ properties: Object.fromEntries(
163
+ Object.entries(t.parameters).map(([key, val]) => {
164
+ const { required: _req, ...rest } = val;
165
+ return [key, rest];
166
+ })
167
+ )
168
+ }
152
169
  }
153
170
  }));
154
171
  }
@@ -610,13 +627,11 @@ var HierarchicalStrategy = class {
610
627
  parameters: {
611
628
  agentName: {
612
629
  type: "string",
613
- description: "The name of the agent to delegate to",
614
- required: true
630
+ description: `The name of the agent to delegate to. Available: ${[...agents.map((a) => a.name)].join(", ")}`
615
631
  },
616
632
  task: {
617
633
  type: "string",
618
- description: "The task to assign to the agent",
619
- required: true
634
+ description: "The task to assign to the agent"
620
635
  }
621
636
  },
622
637
  execute: async (params) => {
@@ -921,6 +936,152 @@ var SQLiteStore = class {
921
936
  }
922
937
  };
923
938
 
939
+ // src/store/postgres.ts
940
+ var import_module2 = require("module");
941
+ var import_meta2 = {};
942
+ var require3 = (0, import_module2.createRequire)(import_meta2.url);
943
+ var SCHEMA_SQL = `
944
+ CREATE EXTENSION IF NOT EXISTS vector;
945
+
946
+ CREATE TABLE IF NOT EXISTS agent_messages (
947
+ id SERIAL PRIMARY KEY,
948
+ agent_id TEXT NOT NULL,
949
+ role TEXT NOT NULL,
950
+ content TEXT NOT NULL,
951
+ timestamp BIGINT NOT NULL,
952
+ tool_calls JSONB,
953
+ tool_call_id TEXT
954
+ );
955
+
956
+ CREATE TABLE IF NOT EXISTS agent_summaries (
957
+ id TEXT PRIMARY KEY,
958
+ agent_id TEXT NOT NULL,
959
+ content TEXT NOT NULL,
960
+ timestamp BIGINT NOT NULL,
961
+ message_range_from BIGINT NOT NULL,
962
+ message_range_to BIGINT NOT NULL,
963
+ embedding vector(768)
964
+ );
965
+
966
+ CREATE INDEX IF NOT EXISTS idx_agent_messages_agent ON agent_messages(agent_id);
967
+ CREATE INDEX IF NOT EXISTS idx_agent_summaries_agent ON agent_summaries(agent_id);
968
+ `;
969
+ var PostgresStore = class _PostgresStore {
970
+ pool;
971
+ constructor(config) {
972
+ const { Pool } = require3("pg");
973
+ this.pool = new Pool({ connectionString: config.connectionString });
974
+ void this.init();
975
+ }
976
+ async init() {
977
+ await this.pool.query(SCHEMA_SQL);
978
+ }
979
+ /** Factory that ensures schema is ready before returning the store. */
980
+ static async create(config) {
981
+ const store = new _PostgresStore(config);
982
+ await store.init();
983
+ return store;
984
+ }
985
+ async saveMessages(agentId, messages) {
986
+ for (const msg of messages) {
987
+ await this.pool.query(
988
+ `INSERT INTO agent_messages (agent_id, role, content, timestamp, tool_calls, tool_call_id)
989
+ VALUES ($1, $2, $3, $4, $5, $6)`,
990
+ [
991
+ agentId,
992
+ msg.role,
993
+ msg.content,
994
+ msg.timestamp,
995
+ msg.toolCalls ? JSON.stringify(msg.toolCalls) : null,
996
+ msg.toolCallId ?? null
997
+ ]
998
+ );
999
+ }
1000
+ }
1001
+ async getRecentMessages(agentId, limit) {
1002
+ const result = await this.pool.query(
1003
+ `SELECT role, content, timestamp, tool_calls, tool_call_id
1004
+ FROM agent_messages
1005
+ WHERE agent_id = $1
1006
+ ORDER BY id DESC
1007
+ LIMIT $2`,
1008
+ [agentId, limit]
1009
+ );
1010
+ return result.rows.reverse().map((row) => ({
1011
+ role: row.role,
1012
+ content: row.content,
1013
+ timestamp: Number(row.timestamp),
1014
+ ...row.tool_calls ? {
1015
+ toolCalls: typeof row.tool_calls === "string" ? JSON.parse(row.tool_calls) : row.tool_calls
1016
+ } : {},
1017
+ ...row.tool_call_id ? { toolCallId: row.tool_call_id } : {}
1018
+ }));
1019
+ }
1020
+ async saveSummary(agentId, summary) {
1021
+ await this.pool.query(
1022
+ `INSERT INTO agent_summaries (id, agent_id, content, timestamp, message_range_from, message_range_to)
1023
+ VALUES ($1, $2, $3, $4, $5, $6)`,
1024
+ [
1025
+ summary.id,
1026
+ agentId,
1027
+ summary.content,
1028
+ summary.timestamp,
1029
+ summary.messageRange.from,
1030
+ summary.messageRange.to
1031
+ ]
1032
+ );
1033
+ }
1034
+ async searchSummaries(agentId, query, limit) {
1035
+ const result = await this.pool.query(
1036
+ `SELECT id, content, timestamp, message_range_from, message_range_to
1037
+ FROM agent_summaries
1038
+ WHERE agent_id = $1 AND content ILIKE $2
1039
+ ORDER BY timestamp DESC
1040
+ LIMIT $3`,
1041
+ [agentId, `%${query}%`, limit]
1042
+ );
1043
+ return result.rows.map((row) => ({
1044
+ id: row.id,
1045
+ content: row.content,
1046
+ timestamp: Number(row.timestamp),
1047
+ messageRange: {
1048
+ from: Number(row.message_range_from),
1049
+ to: Number(row.message_range_to)
1050
+ }
1051
+ }));
1052
+ }
1053
+ async saveEmbedding(agentId, summaryId, embedding) {
1054
+ const vectorLiteral = `[${embedding.join(",")}]`;
1055
+ await this.pool.query(
1056
+ `UPDATE agent_summaries SET embedding = $1 WHERE id = $2 AND agent_id = $3`,
1057
+ [vectorLiteral, summaryId, agentId]
1058
+ );
1059
+ }
1060
+ async searchByEmbedding(agentId, embedding, limit) {
1061
+ const vectorLiteral = `[${embedding.join(",")}]`;
1062
+ const result = await this.pool.query(
1063
+ `SELECT id, content, timestamp, message_range_from, message_range_to
1064
+ FROM agent_summaries
1065
+ WHERE agent_id = $1 AND embedding IS NOT NULL
1066
+ ORDER BY embedding <=> $2
1067
+ LIMIT $3`,
1068
+ [agentId, vectorLiteral, limit]
1069
+ );
1070
+ return result.rows.map((row) => ({
1071
+ id: row.id,
1072
+ content: row.content,
1073
+ timestamp: Number(row.timestamp),
1074
+ messageRange: {
1075
+ from: Number(row.message_range_from),
1076
+ to: Number(row.message_range_to)
1077
+ }
1078
+ }));
1079
+ }
1080
+ async close() {
1081
+ await this.pool.end();
1082
+ }
1083
+ };
1084
+
924
1085
  // src/memory.ts
925
1086
  var Memory = class {
926
1087
  store;
@@ -937,6 +1098,14 @@ var Memory = class {
937
1098
  this.store = new InMemoryStore();
938
1099
  } else if (config.store === "sqlite") {
939
1100
  this.store = new SQLiteStore(config.path ?? "./agent-memory.db");
1101
+ } else if (config.store === "postgres") {
1102
+ const connectionString = config.url ?? config.path;
1103
+ if (!connectionString) {
1104
+ throw new Error(
1105
+ "Memory store 'postgres' requires a connection string via the 'url' config option."
1106
+ );
1107
+ }
1108
+ this.store = new PostgresStore({ connectionString });
940
1109
  } else {
941
1110
  this.store = config.store;
942
1111
  }
@@ -1037,6 +1206,7 @@ var OllamaEmbeddingAdapter = class {
1037
1206
  MockAdapter,
1038
1207
  OllamaEmbeddingAdapter,
1039
1208
  OpenAICompatibleAdapter,
1209
+ PostgresStore,
1040
1210
  SQLiteStore,
1041
1211
  Team,
1042
1212
  Tool,
@@ -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/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"]}
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/store/postgres.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';\nexport { PostgresStore } from './store/postgres';\nexport type { PostgresConfig } from './store/postgres';\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: {\n type: 'object',\n properties: Object.fromEntries(\n Object.entries(t.parameters).map(([key, val]) => {\n const { required: _req, ...rest } = val as unknown as Record<string, unknown>;\n return [key, rest];\n }),\n ),\n },\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: {\n type: 'object',\n properties: Object.fromEntries(\n Object.entries(t.parameters).map(([key, val]) => {\n const { required: _req, ...rest } = val as unknown as Record<string, unknown>;\n return [key, rest];\n }),\n ),\n },\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. Available: ${[...agents.map((a) => a.name)].join(', ')}`,\n },\n task: {\n type: 'string',\n description: 'The task to assign to the agent',\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/store/postgres.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 interface PostgresConfig {\n connectionString: string; // e.g., process.env.DATABASE_URL\n}\n\nconst SCHEMA_SQL = `\nCREATE EXTENSION IF NOT EXISTS vector;\n\nCREATE TABLE IF NOT EXISTS agent_messages (\n id SERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp BIGINT NOT NULL,\n tool_calls JSONB,\n tool_call_id TEXT\n);\n\nCREATE TABLE IF NOT EXISTS agent_summaries (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n content TEXT NOT NULL,\n timestamp BIGINT NOT NULL,\n message_range_from BIGINT NOT NULL,\n message_range_to BIGINT NOT NULL,\n embedding vector(768)\n);\n\nCREATE INDEX IF NOT EXISTS idx_agent_messages_agent ON agent_messages(agent_id);\nCREATE INDEX IF NOT EXISTS idx_agent_summaries_agent ON agent_summaries(agent_id);\n`;\n\nexport class PostgresStore implements MemoryStore {\n private pool: import('pg').Pool;\n\n constructor(config: PostgresConfig) {\n const { Pool } = require('pg') as typeof import('pg');\n this.pool = new Pool({ connectionString: config.connectionString });\n // init is async; callers should await PostgresStore.create() for guaranteed schema setup\n // but we also kick it off here for convenience\n void this.init();\n }\n\n private async init(): Promise<void> {\n await this.pool.query(SCHEMA_SQL);\n }\n\n /** Factory that ensures schema is ready before returning the store. */\n static async create(config: PostgresConfig): Promise<PostgresStore> {\n const store = new PostgresStore(config);\n await store.init();\n return store;\n }\n\n async saveMessages(agentId: string, messages: Message[]): Promise<void> {\n for (const msg of messages) {\n await this.pool.query(\n `INSERT INTO agent_messages (agent_id, role, content, timestamp, tool_calls, tool_call_id)\n VALUES ($1, $2, $3, $4, $5, $6)`,\n [\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 }\n\n async getRecentMessages(agentId: string, limit: number): Promise<Message[]> {\n const result = await this.pool.query<{\n role: Message['role'];\n content: string;\n timestamp: string;\n tool_calls: unknown;\n tool_call_id: string | null;\n }>(\n `SELECT role, content, timestamp, tool_calls, tool_call_id\n FROM agent_messages\n WHERE agent_id = $1\n ORDER BY id DESC\n LIMIT $2`,\n [agentId, limit],\n );\n\n return result.rows.reverse().map((row) => ({\n role: row.role,\n content: row.content,\n timestamp: Number(row.timestamp),\n ...(row.tool_calls\n ? {\n toolCalls:\n typeof row.tool_calls === 'string' ? JSON.parse(row.tool_calls) : row.tool_calls,\n }\n : {}),\n ...(row.tool_call_id ? { toolCallId: row.tool_call_id } : {}),\n }));\n }\n\n async saveSummary(agentId: string, summary: Summary): Promise<void> {\n await this.pool.query(\n `INSERT INTO agent_summaries (id, agent_id, content, timestamp, message_range_from, message_range_to)\n VALUES ($1, $2, $3, $4, $5, $6)`,\n [\n summary.id,\n agentId,\n summary.content,\n summary.timestamp,\n summary.messageRange.from,\n summary.messageRange.to,\n ],\n );\n }\n\n async searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]> {\n const result = await this.pool.query<{\n id: string;\n content: string;\n timestamp: string;\n message_range_from: string;\n message_range_to: string;\n }>(\n `SELECT id, content, timestamp, message_range_from, message_range_to\n FROM agent_summaries\n WHERE agent_id = $1 AND content ILIKE $2\n ORDER BY timestamp DESC\n LIMIT $3`,\n [agentId, `%${query}%`, limit],\n );\n\n return result.rows.map((row) => ({\n id: row.id,\n content: row.content,\n timestamp: Number(row.timestamp),\n messageRange: {\n from: Number(row.message_range_from),\n to: Number(row.message_range_to),\n },\n }));\n }\n\n async saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void> {\n // Format as pgvector literal: '[0.1,0.2,...]'\n const vectorLiteral = `[${embedding.join(',')}]`;\n await this.pool.query(\n `UPDATE agent_summaries SET embedding = $1 WHERE id = $2 AND agent_id = $3`,\n [vectorLiteral, summaryId, agentId],\n );\n }\n\n async searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]> {\n const vectorLiteral = `[${embedding.join(',')}]`;\n const result = await this.pool.query<{\n id: string;\n content: string;\n timestamp: string;\n message_range_from: string;\n message_range_to: string;\n }>(\n `SELECT id, content, timestamp, message_range_from, message_range_to\n FROM agent_summaries\n WHERE agent_id = $1 AND embedding IS NOT NULL\n ORDER BY embedding <=> $2\n LIMIT $3`,\n [agentId, vectorLiteral, limit],\n );\n\n return result.rows.map((row) => ({\n id: row.id,\n content: row.content,\n timestamp: Number(row.timestamp),\n messageRange: {\n from: Number(row.message_range_from),\n to: Number(row.message_range_to),\n },\n }));\n }\n\n async close(): Promise<void> {\n await this.pool.end();\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 { PostgresStore } from './store/postgres';\nimport type { ModelAdapter } from './model/adapter';\nimport type { EmbeddingAdapter } from './model/embedding-adapter';\n\nexport interface MemoryConfig {\n store?: 'memory' | 'sqlite' | 'postgres' | MemoryStore;\n path?: string;\n /** Connection string for PostgreSQL (e.g., process.env.DATABASE_URL). Used when store: 'postgres'. */\n url?: 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 if (config.store === 'postgres') {\n const connectionString = config.url ?? config.path;\n if (!connectionString) {\n throw new Error(\n \"Memory store 'postgres' requires a connection string via the 'url' config option.\",\n );\n }\n this.store = new PostgresStore({ connectionString });\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","import_module","import_meta","require"]}
package/dist/index.d.cts CHANGED
@@ -93,8 +93,10 @@ interface EmbeddingAdapter {
93
93
  }
94
94
 
95
95
  interface MemoryConfig {
96
- store?: 'memory' | 'sqlite' | MemoryStore;
96
+ store?: 'memory' | 'sqlite' | 'postgres' | MemoryStore;
97
97
  path?: string;
98
+ /** Connection string for PostgreSQL (e.g., process.env.DATABASE_URL). Used when store: 'postgres'. */
99
+ url?: string;
98
100
  windowSize?: number;
99
101
  summarizeAfter?: number;
100
102
  /** Optional embedding adapter for semantic (vector) search. Falls back to keyword search if not set. */
@@ -260,4 +262,22 @@ declare class SQLiteStore implements MemoryStore {
260
262
  close(): void;
261
263
  }
262
264
 
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 };
265
+ interface PostgresConfig {
266
+ connectionString: string;
267
+ }
268
+ declare class PostgresStore implements MemoryStore {
269
+ private pool;
270
+ constructor(config: PostgresConfig);
271
+ private init;
272
+ /** Factory that ensures schema is ready before returning the store. */
273
+ static create(config: PostgresConfig): Promise<PostgresStore>;
274
+ saveMessages(agentId: string, messages: Message[]): Promise<void>;
275
+ getRecentMessages(agentId: string, limit: number): Promise<Message[]>;
276
+ saveSummary(agentId: string, summary: Summary): Promise<void>;
277
+ searchSummaries(agentId: string, query: string, limit: number): Promise<Summary[]>;
278
+ saveEmbedding(agentId: string, summaryId: string, embedding: number[]): Promise<void>;
279
+ searchByEmbedding(agentId: string, embedding: number[], limit: number): Promise<Summary[]>;
280
+ close(): Promise<void>;
281
+ }
282
+
283
+ 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, type PostgresConfig, PostgresStore, SQLiteStore, type Summary, Team, type TeamConfig, type TeamResult, Tool, type ToolCall, type ToolDefinition, createMessage, createSummary, isToolCallMessage };