@aman_asmuei/aman-agent 0.5.0 → 0.5.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/README.md +33 -11
- package/dist/index.js +25 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -373,17 +373,39 @@ aman
|
|
|
373
373
|
|
|
374
374
|
## What Makes This Different
|
|
375
375
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
|
379
|
-
|
|
380
|
-
|
|
|
381
|
-
|
|
|
382
|
-
|
|
|
383
|
-
|
|
|
384
|
-
|
|
|
385
|
-
|
|
|
386
|
-
|
|
|
376
|
+
### aman-agent vs other companion runtimes
|
|
377
|
+
|
|
378
|
+
| Feature | aman-agent | Letta / MemGPT | Raw LLM CLI |
|
|
379
|
+
|:---|:---|:---|:---|
|
|
380
|
+
| Identity system | 7 portable layers | None | None |
|
|
381
|
+
| Memory | amem (SQLite + embeddings + graph) | Postgres + embeddings | None |
|
|
382
|
+
| Per-message recall | Progressive disclosure (~10x token savings) | Yes | No |
|
|
383
|
+
| Learns from conversation | Auto-extract (hybrid confirm) | Requires configuration | No |
|
|
384
|
+
| Guardrail enforcement | Runtime tool blocking | None | None |
|
|
385
|
+
| Reminders | Persistent, deadline-aware | None | None |
|
|
386
|
+
| Context compression | LLM-powered summarization | Archival system | Truncation |
|
|
387
|
+
| Tool observation capture | Passive logging of all tool calls | None | None |
|
|
388
|
+
| Token cost visibility | Shows memory injection cost per turn | None | None |
|
|
389
|
+
| Multi-LLM | Anthropic, OpenAI, Ollama | OpenAI-focused | Single provider |
|
|
390
|
+
| Tool execution | Parallel with guardrails | Sequential | None |
|
|
391
|
+
|
|
392
|
+
### amem vs other memory layers
|
|
393
|
+
|
|
394
|
+
| Feature | amem | claude-mem (40K stars) | mem0 |
|
|
395
|
+
|:---|:---|:---|:---|
|
|
396
|
+
| Works with | Any MCP client | Claude Code only | OpenAI-focused |
|
|
397
|
+
| Storage | SQLite + local embeddings | SQLite + Chroma vectors | Cloud vector DB |
|
|
398
|
+
| Progressive disclosure | Compact index + on-demand detail | Yes (10x savings) | No |
|
|
399
|
+
| Memory types | 6 typed (correction > decision > fact) | Untyped observations | Untyped blobs |
|
|
400
|
+
| Knowledge graph | Typed relations between memories | None | None |
|
|
401
|
+
| Reminders | Persistent, deadline-aware | None | None |
|
|
402
|
+
| Scoring | relevance x recency x confidence x importance | Recency-based | Similarity only |
|
|
403
|
+
| Consolidation | Auto merge/prune/promote | None | None |
|
|
404
|
+
| Version history | Immutable snapshots | Immutable observations | None |
|
|
405
|
+
| Token cost visibility | Shown per recall | Shown per injection | None |
|
|
406
|
+
| License | MIT | AGPL-3.0 | Apache-2.0 |
|
|
407
|
+
|
|
408
|
+
> **claude-mem** excels at capturing what Claude Code *did*. **amem** is a structured memory system that works with *any* MCP client, with typed memories, a knowledge graph, reminders, progressive disclosure, and consolidation.
|
|
387
409
|
|
|
388
410
|
---
|
|
389
411
|
|
package/dist/index.js
CHANGED
|
@@ -1455,19 +1455,24 @@ async function recallForMessage(input, mcpManager) {
|
|
|
1455
1455
|
try {
|
|
1456
1456
|
const result = await mcpManager.callTool("memory_recall", {
|
|
1457
1457
|
query: input,
|
|
1458
|
-
limit: 5
|
|
1458
|
+
limit: 5,
|
|
1459
|
+
compact: true
|
|
1459
1460
|
});
|
|
1460
|
-
if (!result || result.startsWith("Error") || result.
|
|
1461
|
-
return
|
|
1461
|
+
if (!result || result.startsWith("Error") || result.includes("No memories found")) {
|
|
1462
|
+
return null;
|
|
1462
1463
|
}
|
|
1463
|
-
|
|
1464
|
+
const tokenEstimate = Math.round(result.split(/\s+/).filter(Boolean).length * 1.3);
|
|
1465
|
+
return {
|
|
1466
|
+
text: `
|
|
1464
1467
|
|
|
1465
1468
|
<relevant-memories>
|
|
1466
1469
|
${result}
|
|
1467
|
-
</relevant-memories
|
|
1470
|
+
</relevant-memories>`,
|
|
1471
|
+
tokenEstimate
|
|
1472
|
+
};
|
|
1468
1473
|
} catch (err) {
|
|
1469
1474
|
log.debug("agent", "memory recall failed", err);
|
|
1470
|
-
return
|
|
1475
|
+
return null;
|
|
1471
1476
|
}
|
|
1472
1477
|
}
|
|
1473
1478
|
function generateSessionId() {
|
|
@@ -1616,9 +1621,11 @@ ${wfMatch.steps}
|
|
|
1616
1621
|
messages.push({ role: "user", content: input });
|
|
1617
1622
|
let augmentedSystemPrompt = activeSystemPrompt;
|
|
1618
1623
|
if (mcpManager) {
|
|
1619
|
-
const
|
|
1620
|
-
if (
|
|
1621
|
-
augmentedSystemPrompt = activeSystemPrompt +
|
|
1624
|
+
const recall = await recallForMessage(input, mcpManager);
|
|
1625
|
+
if (recall) {
|
|
1626
|
+
augmentedSystemPrompt = activeSystemPrompt + recall.text;
|
|
1627
|
+
process.stdout.write(pc3.dim(` [memories: ~${recall.tokenEstimate} tokens]
|
|
1628
|
+
`));
|
|
1622
1629
|
}
|
|
1623
1630
|
}
|
|
1624
1631
|
process.stdout.write(pc3.cyan(`
|
|
@@ -1649,6 +1656,15 @@ ${aiName} > `));
|
|
|
1649
1656
|
process.stdout.write(pc3.dim(` [using ${toolUse.name}...]
|
|
1650
1657
|
`));
|
|
1651
1658
|
const result = await mcpManager.callTool(toolUse.name, toolUse.input);
|
|
1659
|
+
const skipLogging = ["memory_log", "memory_recall", "memory_context", "memory_detail", "reminder_check"].includes(toolUse.name);
|
|
1660
|
+
if (!skipLogging) {
|
|
1661
|
+
mcpManager.callTool("memory_log", {
|
|
1662
|
+
session_id: sessionId,
|
|
1663
|
+
role: "system",
|
|
1664
|
+
content: `[tool:${toolUse.name}] input=${JSON.stringify(toolUse.input).slice(0, 500)} result=${result.slice(0, 500)}`
|
|
1665
|
+
}).catch(() => {
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1652
1668
|
return {
|
|
1653
1669
|
type: "tool_result",
|
|
1654
1670
|
tool_use_id: toolUse.id,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/prompt.ts","../src/token-budget.ts","../src/llm/anthropic.ts","../src/llm/openai.ts","../src/llm/ollama.ts","../src/mcp/client.ts","../src/logger.ts","../src/retry.ts","../src/agent.ts","../src/commands.ts","../src/layers/parsers.ts","../src/hooks.ts","../src/context-manager.ts","../src/memory-extractor.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { assembleSystemPrompt } from \"./prompt.js\";\nimport { createAnthropicClient } from \"./llm/anthropic.js\";\nimport { createOpenAIClient } from \"./llm/openai.js\";\nimport { createOllamaClient } from \"./llm/ollama.js\";\nimport { McpManager } from \"./mcp/client.js\";\nimport { runAgent } from \"./agent.js\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"aman-agent\")\n .description(\"Your AI companion, running locally\")\n .version(__VERSION__)\n .option(\"--model <model>\", \"Override LLM model\")\n .option(\"--budget <tokens>\", \"Token budget for system prompt (default: 8000)\", parseInt)\n .action(async (options) => {\n p.intro(pc.bold(\"aman agent\") + pc.dim(\" — starting your AI companion\"));\n\n // Setup config if needed\n let config = loadConfig();\n if (!config) {\n p.log.info(\"First-time setup — configure your LLM connection.\");\n\n const provider = (await p.select({\n message: \"LLM provider\",\n options: [\n {\n value: \"anthropic\",\n label: \"Claude (Anthropic)\",\n hint: \"recommended\",\n },\n { value: \"openai\", label: \"GPT (OpenAI)\" },\n { value: \"ollama\", label: \"Ollama (local)\", hint: \"free, runs offline\" },\n ],\n initialValue: \"anthropic\",\n })) as \"anthropic\" | \"openai\" | \"ollama\";\n if (p.isCancel(provider)) process.exit(0);\n\n let apiKey = \"\";\n let defaultModel = \"\";\n\n if (provider === \"ollama\") {\n apiKey = \"ollama\";\n const modelInput = (await p.text({\n message: \"Ollama model name\",\n placeholder: \"llama3.2\",\n defaultValue: \"llama3.2\",\n })) as string;\n if (p.isCancel(modelInput)) process.exit(0);\n defaultModel = modelInput || \"llama3.2\";\n } else if (provider === \"anthropic\") {\n p.log.info(\"Get your API key from: https://console.anthropic.com/settings/keys\");\n p.log.info(pc.dim(\"Note: API access is separate from Claude Pro subscription. You need API credits.\"));\n\n apiKey = (await p.text({\n message: \"API key (starts with sk-ant-)\",\n validate: (v) => v.length === 0 ? \"API key is required\" : undefined,\n })) as string;\n if (p.isCancel(apiKey)) process.exit(0);\n\n const modelChoice = (await p.select({\n message: \"Claude model\",\n options: [\n { value: \"claude-sonnet-4-5-20250514\", label: \"Claude Sonnet 4.5\", hint: \"fast, recommended\" },\n { value: \"claude-opus-4-6\", label: \"Claude Opus 4.6\", hint: \"most capable\" },\n { value: \"claude-haiku-4-5-20251001\", label: \"Claude Haiku 4.5\", hint: \"fastest, cheapest\" },\n { value: \"custom\", label: \"Custom model ID\" },\n ],\n initialValue: \"claude-sonnet-4-5-20250514\",\n })) as string;\n if (p.isCancel(modelChoice)) process.exit(0);\n\n if (modelChoice === \"custom\") {\n const customModel = (await p.text({\n message: \"Model ID\",\n placeholder: \"claude-sonnet-4-5-20250514\",\n validate: (v) => v.length === 0 ? \"Model ID is required\" : undefined,\n })) as string;\n if (p.isCancel(customModel)) process.exit(0);\n defaultModel = customModel;\n } else {\n defaultModel = modelChoice;\n }\n } else {\n // OpenAI\n apiKey = (await p.text({\n message: \"API key\",\n validate: (v) => v.length === 0 ? \"API key is required\" : undefined,\n })) as string;\n if (p.isCancel(apiKey)) process.exit(0);\n\n const modelChoice = (await p.select({\n message: \"OpenAI model\",\n options: [\n { value: \"gpt-4o\", label: \"GPT-4o\", hint: \"recommended\" },\n { value: \"gpt-4o-mini\", label: \"GPT-4o Mini\", hint: \"faster, cheaper\" },\n { value: \"o3\", label: \"o3\", hint: \"reasoning model\" },\n { value: \"custom\", label: \"Custom model ID\" },\n ],\n initialValue: \"gpt-4o\",\n })) as string;\n if (p.isCancel(modelChoice)) process.exit(0);\n\n if (modelChoice === \"custom\") {\n const customModel = (await p.text({\n message: \"Model ID\",\n placeholder: \"gpt-4o\",\n validate: (v) => v.length === 0 ? \"Model ID is required\" : undefined,\n })) as string;\n if (p.isCancel(customModel)) process.exit(0);\n defaultModel = customModel;\n } else {\n defaultModel = modelChoice;\n }\n }\n\n config = { provider, apiKey, model: defaultModel };\n saveConfig(config);\n p.log.success(\"Config saved to ~/.aman-agent/config.json\");\n }\n\n // Override model if specified\n const model = options.model || config.model;\n\n // Assemble system prompt from ecosystem with token budget\n const budget = options.budget || undefined;\n const { prompt: systemPrompt, layers, truncated, totalTokens } = assembleSystemPrompt(budget);\n\n if (layers.length === 0) {\n p.log.warning(\n \"No ecosystem configured. Run \" +\n pc.bold(\"npx @aman_asmuei/aman\") +\n \" first.\",\n );\n p.log.info(\"Starting with empty system prompt.\");\n } else {\n p.log.success(\n `Loaded: ${layers.join(\", \")} ${pc.dim(`(${totalTokens.toLocaleString()} tokens)`)}`,\n );\n if (truncated.length > 0) {\n p.log.warning(`Truncated: ${truncated.join(\", \")} ${pc.dim(\"(over budget)\")}`);\n }\n }\n\n p.log.info(`Model: ${pc.dim(model)}`);\n\n // Extract AI name from core.md\n const corePath = path.join(os.homedir(), \".acore\", \"core.md\");\n let aiName = \"Assistant\";\n if (fs.existsSync(corePath)) {\n const content = fs.readFileSync(corePath, \"utf-8\");\n const match = content.match(/^# (.+)$/m);\n if (match) aiName = match[1];\n }\n\n p.log.success(`${pc.bold(aiName)} is ready.`);\n\n // Start MCP servers\n const mcpManager = new McpManager();\n\n p.log.step(\"Connecting to MCP servers...\");\n\n // Connect to aman-mcp (identity, tools, workflows, rules, eval)\n await mcpManager.connect(\"aman\", \"npx\", [\"-y\", \"@aman_asmuei/aman-mcp\"]);\n\n // Connect to amem (memory)\n await mcpManager.connect(\"amem\", \"npx\", [\"-y\", \"@aman_asmuei/amem\"]);\n\n const mcpTools = mcpManager.getTools();\n if (mcpTools.length > 0) {\n p.log.success(`${mcpTools.length} MCP tools available`);\n\n // Memory consolidation\n if (mcpTools.some(t => t.name === \"memory_consolidate\")) {\n try {\n const consolidateResult = await mcpManager.callTool(\"memory_consolidate\", { dry_run: false });\n if (consolidateResult && !consolidateResult.startsWith(\"Error\")) {\n try {\n const report = JSON.parse(consolidateResult);\n if (report.merged > 0 || report.pruned > 0 || report.promoted > 0) {\n p.log.info(\n `Memory health: ${report.healthScore ?? \"?\"}% ` +\n pc.dim(`(merged ${report.merged}, pruned ${report.pruned}, promoted ${report.promoted})`),\n );\n }\n } catch {\n // Non-JSON response\n }\n }\n } catch {\n // Consolidation is non-critical\n }\n }\n } else {\n p.log.info(\n \"No MCP tools connected (install aman-mcp or amem for tool support)\",\n );\n }\n\n // Convert ToolDef[] to ToolDefinition[] for the LLM\n const toolDefs = mcpTools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.input_schema,\n }));\n\n // Create LLM client\n let client;\n if (config.provider === \"anthropic\") {\n client = createAnthropicClient(config.apiKey, model);\n } else if (config.provider === \"ollama\") {\n client = createOllamaClient(model);\n } else {\n client = createOpenAIClient(config.apiKey, model);\n }\n\n // Run the agent\n await runAgent(\n client,\n systemPrompt,\n aiName,\n model,\n toolDefs.length > 0 ? toolDefs : undefined,\n toolDefs.length > 0 ? mcpManager : undefined,\n config.hooks,\n );\n\n // Cleanup on exit\n await mcpManager.disconnect();\n });\n\nprogram.parse();\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface HooksConfig {\n memoryRecall?: boolean;\n sessionResume?: boolean;\n rulesCheck?: boolean;\n workflowSuggest?: boolean;\n evalPrompt?: boolean;\n autoSessionSave?: boolean;\n extractMemories?: boolean;\n}\n\nconst DEFAULT_HOOKS: HooksConfig = {\n memoryRecall: true,\n sessionResume: true,\n rulesCheck: true,\n workflowSuggest: true,\n evalPrompt: true,\n autoSessionSave: true,\n extractMemories: true,\n};\n\nexport interface AgentConfig {\n provider: \"anthropic\" | \"openai\" | \"ollama\";\n apiKey: string;\n model: string;\n hooks?: HooksConfig;\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), \".aman-agent\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\nexport function loadConfig(): AgentConfig | null {\n if (!fs.existsSync(CONFIG_PATH)) return null;\n try {\n const raw = JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\")) as AgentConfig;\n raw.hooks = { ...DEFAULT_HOOKS, ...raw.hooks };\n return raw;\n } catch {\n return null;\n }\n}\n\nexport function saveConfig(config: AgentConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(\n CONFIG_PATH,\n JSON.stringify(config, null, 2) + \"\\n\",\n \"utf-8\",\n );\n}\n\nexport function configExists(): boolean {\n return fs.existsSync(CONFIG_PATH);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { estimateTokens, buildBudgetedPrompt } from \"./token-budget.js\";\nimport type { PromptComponent } from \"./token-budget.js\";\n\ninterface EcosystemFile {\n name: string;\n dir: string;\n file: string;\n}\n\nconst ECOSYSTEM_FILES: EcosystemFile[] = [\n { name: \"identity\", dir: \".acore\", file: \"core.md\" },\n { name: \"tools\", dir: \".akit\", file: \"kit.md\" },\n { name: \"workflows\", dir: \".aflow\", file: \"flow.md\" },\n { name: \"guardrails\", dir: \".arules\", file: \"rules.md\" },\n { name: \"skills\", dir: \".askill\", file: \"skills.md\" },\n];\n\nexport function assembleSystemPrompt(maxTokens?: number): {\n prompt: string;\n layers: string[];\n truncated: string[];\n totalTokens: number;\n} {\n const home = os.homedir();\n const components: PromptComponent[] = [];\n\n for (const entry of ECOSYSTEM_FILES) {\n const filePath = path.join(home, entry.dir, entry.file);\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, \"utf-8\").trim();\n components.push({\n name: entry.name,\n content,\n tokens: estimateTokens(content),\n });\n }\n }\n\n // Project context (not prioritized — appended as extra)\n const contextPath = path.join(process.cwd(), \".acore\", \"context.md\");\n if (fs.existsSync(contextPath)) {\n const content = fs.readFileSync(contextPath, \"utf-8\").trim();\n components.push({\n name: \"context\",\n content,\n tokens: estimateTokens(content),\n });\n }\n\n const budgeted = buildBudgetedPrompt(components, maxTokens);\n\n return {\n prompt: budgeted.prompt,\n layers: budgeted.included,\n truncated: budgeted.truncated,\n totalTokens: budgeted.totalTokens,\n };\n}\n","// Rough token estimation: ~1.3 tokens per word for English markdown\nexport function estimateTokens(text: string): number {\n return Math.round(text.split(/\\s+/).filter(Boolean).length * 1.3);\n}\n\n// Priority order for system prompt components (highest to lowest)\nconst PRIORITIES = [\n \"identity\", // core.md — always include\n \"guardrails\", // rules.md — safety critical\n \"workflows\", // flow.md — behavioral\n \"tools\", // kit.md — capabilities\n \"skills\", // skills.md — can be truncated\n];\n\nexport interface PromptComponent {\n name: string;\n content: string;\n tokens: number;\n}\n\nexport function buildBudgetedPrompt(\n components: PromptComponent[],\n maxTokens: number = 8000, // default budget for system prompt\n): { prompt: string; included: string[]; truncated: string[]; totalTokens: number } {\n const included: string[] = [];\n const truncated: string[] = [];\n const parts: string[] = [];\n let totalTokens = 0;\n\n // Sort by priority\n const sorted = [...components].sort((a, b) => {\n const aPri = PRIORITIES.indexOf(a.name);\n const bPri = PRIORITIES.indexOf(b.name);\n return (aPri === -1 ? 99 : aPri) - (bPri === -1 ? 99 : bPri);\n });\n\n for (const comp of sorted) {\n if (totalTokens + comp.tokens <= maxTokens) {\n parts.push(comp.content);\n included.push(comp.name);\n totalTokens += comp.tokens;\n } else {\n // Try to include a truncated version (first 50% of content)\n const halfContent = comp.content.slice(0, Math.floor(comp.content.length / 2));\n const halfTokens = estimateTokens(halfContent);\n if (totalTokens + halfTokens <= maxTokens) {\n parts.push(halfContent + \"\\n\\n[... truncated for context budget ...]\");\n included.push(comp.name + \" (partial)\");\n totalTokens += halfTokens;\n } else {\n truncated.push(comp.name);\n }\n }\n }\n\n return {\n prompt: parts.join(\"\\n\\n---\\n\\n\"),\n included,\n truncated,\n totalTokens,\n };\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ToolDefinition,\n ChatResponse,\n ContentBlock,\n} from \"./types.js\";\n\nfunction toAnthropicMessages(\n messages: Message[],\n): Anthropic.Messages.MessageParam[] {\n return messages.map((m) => {\n if (typeof m.content === \"string\") {\n return { role: m.role, content: m.content };\n }\n // Complex content blocks (tool_use, tool_result, etc.)\n return {\n role: m.role,\n content: m.content.map((block) => {\n if (block.type === \"text\") {\n return { type: \"text\" as const, text: block.text };\n }\n if (block.type === \"tool_use\") {\n return {\n type: \"tool_use\" as const,\n id: block.id,\n name: block.name,\n input: block.input,\n };\n }\n if (block.type === \"tool_result\") {\n return {\n type: \"tool_result\" as const,\n tool_use_id: block.tool_use_id,\n content: block.content,\n };\n }\n return { type: \"text\" as const, text: \"\" };\n }),\n };\n });\n}\n\nexport function createAnthropicClient(\n apiKey: string,\n model: string,\n): LLMClient {\n const client = new Anthropic({ apiKey });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n tools?: ToolDefinition[],\n ): Promise<ChatResponse> {\n const anthropicMessages = toAnthropicMessages(messages);\n const hasTools = tools && tools.length > 0;\n\n try {\n let fullText = \"\";\n const toolUseBlocks: Array<{\n id: string;\n name: string;\n inputJson: string;\n }> = [];\n let currentBlockType: \"text\" | \"tool_use\" | null = null;\n let currentBlockIndex = -1;\n\n const createParams: Record<string, unknown> = {\n model,\n max_tokens: 8192,\n system: systemPrompt,\n messages: anthropicMessages,\n stream: true,\n };\n\n if (hasTools) {\n createParams.tools = tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema:\n t.input_schema as Anthropic.Messages.Tool[\"input_schema\"],\n }));\n }\n\n const stream = await client.messages.create(\n createParams as unknown as Anthropic.Messages.MessageCreateParamsStreaming,\n );\n\n for await (const event of stream) {\n if (event.type === \"content_block_start\") {\n currentBlockIndex = event.index;\n if (event.content_block.type === \"text\") {\n currentBlockType = \"text\";\n } else if (event.content_block.type === \"tool_use\") {\n currentBlockType = \"tool_use\";\n toolUseBlocks.push({\n id: event.content_block.id,\n name: event.content_block.name,\n inputJson: \"\",\n });\n }\n } else if (event.type === \"content_block_delta\") {\n if (\n currentBlockType === \"text\" &&\n event.delta.type === \"text_delta\"\n ) {\n const text = event.delta.text;\n fullText += text;\n onChunk({ type: \"text\", text });\n } else if (\n currentBlockType === \"tool_use\" &&\n event.delta.type === \"input_json_delta\"\n ) {\n const lastTool = toolUseBlocks[toolUseBlocks.length - 1];\n if (lastTool) {\n lastTool.inputJson += event.delta.partial_json;\n }\n }\n } else if (event.type === \"content_block_stop\") {\n currentBlockType = null;\n }\n }\n\n // Parse tool inputs from accumulated JSON\n const toolUses = toolUseBlocks.map((block) => ({\n id: block.id,\n name: block.name,\n input: (block.inputJson\n ? JSON.parse(block.inputJson)\n : {}) as Record<string, unknown>,\n }));\n\n // Signal done\n onChunk({ type: \"done\" });\n\n // Build content blocks for the message\n if (toolUses.length > 0) {\n const contentBlocks: ContentBlock[] = [];\n if (fullText) {\n contentBlocks.push({ type: \"text\" as const, text: fullText });\n }\n for (const tu of toolUses) {\n contentBlocks.push({\n type: \"tool_use\" as const,\n id: tu.id,\n name: tu.name,\n input: tu.input,\n });\n }\n return {\n message: { role: \"assistant\", content: contentBlocks },\n toolUses,\n };\n }\n\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n } catch (error) {\n if (error instanceof Anthropic.AuthenticationError) {\n throw new Error(\n \"Invalid API key. Run with --model flag or delete ~/.aman-agent/config.json to reconfigure.\",\n );\n }\n if (error instanceof Anthropic.RateLimitError) {\n throw new Error(\"Rate limited by Anthropic. Please wait and retry.\");\n }\n throw error;\n }\n },\n };\n}\n","import OpenAI from \"openai\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ToolDefinition,\n ChatResponse,\n} from \"./types.js\";\n\nfunction toOpenAIMessages(\n systemPrompt: string,\n messages: Message[],\n): OpenAI.Chat.Completions.ChatCompletionMessageParam[] {\n const result: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [\n { role: \"system\", content: systemPrompt },\n ];\n\n for (const m of messages) {\n if (typeof m.content === \"string\") {\n result.push({\n role: m.role as \"user\" | \"assistant\",\n content: m.content,\n });\n } else if (m.role === \"assistant\") {\n // Assistant message with tool calls\n const textParts = m.content.filter((b) => b.type === \"text\");\n const toolUseParts = m.content.filter((b) => b.type === \"tool_use\");\n const text = textParts.map((b) => (\"text\" in b ? b.text : \"\")).join(\"\");\n\n if (toolUseParts.length > 0) {\n result.push({\n role: \"assistant\",\n content: text || null,\n tool_calls: toolUseParts.map((b) => ({\n id: \"id\" in b ? b.id : \"\",\n type: \"function\" as const,\n function: {\n name: \"name\" in b ? b.name : \"\",\n arguments: JSON.stringify(\"input\" in b ? b.input : {}),\n },\n })),\n });\n } else {\n result.push({ role: \"assistant\", content: text });\n }\n } else if (m.role === \"user\") {\n // Check if it contains tool results\n const toolResults = m.content.filter((b) => b.type === \"tool_result\");\n if (toolResults.length > 0) {\n for (const tr of toolResults) {\n if (tr.type === \"tool_result\") {\n result.push({\n role: \"tool\",\n tool_call_id: tr.tool_use_id,\n content: tr.content,\n });\n }\n }\n } else {\n const text = m.content\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\");\n result.push({ role: \"user\", content: text });\n }\n }\n }\n\n return result;\n}\n\nexport function createOpenAIClient(apiKey: string, model: string): LLMClient {\n const client = new OpenAI({ apiKey });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n tools?: ToolDefinition[],\n ): Promise<ChatResponse> {\n const openaiMessages = toOpenAIMessages(systemPrompt, messages);\n const hasTools = tools && tools.length > 0;\n\n try {\n let fullText = \"\";\n const toolCallAccumulators: Map<\n number,\n { id: string; name: string; arguments: string }\n > = new Map();\n\n const createParams: Record<string, unknown> = {\n model,\n max_tokens: 8192,\n messages: openaiMessages,\n stream: true,\n };\n\n if (hasTools) {\n createParams.tools = tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.input_schema,\n },\n }));\n }\n\n const stream = await client.chat.completions.create(\n createParams as unknown as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,\n );\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta;\n if (!delta) continue;\n\n // Stream text content\n if (delta.content) {\n fullText += delta.content;\n onChunk({ type: \"text\", text: delta.content });\n }\n\n // Accumulate tool calls\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index;\n let acc = toolCallAccumulators.get(idx);\n if (!acc) {\n acc = { id: \"\", name: \"\", arguments: \"\" };\n toolCallAccumulators.set(idx, acc);\n }\n if (tc.id) {\n acc.id = tc.id;\n }\n if (tc.function?.name) {\n acc.name = tc.function.name;\n }\n if (tc.function?.arguments) {\n acc.arguments += tc.function.arguments;\n }\n }\n }\n }\n\n // Parse accumulated tool calls\n const toolUses = Array.from(toolCallAccumulators.entries())\n .sort(([a], [b]) => a - b)\n .map(([, acc]) => ({\n id: acc.id,\n name: acc.name,\n input: JSON.parse(acc.arguments || \"{}\") as Record<\n string,\n unknown\n >,\n }));\n\n // Signal done\n onChunk({ type: \"done\" });\n\n // Build response\n if (toolUses.length > 0) {\n const contentBlocks = [\n ...(fullText\n ? [{ type: \"text\" as const, text: fullText }]\n : []),\n ...toolUses.map((tu) => ({\n type: \"tool_use\" as const,\n id: tu.id,\n name: tu.name,\n input: tu.input,\n })),\n ];\n return {\n message: { role: \"assistant\", content: contentBlocks },\n toolUses,\n };\n }\n\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n } catch (error) {\n if (error instanceof OpenAI.AuthenticationError) {\n throw new Error(\n \"Invalid API key. Run with --model flag or delete ~/.aman-agent/config.json to reconfigure.\",\n );\n }\n if (error instanceof OpenAI.RateLimitError) {\n throw new Error(\"Rate limited by OpenAI. Please wait and retry.\");\n }\n throw error;\n }\n },\n };\n}\n","import OpenAI from \"openai\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ChatResponse,\n} from \"./types.js\";\n\nexport function createOllamaClient(\n model: string,\n baseURL?: string,\n): LLMClient {\n const client = new OpenAI({\n baseURL: baseURL || \"http://localhost:11434/v1\",\n apiKey: \"ollama\", // Ollama doesn't require a real key\n });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n _tools?, // Ollama doesn't support tool use — ignored\n ): Promise<ChatResponse> {\n let fullText = \"\";\n\n try {\n const stream = await client.chat.completions.create({\n model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...messages.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\"),\n })),\n ],\n stream: true,\n });\n\n for await (const chunk of stream) {\n const text = chunk.choices[0]?.delta?.content || \"\";\n if (text) {\n fullText += text;\n onChunk({ type: \"text\", text });\n }\n }\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"ECONNREFUSED\")\n ) {\n throw new Error(\n \"Cannot connect to Ollama. Make sure it's running: ollama serve\",\n );\n }\n throw error;\n }\n\n onChunk({ type: \"done\" });\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n },\n };\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { log } from \"../logger.js\";\nimport { withRetry } from \"../retry.js\";\n\ninterface McpConnection {\n name: string;\n client: Client;\n transport: StdioClientTransport;\n}\n\nexport interface ToolDef {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n serverName: string;\n}\n\nexport class McpManager {\n private connections: McpConnection[] = [];\n private tools: ToolDef[] = [];\n\n async connect(\n name: string,\n command: string,\n args: string[],\n ): Promise<void> {\n try {\n const transport = new StdioClientTransport({ command, args });\n const client = new Client({\n name: `aman-agent-${name}`,\n version: \"0.1.0\",\n });\n await client.connect(transport);\n\n this.connections.push({ name, client, transport });\n\n // List tools from this server\n const toolsResult = await client.listTools();\n for (const tool of toolsResult.tools) {\n this.tools.push({\n name: tool.name,\n description: tool.description || \"\",\n input_schema: tool.inputSchema as Record<string, unknown>,\n serverName: name,\n });\n }\n } catch (err) {\n log.error(\"mcp\", \"Failed to connect to \" + name + \" MCP server\", err);\n console.error(` Warning: Could not connect to ${name} MCP server`);\n }\n }\n\n getTools(): ToolDef[] {\n return this.tools;\n }\n\n async callTool(\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<string> {\n const tool = this.tools.find((t) => t.name === toolName);\n if (!tool) return `Error: tool ${toolName} not found`;\n\n const conn = this.connections.find((c) => c.name === tool.serverName);\n if (!conn) return `Error: server ${tool.serverName} not connected`;\n\n try {\n const result = await withRetry(\n () => conn.client.callTool({ name: toolName, arguments: args }),\n { maxAttempts: 2, baseDelay: 500, retryable: (err) => err.message.includes(\"ETIMEDOUT\") || err.message.includes(\"timeout\") },\n );\n // Extract text from result\n if (result.content && Array.isArray(result.content)) {\n return (result.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === \"text\")\n .map((c) => c.text ?? \"\")\n .join(\"\\n\");\n }\n return JSON.stringify(result);\n } catch (error) {\n return `Error calling ${toolName}: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n\n async disconnect(): Promise<void> {\n for (const conn of this.connections) {\n try {\n await conn.client.close();\n } catch (err) {\n log.debug(\"mcp\", \"Cleanup error disconnecting \" + conn.name, err);\n }\n }\n this.connections = [];\n this.tools = [];\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst LOG_DIR = path.join(os.homedir(), \".aman-agent\");\nexport const LOG_PATH = path.join(LOG_DIR, \"debug.log\");\nconst MAX_LOG_SIZE = 1_048_576; // 1MB\n\ninterface LogEntry {\n timestamp: string;\n level: \"debug\" | \"warn\" | \"error\";\n module: string;\n message: string;\n data?: string;\n}\n\nfunction ensureDir(): void {\n if (!fs.existsSync(LOG_DIR)) {\n fs.mkdirSync(LOG_DIR, { recursive: true });\n }\n}\n\nfunction maybeRotate(): void {\n try {\n if (!fs.existsSync(LOG_PATH)) return;\n const stat = fs.statSync(LOG_PATH);\n if (stat.size >= MAX_LOG_SIZE) {\n const backupPath = LOG_PATH + \".1\";\n if (fs.existsSync(backupPath)) fs.unlinkSync(backupPath);\n fs.renameSync(LOG_PATH, backupPath);\n }\n } catch {\n // Rotation failure is non-critical\n }\n}\n\nfunction write(level: LogEntry[\"level\"], module: string, message: string, data?: unknown): void {\n try {\n ensureDir();\n maybeRotate();\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n module,\n message,\n };\n if (data !== undefined) {\n entry.data = data instanceof Error ? data.message : String(data);\n }\n fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + \"\\n\");\n } catch {\n // Logger must never throw\n }\n}\n\nexport const log = {\n debug: (module: string, message: string, data?: unknown) => write(\"debug\", module, message, data),\n warn: (module: string, message: string, data?: unknown) => write(\"warn\", module, message, data),\n error: (module: string, message: string, data?: unknown) => write(\"error\", module, message, data),\n};\n","export interface RetryOptions {\n maxAttempts: number;\n baseDelay: number;\n retryable: (err: Error) => boolean;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n const { maxAttempts, baseDelay, retryable } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n if (!retryable(lastError) || attempt === maxAttempts) {\n throw lastError;\n }\n const delay = baseDelay * Math.pow(2, attempt - 1) * (0.5 + Math.random() * 0.5);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}\n","import * as readline from \"node:readline\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport pc from \"picocolors\";\nimport type {\n LLMClient,\n Message,\n ToolDefinition,\n ToolResultBlock,\n StreamChunk,\n} from \"./llm/types.js\";\nimport { handleCommand } from \"./commands.js\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport {\n onSessionStart,\n onBeforeToolExec,\n onWorkflowMatch,\n onSessionEnd,\n type HookContext,\n} from \"./hooks.js\";\nimport type { HooksConfig } from \"./config.js\";\nimport { trimConversation } from \"./context-manager.js\";\nimport { log } from \"./logger.js\";\nimport { withRetry } from \"./retry.js\";\nimport { extractMemories as runExtraction, type ExtractorState } from \"./memory-extractor.js\";\n\nasync function recallForMessage(\n input: string,\n mcpManager: McpManager,\n): Promise<string> {\n try {\n const result = await mcpManager.callTool(\"memory_recall\", {\n query: input,\n limit: 5,\n });\n if (!result || result.startsWith(\"Error\") || result.trim() === \"[]\") {\n return \"\";\n }\n return `\\n\\n<relevant-memories>\\n${result}\\n</relevant-memories>`;\n } catch (err) {\n log.debug(\"agent\", \"memory recall failed\", err);\n return \"\";\n }\n}\n\n// Generate a session ID for conversation logging\nfunction generateSessionId(): string {\n const now = new Date();\n const pad = (n: number) => n.toString().padStart(2, \"0\");\n return `session-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}`;\n}\n\nexport async function runAgent(\n client: LLMClient,\n systemPrompt: string,\n aiName: string,\n model: string,\n tools?: ToolDefinition[],\n mcpManager?: McpManager,\n hooksConfig?: HooksConfig,\n): Promise<void> {\n const messages: Message[] = [];\n const sessionId = generateSessionId();\n const extractorState: ExtractorState = { turnsSinceLastExtraction: 0, lastExtractionCount: 0 };\n\n const isRetryable = (err: Error) =>\n err.message.includes(\"Rate limit\") ||\n err.message.includes(\"rate limit\") ||\n err.message.includes(\"ECONNRESET\") ||\n err.message.includes(\"ETIMEDOUT\") ||\n err.message.includes(\"fetch failed\");\n\n const onChunkHandler = (chunk: StreamChunk) => {\n if (chunk.type === \"text\" && chunk.text) {\n process.stdout.write(chunk.text);\n }\n if (chunk.type === \"done\") {\n process.stdout.write(\"\\n\");\n }\n };\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n // Handle Ctrl+C gracefully\n rl.on(\"SIGINT\", async () => {\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n await onSessionEnd(hookCtx, messages, sessionId);\n } catch (err) { log.debug(\"agent\", \"session end hook failed on SIGINT\", err); }\n }\n console.log(pc.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n process.exit(0);\n });\n\n const prompt = (): Promise<string> => {\n return new Promise<string>((resolve) => {\n rl.question(pc.green(\"\\nYou > \"), (answer) => {\n resolve(answer);\n });\n });\n };\n\n console.log(\n `\\nType a message, ${pc.dim(\"/help\")} for commands, or ${pc.dim(\"/quit\")} to exit.\\n`,\n );\n\n if (mcpManager && hooksConfig) {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n try {\n const session = await onSessionStart(hookCtx);\n if (session.greeting) console.log(pc.dim(session.greeting));\n if (session.contextInjection) {\n messages.push({ role: \"user\", content: session.contextInjection });\n messages.push({ role: \"assistant\", content: \"I have context from our previous sessions. How can I help?\" });\n }\n } catch (err) { log.warn(\"agent\", \"session start hook failed\", err); }\n }\n\n while (true) {\n const input = await prompt();\n if (!input.trim()) continue;\n\n // Handle slash commands\n const cmdResult = await handleCommand(input, { model, mcpManager });\n if (cmdResult.handled) {\n if (cmdResult.quit) {\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n await onSessionEnd(hookCtx, messages, sessionId);\n } catch (err) { log.debug(\"agent\", \"session end hook failed on quit\", err); }\n }\n console.log(pc.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n return;\n }\n if (cmdResult.exportConversation) {\n try {\n const exportDir = path.join(os.homedir(), \".aman-agent\", \"exports\");\n fs.mkdirSync(exportDir, { recursive: true });\n const exportPath = path.join(exportDir, `${sessionId}.md`);\n\n const lines: string[] = [\n `# Conversation — ${new Date().toLocaleString()}`,\n `**Model:** ${model}`,\n \"\",\n \"---\",\n \"\",\n ];\n\n for (const msg of messages) {\n if (typeof msg.content === \"string\") {\n const label = msg.role === \"user\" ? \"**You:**\" : `**${aiName}:**`;\n lines.push(`${label} ${msg.content}`, \"\");\n }\n }\n\n fs.writeFileSync(exportPath, lines.join(\"\\n\"), \"utf-8\");\n console.log(pc.green(`Exported to ${exportPath}`));\n } catch {\n console.log(pc.red(\"Failed to export conversation.\"));\n }\n continue;\n }\n if (cmdResult.saveConversation && mcpManager) {\n try {\n await saveConversationToMemory(mcpManager, messages, sessionId);\n console.log(pc.green(\"Conversation saved to memory.\"));\n } catch {\n console.log(pc.red(\"Failed to save conversation.\"));\n }\n continue;\n }\n if (cmdResult.output) {\n console.log(cmdResult.output);\n }\n if (cmdResult.clearHistory) {\n messages.length = 0;\n }\n continue;\n }\n\n // Check for workflow match\n let activeSystemPrompt = systemPrompt;\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n const wfMatch = await onWorkflowMatch(input, hookCtx);\n if (wfMatch) {\n const useIt = await new Promise<boolean>((resolve) => {\n rl.question(pc.dim(` Workflow \"${wfMatch.name}\" matches. Use it? (y/N) `), (answer) => resolve(answer.toLowerCase() === \"y\"));\n });\n if (useIt) {\n activeSystemPrompt = systemPrompt + `\\n\\n<active-workflow>\\n${wfMatch.steps}\\n</active-workflow>`;\n console.log(pc.dim(` Using \"${wfMatch.name}\" workflow.`));\n }\n }\n } catch (err) { log.debug(\"agent\", \"workflow match failed\", err); }\n }\n\n // Auto-trim conversation if approaching token limits\n await trimConversation(messages, client);\n\n // Send to LLM\n messages.push({ role: \"user\", content: input });\n\n // Per-message memory recall\n let augmentedSystemPrompt = activeSystemPrompt;\n if (mcpManager) {\n const memories = await recallForMessage(input, mcpManager);\n if (memories) {\n augmentedSystemPrompt = activeSystemPrompt + memories;\n }\n }\n\n process.stdout.write(pc.cyan(`\\n${aiName} > `));\n\n try {\n let response = await withRetry(\n () => client.chat(augmentedSystemPrompt, messages, onChunkHandler, tools),\n { maxAttempts: 3, baseDelay: 1000, retryable: isRetryable },\n );\n\n // Add assistant message to history\n messages.push(response.message);\n\n // Agentic tool loop: execute tools until LLM stops requesting them\n while (response.toolUses.length > 0 && mcpManager) {\n const toolResults: ToolResultBlock[] = await Promise.all(\n response.toolUses.map(async (toolUse) => {\n if (hooksConfig) {\n const hookCtx: HookContext = { mcpManager: mcpManager!, config: hooksConfig };\n const check = await onBeforeToolExec(toolUse.name, toolUse.input, hookCtx);\n if (!check.allow) {\n process.stdout.write(pc.red(` [BLOCKED: ${check.reason}]\\n`));\n return {\n type: \"tool_result\" as const,\n tool_use_id: toolUse.id,\n content: `BLOCKED by guardrail: ${check.reason}`,\n is_error: true,\n };\n }\n }\n\n process.stdout.write(pc.dim(` [using ${toolUse.name}...]\\n`));\n const result = await mcpManager.callTool(toolUse.name, toolUse.input);\n return {\n type: \"tool_result\" as const,\n tool_use_id: toolUse.id,\n content: result,\n };\n }),\n );\n\n // Add tool results as a user message\n messages.push({\n role: \"user\",\n content: toolResults,\n });\n\n // Call LLM again with tool results\n response = await withRetry(\n () => client.chat(augmentedSystemPrompt, messages, onChunkHandler, tools),\n { maxAttempts: 3, baseDelay: 1000, retryable: isRetryable },\n );\n\n // Add assistant response to history\n messages.push(response.message);\n }\n\n // Memory extraction (runs silently after response)\n if (mcpManager && hooksConfig?.extractMemories) {\n const assistantText = typeof response.message.content === \"string\"\n ? response.message.content\n : response.message.content\n .filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\");\n\n if (assistantText) {\n const confirmFn = async (content: string): Promise<boolean> => {\n return new Promise<boolean>((resolve) => {\n rl.question(\n pc.dim(` Remember: \"${content}\"? (y/N) `),\n (answer) => resolve(answer.toLowerCase() === \"y\"),\n );\n });\n };\n\n const count = await runExtraction(\n input, assistantText, client, mcpManager, extractorState, confirmFn,\n );\n if (count > 0) {\n process.stdout.write(pc.dim(` [${count} memory${count > 1 ? \"ies\" : \"\"} stored]\\n`));\n }\n }\n } else {\n extractorState.turnsSinceLastExtraction++;\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n console.error(pc.red(`\\nError: ${message}`));\n // Remove the user message that failed\n messages.pop();\n }\n }\n}\n\n// Save conversation messages to amem's memory_log\nasync function saveConversationToMemory(\n mcpManager: McpManager,\n messages: Message[],\n sessionId: string,\n): Promise<void> {\n // Save last 50 messages\n const recentMessages = messages.slice(-50);\n\n for (const msg of recentMessages) {\n if (typeof msg.content !== \"string\") continue;\n try {\n await mcpManager.callTool(\"memory_log\", {\n session_id: sessionId,\n role: msg.role,\n content: msg.content.slice(0, 5000),\n });\n } catch (err) {\n log.debug(\"agent\", \"memory_log write failed\", err);\n }\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport pc from \"picocolors\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport { getEcosystemStatus } from \"./layers/parsers.js\";\n\nexport interface CommandResult {\n handled: boolean;\n output?: string;\n quit?: boolean;\n clearHistory?: boolean;\n saveConversation?: boolean;\n exportConversation?: boolean;\n}\n\nexport interface CommandContext {\n model?: string;\n mcpManager?: McpManager;\n}\n\nfunction readEcosystemFile(filePath: string, label: string): string {\n if (!fs.existsSync(filePath)) {\n return pc.dim(`No ${label} file found at ${filePath}`);\n }\n return fs.readFileSync(filePath, \"utf-8\").trim();\n}\n\nfunction parseCommand(input: string): { base: string; action?: string; args: string[] } {\n const trimmed = input.trim();\n const parts = trimmed.split(/\\s+/);\n const base = parts[0].toLowerCase().replace(/^\\//, \"\");\n const action = parts.length > 1 ? parts[1].toLowerCase() : undefined;\n const args = parts.slice(2);\n return { base, action, args };\n}\n\nasync function mcpWrite(\n ctx: CommandContext,\n layer: string,\n tool: string,\n args: Record<string, unknown>,\n): Promise<string> {\n if (!ctx.mcpManager) {\n return pc.red(`Cannot modify ${layer}: aman-mcp not connected. Start it with: npx @aman_asmuei/aman-mcp`);\n }\n const result = await ctx.mcpManager.callTool(tool, args);\n if (result.startsWith(\"Error\")) {\n return pc.red(result);\n }\n return pc.green(result);\n}\n\n// --- Layer Handlers ---\n\nasync function handleIdentityCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".acore\", \"core.md\"), \"identity (acore)\");\n return { handled: true, output: content };\n }\n if (action === \"update\") {\n if (args.length === 0) {\n return {\n handled: true,\n output: pc.yellow(\"Usage: /identity update <section>\\nTip: describe changes in natural language and the AI will update via MCP.\"),\n };\n }\n const section = args[0];\n const content = args.slice(1).join(\" \");\n if (!content) {\n return {\n handled: true,\n output: pc.yellow(\"Usage: /identity update <section> <new content...>\\nExample: /identity update Personality Warm, curious, and direct.\"),\n };\n }\n const output = await mcpWrite(ctx, \"identity\", \"identity_update_section\", { section, content });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /identity ${action}. Use /identity or /identity update <section>.`) };\n}\n\nasync function handleRulesCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".arules\", \"rules.md\"), \"guardrails (arules)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules add <category> <rule text...>\") };\n }\n const category = args[0];\n const rule = args.slice(1).join(\" \");\n const output = await mcpWrite(ctx, \"rules\", \"rules_add\", { category, rule });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules remove <category> <index>\") };\n }\n const output = await mcpWrite(ctx, \"rules\", \"rules_remove\", { category: args[0], index: parseInt(args[1], 10) });\n return { handled: true, output };\n }\n if (action === \"toggle\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules toggle <category> <index>\") };\n }\n const output = await mcpWrite(ctx, \"rules\", \"rules_toggle\", { category: args[0], index: parseInt(args[1], 10) });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /rules ${action}. Use /rules [add|remove|toggle].`) };\n}\n\nasync function handleWorkflowsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".aflow\", \"flow.md\"), \"workflows (aflow)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /workflows add <name>\") };\n }\n const output = await mcpWrite(ctx, \"workflows\", \"workflow_add\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /workflows remove <name>\") };\n }\n const output = await mcpWrite(ctx, \"workflows\", \"workflow_remove\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /workflows ${action}. Use /workflows [add|remove].`) };\n}\n\nasync function handleToolsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".akit\", \"kit.md\"), \"tools (akit)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 3) {\n return { handled: true, output: pc.yellow(\"Usage: /tools add <name> <type> <description...>\") };\n }\n const name = args[0];\n const type = args[1];\n const description = args.slice(2).join(\" \");\n const output = await mcpWrite(ctx, \"tools\", \"tools_add\", { name, type, description });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /tools remove <name>\") };\n }\n const output = await mcpWrite(ctx, \"tools\", \"tools_remove\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /tools ${action}. Use /tools [add|remove].`) };\n}\n\nasync function handleSkillsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".askill\", \"skills.md\"), \"skills (askill)\");\n return { handled: true, output: content };\n }\n if (action === \"install\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /skills install <name>\") };\n }\n const output = await mcpWrite(ctx, \"skills\", \"skill_install\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n if (action === \"uninstall\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /skills uninstall <name>\") };\n }\n const output = await mcpWrite(ctx, \"skills\", \"skill_uninstall\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /skills ${action}. Use /skills [install|uninstall].`) };\n}\n\nasync function handleEvalCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".aeval\", \"eval.md\"), \"evaluation (aeval)\");\n return { handled: true, output: content };\n }\n if (action === \"milestone\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /eval milestone <text...>\") };\n }\n const text = args.join(\" \");\n const output = await mcpWrite(ctx, \"eval\", \"eval_milestone\", { text });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /eval ${action}. Use /eval or /eval milestone <text>.`) };\n}\n\nasync function handleMemoryCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n if (!action) {\n // Default: show recent memory context via MCP\n if (!ctx.mcpManager) {\n return {\n handled: true,\n output: pc.red(\"Memory not available: aman-mcp not connected. Start it with: npx @aman_asmuei/aman-mcp\"),\n };\n }\n const result = await ctx.mcpManager.callTool(\"memory_context\", {});\n if (result.startsWith(\"Error\")) {\n return { handled: true, output: pc.red(result) };\n }\n return { handled: true, output: result };\n }\n if (action === \"search\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /memory search <query...>\") };\n }\n const query = args.join(\" \");\n const output = await mcpWrite(ctx, \"memory\", \"memory_recall\", { query });\n return { handled: true, output };\n }\n if (action === \"clear\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /memory clear <category>\") };\n }\n const output = await mcpWrite(ctx, \"memory\", \"memory_forget\", { category: args[0] });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /memory ${action}. Use /memory [search|clear].`) };\n}\n\nfunction handleStatusCommand(ctx: CommandContext): CommandResult {\n const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;\n const amemConnected = mcpToolCount > 0; // simplified check\n const status = getEcosystemStatus(mcpToolCount, amemConnected);\n\n const lines: string[] = [pc.bold(\"Aman Ecosystem Dashboard\"), \"\"];\n\n for (const layer of status.layers) {\n const icon = layer.exists ? pc.green(\"●\") : pc.dim(\"○\");\n const name = pc.bold(layer.name.padEnd(12));\n const summary = layer.exists ? layer.summary : pc.dim(\"not configured\");\n lines.push(` ${icon} ${name} ${summary}`);\n }\n\n lines.push(\"\");\n lines.push(` ${status.mcpConnected ? pc.green(\"●\") : pc.dim(\"○\")} ${pc.bold(\"MCP\".padEnd(12))} ${status.mcpConnected ? `${status.mcpToolCount} tools available` : pc.dim(\"not connected\")}`);\n lines.push(` ${status.amemConnected ? pc.green(\"●\") : pc.dim(\"○\")} ${pc.bold(\"Memory\".padEnd(12))} ${status.amemConnected ? \"connected\" : pc.dim(\"not connected\")}`);\n\n return { handled: true, output: lines.join(\"\\n\") };\n}\n\nfunction handleDoctorCommand(ctx: CommandContext): CommandResult {\n const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;\n const amemConnected = mcpToolCount > 0;\n const status = getEcosystemStatus(mcpToolCount, amemConnected);\n\n const lines: string[] = [pc.bold(\"Aman Health Check\"), \"\"];\n\n for (const layer of status.layers) {\n const check = layer.exists ? pc.green(\"✓\") : pc.red(\"✗\");\n const name = layer.name.padEnd(12);\n const detail = layer.exists ? pc.green(layer.summary) : pc.red(\"missing\");\n lines.push(` ${check} ${name} ${detail}`);\n }\n\n lines.push(\"\");\n lines.push(` ${status.mcpConnected ? pc.green(\"✓\") : pc.red(\"✗\")} ${\"MCP\".padEnd(12)} ${status.mcpConnected ? pc.green(`${status.mcpToolCount} tools`) : pc.red(\"not connected\")}`);\n lines.push(` ${status.amemConnected ? pc.green(\"✓\") : pc.red(\"✗\")} ${\"Memory\".padEnd(12)} ${status.amemConnected ? pc.green(\"connected\") : pc.red(\"not connected\")}`);\n\n return { handled: true, output: lines.join(\"\\n\") };\n}\n\nfunction handleHelp(): CommandResult {\n return {\n handled: true,\n output: [\n pc.bold(\"Commands:\"),\n ` ${pc.cyan(\"/help\")} Show this help`,\n ` ${pc.cyan(\"/identity\")} View identity [update <section>]`,\n ` ${pc.cyan(\"/rules\")} View rules [add|remove|toggle ...]`,\n ` ${pc.cyan(\"/workflows\")} View workflows [add|remove ...]`,\n ` ${pc.cyan(\"/tools\")} View tools [add|remove ...]`,\n ` ${pc.cyan(\"/skills\")} View skills [install|uninstall ...]`,\n ` ${pc.cyan(\"/eval\")} View evaluation [milestone ...]`,\n ` ${pc.cyan(\"/memory\")} View recent memories [search|clear ...]`,\n ` ${pc.cyan(\"/status\")} Ecosystem dashboard`,\n ` ${pc.cyan(\"/doctor\")} Health check all layers`,\n ` ${pc.cyan(\"/decisions\")} View decision log [<project>]`,\n ` ${pc.cyan(\"/export\")} Export conversation to markdown`,\n ` ${pc.cyan(\"/debug\")} Show debug log`,\n ` ${pc.cyan(\"/save\")} Save conversation to memory`,\n ` ${pc.cyan(\"/model\")} Show current LLM model`,\n ` ${pc.cyan(\"/update\")} Check for updates`,\n ` ${pc.cyan(\"/reconfig\")} Reset LLM config`,\n ` ${pc.cyan(\"/clear\")} Clear conversation history`,\n ` ${pc.cyan(\"/quit\")} Exit`,\n ].join(\"\\n\"),\n };\n}\n\nfunction handleSave(): CommandResult {\n return { handled: true, saveConversation: true };\n}\n\nfunction handleReconfig(): CommandResult {\n const configPath = path.join(os.homedir(), \".aman-agent\", \"config.json\");\n if (fs.existsSync(configPath)) {\n fs.unlinkSync(configPath);\n }\n return {\n handled: true,\n quit: true,\n output: [\n pc.green(\"Config reset.\"),\n `Run ${pc.bold(\"npx @aman_asmuei/aman-agent\")} again to reconfigure your LLM provider, model, and API key.`,\n ].join(\"\\n\"),\n };\n}\n\nfunction handleUpdate(): CommandResult {\n try {\n const current = execFileSync(\"npm\", [\"view\", \"@aman_asmuei/aman-agent\", \"version\"], { encoding: \"utf-8\" }).trim();\n const local = JSON.parse(fs.readFileSync(path.join(__dirname, \"..\", \"package.json\"), \"utf-8\")).version;\n if (current === local) {\n return { handled: true, output: `${pc.green(\"Up to date\")} — v${local}` };\n }\n return {\n handled: true,\n output: [\n `${pc.yellow(\"Update available:\")} v${local} → v${current}`,\n \"\",\n `Run this in your terminal:`,\n ` ${pc.bold(\"npm install -g @aman_asmuei/aman-agent@latest\")}`,\n \"\",\n `Or use npx (always latest):`,\n ` ${pc.bold(\"npx @aman_asmuei/aman-agent@latest\")}`,\n ].join(\"\\n\"),\n };\n } catch {\n return {\n handled: true,\n output: [\n `To update, run in your terminal:`,\n ` ${pc.bold(\"npm install -g @aman_asmuei/aman-agent@latest\")}`,\n \"\",\n `Or use npx (always latest):`,\n ` ${pc.bold(\"npx @aman_asmuei/aman-agent@latest\")}`,\n ].join(\"\\n\"),\n };\n }\n}\n\nasync function handleDecisionsCommand(\n action: string | undefined,\n _args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n if (!ctx.mcpManager) {\n return { handled: true, output: pc.red(\"Decisions not available: MCP not connected.\") };\n }\n const scope = action || undefined;\n const result = await ctx.mcpManager.callTool(\"memory_recall\", {\n query: \"decision\",\n type: \"decision\",\n limit: 20,\n ...(scope ? { scope } : {}),\n });\n if (result.startsWith(\"Error\")) {\n return { handled: true, output: pc.red(result) };\n }\n return { handled: true, output: pc.bold(\"Decision Log:\\n\") + result };\n}\n\nfunction handleExportCommand(): CommandResult {\n return { handled: true, exportConversation: true };\n}\n\nfunction handleDebugCommand(): CommandResult {\n const logPath = path.join(os.homedir(), \".aman-agent\", \"debug.log\");\n if (!fs.existsSync(logPath)) {\n return { handled: true, output: pc.dim(\"No debug log found.\") };\n }\n const content = fs.readFileSync(logPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\");\n const last20 = lines.slice(-20).join(\"\\n\");\n return { handled: true, output: pc.bold(\"Debug Log (last 20 entries):\\n\") + pc.dim(last20) };\n}\n\n// --- Main Router ---\n\nexport async function handleCommand(input: string, ctx: CommandContext): Promise<CommandResult> {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return { handled: false };\n\n const { base, action, args } = parseCommand(trimmed);\n\n switch (base) {\n case \"quit\":\n case \"exit\":\n case \"q\":\n return { handled: true, quit: true };\n case \"help\":\n return handleHelp();\n case \"clear\":\n return { handled: true, output: pc.dim(\"Conversation cleared.\"), clearHistory: true };\n case \"model\":\n return { handled: true, output: ctx.model ? `Model: ${pc.bold(ctx.model)}` : \"Model: unknown\" };\n case \"identity\":\n return handleIdentityCommand(action, args, ctx);\n case \"rules\":\n return handleRulesCommand(action, args, ctx);\n case \"workflows\":\n return handleWorkflowsCommand(action, args, ctx);\n case \"tools\":\n return handleToolsCommand(action, args, ctx);\n case \"skills\":\n return handleSkillsCommand(action, args, ctx);\n case \"eval\":\n return handleEvalCommand(action, args, ctx);\n case \"memory\":\n return handleMemoryCommand(action, args, ctx);\n case \"status\":\n return handleStatusCommand(ctx);\n case \"doctor\":\n return handleDoctorCommand(ctx);\n case \"save\":\n return handleSave();\n case \"decisions\":\n return handleDecisionsCommand(action, args, ctx);\n case \"export\":\n return handleExportCommand();\n case \"debug\":\n return handleDebugCommand();\n case \"update-config\":\n case \"reconfig\":\n return handleReconfig();\n case \"update\":\n case \"upgrade\":\n return handleUpdate();\n default:\n return { handled: true, output: `Unknown command: /${base}. Type ${pc.cyan(\"/help\")} for available commands.` };\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst home = os.homedir();\n\ninterface LayerStatus {\n name: string;\n exists: boolean;\n path: string;\n summary: string;\n}\n\nexport interface EcosystemStatus {\n layers: LayerStatus[];\n mcpConnected: boolean;\n mcpToolCount: number;\n amemConnected: boolean;\n}\n\nconst LAYER_FILES = [\n { name: \"identity\", dir: \".acore\", file: \"core.md\" },\n { name: \"rules\", dir: \".arules\", file: \"rules.md\" },\n { name: \"workflows\", dir: \".aflow\", file: \"flow.md\" },\n { name: \"tools\", dir: \".akit\", file: \"kit.md\" },\n { name: \"skills\", dir: \".askill\", file: \"skills.md\" },\n { name: \"eval\", dir: \".aeval\", file: \"eval.md\" },\n] as const;\n\nfunction countLines(content: string, pattern: RegExp): number {\n return (content.match(pattern) || []).length;\n}\n\nfunction getLayerSummary(name: string, content: string): string {\n switch (name) {\n case \"identity\": {\n const nameMatch = content.match(/^# (.+)/m);\n return nameMatch ? nameMatch[1] : \"configured\";\n }\n case \"rules\":\n return `${countLines(content, /^- /gm)} rules`;\n case \"workflows\":\n return `${countLines(content, /^## /gm)} workflows`;\n case \"tools\":\n return `${countLines(content, /^- \\*\\*/gm)} tools`;\n case \"skills\":\n return `${countLines(content, /^### /gm)} skills`;\n case \"eval\": {\n const sessions = countLines(content, /^### Session/gm);\n return `${sessions} sessions logged`;\n }\n default:\n return \"unknown\";\n }\n}\n\nexport function getEcosystemStatus(\n mcpToolCount: number,\n amemConnected: boolean,\n): EcosystemStatus {\n const layers: LayerStatus[] = LAYER_FILES.map((entry) => {\n const filePath = path.join(home, entry.dir, entry.file);\n const exists = fs.existsSync(filePath);\n let summary = \"not configured\";\n\n if (exists) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n summary = getLayerSummary(entry.name, content);\n }\n\n return { name: entry.name, exists, path: filePath, summary };\n });\n\n return {\n layers,\n mcpConnected: mcpToolCount > 0,\n mcpToolCount,\n amemConnected,\n };\n}\n\nexport function readLayerFile(name: string): string | null {\n const entry = LAYER_FILES.find((l) => l.name === name);\n if (!entry) return null;\n const filePath = path.join(home, entry.dir, entry.file);\n if (!fs.existsSync(filePath)) return null;\n return fs.readFileSync(filePath, \"utf-8\").trim();\n}\n","import pc from \"picocolors\";\nimport * as p from \"@clack/prompts\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport type { Message } from \"./llm/types.js\";\nimport type { HooksConfig } from \"./config.js\";\nimport { log } from \"./logger.js\";\n\nfunction getTimeContext(): string {\n const now = new Date();\n const hour = now.getHours();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n const day = days[now.getDay()];\n\n let period: string;\n if (hour < 6) period = \"late-night\";\n else if (hour < 12) period = \"morning\";\n else if (hour < 17) period = \"afternoon\";\n else if (hour < 21) period = \"evening\";\n else period = \"night\";\n\n const timeStr = now.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n const dateStr = now.toLocaleDateString();\n\n return `<time-context>\\nCurrent time: ${dateStr} ${timeStr} (${period}, ${day})\\nAdapt your tone naturally — don't announce the time, just be contextually appropriate.\\n</time-context>`;\n}\n\nexport interface HookContext {\n mcpManager: McpManager;\n config: HooksConfig;\n}\n\nlet isHookCall = false;\n\nexport async function onSessionStart(\n ctx: HookContext,\n): Promise<{ greeting?: string; contextInjection?: string }> {\n let greeting = \"\";\n let contextInjection = \"\";\n\n if (ctx.config.memoryRecall) {\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"memory_context\", {});\n if (result && !result.startsWith(\"Error\")) {\n greeting += result;\n }\n } catch (err) {\n log.warn(\"hooks\", \"memory_context recall failed\", err);\n } finally {\n isHookCall = false;\n }\n }\n\n if (ctx.config.sessionResume) {\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"identity_summary\", {});\n if (result && !result.startsWith(\"Error\")) {\n if (greeting) greeting += \"\\n\";\n greeting += result;\n }\n } catch (err) {\n log.warn(\"hooks\", \"identity_summary failed\", err);\n } finally {\n isHookCall = false;\n }\n }\n\n // Time context\n const timeContext = getTimeContext();\n if (greeting) greeting += \"\\n\" + timeContext;\n else greeting = timeContext;\n\n // Check reminders\n try {\n isHookCall = true;\n const reminderResult = await ctx.mcpManager.callTool(\"reminder_check\", {});\n if (reminderResult && !reminderResult.startsWith(\"Error\") && !reminderResult.includes(\"No pending\")) {\n greeting += \"\\n\\n<pending-reminders>\\n\" + reminderResult + \"\\n</pending-reminders>\";\n }\n } catch (err) {\n log.debug(\"hooks\", \"reminder_check failed\", err);\n } finally {\n isHookCall = false;\n }\n\n if (greeting) {\n contextInjection = `<session-context>\\n${greeting}\\n</session-context>`;\n }\n\n return {\n greeting: greeting || undefined,\n contextInjection: contextInjection || undefined,\n };\n}\n\nexport async function onBeforeToolExec(\n toolName: string,\n toolArgs: Record<string, unknown>,\n ctx: HookContext,\n): Promise<{ allow: boolean; reason?: string }> {\n if (!ctx.config.rulesCheck || isHookCall) {\n return { allow: true };\n }\n\n if (toolName === \"rules_check\") {\n return { allow: true };\n }\n\n try {\n isHookCall = true;\n const description = `${toolName}(${JSON.stringify(toolArgs)})`;\n const result = await ctx.mcpManager.callTool(\"rules_check\", {\n action: description,\n });\n\n try {\n const parsed = JSON.parse(result) as {\n violations?: string[];\n };\n if (parsed.violations && parsed.violations.length > 0) {\n return {\n allow: false,\n reason: parsed.violations.join(\"; \"),\n };\n }\n } catch (err) {\n log.debug(\"hooks\", \"rules_check parse failed\", err);\n }\n\n return { allow: true };\n } catch (err) {\n log.warn(\"hooks\", \"rules_check call failed\", err);\n return { allow: true };\n } finally {\n isHookCall = false;\n }\n}\n\nexport async function onWorkflowMatch(\n userInput: string,\n ctx: HookContext,\n): Promise<{ name: string; steps: string } | null> {\n if (!ctx.config.workflowSuggest) {\n return null;\n }\n\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"workflow_list\", {});\n\n const workflows = JSON.parse(result) as Array<{\n name: string;\n description?: string;\n steps?: string[];\n }>;\n\n const inputLower = userInput.toLowerCase();\n\n for (const wf of workflows) {\n const nameLower = wf.name.toLowerCase();\n\n // Check if user input contains workflow name\n if (inputLower.includes(nameLower)) {\n const steps = (wf.steps || [])\n .map((s, i) => `${i + 1}. ${s}`)\n .join(\"\\n\");\n return { name: wf.name, steps };\n }\n\n // Check significant words from description\n if (wf.description) {\n const words = wf.description\n .split(/\\s+/)\n .filter((w) => w.length > 4)\n .map((w) => w.toLowerCase());\n\n for (const word of words) {\n if (inputLower.includes(word)) {\n const steps = (wf.steps || [])\n .map((s, i) => `${i + 1}. ${s}`)\n .join(\"\\n\");\n return { name: wf.name, steps };\n }\n }\n }\n }\n\n return null;\n } catch (err) {\n log.debug(\"hooks\", \"workflow_list failed\", err);\n return null;\n } finally {\n isHookCall = false;\n }\n}\n\nexport async function onSessionEnd(\n ctx: HookContext,\n messages: Message[],\n sessionId: string,\n): Promise<void> {\n try {\n // Auto-save conversation to amem memory_log\n if (ctx.config.autoSessionSave && messages.length > 2) {\n console.log(pc.dim(\"\\n Saving conversation to memory...\"));\n\n // Save last 50 text messages to memory_log\n const textMessages = messages\n .filter((m) => typeof m.content === \"string\")\n .slice(-50);\n\n for (const msg of textMessages) {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"memory_log\", {\n session_id: sessionId,\n role: msg.role,\n content: (msg.content as string).slice(0, 5000),\n });\n } catch (err) {\n log.debug(\"hooks\", \"memory_log write failed for \" + sessionId, err);\n } finally {\n isHookCall = false;\n }\n }\n\n // Update session resume in identity\n let lastUserMsg = \"\";\n for (let i = messages.length - 1; i >= 0; i--) {\n if (\n messages[i].role === \"user\" &&\n typeof messages[i].content === \"string\"\n ) {\n lastUserMsg = messages[i].content as string;\n break;\n }\n }\n\n if (lastUserMsg) {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"identity_update_session\", {\n resume: lastUserMsg.slice(0, 200),\n topics: \"See conversation history\",\n decisions: \"See conversation history\",\n });\n } finally {\n isHookCall = false;\n }\n }\n\n console.log(pc.dim(` Saved ${textMessages.length} messages (session: ${sessionId})`));\n }\n\n // Session rating prompt\n if (ctx.config.evalPrompt) {\n const rating = await p.select({\n message: \"Quick rating for this session?\",\n options: [\n { value: \"great\", label: \"Great\" },\n { value: \"good\", label: \"Good\" },\n { value: \"okay\", label: \"Okay\" },\n { value: \"skip\", label: \"Skip\" },\n ],\n initialValue: \"skip\",\n });\n\n if (!p.isCancel(rating) && rating !== \"skip\") {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"eval_log\", {\n rating: rating as string,\n highlights: \"Quick session rating\",\n improvements: \"\",\n });\n } finally {\n isHookCall = false;\n }\n }\n }\n } catch (err) {\n log.warn(\"hooks\", \"session end hook failed\", err);\n }\n}\n","import type { Message, LLMClient } from \"./llm/types.js\";\nimport { log } from \"./logger.js\";\n\n// Rough token estimation: ~1.3 tokens per word\nfunction estimateMessageTokens(msg: Message): number {\n if (typeof msg.content === \"string\") {\n return Math.round(msg.content.split(/\\s+/).filter(Boolean).length * 1.3);\n }\n // Content blocks — estimate from stringified content\n let text = \"\";\n for (const block of msg.content) {\n if (block.type === \"text\") text += block.text;\n else if (block.type === \"tool_result\") text += block.content;\n else if (block.type === \"tool_use\") text += JSON.stringify(block.input);\n }\n return Math.round(text.split(/\\s+/).filter(Boolean).length * 1.3);\n}\n\nfunction estimateTotalTokens(messages: Message[]): number {\n let total = 0;\n for (const msg of messages) {\n total += estimateMessageTokens(msg);\n }\n return total;\n}\n\n// Maximum conversation tokens before trimming (leave room for system prompt + response)\nconst MAX_CONVERSATION_TOKENS = 80_000;\n// How many recent messages to always keep\nconst KEEP_RECENT = 10;\n// How many initial messages to always keep (session context injection)\nconst KEEP_INITIAL = 2;\n\n/**\n * Trims conversation history when it gets too long.\n * Keeps initial context messages and recent messages.\n * Replaces middle messages with a summary.\n * Mutates the messages array in place.\n */\nexport async function trimConversation(\n messages: Message[],\n client: LLMClient,\n): Promise<void> {\n const totalTokens = estimateTotalTokens(messages);\n\n if (totalTokens < MAX_CONVERSATION_TOKENS || messages.length <= KEEP_INITIAL + KEEP_RECENT) {\n return;\n }\n\n const initial = messages.slice(0, KEEP_INITIAL);\n const recent = messages.slice(-KEEP_RECENT);\n const middle = messages.slice(KEEP_INITIAL, messages.length - KEEP_RECENT);\n\n const middleText = middle\n .filter((m) => typeof m.content === \"string\" && m.content.length > 0)\n .map((m) => `[${m.role}]: ${(m.content as string).slice(0, 500)}`)\n .slice(0, 30)\n .join(\"\\n\");\n\n let summaryText: string;\n\n try {\n const summaryPrompt = \"Summarize the following conversation messages in 3-5 bullet points. Preserve: decisions made, user preferences expressed, action items, and key facts discussed. Be concise.\\n\\n\" + middleText;\n\n let fullText = \"\";\n await client.chat(\n \"You are a concise summarizer. Return only bullet points, no preamble.\",\n [{ role: \"user\", content: summaryPrompt }],\n (chunk) => {\n if (chunk.type === \"text\" && chunk.text) fullText += chunk.text;\n },\n );\n\n summaryText = `<conversation-summary>\\nSummary of ${middle.length} earlier messages:\\n\\n${fullText}\\n</conversation-summary>`;\n log.debug(\"context\", `Summarized ${middle.length} messages via LLM`);\n } catch (err) {\n log.warn(\"context\", \"LLM summarization failed, using fallback\", err);\n const summaryParts: string[] = [];\n for (const msg of middle) {\n if (typeof msg.content === \"string\" && msg.content.length > 0) {\n const preview = msg.content.slice(0, 150);\n summaryParts.push(`[${msg.role}]: ${preview}${msg.content.length > 150 ? \"...\" : \"\"}`);\n }\n }\n summaryText = `<conversation-summary>\\nSummary of ${middle.length} earlier messages:\\n\\n${summaryParts.slice(0, 20).join(\"\\n\")}\\n</conversation-summary>`;\n }\n\n messages.length = 0;\n messages.push(...initial);\n messages.push({ role: \"user\", content: summaryText });\n messages.push({ role: \"assistant\", content: \"I have the context from our earlier conversation. Let's continue.\" });\n messages.push(...recent);\n}\n","import type { LLMClient } from \"./llm/types.js\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport { log } from \"./logger.js\";\n\nexport interface ExtractionCandidate {\n content: string;\n type: \"preference\" | \"fact\" | \"pattern\" | \"decision\" | \"correction\" | \"topology\";\n tags: string[];\n confidence: number;\n scope: string;\n}\n\nconst AUTO_STORE_TYPES = new Set([\"preference\", \"fact\", \"pattern\", \"topology\"]);\nconst CONFIRM_TYPES = new Set([\"decision\", \"correction\"]);\nconst VALID_TYPES = new Set([...AUTO_STORE_TYPES, ...CONFIRM_TYPES]);\nconst MIN_RESPONSE_LENGTH = 50;\nconst MIN_TURNS_BETWEEN_EMPTY = 3;\n\nconst EXTRACTION_PROMPT = `Analyze this conversation turn. Extract any information worth remembering long-term.\n\nReturn a JSON array (empty [] if nothing worth storing):\n[{\n \"content\": \"what to remember — be specific and self-contained\",\n \"type\": \"preference|fact|pattern|decision|correction|topology\",\n \"tags\": [\"relevant\", \"tags\"],\n \"confidence\": 0.0-1.0,\n \"scope\": \"global\"\n}]\n\nType guide:\n- \"preference\" = user likes/dislikes/preferences\n- \"fact\" = objective information about systems, people, projects\n- \"pattern\" = recurring behavior, coding style, approach\n- \"topology\" = how systems/components connect to each other\n- \"decision\" = explicit choice between alternatives (requires confirmation)\n- \"correction\" = user correcting a prior wrong assumption (requires confirmation)\n\nRules:\n- Only extract genuinely useful LONG-TERM information\n- Skip ephemeral things (\"user asked about X\" is NOT useful)\n- Be conservative — 90% of turns produce nothing worth storing\n- Return ONLY the JSON array, no other text`;\n\nexport function shouldExtract(\n assistantResponse: string,\n turnsSinceLastExtraction: number,\n lastExtractionCount: number,\n): boolean {\n if (lastExtractionCount > 0) return true;\n if (assistantResponse.length < MIN_RESPONSE_LENGTH) return false;\n if (turnsSinceLastExtraction < MIN_TURNS_BETWEEN_EMPTY) return false;\n return true;\n}\n\nexport function parseExtractionResult(raw: string): ExtractionCandidate[] {\n try {\n let cleaned = raw.trim();\n const codeBlockMatch = cleaned.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/);\n if (codeBlockMatch) {\n cleaned = codeBlockMatch[1].trim();\n }\n\n const parsed = JSON.parse(cleaned);\n if (!Array.isArray(parsed)) return [];\n\n return parsed.filter(\n (item: Record<string, unknown>) =>\n typeof item.content === \"string\" &&\n item.content.length > 0 &&\n typeof item.type === \"string\" &&\n VALID_TYPES.has(item.type),\n ) as ExtractionCandidate[];\n } catch {\n return [];\n }\n}\n\nexport interface ExtractorState {\n turnsSinceLastExtraction: number;\n lastExtractionCount: number;\n}\n\nexport async function extractMemories(\n userMessage: string,\n assistantResponse: string,\n client: LLMClient,\n mcpManager: McpManager,\n state: ExtractorState,\n confirmFn: (content: string) => Promise<boolean>,\n): Promise<number> {\n if (!shouldExtract(assistantResponse, state.turnsSinceLastExtraction, state.lastExtractionCount)) {\n state.turnsSinceLastExtraction++;\n return 0;\n }\n\n try {\n const conversationTurn = `User: ${userMessage.slice(0, 2000)}\\n\\nAssistant: ${assistantResponse.slice(0, 2000)}`;\n\n let fullText = \"\";\n await client.chat(\n EXTRACTION_PROMPT,\n [{ role: \"user\", content: conversationTurn }],\n (chunk) => {\n if (chunk.type === \"text\" && chunk.text) fullText += chunk.text;\n },\n );\n\n const candidates = parseExtractionResult(fullText);\n state.turnsSinceLastExtraction = 0;\n state.lastExtractionCount = candidates.length;\n\n if (candidates.length === 0) return 0;\n\n let stored = 0;\n\n for (const candidate of candidates) {\n // Dedup check\n try {\n const existing = await mcpManager.callTool(\"memory_recall\", {\n query: candidate.content,\n limit: 1,\n });\n if (existing && !existing.startsWith(\"Error\")) {\n try {\n const parsed = JSON.parse(existing);\n if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].score > 0.85) {\n log.debug(\"extractor\", \"Skipping duplicate: \" + candidate.content);\n continue;\n }\n } catch { /* Parse failed, proceed */ }\n }\n } catch { /* Dedup failed, proceed */ }\n\n // Confirm decisions/corrections\n if (CONFIRM_TYPES.has(candidate.type)) {\n const confirmed = await confirmFn(candidate.content);\n if (!confirmed) continue;\n }\n\n // Store\n try {\n await mcpManager.callTool(\"memory_store\", {\n content: candidate.content,\n type: candidate.type,\n tags: candidate.tags,\n confidence: candidate.confidence,\n source: \"auto-extraction\",\n scope: candidate.scope,\n });\n stored++;\n log.debug(\"extractor\", \"Stored \" + candidate.type + \": \" + candidate.content);\n } catch (err) {\n log.warn(\"extractor\", \"Failed to store: \" + candidate.content, err);\n }\n }\n\n return stored;\n } catch (err) {\n log.debug(\"extractor\", \"extraction failed\", err);\n state.turnsSinceLastExtraction = 0;\n state.lastExtractionCount = 0;\n return 0;\n }\n}\n"],"mappings":"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","names":["p","pc","fs","path","os","text","home","os","path","fs","text","text","OpenAI","text","fs","path","os","fs","path","os","pc","fs","path","os","fs","path","os","fs","home","os","path","text","pc","pc","text","pc","path","os","fs","fs","path","os","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/prompt.ts","../src/token-budget.ts","../src/llm/anthropic.ts","../src/llm/openai.ts","../src/llm/ollama.ts","../src/mcp/client.ts","../src/logger.ts","../src/retry.ts","../src/agent.ts","../src/commands.ts","../src/layers/parsers.ts","../src/hooks.ts","../src/context-manager.ts","../src/memory-extractor.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { assembleSystemPrompt } from \"./prompt.js\";\nimport { createAnthropicClient } from \"./llm/anthropic.js\";\nimport { createOpenAIClient } from \"./llm/openai.js\";\nimport { createOllamaClient } from \"./llm/ollama.js\";\nimport { McpManager } from \"./mcp/client.js\";\nimport { runAgent } from \"./agent.js\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"aman-agent\")\n .description(\"Your AI companion, running locally\")\n .version(__VERSION__)\n .option(\"--model <model>\", \"Override LLM model\")\n .option(\"--budget <tokens>\", \"Token budget for system prompt (default: 8000)\", parseInt)\n .action(async (options) => {\n p.intro(pc.bold(\"aman agent\") + pc.dim(\" — starting your AI companion\"));\n\n // Setup config if needed\n let config = loadConfig();\n if (!config) {\n p.log.info(\"First-time setup — configure your LLM connection.\");\n\n const provider = (await p.select({\n message: \"LLM provider\",\n options: [\n {\n value: \"anthropic\",\n label: \"Claude (Anthropic)\",\n hint: \"recommended\",\n },\n { value: \"openai\", label: \"GPT (OpenAI)\" },\n { value: \"ollama\", label: \"Ollama (local)\", hint: \"free, runs offline\" },\n ],\n initialValue: \"anthropic\",\n })) as \"anthropic\" | \"openai\" | \"ollama\";\n if (p.isCancel(provider)) process.exit(0);\n\n let apiKey = \"\";\n let defaultModel = \"\";\n\n if (provider === \"ollama\") {\n apiKey = \"ollama\";\n const modelInput = (await p.text({\n message: \"Ollama model name\",\n placeholder: \"llama3.2\",\n defaultValue: \"llama3.2\",\n })) as string;\n if (p.isCancel(modelInput)) process.exit(0);\n defaultModel = modelInput || \"llama3.2\";\n } else if (provider === \"anthropic\") {\n p.log.info(\"Get your API key from: https://console.anthropic.com/settings/keys\");\n p.log.info(pc.dim(\"Note: API access is separate from Claude Pro subscription. You need API credits.\"));\n\n apiKey = (await p.text({\n message: \"API key (starts with sk-ant-)\",\n validate: (v) => v.length === 0 ? \"API key is required\" : undefined,\n })) as string;\n if (p.isCancel(apiKey)) process.exit(0);\n\n const modelChoice = (await p.select({\n message: \"Claude model\",\n options: [\n { value: \"claude-sonnet-4-5-20250514\", label: \"Claude Sonnet 4.5\", hint: \"fast, recommended\" },\n { value: \"claude-opus-4-6\", label: \"Claude Opus 4.6\", hint: \"most capable\" },\n { value: \"claude-haiku-4-5-20251001\", label: \"Claude Haiku 4.5\", hint: \"fastest, cheapest\" },\n { value: \"custom\", label: \"Custom model ID\" },\n ],\n initialValue: \"claude-sonnet-4-5-20250514\",\n })) as string;\n if (p.isCancel(modelChoice)) process.exit(0);\n\n if (modelChoice === \"custom\") {\n const customModel = (await p.text({\n message: \"Model ID\",\n placeholder: \"claude-sonnet-4-5-20250514\",\n validate: (v) => v.length === 0 ? \"Model ID is required\" : undefined,\n })) as string;\n if (p.isCancel(customModel)) process.exit(0);\n defaultModel = customModel;\n } else {\n defaultModel = modelChoice;\n }\n } else {\n // OpenAI\n apiKey = (await p.text({\n message: \"API key\",\n validate: (v) => v.length === 0 ? \"API key is required\" : undefined,\n })) as string;\n if (p.isCancel(apiKey)) process.exit(0);\n\n const modelChoice = (await p.select({\n message: \"OpenAI model\",\n options: [\n { value: \"gpt-4o\", label: \"GPT-4o\", hint: \"recommended\" },\n { value: \"gpt-4o-mini\", label: \"GPT-4o Mini\", hint: \"faster, cheaper\" },\n { value: \"o3\", label: \"o3\", hint: \"reasoning model\" },\n { value: \"custom\", label: \"Custom model ID\" },\n ],\n initialValue: \"gpt-4o\",\n })) as string;\n if (p.isCancel(modelChoice)) process.exit(0);\n\n if (modelChoice === \"custom\") {\n const customModel = (await p.text({\n message: \"Model ID\",\n placeholder: \"gpt-4o\",\n validate: (v) => v.length === 0 ? \"Model ID is required\" : undefined,\n })) as string;\n if (p.isCancel(customModel)) process.exit(0);\n defaultModel = customModel;\n } else {\n defaultModel = modelChoice;\n }\n }\n\n config = { provider, apiKey, model: defaultModel };\n saveConfig(config);\n p.log.success(\"Config saved to ~/.aman-agent/config.json\");\n }\n\n // Override model if specified\n const model = options.model || config.model;\n\n // Assemble system prompt from ecosystem with token budget\n const budget = options.budget || undefined;\n const { prompt: systemPrompt, layers, truncated, totalTokens } = assembleSystemPrompt(budget);\n\n if (layers.length === 0) {\n p.log.warning(\n \"No ecosystem configured. Run \" +\n pc.bold(\"npx @aman_asmuei/aman\") +\n \" first.\",\n );\n p.log.info(\"Starting with empty system prompt.\");\n } else {\n p.log.success(\n `Loaded: ${layers.join(\", \")} ${pc.dim(`(${totalTokens.toLocaleString()} tokens)`)}`,\n );\n if (truncated.length > 0) {\n p.log.warning(`Truncated: ${truncated.join(\", \")} ${pc.dim(\"(over budget)\")}`);\n }\n }\n\n p.log.info(`Model: ${pc.dim(model)}`);\n\n // Extract AI name from core.md\n const corePath = path.join(os.homedir(), \".acore\", \"core.md\");\n let aiName = \"Assistant\";\n if (fs.existsSync(corePath)) {\n const content = fs.readFileSync(corePath, \"utf-8\");\n const match = content.match(/^# (.+)$/m);\n if (match) aiName = match[1];\n }\n\n p.log.success(`${pc.bold(aiName)} is ready.`);\n\n // Start MCP servers\n const mcpManager = new McpManager();\n\n p.log.step(\"Connecting to MCP servers...\");\n\n // Connect to aman-mcp (identity, tools, workflows, rules, eval)\n await mcpManager.connect(\"aman\", \"npx\", [\"-y\", \"@aman_asmuei/aman-mcp\"]);\n\n // Connect to amem (memory)\n await mcpManager.connect(\"amem\", \"npx\", [\"-y\", \"@aman_asmuei/amem\"]);\n\n const mcpTools = mcpManager.getTools();\n if (mcpTools.length > 0) {\n p.log.success(`${mcpTools.length} MCP tools available`);\n\n // Memory consolidation\n if (mcpTools.some(t => t.name === \"memory_consolidate\")) {\n try {\n const consolidateResult = await mcpManager.callTool(\"memory_consolidate\", { dry_run: false });\n if (consolidateResult && !consolidateResult.startsWith(\"Error\")) {\n try {\n const report = JSON.parse(consolidateResult);\n if (report.merged > 0 || report.pruned > 0 || report.promoted > 0) {\n p.log.info(\n `Memory health: ${report.healthScore ?? \"?\"}% ` +\n pc.dim(`(merged ${report.merged}, pruned ${report.pruned}, promoted ${report.promoted})`),\n );\n }\n } catch {\n // Non-JSON response\n }\n }\n } catch {\n // Consolidation is non-critical\n }\n }\n } else {\n p.log.info(\n \"No MCP tools connected (install aman-mcp or amem for tool support)\",\n );\n }\n\n // Convert ToolDef[] to ToolDefinition[] for the LLM\n const toolDefs = mcpTools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.input_schema,\n }));\n\n // Create LLM client\n let client;\n if (config.provider === \"anthropic\") {\n client = createAnthropicClient(config.apiKey, model);\n } else if (config.provider === \"ollama\") {\n client = createOllamaClient(model);\n } else {\n client = createOpenAIClient(config.apiKey, model);\n }\n\n // Run the agent\n await runAgent(\n client,\n systemPrompt,\n aiName,\n model,\n toolDefs.length > 0 ? toolDefs : undefined,\n toolDefs.length > 0 ? mcpManager : undefined,\n config.hooks,\n );\n\n // Cleanup on exit\n await mcpManager.disconnect();\n });\n\nprogram.parse();\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface HooksConfig {\n memoryRecall?: boolean;\n sessionResume?: boolean;\n rulesCheck?: boolean;\n workflowSuggest?: boolean;\n evalPrompt?: boolean;\n autoSessionSave?: boolean;\n extractMemories?: boolean;\n}\n\nconst DEFAULT_HOOKS: HooksConfig = {\n memoryRecall: true,\n sessionResume: true,\n rulesCheck: true,\n workflowSuggest: true,\n evalPrompt: true,\n autoSessionSave: true,\n extractMemories: true,\n};\n\nexport interface AgentConfig {\n provider: \"anthropic\" | \"openai\" | \"ollama\";\n apiKey: string;\n model: string;\n hooks?: HooksConfig;\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), \".aman-agent\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\nexport function loadConfig(): AgentConfig | null {\n if (!fs.existsSync(CONFIG_PATH)) return null;\n try {\n const raw = JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\")) as AgentConfig;\n raw.hooks = { ...DEFAULT_HOOKS, ...raw.hooks };\n return raw;\n } catch {\n return null;\n }\n}\n\nexport function saveConfig(config: AgentConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(\n CONFIG_PATH,\n JSON.stringify(config, null, 2) + \"\\n\",\n \"utf-8\",\n );\n}\n\nexport function configExists(): boolean {\n return fs.existsSync(CONFIG_PATH);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { estimateTokens, buildBudgetedPrompt } from \"./token-budget.js\";\nimport type { PromptComponent } from \"./token-budget.js\";\n\ninterface EcosystemFile {\n name: string;\n dir: string;\n file: string;\n}\n\nconst ECOSYSTEM_FILES: EcosystemFile[] = [\n { name: \"identity\", dir: \".acore\", file: \"core.md\" },\n { name: \"tools\", dir: \".akit\", file: \"kit.md\" },\n { name: \"workflows\", dir: \".aflow\", file: \"flow.md\" },\n { name: \"guardrails\", dir: \".arules\", file: \"rules.md\" },\n { name: \"skills\", dir: \".askill\", file: \"skills.md\" },\n];\n\nexport function assembleSystemPrompt(maxTokens?: number): {\n prompt: string;\n layers: string[];\n truncated: string[];\n totalTokens: number;\n} {\n const home = os.homedir();\n const components: PromptComponent[] = [];\n\n for (const entry of ECOSYSTEM_FILES) {\n const filePath = path.join(home, entry.dir, entry.file);\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, \"utf-8\").trim();\n components.push({\n name: entry.name,\n content,\n tokens: estimateTokens(content),\n });\n }\n }\n\n // Project context (not prioritized — appended as extra)\n const contextPath = path.join(process.cwd(), \".acore\", \"context.md\");\n if (fs.existsSync(contextPath)) {\n const content = fs.readFileSync(contextPath, \"utf-8\").trim();\n components.push({\n name: \"context\",\n content,\n tokens: estimateTokens(content),\n });\n }\n\n const budgeted = buildBudgetedPrompt(components, maxTokens);\n\n return {\n prompt: budgeted.prompt,\n layers: budgeted.included,\n truncated: budgeted.truncated,\n totalTokens: budgeted.totalTokens,\n };\n}\n","// Rough token estimation: ~1.3 tokens per word for English markdown\nexport function estimateTokens(text: string): number {\n return Math.round(text.split(/\\s+/).filter(Boolean).length * 1.3);\n}\n\n// Priority order for system prompt components (highest to lowest)\nconst PRIORITIES = [\n \"identity\", // core.md — always include\n \"guardrails\", // rules.md — safety critical\n \"workflows\", // flow.md — behavioral\n \"tools\", // kit.md — capabilities\n \"skills\", // skills.md — can be truncated\n];\n\nexport interface PromptComponent {\n name: string;\n content: string;\n tokens: number;\n}\n\nexport function buildBudgetedPrompt(\n components: PromptComponent[],\n maxTokens: number = 8000, // default budget for system prompt\n): { prompt: string; included: string[]; truncated: string[]; totalTokens: number } {\n const included: string[] = [];\n const truncated: string[] = [];\n const parts: string[] = [];\n let totalTokens = 0;\n\n // Sort by priority\n const sorted = [...components].sort((a, b) => {\n const aPri = PRIORITIES.indexOf(a.name);\n const bPri = PRIORITIES.indexOf(b.name);\n return (aPri === -1 ? 99 : aPri) - (bPri === -1 ? 99 : bPri);\n });\n\n for (const comp of sorted) {\n if (totalTokens + comp.tokens <= maxTokens) {\n parts.push(comp.content);\n included.push(comp.name);\n totalTokens += comp.tokens;\n } else {\n // Try to include a truncated version (first 50% of content)\n const halfContent = comp.content.slice(0, Math.floor(comp.content.length / 2));\n const halfTokens = estimateTokens(halfContent);\n if (totalTokens + halfTokens <= maxTokens) {\n parts.push(halfContent + \"\\n\\n[... truncated for context budget ...]\");\n included.push(comp.name + \" (partial)\");\n totalTokens += halfTokens;\n } else {\n truncated.push(comp.name);\n }\n }\n }\n\n return {\n prompt: parts.join(\"\\n\\n---\\n\\n\"),\n included,\n truncated,\n totalTokens,\n };\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ToolDefinition,\n ChatResponse,\n ContentBlock,\n} from \"./types.js\";\n\nfunction toAnthropicMessages(\n messages: Message[],\n): Anthropic.Messages.MessageParam[] {\n return messages.map((m) => {\n if (typeof m.content === \"string\") {\n return { role: m.role, content: m.content };\n }\n // Complex content blocks (tool_use, tool_result, etc.)\n return {\n role: m.role,\n content: m.content.map((block) => {\n if (block.type === \"text\") {\n return { type: \"text\" as const, text: block.text };\n }\n if (block.type === \"tool_use\") {\n return {\n type: \"tool_use\" as const,\n id: block.id,\n name: block.name,\n input: block.input,\n };\n }\n if (block.type === \"tool_result\") {\n return {\n type: \"tool_result\" as const,\n tool_use_id: block.tool_use_id,\n content: block.content,\n };\n }\n return { type: \"text\" as const, text: \"\" };\n }),\n };\n });\n}\n\nexport function createAnthropicClient(\n apiKey: string,\n model: string,\n): LLMClient {\n const client = new Anthropic({ apiKey });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n tools?: ToolDefinition[],\n ): Promise<ChatResponse> {\n const anthropicMessages = toAnthropicMessages(messages);\n const hasTools = tools && tools.length > 0;\n\n try {\n let fullText = \"\";\n const toolUseBlocks: Array<{\n id: string;\n name: string;\n inputJson: string;\n }> = [];\n let currentBlockType: \"text\" | \"tool_use\" | null = null;\n let currentBlockIndex = -1;\n\n const createParams: Record<string, unknown> = {\n model,\n max_tokens: 8192,\n system: systemPrompt,\n messages: anthropicMessages,\n stream: true,\n };\n\n if (hasTools) {\n createParams.tools = tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema:\n t.input_schema as Anthropic.Messages.Tool[\"input_schema\"],\n }));\n }\n\n const stream = await client.messages.create(\n createParams as unknown as Anthropic.Messages.MessageCreateParamsStreaming,\n );\n\n for await (const event of stream) {\n if (event.type === \"content_block_start\") {\n currentBlockIndex = event.index;\n if (event.content_block.type === \"text\") {\n currentBlockType = \"text\";\n } else if (event.content_block.type === \"tool_use\") {\n currentBlockType = \"tool_use\";\n toolUseBlocks.push({\n id: event.content_block.id,\n name: event.content_block.name,\n inputJson: \"\",\n });\n }\n } else if (event.type === \"content_block_delta\") {\n if (\n currentBlockType === \"text\" &&\n event.delta.type === \"text_delta\"\n ) {\n const text = event.delta.text;\n fullText += text;\n onChunk({ type: \"text\", text });\n } else if (\n currentBlockType === \"tool_use\" &&\n event.delta.type === \"input_json_delta\"\n ) {\n const lastTool = toolUseBlocks[toolUseBlocks.length - 1];\n if (lastTool) {\n lastTool.inputJson += event.delta.partial_json;\n }\n }\n } else if (event.type === \"content_block_stop\") {\n currentBlockType = null;\n }\n }\n\n // Parse tool inputs from accumulated JSON\n const toolUses = toolUseBlocks.map((block) => ({\n id: block.id,\n name: block.name,\n input: (block.inputJson\n ? JSON.parse(block.inputJson)\n : {}) as Record<string, unknown>,\n }));\n\n // Signal done\n onChunk({ type: \"done\" });\n\n // Build content blocks for the message\n if (toolUses.length > 0) {\n const contentBlocks: ContentBlock[] = [];\n if (fullText) {\n contentBlocks.push({ type: \"text\" as const, text: fullText });\n }\n for (const tu of toolUses) {\n contentBlocks.push({\n type: \"tool_use\" as const,\n id: tu.id,\n name: tu.name,\n input: tu.input,\n });\n }\n return {\n message: { role: \"assistant\", content: contentBlocks },\n toolUses,\n };\n }\n\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n } catch (error) {\n if (error instanceof Anthropic.AuthenticationError) {\n throw new Error(\n \"Invalid API key. Run with --model flag or delete ~/.aman-agent/config.json to reconfigure.\",\n );\n }\n if (error instanceof Anthropic.RateLimitError) {\n throw new Error(\"Rate limited by Anthropic. Please wait and retry.\");\n }\n throw error;\n }\n },\n };\n}\n","import OpenAI from \"openai\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ToolDefinition,\n ChatResponse,\n} from \"./types.js\";\n\nfunction toOpenAIMessages(\n systemPrompt: string,\n messages: Message[],\n): OpenAI.Chat.Completions.ChatCompletionMessageParam[] {\n const result: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [\n { role: \"system\", content: systemPrompt },\n ];\n\n for (const m of messages) {\n if (typeof m.content === \"string\") {\n result.push({\n role: m.role as \"user\" | \"assistant\",\n content: m.content,\n });\n } else if (m.role === \"assistant\") {\n // Assistant message with tool calls\n const textParts = m.content.filter((b) => b.type === \"text\");\n const toolUseParts = m.content.filter((b) => b.type === \"tool_use\");\n const text = textParts.map((b) => (\"text\" in b ? b.text : \"\")).join(\"\");\n\n if (toolUseParts.length > 0) {\n result.push({\n role: \"assistant\",\n content: text || null,\n tool_calls: toolUseParts.map((b) => ({\n id: \"id\" in b ? b.id : \"\",\n type: \"function\" as const,\n function: {\n name: \"name\" in b ? b.name : \"\",\n arguments: JSON.stringify(\"input\" in b ? b.input : {}),\n },\n })),\n });\n } else {\n result.push({ role: \"assistant\", content: text });\n }\n } else if (m.role === \"user\") {\n // Check if it contains tool results\n const toolResults = m.content.filter((b) => b.type === \"tool_result\");\n if (toolResults.length > 0) {\n for (const tr of toolResults) {\n if (tr.type === \"tool_result\") {\n result.push({\n role: \"tool\",\n tool_call_id: tr.tool_use_id,\n content: tr.content,\n });\n }\n }\n } else {\n const text = m.content\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\");\n result.push({ role: \"user\", content: text });\n }\n }\n }\n\n return result;\n}\n\nexport function createOpenAIClient(apiKey: string, model: string): LLMClient {\n const client = new OpenAI({ apiKey });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n tools?: ToolDefinition[],\n ): Promise<ChatResponse> {\n const openaiMessages = toOpenAIMessages(systemPrompt, messages);\n const hasTools = tools && tools.length > 0;\n\n try {\n let fullText = \"\";\n const toolCallAccumulators: Map<\n number,\n { id: string; name: string; arguments: string }\n > = new Map();\n\n const createParams: Record<string, unknown> = {\n model,\n max_tokens: 8192,\n messages: openaiMessages,\n stream: true,\n };\n\n if (hasTools) {\n createParams.tools = tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.input_schema,\n },\n }));\n }\n\n const stream = await client.chat.completions.create(\n createParams as unknown as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,\n );\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta;\n if (!delta) continue;\n\n // Stream text content\n if (delta.content) {\n fullText += delta.content;\n onChunk({ type: \"text\", text: delta.content });\n }\n\n // Accumulate tool calls\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index;\n let acc = toolCallAccumulators.get(idx);\n if (!acc) {\n acc = { id: \"\", name: \"\", arguments: \"\" };\n toolCallAccumulators.set(idx, acc);\n }\n if (tc.id) {\n acc.id = tc.id;\n }\n if (tc.function?.name) {\n acc.name = tc.function.name;\n }\n if (tc.function?.arguments) {\n acc.arguments += tc.function.arguments;\n }\n }\n }\n }\n\n // Parse accumulated tool calls\n const toolUses = Array.from(toolCallAccumulators.entries())\n .sort(([a], [b]) => a - b)\n .map(([, acc]) => ({\n id: acc.id,\n name: acc.name,\n input: JSON.parse(acc.arguments || \"{}\") as Record<\n string,\n unknown\n >,\n }));\n\n // Signal done\n onChunk({ type: \"done\" });\n\n // Build response\n if (toolUses.length > 0) {\n const contentBlocks = [\n ...(fullText\n ? [{ type: \"text\" as const, text: fullText }]\n : []),\n ...toolUses.map((tu) => ({\n type: \"tool_use\" as const,\n id: tu.id,\n name: tu.name,\n input: tu.input,\n })),\n ];\n return {\n message: { role: \"assistant\", content: contentBlocks },\n toolUses,\n };\n }\n\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n } catch (error) {\n if (error instanceof OpenAI.AuthenticationError) {\n throw new Error(\n \"Invalid API key. Run with --model flag or delete ~/.aman-agent/config.json to reconfigure.\",\n );\n }\n if (error instanceof OpenAI.RateLimitError) {\n throw new Error(\"Rate limited by OpenAI. Please wait and retry.\");\n }\n throw error;\n }\n },\n };\n}\n","import OpenAI from \"openai\";\nimport type {\n LLMClient,\n Message,\n StreamChunk,\n ChatResponse,\n} from \"./types.js\";\n\nexport function createOllamaClient(\n model: string,\n baseURL?: string,\n): LLMClient {\n const client = new OpenAI({\n baseURL: baseURL || \"http://localhost:11434/v1\",\n apiKey: \"ollama\", // Ollama doesn't require a real key\n });\n\n return {\n async chat(\n systemPrompt: string,\n messages: Message[],\n onChunk: (chunk: StreamChunk) => void,\n _tools?, // Ollama doesn't support tool use — ignored\n ): Promise<ChatResponse> {\n let fullText = \"\";\n\n try {\n const stream = await client.chat.completions.create({\n model,\n max_tokens: 8192,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...messages.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\"),\n })),\n ],\n stream: true,\n });\n\n for await (const chunk of stream) {\n const text = chunk.choices[0]?.delta?.content || \"\";\n if (text) {\n fullText += text;\n onChunk({ type: \"text\", text });\n }\n }\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"ECONNREFUSED\")\n ) {\n throw new Error(\n \"Cannot connect to Ollama. Make sure it's running: ollama serve\",\n );\n }\n throw error;\n }\n\n onChunk({ type: \"done\" });\n return {\n message: { role: \"assistant\", content: fullText },\n toolUses: [],\n };\n },\n };\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { log } from \"../logger.js\";\nimport { withRetry } from \"../retry.js\";\n\ninterface McpConnection {\n name: string;\n client: Client;\n transport: StdioClientTransport;\n}\n\nexport interface ToolDef {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n serverName: string;\n}\n\nexport class McpManager {\n private connections: McpConnection[] = [];\n private tools: ToolDef[] = [];\n\n async connect(\n name: string,\n command: string,\n args: string[],\n ): Promise<void> {\n try {\n const transport = new StdioClientTransport({ command, args });\n const client = new Client({\n name: `aman-agent-${name}`,\n version: \"0.1.0\",\n });\n await client.connect(transport);\n\n this.connections.push({ name, client, transport });\n\n // List tools from this server\n const toolsResult = await client.listTools();\n for (const tool of toolsResult.tools) {\n this.tools.push({\n name: tool.name,\n description: tool.description || \"\",\n input_schema: tool.inputSchema as Record<string, unknown>,\n serverName: name,\n });\n }\n } catch (err) {\n log.error(\"mcp\", \"Failed to connect to \" + name + \" MCP server\", err);\n console.error(` Warning: Could not connect to ${name} MCP server`);\n }\n }\n\n getTools(): ToolDef[] {\n return this.tools;\n }\n\n async callTool(\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<string> {\n const tool = this.tools.find((t) => t.name === toolName);\n if (!tool) return `Error: tool ${toolName} not found`;\n\n const conn = this.connections.find((c) => c.name === tool.serverName);\n if (!conn) return `Error: server ${tool.serverName} not connected`;\n\n try {\n const result = await withRetry(\n () => conn.client.callTool({ name: toolName, arguments: args }),\n { maxAttempts: 2, baseDelay: 500, retryable: (err) => err.message.includes(\"ETIMEDOUT\") || err.message.includes(\"timeout\") },\n );\n // Extract text from result\n if (result.content && Array.isArray(result.content)) {\n return (result.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === \"text\")\n .map((c) => c.text ?? \"\")\n .join(\"\\n\");\n }\n return JSON.stringify(result);\n } catch (error) {\n return `Error calling ${toolName}: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n\n async disconnect(): Promise<void> {\n for (const conn of this.connections) {\n try {\n await conn.client.close();\n } catch (err) {\n log.debug(\"mcp\", \"Cleanup error disconnecting \" + conn.name, err);\n }\n }\n this.connections = [];\n this.tools = [];\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst LOG_DIR = path.join(os.homedir(), \".aman-agent\");\nexport const LOG_PATH = path.join(LOG_DIR, \"debug.log\");\nconst MAX_LOG_SIZE = 1_048_576; // 1MB\n\ninterface LogEntry {\n timestamp: string;\n level: \"debug\" | \"warn\" | \"error\";\n module: string;\n message: string;\n data?: string;\n}\n\nfunction ensureDir(): void {\n if (!fs.existsSync(LOG_DIR)) {\n fs.mkdirSync(LOG_DIR, { recursive: true });\n }\n}\n\nfunction maybeRotate(): void {\n try {\n if (!fs.existsSync(LOG_PATH)) return;\n const stat = fs.statSync(LOG_PATH);\n if (stat.size >= MAX_LOG_SIZE) {\n const backupPath = LOG_PATH + \".1\";\n if (fs.existsSync(backupPath)) fs.unlinkSync(backupPath);\n fs.renameSync(LOG_PATH, backupPath);\n }\n } catch {\n // Rotation failure is non-critical\n }\n}\n\nfunction write(level: LogEntry[\"level\"], module: string, message: string, data?: unknown): void {\n try {\n ensureDir();\n maybeRotate();\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n module,\n message,\n };\n if (data !== undefined) {\n entry.data = data instanceof Error ? data.message : String(data);\n }\n fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + \"\\n\");\n } catch {\n // Logger must never throw\n }\n}\n\nexport const log = {\n debug: (module: string, message: string, data?: unknown) => write(\"debug\", module, message, data),\n warn: (module: string, message: string, data?: unknown) => write(\"warn\", module, message, data),\n error: (module: string, message: string, data?: unknown) => write(\"error\", module, message, data),\n};\n","export interface RetryOptions {\n maxAttempts: number;\n baseDelay: number;\n retryable: (err: Error) => boolean;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n const { maxAttempts, baseDelay, retryable } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n if (!retryable(lastError) || attempt === maxAttempts) {\n throw lastError;\n }\n const delay = baseDelay * Math.pow(2, attempt - 1) * (0.5 + Math.random() * 0.5);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}\n","import * as readline from \"node:readline\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport pc from \"picocolors\";\nimport type {\n LLMClient,\n Message,\n ToolDefinition,\n ToolResultBlock,\n StreamChunk,\n} from \"./llm/types.js\";\nimport { handleCommand } from \"./commands.js\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport {\n onSessionStart,\n onBeforeToolExec,\n onWorkflowMatch,\n onSessionEnd,\n type HookContext,\n} from \"./hooks.js\";\nimport type { HooksConfig } from \"./config.js\";\nimport { trimConversation } from \"./context-manager.js\";\nimport { log } from \"./logger.js\";\nimport { withRetry } from \"./retry.js\";\nimport { extractMemories as runExtraction, type ExtractorState } from \"./memory-extractor.js\";\n\ninterface RecallResult {\n text: string;\n tokenEstimate: number;\n}\n\nasync function recallForMessage(\n input: string,\n mcpManager: McpManager,\n): Promise<RecallResult | null> {\n try {\n const result = await mcpManager.callTool(\"memory_recall\", {\n query: input,\n limit: 5,\n compact: true,\n });\n if (!result || result.startsWith(\"Error\") || result.includes(\"No memories found\")) {\n return null;\n }\n // Estimate tokens: ~1.3 tokens per word\n const tokenEstimate = Math.round(result.split(/\\s+/).filter(Boolean).length * 1.3);\n return {\n text: `\\n\\n<relevant-memories>\\n${result}\\n</relevant-memories>`,\n tokenEstimate,\n };\n } catch (err) {\n log.debug(\"agent\", \"memory recall failed\", err);\n return null;\n }\n}\n\n// Generate a session ID for conversation logging\nfunction generateSessionId(): string {\n const now = new Date();\n const pad = (n: number) => n.toString().padStart(2, \"0\");\n return `session-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}`;\n}\n\nexport async function runAgent(\n client: LLMClient,\n systemPrompt: string,\n aiName: string,\n model: string,\n tools?: ToolDefinition[],\n mcpManager?: McpManager,\n hooksConfig?: HooksConfig,\n): Promise<void> {\n const messages: Message[] = [];\n const sessionId = generateSessionId();\n const extractorState: ExtractorState = { turnsSinceLastExtraction: 0, lastExtractionCount: 0 };\n\n const isRetryable = (err: Error) =>\n err.message.includes(\"Rate limit\") ||\n err.message.includes(\"rate limit\") ||\n err.message.includes(\"ECONNRESET\") ||\n err.message.includes(\"ETIMEDOUT\") ||\n err.message.includes(\"fetch failed\");\n\n const onChunkHandler = (chunk: StreamChunk) => {\n if (chunk.type === \"text\" && chunk.text) {\n process.stdout.write(chunk.text);\n }\n if (chunk.type === \"done\") {\n process.stdout.write(\"\\n\");\n }\n };\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n // Handle Ctrl+C gracefully\n rl.on(\"SIGINT\", async () => {\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n await onSessionEnd(hookCtx, messages, sessionId);\n } catch (err) { log.debug(\"agent\", \"session end hook failed on SIGINT\", err); }\n }\n console.log(pc.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n process.exit(0);\n });\n\n const prompt = (): Promise<string> => {\n return new Promise<string>((resolve) => {\n rl.question(pc.green(\"\\nYou > \"), (answer) => {\n resolve(answer);\n });\n });\n };\n\n console.log(\n `\\nType a message, ${pc.dim(\"/help\")} for commands, or ${pc.dim(\"/quit\")} to exit.\\n`,\n );\n\n if (mcpManager && hooksConfig) {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n try {\n const session = await onSessionStart(hookCtx);\n if (session.greeting) console.log(pc.dim(session.greeting));\n if (session.contextInjection) {\n messages.push({ role: \"user\", content: session.contextInjection });\n messages.push({ role: \"assistant\", content: \"I have context from our previous sessions. How can I help?\" });\n }\n } catch (err) { log.warn(\"agent\", \"session start hook failed\", err); }\n }\n\n while (true) {\n const input = await prompt();\n if (!input.trim()) continue;\n\n // Handle slash commands\n const cmdResult = await handleCommand(input, { model, mcpManager });\n if (cmdResult.handled) {\n if (cmdResult.quit) {\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n await onSessionEnd(hookCtx, messages, sessionId);\n } catch (err) { log.debug(\"agent\", \"session end hook failed on quit\", err); }\n }\n console.log(pc.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n return;\n }\n if (cmdResult.exportConversation) {\n try {\n const exportDir = path.join(os.homedir(), \".aman-agent\", \"exports\");\n fs.mkdirSync(exportDir, { recursive: true });\n const exportPath = path.join(exportDir, `${sessionId}.md`);\n\n const lines: string[] = [\n `# Conversation — ${new Date().toLocaleString()}`,\n `**Model:** ${model}`,\n \"\",\n \"---\",\n \"\",\n ];\n\n for (const msg of messages) {\n if (typeof msg.content === \"string\") {\n const label = msg.role === \"user\" ? \"**You:**\" : `**${aiName}:**`;\n lines.push(`${label} ${msg.content}`, \"\");\n }\n }\n\n fs.writeFileSync(exportPath, lines.join(\"\\n\"), \"utf-8\");\n console.log(pc.green(`Exported to ${exportPath}`));\n } catch {\n console.log(pc.red(\"Failed to export conversation.\"));\n }\n continue;\n }\n if (cmdResult.saveConversation && mcpManager) {\n try {\n await saveConversationToMemory(mcpManager, messages, sessionId);\n console.log(pc.green(\"Conversation saved to memory.\"));\n } catch {\n console.log(pc.red(\"Failed to save conversation.\"));\n }\n continue;\n }\n if (cmdResult.output) {\n console.log(cmdResult.output);\n }\n if (cmdResult.clearHistory) {\n messages.length = 0;\n }\n continue;\n }\n\n // Check for workflow match\n let activeSystemPrompt = systemPrompt;\n if (mcpManager && hooksConfig) {\n try {\n const hookCtx: HookContext = { mcpManager, config: hooksConfig };\n const wfMatch = await onWorkflowMatch(input, hookCtx);\n if (wfMatch) {\n const useIt = await new Promise<boolean>((resolve) => {\n rl.question(pc.dim(` Workflow \"${wfMatch.name}\" matches. Use it? (y/N) `), (answer) => resolve(answer.toLowerCase() === \"y\"));\n });\n if (useIt) {\n activeSystemPrompt = systemPrompt + `\\n\\n<active-workflow>\\n${wfMatch.steps}\\n</active-workflow>`;\n console.log(pc.dim(` Using \"${wfMatch.name}\" workflow.`));\n }\n }\n } catch (err) { log.debug(\"agent\", \"workflow match failed\", err); }\n }\n\n // Auto-trim conversation if approaching token limits\n await trimConversation(messages, client);\n\n // Send to LLM\n messages.push({ role: \"user\", content: input });\n\n // Per-message memory recall\n let augmentedSystemPrompt = activeSystemPrompt;\n if (mcpManager) {\n const recall = await recallForMessage(input, mcpManager);\n if (recall) {\n augmentedSystemPrompt = activeSystemPrompt + recall.text;\n process.stdout.write(pc.dim(` [memories: ~${recall.tokenEstimate} tokens]\\n`));\n }\n }\n\n process.stdout.write(pc.cyan(`\\n${aiName} > `));\n\n try {\n let response = await withRetry(\n () => client.chat(augmentedSystemPrompt, messages, onChunkHandler, tools),\n { maxAttempts: 3, baseDelay: 1000, retryable: isRetryable },\n );\n\n // Add assistant message to history\n messages.push(response.message);\n\n // Agentic tool loop: execute tools until LLM stops requesting them\n while (response.toolUses.length > 0 && mcpManager) {\n const toolResults: ToolResultBlock[] = await Promise.all(\n response.toolUses.map(async (toolUse) => {\n if (hooksConfig) {\n const hookCtx: HookContext = { mcpManager: mcpManager!, config: hooksConfig };\n const check = await onBeforeToolExec(toolUse.name, toolUse.input, hookCtx);\n if (!check.allow) {\n process.stdout.write(pc.red(` [BLOCKED: ${check.reason}]\\n`));\n return {\n type: \"tool_result\" as const,\n tool_use_id: toolUse.id,\n content: `BLOCKED by guardrail: ${check.reason}`,\n is_error: true,\n };\n }\n }\n\n process.stdout.write(pc.dim(` [using ${toolUse.name}...]\\n`));\n const result = await mcpManager.callTool(toolUse.name, toolUse.input);\n\n // Log tool observation to amem (passive capture, fire-and-forget)\n const skipLogging = [\"memory_log\", \"memory_recall\", \"memory_context\", \"memory_detail\", \"reminder_check\"].includes(toolUse.name);\n if (!skipLogging) {\n mcpManager.callTool(\"memory_log\", {\n session_id: sessionId,\n role: \"system\",\n content: `[tool:${toolUse.name}] input=${JSON.stringify(toolUse.input).slice(0, 500)} result=${result.slice(0, 500)}`,\n }).catch(() => {});\n }\n\n return {\n type: \"tool_result\" as const,\n tool_use_id: toolUse.id,\n content: result,\n };\n }),\n );\n\n // Add tool results as a user message\n messages.push({\n role: \"user\",\n content: toolResults,\n });\n\n // Call LLM again with tool results\n response = await withRetry(\n () => client.chat(augmentedSystemPrompt, messages, onChunkHandler, tools),\n { maxAttempts: 3, baseDelay: 1000, retryable: isRetryable },\n );\n\n // Add assistant response to history\n messages.push(response.message);\n }\n\n // Memory extraction (runs silently after response)\n if (mcpManager && hooksConfig?.extractMemories) {\n const assistantText = typeof response.message.content === \"string\"\n ? response.message.content\n : response.message.content\n .filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? b.text : \"\"))\n .join(\"\");\n\n if (assistantText) {\n const confirmFn = async (content: string): Promise<boolean> => {\n return new Promise<boolean>((resolve) => {\n rl.question(\n pc.dim(` Remember: \"${content}\"? (y/N) `),\n (answer) => resolve(answer.toLowerCase() === \"y\"),\n );\n });\n };\n\n const count = await runExtraction(\n input, assistantText, client, mcpManager, extractorState, confirmFn,\n );\n if (count > 0) {\n process.stdout.write(pc.dim(` [${count} memory${count > 1 ? \"ies\" : \"\"} stored]\\n`));\n }\n }\n } else {\n extractorState.turnsSinceLastExtraction++;\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n console.error(pc.red(`\\nError: ${message}`));\n // Remove the user message that failed\n messages.pop();\n }\n }\n}\n\n// Save conversation messages to amem's memory_log\nasync function saveConversationToMemory(\n mcpManager: McpManager,\n messages: Message[],\n sessionId: string,\n): Promise<void> {\n // Save last 50 messages\n const recentMessages = messages.slice(-50);\n\n for (const msg of recentMessages) {\n if (typeof msg.content !== \"string\") continue;\n try {\n await mcpManager.callTool(\"memory_log\", {\n session_id: sessionId,\n role: msg.role,\n content: msg.content.slice(0, 5000),\n });\n } catch (err) {\n log.debug(\"agent\", \"memory_log write failed\", err);\n }\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport pc from \"picocolors\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport { getEcosystemStatus } from \"./layers/parsers.js\";\n\nexport interface CommandResult {\n handled: boolean;\n output?: string;\n quit?: boolean;\n clearHistory?: boolean;\n saveConversation?: boolean;\n exportConversation?: boolean;\n}\n\nexport interface CommandContext {\n model?: string;\n mcpManager?: McpManager;\n}\n\nfunction readEcosystemFile(filePath: string, label: string): string {\n if (!fs.existsSync(filePath)) {\n return pc.dim(`No ${label} file found at ${filePath}`);\n }\n return fs.readFileSync(filePath, \"utf-8\").trim();\n}\n\nfunction parseCommand(input: string): { base: string; action?: string; args: string[] } {\n const trimmed = input.trim();\n const parts = trimmed.split(/\\s+/);\n const base = parts[0].toLowerCase().replace(/^\\//, \"\");\n const action = parts.length > 1 ? parts[1].toLowerCase() : undefined;\n const args = parts.slice(2);\n return { base, action, args };\n}\n\nasync function mcpWrite(\n ctx: CommandContext,\n layer: string,\n tool: string,\n args: Record<string, unknown>,\n): Promise<string> {\n if (!ctx.mcpManager) {\n return pc.red(`Cannot modify ${layer}: aman-mcp not connected. Start it with: npx @aman_asmuei/aman-mcp`);\n }\n const result = await ctx.mcpManager.callTool(tool, args);\n if (result.startsWith(\"Error\")) {\n return pc.red(result);\n }\n return pc.green(result);\n}\n\n// --- Layer Handlers ---\n\nasync function handleIdentityCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".acore\", \"core.md\"), \"identity (acore)\");\n return { handled: true, output: content };\n }\n if (action === \"update\") {\n if (args.length === 0) {\n return {\n handled: true,\n output: pc.yellow(\"Usage: /identity update <section>\\nTip: describe changes in natural language and the AI will update via MCP.\"),\n };\n }\n const section = args[0];\n const content = args.slice(1).join(\" \");\n if (!content) {\n return {\n handled: true,\n output: pc.yellow(\"Usage: /identity update <section> <new content...>\\nExample: /identity update Personality Warm, curious, and direct.\"),\n };\n }\n const output = await mcpWrite(ctx, \"identity\", \"identity_update_section\", { section, content });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /identity ${action}. Use /identity or /identity update <section>.`) };\n}\n\nasync function handleRulesCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".arules\", \"rules.md\"), \"guardrails (arules)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules add <category> <rule text...>\") };\n }\n const category = args[0];\n const rule = args.slice(1).join(\" \");\n const output = await mcpWrite(ctx, \"rules\", \"rules_add\", { category, rule });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules remove <category> <index>\") };\n }\n const output = await mcpWrite(ctx, \"rules\", \"rules_remove\", { category: args[0], index: parseInt(args[1], 10) });\n return { handled: true, output };\n }\n if (action === \"toggle\") {\n if (args.length < 2) {\n return { handled: true, output: pc.yellow(\"Usage: /rules toggle <category> <index>\") };\n }\n const output = await mcpWrite(ctx, \"rules\", \"rules_toggle\", { category: args[0], index: parseInt(args[1], 10) });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /rules ${action}. Use /rules [add|remove|toggle].`) };\n}\n\nasync function handleWorkflowsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".aflow\", \"flow.md\"), \"workflows (aflow)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /workflows add <name>\") };\n }\n const output = await mcpWrite(ctx, \"workflows\", \"workflow_add\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /workflows remove <name>\") };\n }\n const output = await mcpWrite(ctx, \"workflows\", \"workflow_remove\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /workflows ${action}. Use /workflows [add|remove].`) };\n}\n\nasync function handleToolsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".akit\", \"kit.md\"), \"tools (akit)\");\n return { handled: true, output: content };\n }\n if (action === \"add\") {\n if (args.length < 3) {\n return { handled: true, output: pc.yellow(\"Usage: /tools add <name> <type> <description...>\") };\n }\n const name = args[0];\n const type = args[1];\n const description = args.slice(2).join(\" \");\n const output = await mcpWrite(ctx, \"tools\", \"tools_add\", { name, type, description });\n return { handled: true, output };\n }\n if (action === \"remove\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /tools remove <name>\") };\n }\n const output = await mcpWrite(ctx, \"tools\", \"tools_remove\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /tools ${action}. Use /tools [add|remove].`) };\n}\n\nasync function handleSkillsCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".askill\", \"skills.md\"), \"skills (askill)\");\n return { handled: true, output: content };\n }\n if (action === \"install\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /skills install <name>\") };\n }\n const output = await mcpWrite(ctx, \"skills\", \"skill_install\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n if (action === \"uninstall\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /skills uninstall <name>\") };\n }\n const output = await mcpWrite(ctx, \"skills\", \"skill_uninstall\", { name: args.join(\" \") });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /skills ${action}. Use /skills [install|uninstall].`) };\n}\n\nasync function handleEvalCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n const home = os.homedir();\n if (!action) {\n const content = readEcosystemFile(path.join(home, \".aeval\", \"eval.md\"), \"evaluation (aeval)\");\n return { handled: true, output: content };\n }\n if (action === \"milestone\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /eval milestone <text...>\") };\n }\n const text = args.join(\" \");\n const output = await mcpWrite(ctx, \"eval\", \"eval_milestone\", { text });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /eval ${action}. Use /eval or /eval milestone <text>.`) };\n}\n\nasync function handleMemoryCommand(\n action: string | undefined,\n args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n if (!action) {\n // Default: show recent memory context via MCP\n if (!ctx.mcpManager) {\n return {\n handled: true,\n output: pc.red(\"Memory not available: aman-mcp not connected. Start it with: npx @aman_asmuei/aman-mcp\"),\n };\n }\n const result = await ctx.mcpManager.callTool(\"memory_context\", {});\n if (result.startsWith(\"Error\")) {\n return { handled: true, output: pc.red(result) };\n }\n return { handled: true, output: result };\n }\n if (action === \"search\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /memory search <query...>\") };\n }\n const query = args.join(\" \");\n const output = await mcpWrite(ctx, \"memory\", \"memory_recall\", { query });\n return { handled: true, output };\n }\n if (action === \"clear\") {\n if (args.length < 1) {\n return { handled: true, output: pc.yellow(\"Usage: /memory clear <category>\") };\n }\n const output = await mcpWrite(ctx, \"memory\", \"memory_forget\", { category: args[0] });\n return { handled: true, output };\n }\n return { handled: true, output: pc.yellow(`Unknown action: /memory ${action}. Use /memory [search|clear].`) };\n}\n\nfunction handleStatusCommand(ctx: CommandContext): CommandResult {\n const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;\n const amemConnected = mcpToolCount > 0; // simplified check\n const status = getEcosystemStatus(mcpToolCount, amemConnected);\n\n const lines: string[] = [pc.bold(\"Aman Ecosystem Dashboard\"), \"\"];\n\n for (const layer of status.layers) {\n const icon = layer.exists ? pc.green(\"●\") : pc.dim(\"○\");\n const name = pc.bold(layer.name.padEnd(12));\n const summary = layer.exists ? layer.summary : pc.dim(\"not configured\");\n lines.push(` ${icon} ${name} ${summary}`);\n }\n\n lines.push(\"\");\n lines.push(` ${status.mcpConnected ? pc.green(\"●\") : pc.dim(\"○\")} ${pc.bold(\"MCP\".padEnd(12))} ${status.mcpConnected ? `${status.mcpToolCount} tools available` : pc.dim(\"not connected\")}`);\n lines.push(` ${status.amemConnected ? pc.green(\"●\") : pc.dim(\"○\")} ${pc.bold(\"Memory\".padEnd(12))} ${status.amemConnected ? \"connected\" : pc.dim(\"not connected\")}`);\n\n return { handled: true, output: lines.join(\"\\n\") };\n}\n\nfunction handleDoctorCommand(ctx: CommandContext): CommandResult {\n const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;\n const amemConnected = mcpToolCount > 0;\n const status = getEcosystemStatus(mcpToolCount, amemConnected);\n\n const lines: string[] = [pc.bold(\"Aman Health Check\"), \"\"];\n\n for (const layer of status.layers) {\n const check = layer.exists ? pc.green(\"✓\") : pc.red(\"✗\");\n const name = layer.name.padEnd(12);\n const detail = layer.exists ? pc.green(layer.summary) : pc.red(\"missing\");\n lines.push(` ${check} ${name} ${detail}`);\n }\n\n lines.push(\"\");\n lines.push(` ${status.mcpConnected ? pc.green(\"✓\") : pc.red(\"✗\")} ${\"MCP\".padEnd(12)} ${status.mcpConnected ? pc.green(`${status.mcpToolCount} tools`) : pc.red(\"not connected\")}`);\n lines.push(` ${status.amemConnected ? pc.green(\"✓\") : pc.red(\"✗\")} ${\"Memory\".padEnd(12)} ${status.amemConnected ? pc.green(\"connected\") : pc.red(\"not connected\")}`);\n\n return { handled: true, output: lines.join(\"\\n\") };\n}\n\nfunction handleHelp(): CommandResult {\n return {\n handled: true,\n output: [\n pc.bold(\"Commands:\"),\n ` ${pc.cyan(\"/help\")} Show this help`,\n ` ${pc.cyan(\"/identity\")} View identity [update <section>]`,\n ` ${pc.cyan(\"/rules\")} View rules [add|remove|toggle ...]`,\n ` ${pc.cyan(\"/workflows\")} View workflows [add|remove ...]`,\n ` ${pc.cyan(\"/tools\")} View tools [add|remove ...]`,\n ` ${pc.cyan(\"/skills\")} View skills [install|uninstall ...]`,\n ` ${pc.cyan(\"/eval\")} View evaluation [milestone ...]`,\n ` ${pc.cyan(\"/memory\")} View recent memories [search|clear ...]`,\n ` ${pc.cyan(\"/status\")} Ecosystem dashboard`,\n ` ${pc.cyan(\"/doctor\")} Health check all layers`,\n ` ${pc.cyan(\"/decisions\")} View decision log [<project>]`,\n ` ${pc.cyan(\"/export\")} Export conversation to markdown`,\n ` ${pc.cyan(\"/debug\")} Show debug log`,\n ` ${pc.cyan(\"/save\")} Save conversation to memory`,\n ` ${pc.cyan(\"/model\")} Show current LLM model`,\n ` ${pc.cyan(\"/update\")} Check for updates`,\n ` ${pc.cyan(\"/reconfig\")} Reset LLM config`,\n ` ${pc.cyan(\"/clear\")} Clear conversation history`,\n ` ${pc.cyan(\"/quit\")} Exit`,\n ].join(\"\\n\"),\n };\n}\n\nfunction handleSave(): CommandResult {\n return { handled: true, saveConversation: true };\n}\n\nfunction handleReconfig(): CommandResult {\n const configPath = path.join(os.homedir(), \".aman-agent\", \"config.json\");\n if (fs.existsSync(configPath)) {\n fs.unlinkSync(configPath);\n }\n return {\n handled: true,\n quit: true,\n output: [\n pc.green(\"Config reset.\"),\n `Run ${pc.bold(\"npx @aman_asmuei/aman-agent\")} again to reconfigure your LLM provider, model, and API key.`,\n ].join(\"\\n\"),\n };\n}\n\nfunction handleUpdate(): CommandResult {\n try {\n const current = execFileSync(\"npm\", [\"view\", \"@aman_asmuei/aman-agent\", \"version\"], { encoding: \"utf-8\" }).trim();\n const local = JSON.parse(fs.readFileSync(path.join(__dirname, \"..\", \"package.json\"), \"utf-8\")).version;\n if (current === local) {\n return { handled: true, output: `${pc.green(\"Up to date\")} — v${local}` };\n }\n return {\n handled: true,\n output: [\n `${pc.yellow(\"Update available:\")} v${local} → v${current}`,\n \"\",\n `Run this in your terminal:`,\n ` ${pc.bold(\"npm install -g @aman_asmuei/aman-agent@latest\")}`,\n \"\",\n `Or use npx (always latest):`,\n ` ${pc.bold(\"npx @aman_asmuei/aman-agent@latest\")}`,\n ].join(\"\\n\"),\n };\n } catch {\n return {\n handled: true,\n output: [\n `To update, run in your terminal:`,\n ` ${pc.bold(\"npm install -g @aman_asmuei/aman-agent@latest\")}`,\n \"\",\n `Or use npx (always latest):`,\n ` ${pc.bold(\"npx @aman_asmuei/aman-agent@latest\")}`,\n ].join(\"\\n\"),\n };\n }\n}\n\nasync function handleDecisionsCommand(\n action: string | undefined,\n _args: string[],\n ctx: CommandContext,\n): Promise<CommandResult> {\n if (!ctx.mcpManager) {\n return { handled: true, output: pc.red(\"Decisions not available: MCP not connected.\") };\n }\n const scope = action || undefined;\n const result = await ctx.mcpManager.callTool(\"memory_recall\", {\n query: \"decision\",\n type: \"decision\",\n limit: 20,\n ...(scope ? { scope } : {}),\n });\n if (result.startsWith(\"Error\")) {\n return { handled: true, output: pc.red(result) };\n }\n return { handled: true, output: pc.bold(\"Decision Log:\\n\") + result };\n}\n\nfunction handleExportCommand(): CommandResult {\n return { handled: true, exportConversation: true };\n}\n\nfunction handleDebugCommand(): CommandResult {\n const logPath = path.join(os.homedir(), \".aman-agent\", \"debug.log\");\n if (!fs.existsSync(logPath)) {\n return { handled: true, output: pc.dim(\"No debug log found.\") };\n }\n const content = fs.readFileSync(logPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\");\n const last20 = lines.slice(-20).join(\"\\n\");\n return { handled: true, output: pc.bold(\"Debug Log (last 20 entries):\\n\") + pc.dim(last20) };\n}\n\n// --- Main Router ---\n\nexport async function handleCommand(input: string, ctx: CommandContext): Promise<CommandResult> {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return { handled: false };\n\n const { base, action, args } = parseCommand(trimmed);\n\n switch (base) {\n case \"quit\":\n case \"exit\":\n case \"q\":\n return { handled: true, quit: true };\n case \"help\":\n return handleHelp();\n case \"clear\":\n return { handled: true, output: pc.dim(\"Conversation cleared.\"), clearHistory: true };\n case \"model\":\n return { handled: true, output: ctx.model ? `Model: ${pc.bold(ctx.model)}` : \"Model: unknown\" };\n case \"identity\":\n return handleIdentityCommand(action, args, ctx);\n case \"rules\":\n return handleRulesCommand(action, args, ctx);\n case \"workflows\":\n return handleWorkflowsCommand(action, args, ctx);\n case \"tools\":\n return handleToolsCommand(action, args, ctx);\n case \"skills\":\n return handleSkillsCommand(action, args, ctx);\n case \"eval\":\n return handleEvalCommand(action, args, ctx);\n case \"memory\":\n return handleMemoryCommand(action, args, ctx);\n case \"status\":\n return handleStatusCommand(ctx);\n case \"doctor\":\n return handleDoctorCommand(ctx);\n case \"save\":\n return handleSave();\n case \"decisions\":\n return handleDecisionsCommand(action, args, ctx);\n case \"export\":\n return handleExportCommand();\n case \"debug\":\n return handleDebugCommand();\n case \"update-config\":\n case \"reconfig\":\n return handleReconfig();\n case \"update\":\n case \"upgrade\":\n return handleUpdate();\n default:\n return { handled: true, output: `Unknown command: /${base}. Type ${pc.cyan(\"/help\")} for available commands.` };\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst home = os.homedir();\n\ninterface LayerStatus {\n name: string;\n exists: boolean;\n path: string;\n summary: string;\n}\n\nexport interface EcosystemStatus {\n layers: LayerStatus[];\n mcpConnected: boolean;\n mcpToolCount: number;\n amemConnected: boolean;\n}\n\nconst LAYER_FILES = [\n { name: \"identity\", dir: \".acore\", file: \"core.md\" },\n { name: \"rules\", dir: \".arules\", file: \"rules.md\" },\n { name: \"workflows\", dir: \".aflow\", file: \"flow.md\" },\n { name: \"tools\", dir: \".akit\", file: \"kit.md\" },\n { name: \"skills\", dir: \".askill\", file: \"skills.md\" },\n { name: \"eval\", dir: \".aeval\", file: \"eval.md\" },\n] as const;\n\nfunction countLines(content: string, pattern: RegExp): number {\n return (content.match(pattern) || []).length;\n}\n\nfunction getLayerSummary(name: string, content: string): string {\n switch (name) {\n case \"identity\": {\n const nameMatch = content.match(/^# (.+)/m);\n return nameMatch ? nameMatch[1] : \"configured\";\n }\n case \"rules\":\n return `${countLines(content, /^- /gm)} rules`;\n case \"workflows\":\n return `${countLines(content, /^## /gm)} workflows`;\n case \"tools\":\n return `${countLines(content, /^- \\*\\*/gm)} tools`;\n case \"skills\":\n return `${countLines(content, /^### /gm)} skills`;\n case \"eval\": {\n const sessions = countLines(content, /^### Session/gm);\n return `${sessions} sessions logged`;\n }\n default:\n return \"unknown\";\n }\n}\n\nexport function getEcosystemStatus(\n mcpToolCount: number,\n amemConnected: boolean,\n): EcosystemStatus {\n const layers: LayerStatus[] = LAYER_FILES.map((entry) => {\n const filePath = path.join(home, entry.dir, entry.file);\n const exists = fs.existsSync(filePath);\n let summary = \"not configured\";\n\n if (exists) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n summary = getLayerSummary(entry.name, content);\n }\n\n return { name: entry.name, exists, path: filePath, summary };\n });\n\n return {\n layers,\n mcpConnected: mcpToolCount > 0,\n mcpToolCount,\n amemConnected,\n };\n}\n\nexport function readLayerFile(name: string): string | null {\n const entry = LAYER_FILES.find((l) => l.name === name);\n if (!entry) return null;\n const filePath = path.join(home, entry.dir, entry.file);\n if (!fs.existsSync(filePath)) return null;\n return fs.readFileSync(filePath, \"utf-8\").trim();\n}\n","import pc from \"picocolors\";\nimport * as p from \"@clack/prompts\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport type { Message } from \"./llm/types.js\";\nimport type { HooksConfig } from \"./config.js\";\nimport { log } from \"./logger.js\";\n\nfunction getTimeContext(): string {\n const now = new Date();\n const hour = now.getHours();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n const day = days[now.getDay()];\n\n let period: string;\n if (hour < 6) period = \"late-night\";\n else if (hour < 12) period = \"morning\";\n else if (hour < 17) period = \"afternoon\";\n else if (hour < 21) period = \"evening\";\n else period = \"night\";\n\n const timeStr = now.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n const dateStr = now.toLocaleDateString();\n\n return `<time-context>\\nCurrent time: ${dateStr} ${timeStr} (${period}, ${day})\\nAdapt your tone naturally — don't announce the time, just be contextually appropriate.\\n</time-context>`;\n}\n\nexport interface HookContext {\n mcpManager: McpManager;\n config: HooksConfig;\n}\n\nlet isHookCall = false;\n\nexport async function onSessionStart(\n ctx: HookContext,\n): Promise<{ greeting?: string; contextInjection?: string }> {\n let greeting = \"\";\n let contextInjection = \"\";\n\n if (ctx.config.memoryRecall) {\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"memory_context\", {});\n if (result && !result.startsWith(\"Error\")) {\n greeting += result;\n }\n } catch (err) {\n log.warn(\"hooks\", \"memory_context recall failed\", err);\n } finally {\n isHookCall = false;\n }\n }\n\n if (ctx.config.sessionResume) {\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"identity_summary\", {});\n if (result && !result.startsWith(\"Error\")) {\n if (greeting) greeting += \"\\n\";\n greeting += result;\n }\n } catch (err) {\n log.warn(\"hooks\", \"identity_summary failed\", err);\n } finally {\n isHookCall = false;\n }\n }\n\n // Time context\n const timeContext = getTimeContext();\n if (greeting) greeting += \"\\n\" + timeContext;\n else greeting = timeContext;\n\n // Check reminders\n try {\n isHookCall = true;\n const reminderResult = await ctx.mcpManager.callTool(\"reminder_check\", {});\n if (reminderResult && !reminderResult.startsWith(\"Error\") && !reminderResult.includes(\"No pending\")) {\n greeting += \"\\n\\n<pending-reminders>\\n\" + reminderResult + \"\\n</pending-reminders>\";\n }\n } catch (err) {\n log.debug(\"hooks\", \"reminder_check failed\", err);\n } finally {\n isHookCall = false;\n }\n\n if (greeting) {\n contextInjection = `<session-context>\\n${greeting}\\n</session-context>`;\n }\n\n return {\n greeting: greeting || undefined,\n contextInjection: contextInjection || undefined,\n };\n}\n\nexport async function onBeforeToolExec(\n toolName: string,\n toolArgs: Record<string, unknown>,\n ctx: HookContext,\n): Promise<{ allow: boolean; reason?: string }> {\n if (!ctx.config.rulesCheck || isHookCall) {\n return { allow: true };\n }\n\n if (toolName === \"rules_check\") {\n return { allow: true };\n }\n\n try {\n isHookCall = true;\n const description = `${toolName}(${JSON.stringify(toolArgs)})`;\n const result = await ctx.mcpManager.callTool(\"rules_check\", {\n action: description,\n });\n\n try {\n const parsed = JSON.parse(result) as {\n violations?: string[];\n };\n if (parsed.violations && parsed.violations.length > 0) {\n return {\n allow: false,\n reason: parsed.violations.join(\"; \"),\n };\n }\n } catch (err) {\n log.debug(\"hooks\", \"rules_check parse failed\", err);\n }\n\n return { allow: true };\n } catch (err) {\n log.warn(\"hooks\", \"rules_check call failed\", err);\n return { allow: true };\n } finally {\n isHookCall = false;\n }\n}\n\nexport async function onWorkflowMatch(\n userInput: string,\n ctx: HookContext,\n): Promise<{ name: string; steps: string } | null> {\n if (!ctx.config.workflowSuggest) {\n return null;\n }\n\n try {\n isHookCall = true;\n const result = await ctx.mcpManager.callTool(\"workflow_list\", {});\n\n const workflows = JSON.parse(result) as Array<{\n name: string;\n description?: string;\n steps?: string[];\n }>;\n\n const inputLower = userInput.toLowerCase();\n\n for (const wf of workflows) {\n const nameLower = wf.name.toLowerCase();\n\n // Check if user input contains workflow name\n if (inputLower.includes(nameLower)) {\n const steps = (wf.steps || [])\n .map((s, i) => `${i + 1}. ${s}`)\n .join(\"\\n\");\n return { name: wf.name, steps };\n }\n\n // Check significant words from description\n if (wf.description) {\n const words = wf.description\n .split(/\\s+/)\n .filter((w) => w.length > 4)\n .map((w) => w.toLowerCase());\n\n for (const word of words) {\n if (inputLower.includes(word)) {\n const steps = (wf.steps || [])\n .map((s, i) => `${i + 1}. ${s}`)\n .join(\"\\n\");\n return { name: wf.name, steps };\n }\n }\n }\n }\n\n return null;\n } catch (err) {\n log.debug(\"hooks\", \"workflow_list failed\", err);\n return null;\n } finally {\n isHookCall = false;\n }\n}\n\nexport async function onSessionEnd(\n ctx: HookContext,\n messages: Message[],\n sessionId: string,\n): Promise<void> {\n try {\n // Auto-save conversation to amem memory_log\n if (ctx.config.autoSessionSave && messages.length > 2) {\n console.log(pc.dim(\"\\n Saving conversation to memory...\"));\n\n // Save last 50 text messages to memory_log\n const textMessages = messages\n .filter((m) => typeof m.content === \"string\")\n .slice(-50);\n\n for (const msg of textMessages) {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"memory_log\", {\n session_id: sessionId,\n role: msg.role,\n content: (msg.content as string).slice(0, 5000),\n });\n } catch (err) {\n log.debug(\"hooks\", \"memory_log write failed for \" + sessionId, err);\n } finally {\n isHookCall = false;\n }\n }\n\n // Update session resume in identity\n let lastUserMsg = \"\";\n for (let i = messages.length - 1; i >= 0; i--) {\n if (\n messages[i].role === \"user\" &&\n typeof messages[i].content === \"string\"\n ) {\n lastUserMsg = messages[i].content as string;\n break;\n }\n }\n\n if (lastUserMsg) {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"identity_update_session\", {\n resume: lastUserMsg.slice(0, 200),\n topics: \"See conversation history\",\n decisions: \"See conversation history\",\n });\n } finally {\n isHookCall = false;\n }\n }\n\n console.log(pc.dim(` Saved ${textMessages.length} messages (session: ${sessionId})`));\n }\n\n // Session rating prompt\n if (ctx.config.evalPrompt) {\n const rating = await p.select({\n message: \"Quick rating for this session?\",\n options: [\n { value: \"great\", label: \"Great\" },\n { value: \"good\", label: \"Good\" },\n { value: \"okay\", label: \"Okay\" },\n { value: \"skip\", label: \"Skip\" },\n ],\n initialValue: \"skip\",\n });\n\n if (!p.isCancel(rating) && rating !== \"skip\") {\n try {\n isHookCall = true;\n await ctx.mcpManager.callTool(\"eval_log\", {\n rating: rating as string,\n highlights: \"Quick session rating\",\n improvements: \"\",\n });\n } finally {\n isHookCall = false;\n }\n }\n }\n } catch (err) {\n log.warn(\"hooks\", \"session end hook failed\", err);\n }\n}\n","import type { Message, LLMClient } from \"./llm/types.js\";\nimport { log } from \"./logger.js\";\n\n// Rough token estimation: ~1.3 tokens per word\nfunction estimateMessageTokens(msg: Message): number {\n if (typeof msg.content === \"string\") {\n return Math.round(msg.content.split(/\\s+/).filter(Boolean).length * 1.3);\n }\n // Content blocks — estimate from stringified content\n let text = \"\";\n for (const block of msg.content) {\n if (block.type === \"text\") text += block.text;\n else if (block.type === \"tool_result\") text += block.content;\n else if (block.type === \"tool_use\") text += JSON.stringify(block.input);\n }\n return Math.round(text.split(/\\s+/).filter(Boolean).length * 1.3);\n}\n\nfunction estimateTotalTokens(messages: Message[]): number {\n let total = 0;\n for (const msg of messages) {\n total += estimateMessageTokens(msg);\n }\n return total;\n}\n\n// Maximum conversation tokens before trimming (leave room for system prompt + response)\nconst MAX_CONVERSATION_TOKENS = 80_000;\n// How many recent messages to always keep\nconst KEEP_RECENT = 10;\n// How many initial messages to always keep (session context injection)\nconst KEEP_INITIAL = 2;\n\n/**\n * Trims conversation history when it gets too long.\n * Keeps initial context messages and recent messages.\n * Replaces middle messages with a summary.\n * Mutates the messages array in place.\n */\nexport async function trimConversation(\n messages: Message[],\n client: LLMClient,\n): Promise<void> {\n const totalTokens = estimateTotalTokens(messages);\n\n if (totalTokens < MAX_CONVERSATION_TOKENS || messages.length <= KEEP_INITIAL + KEEP_RECENT) {\n return;\n }\n\n const initial = messages.slice(0, KEEP_INITIAL);\n const recent = messages.slice(-KEEP_RECENT);\n const middle = messages.slice(KEEP_INITIAL, messages.length - KEEP_RECENT);\n\n const middleText = middle\n .filter((m) => typeof m.content === \"string\" && m.content.length > 0)\n .map((m) => `[${m.role}]: ${(m.content as string).slice(0, 500)}`)\n .slice(0, 30)\n .join(\"\\n\");\n\n let summaryText: string;\n\n try {\n const summaryPrompt = \"Summarize the following conversation messages in 3-5 bullet points. Preserve: decisions made, user preferences expressed, action items, and key facts discussed. Be concise.\\n\\n\" + middleText;\n\n let fullText = \"\";\n await client.chat(\n \"You are a concise summarizer. Return only bullet points, no preamble.\",\n [{ role: \"user\", content: summaryPrompt }],\n (chunk) => {\n if (chunk.type === \"text\" && chunk.text) fullText += chunk.text;\n },\n );\n\n summaryText = `<conversation-summary>\\nSummary of ${middle.length} earlier messages:\\n\\n${fullText}\\n</conversation-summary>`;\n log.debug(\"context\", `Summarized ${middle.length} messages via LLM`);\n } catch (err) {\n log.warn(\"context\", \"LLM summarization failed, using fallback\", err);\n const summaryParts: string[] = [];\n for (const msg of middle) {\n if (typeof msg.content === \"string\" && msg.content.length > 0) {\n const preview = msg.content.slice(0, 150);\n summaryParts.push(`[${msg.role}]: ${preview}${msg.content.length > 150 ? \"...\" : \"\"}`);\n }\n }\n summaryText = `<conversation-summary>\\nSummary of ${middle.length} earlier messages:\\n\\n${summaryParts.slice(0, 20).join(\"\\n\")}\\n</conversation-summary>`;\n }\n\n messages.length = 0;\n messages.push(...initial);\n messages.push({ role: \"user\", content: summaryText });\n messages.push({ role: \"assistant\", content: \"I have the context from our earlier conversation. Let's continue.\" });\n messages.push(...recent);\n}\n","import type { LLMClient } from \"./llm/types.js\";\nimport type { McpManager } from \"./mcp/client.js\";\nimport { log } from \"./logger.js\";\n\nexport interface ExtractionCandidate {\n content: string;\n type: \"preference\" | \"fact\" | \"pattern\" | \"decision\" | \"correction\" | \"topology\";\n tags: string[];\n confidence: number;\n scope: string;\n}\n\nconst AUTO_STORE_TYPES = new Set([\"preference\", \"fact\", \"pattern\", \"topology\"]);\nconst CONFIRM_TYPES = new Set([\"decision\", \"correction\"]);\nconst VALID_TYPES = new Set([...AUTO_STORE_TYPES, ...CONFIRM_TYPES]);\nconst MIN_RESPONSE_LENGTH = 50;\nconst MIN_TURNS_BETWEEN_EMPTY = 3;\n\nconst EXTRACTION_PROMPT = `Analyze this conversation turn. Extract any information worth remembering long-term.\n\nReturn a JSON array (empty [] if nothing worth storing):\n[{\n \"content\": \"what to remember — be specific and self-contained\",\n \"type\": \"preference|fact|pattern|decision|correction|topology\",\n \"tags\": [\"relevant\", \"tags\"],\n \"confidence\": 0.0-1.0,\n \"scope\": \"global\"\n}]\n\nType guide:\n- \"preference\" = user likes/dislikes/preferences\n- \"fact\" = objective information about systems, people, projects\n- \"pattern\" = recurring behavior, coding style, approach\n- \"topology\" = how systems/components connect to each other\n- \"decision\" = explicit choice between alternatives (requires confirmation)\n- \"correction\" = user correcting a prior wrong assumption (requires confirmation)\n\nRules:\n- Only extract genuinely useful LONG-TERM information\n- Skip ephemeral things (\"user asked about X\" is NOT useful)\n- Be conservative — 90% of turns produce nothing worth storing\n- Return ONLY the JSON array, no other text`;\n\nexport function shouldExtract(\n assistantResponse: string,\n turnsSinceLastExtraction: number,\n lastExtractionCount: number,\n): boolean {\n if (lastExtractionCount > 0) return true;\n if (assistantResponse.length < MIN_RESPONSE_LENGTH) return false;\n if (turnsSinceLastExtraction < MIN_TURNS_BETWEEN_EMPTY) return false;\n return true;\n}\n\nexport function parseExtractionResult(raw: string): ExtractionCandidate[] {\n try {\n let cleaned = raw.trim();\n const codeBlockMatch = cleaned.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/);\n if (codeBlockMatch) {\n cleaned = codeBlockMatch[1].trim();\n }\n\n const parsed = JSON.parse(cleaned);\n if (!Array.isArray(parsed)) return [];\n\n return parsed.filter(\n (item: Record<string, unknown>) =>\n typeof item.content === \"string\" &&\n item.content.length > 0 &&\n typeof item.type === \"string\" &&\n VALID_TYPES.has(item.type),\n ) as ExtractionCandidate[];\n } catch {\n return [];\n }\n}\n\nexport interface ExtractorState {\n turnsSinceLastExtraction: number;\n lastExtractionCount: number;\n}\n\nexport async function extractMemories(\n userMessage: string,\n assistantResponse: string,\n client: LLMClient,\n mcpManager: McpManager,\n state: ExtractorState,\n confirmFn: (content: string) => Promise<boolean>,\n): Promise<number> {\n if (!shouldExtract(assistantResponse, state.turnsSinceLastExtraction, state.lastExtractionCount)) {\n state.turnsSinceLastExtraction++;\n return 0;\n }\n\n try {\n const conversationTurn = `User: ${userMessage.slice(0, 2000)}\\n\\nAssistant: ${assistantResponse.slice(0, 2000)}`;\n\n let fullText = \"\";\n await client.chat(\n EXTRACTION_PROMPT,\n [{ role: \"user\", content: conversationTurn }],\n (chunk) => {\n if (chunk.type === \"text\" && chunk.text) fullText += chunk.text;\n },\n );\n\n const candidates = parseExtractionResult(fullText);\n state.turnsSinceLastExtraction = 0;\n state.lastExtractionCount = candidates.length;\n\n if (candidates.length === 0) return 0;\n\n let stored = 0;\n\n for (const candidate of candidates) {\n // Dedup check\n try {\n const existing = await mcpManager.callTool(\"memory_recall\", {\n query: candidate.content,\n limit: 1,\n });\n if (existing && !existing.startsWith(\"Error\")) {\n try {\n const parsed = JSON.parse(existing);\n if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].score > 0.85) {\n log.debug(\"extractor\", \"Skipping duplicate: \" + candidate.content);\n continue;\n }\n } catch { /* Parse failed, proceed */ }\n }\n } catch { /* Dedup failed, proceed */ }\n\n // Confirm decisions/corrections\n if (CONFIRM_TYPES.has(candidate.type)) {\n const confirmed = await confirmFn(candidate.content);\n if (!confirmed) continue;\n }\n\n // Store\n try {\n await mcpManager.callTool(\"memory_store\", {\n content: candidate.content,\n type: candidate.type,\n tags: candidate.tags,\n confidence: candidate.confidence,\n source: \"auto-extraction\",\n scope: candidate.scope,\n });\n stored++;\n log.debug(\"extractor\", \"Stored \" + candidate.type + \": \" + candidate.content);\n } catch (err) {\n log.warn(\"extractor\", \"Failed to store: \" + candidate.content, err);\n }\n }\n\n return stored;\n } catch (err) {\n log.debug(\"extractor\", \"extraction failed\", err);\n state.turnsSinceLastExtraction = 0;\n state.lastExtractionCount = 0;\n return 0;\n }\n}\n"],"mappings":"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","names":["p","pc","fs","path","os","text","home","os","path","fs","text","text","OpenAI","text","fs","path","os","fs","path","os","pc","fs","path","os","fs","path","os","fs","home","os","path","text","pc","pc","text","pc","path","os","fs","fs","path","os","pc"]}
|