@axiom-lattice/core 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/base/BaseLatticeManager.ts","../src/model_lattice/ModelLattice.ts","../src/model_lattice/ModelLatticeManager.ts","../src/tool_lattice/get_current_date_time/index.ts","../src/tool_lattice/ToolLatticeManager.ts","../src/util/genUIMarkdown.ts","../src/tool_lattice/createToolApproveWrapper.ts","../src/tool_lattice/internet_search/index.ts","../src/util/genUICard.ts","../src/agent_lattice/types.ts","../src/memory_lattice/DefaultMemorySaver.ts","../src/memory_lattice/MemoryLatticeManager.ts","../src/agent_lattice/builders/state.ts","../src/agent_lattice/builders/ReActAgentGraphBuilder.ts","../src/deep_agent_new/agent.ts","../src/deep_agent_new/middleware/fs.ts","../src/deep_agent_new/backends/utils.ts","../src/deep_agent_new/backends/state.ts","../src/deep_agent_new/middleware/subagents.ts","../src/deep_agent_new/middleware/patch_tool_calls.ts","../src/deep_agent_new/backends/filesystem.ts","../src/deep_agent_new/middleware/todos.ts","../src/agent_lattice/builders/DeepAgentGraphBuilder.ts","../src/agent_lattice/builders/AgentGraphBuilderFactory.ts","../src/agent_lattice/builders/AgentParamsBuilder.ts","../src/agent_lattice/AgentLatticeManager.ts","../src/chunk_buffer_lattice/ChunkBuffer.ts","../src/chunk_buffer_lattice/types.ts","../src/chunk_buffer_lattice/InMemoryChunkBuffer.ts","../src/chunk_buffer_lattice/ChunkBufferLatticeManager.ts"],"sourcesContent":["// 导出核心模块\nexport * from \"./model_lattice\";\nexport * from \"./tool_lattice\";\nexport * from \"./agent_lattice\";\nexport * from \"./memory_lattice\";\nexport * from \"./chunk_buffer_lattice\";\n\n// 重新导出协议接口 - 使用命名导出避免冲突\nimport * as Protocols from \"@axiom-lattice/protocols\";\nexport { Protocols };\n","/**\n * BaseLatticeManager - 抽象基类,为各种Lattice管理器提供通用功能\n * 使用统一的Lattice注册表,不同类型的Lattice通过前缀区分\n * @template TItem - 管理的项目类型\n */\nexport abstract class BaseLatticeManager<TItem = any> {\n // 全局统一的Lattice注册表\n protected static registry: Map<string, any> = new Map();\n\n /**\n * 受保护的构造函数,防止外部直接实例化\n */\n protected constructor() {\n // 空实现\n }\n\n /**\n * 获取管理器实例(由子类实现)\n */\n public static getInstance(): BaseLatticeManager<any> {\n throw new Error(\"必须由子类实现\");\n }\n\n /**\n * 获取Lattice类型,用于构造键前缀\n * 子类必须重写此方法以提供唯一的类型标识符\n */\n protected abstract getLatticeType(): string;\n\n /**\n * 构造完整的键名,包含类型前缀\n * @param key 原始键名\n */\n protected getFullKey(key: string): string {\n return `${this.getLatticeType()}.${key}`;\n }\n\n /**\n * 注册项目\n * @param key 项目键名(不含前缀)\n * @param item 项目实例\n */\n public register(key: string, item: TItem): void {\n const fullKey = this.getFullKey(key);\n if (BaseLatticeManager.registry.has(fullKey)) {\n throw new Error(`项目 \"${fullKey}\" 已经存在,无法重复注册`);\n }\n\n BaseLatticeManager.registry.set(fullKey, item);\n }\n\n /**\n * 获取指定项目\n * @param key 项目键名(不含前缀)\n */\n public get(key: string): TItem | undefined {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.get(fullKey) as TItem | undefined;\n }\n\n /**\n * 获取所有当前类型的项目\n */\n public getAll(): TItem[] {\n const prefix = `${this.getLatticeType()}.`;\n const result: TItem[] = [];\n\n for (const [key, value] of BaseLatticeManager.registry.entries()) {\n if (key.startsWith(prefix)) {\n result.push(value as TItem);\n }\n }\n\n return result;\n }\n\n /**\n * 检查项目是否存在\n * @param key 项目键名(不含前缀)\n */\n public has(key: string): boolean {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.has(fullKey);\n }\n\n /**\n * 移除项目\n * @param key 项目键名(不含前缀)\n */\n public remove(key: string): boolean {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.delete(fullKey);\n }\n\n /**\n * 清空当前类型的所有项目\n */\n public clear(): void {\n const prefix = `${this.getLatticeType()}.`;\n const keysToDelete: string[] = [];\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n keysToDelete.push(key);\n }\n }\n\n for (const key of keysToDelete) {\n BaseLatticeManager.registry.delete(key);\n }\n }\n\n /**\n * 获取当前类型的项目数量\n */\n public count(): number {\n const prefix = `${this.getLatticeType()}.`;\n let count = 0;\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n count++;\n }\n }\n\n return count;\n }\n\n /**\n * 获取当前类型的项目键名列表(不含前缀)\n */\n public keys(): string[] {\n const prefix = `${this.getLatticeType()}.`;\n const prefixLength = prefix.length;\n const result: string[] = [];\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n result.push(key.substring(prefixLength));\n }\n }\n\n return result;\n }\n}\n","import {\n AIMessage,\n BaseMessage,\n BaseMessageLike,\n HumanMessage,\n} from \"@langchain/core/messages\";\nimport { ChatDeepSeek } from \"@langchain/deepseek\";\nimport { AzureChatOpenAI, ChatOpenAI } from \"@langchain/openai\";\nimport { z } from \"zod\";\nimport { ZodType as ZodTypeV3 } from \"zod/v3\";\nimport { $ZodType as ZodTypeV4 } from \"zod/v4/core\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n BaseLanguageModel,\n BaseLanguageModelInput,\n} from \"@langchain/core/language_models/base\";\nimport {\n CallbackManagerForLLMRun,\n Callbacks,\n} from \"@langchain/core/callbacks/manager\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nBaseLanguageModel;\nimport { LLMConfig } from \"@axiom-lattice/protocols\";\n\n/**\n * ModelLattice类,继承自BaseChatModel\n * 简化版本,只保留通过LLMConfig创建LLM实例的功能\n */\nexport class ModelLattice extends BaseChatModel {\n private config: LLMConfig;\n private llm: BaseChatModel;\n\n lc_namespace: string[] = [\"langchain\", \"model_lattice\"];\n\n /**\n * 构造函数\n * @param config LLM配置\n */\n constructor(config: LLMConfig) {\n super({});\n this.config = config;\n this.llm = this.initChatModel(config);\n }\n\n /**\n * 返回模型类型\n */\n _llmType(): string {\n return \"model_lattice\";\n }\n\n /**\n * 返回模型类型\n */\n _modelType(): string {\n return this.llm._modelType();\n }\n\n /**\n * 实现BaseChatModel的_generate方法\n * @param messages 消息数组\n * @param options 调用选项\n * @param runManager 回调管理器\n * @returns 聊天结果\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n return this.llm._generate(messages, options as any, runManager);\n }\n\n /**\n * 将工具绑定到模型\n * @param tools 工具列表\n * @param tool_choice 工具选择选项\n * @returns 绑定工具后的模型\n */\n bindTools(\n tools: any[],\n {\n tool_choice = \"auto\",\n ...kwargs\n }: {\n tool_choice?: \"auto\" | \"none\" | \"required\" | any;\n [key: string]: any;\n } = {}\n ): any {\n // 如果底层LLM实现了bindTools方法,则使用它的实现\n if (typeof this.llm.bindTools === \"function\") {\n return this.llm.bindTools(tools, {\n tool_choice,\n ...kwargs,\n });\n }\n\n // 如果底层LLM没有实现bindTools方法,抛出错误\n throw new Error(\"llm not support bindTools\");\n }\n\n /**\n * 使用结构化输出调用LLM\n * @param input 输入\n * @param schema 结构化输出的schema\n * @param options 调用选项\n * @returns 结构化输出\n */\n async invokeWithStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n input: BaseLanguageModelInput,\n schema: ZodTypeV3<RunOutput> | ZodTypeV4<RunOutput> | Record<string, any>,\n options?: BaseChatModelCallOptions & {\n includeRaw?: boolean;\n name?: string;\n method?: \"functionCalling\" | \"jsonMode\";\n }\n ): Promise<RunOutput | { raw: BaseMessage; parsed: RunOutput }> {\n // 使用LLM的withStructuredOutput方法\n if (this.llm.withStructuredOutput) {\n // 使用类型断言解决类型兼容性问题\n const structuredLLM = this.llm.withStructuredOutput(schema, {\n includeRaw: options?.includeRaw ?? false,\n name: options?.name,\n method: options?.method,\n } as any);\n\n return structuredLLM.invoke(input, options);\n }\n\n // 如果LLM没有withStructuredOutput方法,抛出错误\n throw new Error(\"当前LLM不支持结构化输出\");\n }\n\n /**\n * 创建LLM实例\n * @param config LLM配置\n * @returns LLM实例\n */\n private initChatModel(config: LLMConfig): BaseChatModel {\n if (config.provider === \"azure\") {\n return new AzureChatOpenAI({\n azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,\n azureOpenAIApiInstanceName: \"convertlab-westus\",\n azureOpenAIApiDeploymentName: config.model,\n azureOpenAIApiVersion: \"2024-02-01\",\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n streaming: config.streaming,\n });\n } else if (config.provider === \"deepseek\") {\n return new ChatDeepSeek({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"DEEPSEEK_API_KEY\"],\n streaming: config.streaming,\n });\n } else if (config.provider === \"siliconcloud\") {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"SILICONCLOUD_API_KEY\"],\n configuration: {\n baseURL: \"https://api.siliconflow.cn/v1\",\n },\n streaming: config.streaming,\n });\n } else if (config.provider === \"volcengine\") {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"VOLCENGINE_API_KEY\"],\n configuration: {\n baseURL: \"https://ark.cn-beijing.volces.com/api/v3\",\n },\n streaming: config.streaming,\n });\n } else {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n streaming: config.streaming,\n apiKey: process.env[config.apiKeyEnvName || \"OPENAI_API_KEY\"],\n configuration: {\n baseURL: config.baseURL,\n },\n });\n }\n }\n}\n","import { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { ModelLattice as LLMModelLattice } from \"./ModelLattice\";\nimport { LLMConfig } from \"@axiom-lattice/protocols\";\n\n// 模型配置接口,直接使用 LLMConfig\nexport type ModelConfig = LLMConfig;\n\n// 模型客户端类型,使用 LLMManager\ntype ModelClient = LLMModelLattice;\n\n// 定义接口\nexport interface ModelLatticeInterface {\n key: string;\n client: ModelClient;\n}\n\n/**\n * ModelLatticeManager - 单例模型Lattice管理器\n * 负责注册、管理各种语言模型Lattice\n */\nexport class ModelLatticeManager extends BaseLatticeManager<ModelLatticeInterface> {\n private static _instance: ModelLatticeManager;\n\n /**\n * 获取ModelLatticeManager单例实例\n */\n public static getInstance(): ModelLatticeManager {\n if (!ModelLatticeManager._instance) {\n ModelLatticeManager._instance = new ModelLatticeManager();\n }\n return ModelLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"models\";\n }\n\n /**\n * 注册模型Lattice\n * @param key Lattice键名\n * @param config 模型配置\n */\n public registerLattice(key: string, config: ModelConfig): void {\n // 使用 LLMManager 创建客户端\n const client = new LLMModelLattice(config);\n\n // 创建模型Lattice对象\n const modelLattice: ModelLatticeInterface = {\n key,\n client,\n };\n\n // 调用基类的register方法\n this.register(key, modelLattice);\n }\n\n /**\n * 获取ModelLattice\n * @param key Lattice键名\n */\n public getModelLattice(key: string): ModelLatticeInterface {\n const modelLattice = this.get(key);\n if (!modelLattice) {\n throw new Error(`ModelLattice ${key} not found`);\n }\n return modelLattice;\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): ModelLatticeInterface[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 清空所有Lattice\n */\n public clearLattices(): void {\n this.clear();\n }\n\n /**\n * 获取Lattice数量\n */\n public getLatticeCount(): number {\n return this.count();\n }\n\n /**\n * 获取Lattice键名列表\n */\n public getLatticeKeys(): string[] {\n return this.keys();\n }\n}\n\n// 导出单例实例\nexport const modelLatticeManager = ModelLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerModelLattice = (key: string, config: ModelConfig) =>\n modelLatticeManager.registerLattice(key, config);\n\nexport const getModelLattice = (key: string) =>\n modelLatticeManager.getModelLattice(key);\n","import z from \"zod\";\nimport { registerToolLattice } from \"../ToolLatticeManager\";\n\nregisterToolLattice(\n \"get_current_date_time\",\n {\n name: \"get_current_date_time\",\n description: \"获取当前日期时间\",\n schema: z.object({}),\n },\n async () => {\n return \"当前日期时间:\" + new Date().toLocaleString();\n }\n);\n","import { StructuredTool, tool } from \"@langchain/core/tools\";\nimport { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { ToolConfig, ToolExecutor } from \"@axiom-lattice/protocols\";\nimport { createToolApproveWrapper } from \"./createToolApproveWrapper\";\n\n// 工具定义接口 - 使用协议中的ToolConfig\nexport type ToolDefinition = ToolConfig;\n\n// Lattice 接口定义\nexport interface ToolLattice {\n key: string;\n config: ToolConfig;\n client: StructuredTool;\n}\n\n/**\n * ToolLatticeManager - 单例工具Lattice管理器\n * 负责注册、管理各种工具Lattice\n */\nexport class ToolLatticeManager extends BaseLatticeManager<ToolLattice> {\n private static _instance: ToolLatticeManager;\n\n /**\n * 获取ToolLatticeManager单例实例\n */\n public static getInstance(): ToolLatticeManager {\n if (!ToolLatticeManager._instance) {\n ToolLatticeManager._instance = new ToolLatticeManager();\n }\n return ToolLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"tools\";\n }\n\n /**\n * 注册工具Lattice\n * @param key Lattice键名\n * @param config 工具配置(定义)\n * @param executor 工具执行函数\n */\n public registerLattice<TInput = any, TOutput = any>(\n key: string,\n config: ToolConfig,\n executor: ToolExecutor<TInput, TOutput>\n ): void {\n // 创建工具Lattice对象\n let toolExecutor;\n\n if (config.needUserApprove) {\n toolExecutor = createToolApproveWrapper<TInput, TOutput>(\n config,\n executor\n );\n } else {\n toolExecutor = async (input: TInput, exe_config: any) => {\n const result = await executor(input, exe_config);\n return result;\n };\n }\n\n const toolLattice: ToolLattice = {\n key,\n config,\n client: tool(toolExecutor as ToolExecutor, config),\n };\n\n // 调用基类的register方法\n this.register(key, toolLattice);\n }\n\n /**\n * 获取ToolLattice\n * @param key Lattice键名\n */\n public getToolLattice(key: string): ToolLattice | undefined {\n return this.get(key);\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): ToolLattice[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 清空所有Lattice\n */\n public clearLattices(): void {\n this.clear();\n }\n\n /**\n * 获取Lattice数量\n */\n public getLatticeCount(): number {\n return this.count();\n }\n\n /**\n * 获取Lattice键名列表\n */\n public getLatticeKeys(): string[] {\n return this.keys();\n }\n\n /**\n * 获取工具定义\n * @param key Lattice键名\n */\n public getToolDefinition(key: string): ToolDefinition {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n throw new Error(`ToolLattice ${key} not found`);\n }\n return toolLattice.config;\n }\n\n /**\n * 获取工具客户端\n * @param key Lattice键名\n */\n public getToolClient(key: string): StructuredTool {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n throw new Error(`ToolLattice ${key} not found`);\n }\n return toolLattice.client;\n }\n\n /**\n * 获取所有工具定义\n */\n public getAllToolDefinitions(): ToolDefinition[] {\n return this.getAllLattices().map((lattice) => lattice.config);\n }\n\n /**\n * 验证工具输入参数\n * @param key Lattice键名\n * @param input 输入参数\n */\n public validateToolInput(key: string, input: any): boolean {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n return false;\n }\n\n try {\n if (toolLattice.config.schema) {\n toolLattice.config.schema.parse(input);\n }\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// 导出单例实例\nexport const toolLatticeManager = ToolLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerToolLattice = (\n key: string,\n config: ToolConfig,\n executor: ToolExecutor\n) => toolLatticeManager.registerLattice(key, config, executor);\n\nexport const getToolLattice = (key: string) =>\n toolLatticeManager.getToolLattice(key);\n\nexport const getToolDefinition = (key: string) =>\n toolLatticeManager.getToolDefinition(key);\n\nexport const getToolClient = (key: string) =>\n toolLatticeManager.getToolClient(key);\n\nexport const getAllToolDefinitions = () =>\n toolLatticeManager.getAllToolDefinitions();\n\nexport const validateToolInput = (key: string, input: any) =>\n toolLatticeManager.validateToolInput(key, input);\n","export const genUIMarkdown = (type: string, data: any) => {\n return [\"```\" + type, JSON.stringify(data), \"```\"].join(\"\\n\");\n};\n","import { AIMessage, isAIMessage } from \"@langchain/core/messages\";\nimport { ToolLatticeManager } from \"./ToolLatticeManager\";\nimport { ToolLattice } from \"./ToolLatticeManager\";\nimport { genUIMarkdown } from \"../util/genUIMarkdown\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport { UserFeedbackResponse } from \"../types\";\nimport { END, interrupt } from \"@langchain/langgraph\";\nimport { ToolConfig, ToolExecutor } from \"@axiom-lattice/protocols\";\nexport function createToolApproveWrapper<TInput = any, TOutput = any>(\n tool_config: ToolConfig,\n toolExecutor: ToolExecutor<TInput, TOutput>\n) {\n return async (input: TInput, exe_config: any) => {\n const messagePrefix = \"Tool execution requires approval\";\n const description = `${messagePrefix}\\n\\nTool: ${tool_config.name}\\nArgs: ${JSON.stringify(input, null, 2)}`;\n\n const md = genUIMarkdown(\"confirm\", {\n message: description,\n tool_call: {\n tool_call_id: exe_config.id,\n tool_name: tool_config.name,\n tool_args: input,\n tool_config: tool_config,\n },\n });\n\n const feedback: UserFeedbackResponse = await interrupt(md);\n\n if (feedback.data.action === \"yes\") {\n return await toolExecutor(input, exe_config);\n } else {\n return {\n goto: END,\n };\n }\n };\n}\n","import z from \"zod\";\nimport { registerToolLattice } from \"../ToolLatticeManager\";\nimport { TavilySearch } from \"@langchain/tavily\";\nimport \"dotenv/config\";\nimport { LangGraphRunnableConfig } from \"@langchain/langgraph\";\nimport { genUICard } from \"@util/genUICard\";\n\ntype Topic = \"general\" | \"news\" | \"finance\";\n\nregisterToolLattice(\n \"internet_search\",\n {\n name: \"internet_search\",\n description: \"Run a web search\",\n needUserApprove: false,\n schema: z.object({\n query: z.string().describe(\"The search query\"),\n maxResults: z\n .number()\n .optional()\n .default(5)\n .describe(\"Maximum number of results to return\"),\n topic: z\n .enum([\"general\", \"news\", \"finance\"])\n .optional()\n .default(\"general\")\n .describe(\"Search topic category\"),\n includeRawContent: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether to include raw content\"),\n }),\n },\n async (\n {\n query,\n maxResults = 5,\n topic = \"general\" as Topic,\n includeRawContent = false,\n }: {\n query: string;\n maxResults?: number;\n topic?: Topic;\n includeRawContent?: boolean;\n },\n config: LangGraphRunnableConfig\n ) => {\n /**\n * Run a web search\n */\n console.log(\"[DEBUG][internet_search] Starting search with params:\", {\n query,\n maxResults,\n topic,\n includeRawContent,\n });\n\n // Note: You'll need to install and import tavily-js or similar package\n console.log(\"[DEBUG][internet_search] Creating TavilySearch instance...\");\n const tavilySearch = new TavilySearch({\n maxResults,\n tavilyApiKey: process.env.TAVILY_API_KEY,\n includeRawContent,\n topic,\n });\n\n console.log(\"[DEBUG][internet_search] Invoking search for query:\", query);\n const tavilyResponse = await tavilySearch.invoke({ query });\n console.log(\n \"[DEBUG][internet_search] Search completed. Results count:\",\n tavilyResponse.results?.length ?? 0\n );\n\n const result = genUICard(\"Internet Search:\" + query, \"generic_data_table\", {\n dataSource: tavilyResponse.results,\n });\n console.log(\"[DEBUG][internet_search] Returning UI card result\");\n\n return result;\n }\n);\n","export const genUICard = (title: string, type: string, data: any) => {\n return [title, \"```\" + type, JSON.stringify(data), \"```\"].join(\"\\n\");\n};\n","/**\n * Agent Lattice 类型定义\n *\n * 包含Agent Lattice相关的所有类型定义,供其他模块共享使用\n */\n\nimport { z } from \"zod\";\nimport { ModelLattice } from \"@model_lattice/ModelLattice\";\nimport { CompiledStateGraph } from \"@langchain/langgraph\";\nimport {\n AgentType,\n AgentConfig,\n ReactAgentConfig,\n DeepAgentConfig,\n PlanExecuteAgentConfig,\n SequentialAgentConfig,\n AgentConfigWithTools,\n GraphBuildOptions,\n hasTools,\n isDeepAgentConfig,\n getToolsFromConfig,\n getSubAgentsFromConfig,\n} from \"@axiom-lattice/protocols\";\nimport { ReactAgent } from \"langchain\";\n\n// Re-export types from protocols\nexport {\n AgentType,\n AgentConfig,\n ReactAgentConfig,\n DeepAgentConfig,\n PlanExecuteAgentConfig,\n SequentialAgentConfig,\n AgentConfigWithTools,\n GraphBuildOptions,\n hasTools,\n isDeepAgentConfig,\n getToolsFromConfig,\n getSubAgentsFromConfig,\n};\n\n// Agent客户端类型 - CompiledStateGraph\nexport type AgentClient =\n | CompiledStateGraph<any, any, any, any, any>\n | ReactAgent<any, any, any, any>;\n\n// AgentLattice接口定义\nexport interface AgentLattice {\n config: AgentConfig;\n client?: AgentClient | undefined;\n}\n\n// Agent构建参数接口\nexport interface AgentBuildParams {\n tools: Array<{\n key: string;\n definition: any;\n executor: any;\n }>;\n model: ModelLattice;\n subAgents: Array<{\n key: string;\n config: AgentConfig;\n client: AgentClient | undefined;\n }>;\n prompt: string;\n stateSchema?: z.ZodObject<any, any, any, any, any>;\n}\n","import { MemorySaver } from \"@langchain/langgraph\";\nimport { registerCheckpointSaver } from \"./MemoryLatticeManager\";\nconst memory = new MemorySaver();\nregisterCheckpointSaver(\"default\", memory);\n","/**\n * MemoryLatticeManager\n *\n * 记忆Lattice管理器,负责管理和注册检查点保存器\n */\n\nimport { BaseCheckpointSaver } from \"@langchain/langgraph-checkpoint\";\nimport { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { MemoryLatticeProtocol, MemoryType } from \"@axiom-lattice/protocols\";\n\n// Re-export types from protocols\nexport { MemoryType };\n\n/**\n * 记忆Lattice管理器类\n */\nexport class MemoryLatticeManager extends BaseLatticeManager {\n private static instance: MemoryLatticeManager;\n\n // 检查点保存器注册表\n private static checkpointSavers: Map<string, BaseCheckpointSaver> = new Map();\n\n /**\n * 私有构造函数,防止外部直接实例化\n */\n private constructor() {\n super();\n }\n\n /**\n * 获取单例实例\n */\n public static getInstance(): MemoryLatticeManager {\n if (!MemoryLatticeManager.instance) {\n MemoryLatticeManager.instance = new MemoryLatticeManager();\n }\n return MemoryLatticeManager.instance;\n }\n\n /**\n * 获取Lattice类型\n */\n protected getLatticeType(): string {\n return \"memory\";\n }\n\n /**\n * 注册检查点保存器\n * @param key 保存器键名\n * @param saver 检查点保存器实例\n */\n public registerCheckpointSaver(\n key: string,\n saver: BaseCheckpointSaver\n ): void {\n if (MemoryLatticeManager.checkpointSavers.has(key)) {\n console.warn(`检查点保存器 \"${key}\" 已经存在,将会覆盖旧的检查点保存器`);\n }\n\n MemoryLatticeManager.checkpointSavers.set(key, saver);\n }\n\n /**\n * 获取检查点保存器\n * @param key 保存器键名\n */\n public getCheckpointSaver(key: string): BaseCheckpointSaver {\n const saver = MemoryLatticeManager.checkpointSavers.get(key);\n if (!saver) {\n throw new Error(`检查点保存器 \"${key}\" 不存在`);\n }\n return saver;\n }\n\n /**\n * 获取所有已注册的检查点保存器键名\n */\n public getCheckpointSaverKeys(): string[] {\n return Array.from(MemoryLatticeManager.checkpointSavers.keys());\n }\n\n /**\n * 检查检查点保存器是否存在\n * @param key 保存器键名\n */\n public hasCheckpointSaver(key: string): boolean {\n return MemoryLatticeManager.checkpointSavers.has(key);\n }\n\n /**\n * 移除检查点保存器\n * @param key 保存器键名\n */\n public removeCheckpointSaver(key: string): boolean {\n return MemoryLatticeManager.checkpointSavers.delete(key);\n }\n}\n\nexport const getCheckpointSaver = (key: string) =>\n MemoryLatticeManager.getInstance().getCheckpointSaver(key);\n\nexport const registerCheckpointSaver = (\n key: string,\n saver: BaseCheckpointSaver\n) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);\n","/**\n * State definitions for Deep Agents\n *\n * TypeScript equivalents of the Python state classes using LangGraph's Annotation.Root() pattern.\n * Defines Todo interface and DeepAgentState using MessagesAnnotation as base with proper reducer functions.\n */\n\nimport \"@langchain/langgraph/zod\";\nimport { MessagesZodState } from \"@langchain/langgraph\";\nimport { withLangGraph } from \"@langchain/langgraph/zod\";\nimport { z } from \"zod\";\n\n/**\n * File reducer function that merges file dictionaries\n * Matches the Python file_reducer function behavior exactly\n */\nexport function fileReducer(\n left: Record<string, string> | null | undefined,\n right: Record<string, string> | null | undefined\n): Record<string, string> {\n if (left == null) {\n return right || {};\n } else if (right == null) {\n return left;\n } else {\n return { ...left, ...right };\n }\n}\n\nexport const createReactAgentSchema = (\n schema?: z.ZodObject<any, any, any, any, any>\n) => {\n return schema ? MessagesZodState.extend(schema.shape) : undefined;\n};\n","/**\n * ReAct Agent Graph Builder\n *\n * 实现 ReAct 类型的 Agent Graph 构建\n */\n\nimport { CompiledStateGraph, MessagesZodState } from \"@langchain/langgraph\";\nimport { DynamicTool } from \"@langchain/core/tools\";\nimport { AgentLattice, AgentBuildParams, AgentClient } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { getToolClient } from \"../../tool_lattice/ToolLatticeManager\";\nimport { createReactAgent } from \"@langchain/langgraph/prebuilt\";\nimport { getCheckpointSaver } from \"@memory_lattice\";\nimport { createReactAgentSchema } from \"./state\";\nimport { createAgent } from \"langchain\";\n\nexport class ReActAgentGraphBuilder implements AgentGraphBuilder {\n /**\n * 构建ReAct Agent Graph\n *\n * @param agentLattice Agent Lattice对象\n * @param params Agent构建参数\n * @returns 返回CompiledGraph对象\n */\n build(agentLattice: AgentLattice, params: AgentBuildParams): AgentClient {\n // 创建符合 DynamicTool 接口的工具对象\n const tools = params.tools\n .map((t) => {\n // 使用 DynamicTool 构造工具对象\n const tool = getToolClient(t.key);\n return tool;\n })\n .filter((tool) => tool !== undefined);\n\n const stateSchema = createReactAgentSchema(params.stateSchema);\n\n return createAgent({\n model: params.model,\n tools: tools,\n systemPrompt: params.prompt,\n name: agentLattice.config.name,\n checkpointer: getCheckpointSaver(\"default\"),\n stateSchema: stateSchema as any,\n });\n }\n}\n","import {\n createAgent,\n humanInTheLoopMiddleware,\n anthropicPromptCachingMiddleware,\n summarizationMiddleware,\n type AgentMiddleware,\n type ReactAgent,\n type InterruptOnConfig,\n} from \"langchain\";\nimport type { StructuredTool } from \"@langchain/core/tools\";\nimport type { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n} from \"@langchain/langgraph-checkpoint\";\n\nimport {\n createFilesystemMiddleware,\n createSubAgentMiddleware,\n createPatchToolCallsMiddleware,\n type SubAgent,\n} from \"./middleware/index.js\";\nimport { StateBackend, type BackendProtocol } from \"./backends/index.js\";\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\nimport { AnnotationRoot } from \"@langchain/langgraph\";\nimport { CompiledSubAgent } from \"./middleware/subagents.js\";\nimport { todoListMiddleware } from \"./middleware/todos.js\";\n/**\n * Configuration parameters for creating a Deep Agent\n * Matches Python's create_deep_agent parameters\n */\nexport interface CreateDeepAgentParams<\n ContextSchema extends\n | AnnotationRoot<any>\n | InteropZodObject = AnnotationRoot<any>\n> {\n /** The model to use (model name string or LanguageModelLike instance). Defaults to claude-sonnet-4-5-20250929 */\n model?: BaseLanguageModel | string;\n /** Tools the agent should have access to */\n tools?: StructuredTool[];\n /** Custom system prompt for the agent. This will be combined with the base agent prompt */\n systemPrompt?: string;\n /** Custom middleware to apply after standard middleware */\n middleware?: AgentMiddleware[];\n /** List of subagent specifications for task delegation */\n subagents?: (SubAgent | CompiledSubAgent)[];\n /** Structured output response format for the agent */\n responseFormat?: any; // ResponseFormat type is complex, using any for now\n /** Optional schema for context (not persisted between invocations) */\n contextSchema?: ContextSchema;\n /** Optional checkpointer for persisting agent state between runs */\n checkpointer?: BaseCheckpointSaver | boolean;\n /** Optional store for persisting longterm memories */\n store?: BaseStore;\n /**\n * Optional backend for filesystem operations.\n * Can be either a backend instance or a factory function that creates one.\n * The factory receives a config object with state and store.\n */\n backend?:\n | BackendProtocol\n | ((config: { state: unknown; store?: BaseStore }) => BackendProtocol);\n /** Optional interrupt configuration mapping tool names to interrupt configs */\n interruptOn?: Record<string, boolean | InterruptOnConfig>;\n /** The name of the agent */\n name?: string;\n}\n\nconst BASE_PROMPT = `In order to complete the objective that the user asks of you, you have access to a number of standard tools.`;\n\n/**\n * Create a Deep Agent with middleware-based architecture.\n *\n * Matches Python's create_deep_agent function, using middleware for all features:\n * - Todo management (todoListMiddleware)\n * - Filesystem tools (createFilesystemMiddleware)\n * - Subagent delegation (createSubAgentMiddleware)\n * - Conversation summarization (summarizationMiddleware)\n * - Prompt caching (anthropicPromptCachingMiddleware)\n * - Tool call patching (createPatchToolCallsMiddleware)\n * - Human-in-the-loop (humanInTheLoopMiddleware) - optional\n *\n * @param params Configuration parameters for the agent\n * @returns ReactAgent instance ready for invocation\n */\nexport function createDeepAgent<\n ContextSchema extends\n | AnnotationRoot<any>\n | InteropZodObject = AnnotationRoot<any>\n>(\n params: CreateDeepAgentParams<ContextSchema> = {}\n): ReactAgent<any, any, ContextSchema, any> {\n const {\n model = \"claude-sonnet-4-5-20250929\",\n tools = [],\n systemPrompt,\n middleware: customMiddleware = [],\n subagents = [],\n responseFormat,\n contextSchema,\n checkpointer,\n store,\n backend,\n interruptOn,\n name,\n } = params;\n\n // Combine system prompt with base prompt like Python implementation\n const finalSystemPrompt = systemPrompt\n ? `${systemPrompt}\\n\\n${BASE_PROMPT}`\n : BASE_PROMPT;\n\n // Create backend configuration for filesystem middleware\n // If no backend is provided, use a factory that creates a StateBackend\n const filesystemBackend = backend\n ? backend\n : (config: { state: unknown; store?: BaseStore }) =>\n new StateBackend(config);\n\n const middleware: AgentMiddleware[] = [\n // Provides todo list management capabilities for tracking tasks\n todoListMiddleware(),\n // Enables filesystem operations and optional long-term memory storage\n createFilesystemMiddleware({ backend: filesystemBackend }),\n // Enables delegation to specialized subagents for complex tasks\n createSubAgentMiddleware({\n defaultModel: model,\n defaultTools: tools,\n defaultMiddleware: [\n // Subagent middleware: Todo list management\n todoListMiddleware(),\n // Subagent middleware: Filesystem operations\n createFilesystemMiddleware({\n backend: filesystemBackend,\n }),\n // Subagent middleware: Automatic conversation summarization when token limits are approached\n summarizationMiddleware({\n model,\n trigger: { tokens: 170_000 },\n keep: { messages: 6 },\n }),\n // Subagent middleware: Anthropic prompt caching for improved performance\n anthropicPromptCachingMiddleware({\n unsupportedModelBehavior: \"ignore\",\n }),\n // Subagent middleware: Patches tool calls for compatibility\n createPatchToolCallsMiddleware(),\n ],\n defaultInterruptOn: interruptOn,\n subagents,\n generalPurposeAgent: true,\n }),\n // Automatically summarizes conversation history when token limits are approached\n summarizationMiddleware({\n model,\n trigger: { tokens: 170_000 },\n keep: { messages: 6 },\n }),\n // Enables Anthropic prompt caching for improved performance and reduced costs\n anthropicPromptCachingMiddleware({\n unsupportedModelBehavior: \"ignore\",\n }),\n // Patches tool calls to ensure compatibility across different model providers\n createPatchToolCallsMiddleware(),\n ];\n\n // Add human-in-the-loop middleware if interrupt config provided\n if (interruptOn) {\n middleware.push(humanInTheLoopMiddleware({ interruptOn }));\n }\n\n // Add custom middleware last (after all built-in middleware)\n middleware.push(...customMiddleware);\n\n return createAgent({\n model,\n systemPrompt: finalSystemPrompt,\n tools,\n middleware,\n responseFormat,\n contextSchema,\n checkpointer,\n store,\n name,\n });\n}\n","/**\n * Middleware for providing filesystem tools to an agent.\n *\n * Provides ls, read_file, write_file, edit_file, glob, and grep tools with support for:\n * - Pluggable backends (StateBackend, StoreBackend, FilesystemBackend, CompositeBackend)\n * - Tool result eviction for large outputs\n */\n\nimport { createMiddleware, tool, ToolMessage } from \"langchain\";\nimport { Command, isCommand, getCurrentTaskInput } from \"@langchain/langgraph\";\nimport { z as z3 } from \"zod/v3\";\nimport { withLangGraph } from \"@langchain/langgraph/zod\";\nimport type {\n BackendProtocol,\n BackendFactory,\n FileData,\n StateAndStore,\n} from \"../backends/protocol.js\";\nimport { StateBackend } from \"../backends/state.js\";\nimport { sanitizeToolCallId } from \"../backends/utils.js\";\n\n/**\n * Zod v3 schema for FileData (re-export from backends)\n */\nconst FileDataSchema = z3.object({\n content: z3.array(z3.string()),\n created_at: z3.string(),\n modified_at: z3.string(),\n});\n\nexport type { FileData };\n\n/**\n * Merge file updates with support for deletions.\n */\nfunction fileDataReducer(\n left: Record<string, FileData> | undefined,\n right: Record<string, FileData | null>\n): Record<string, FileData> {\n if (left === undefined) {\n const result: Record<string, FileData> = {};\n for (const [key, value] of Object.entries(right)) {\n if (value !== null) {\n result[key] = value;\n }\n }\n return result;\n }\n\n const result = { ...left };\n for (const [key, value] of Object.entries(right)) {\n if (value === null) {\n delete result[key];\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Shared filesystem state schema.\n * Defined at module level to ensure the same object identity is used across all agents,\n * preventing \"Channel already exists with different type\" errors when multiple agents\n * use createFilesystemMiddleware.\n */\nconst FilesystemStateSchema = z3.object({\n files: withLangGraph(\n z3.record(z3.string(), FileDataSchema).default({}) as any,\n {\n reducer: {\n fn: fileDataReducer,\n schema: z3.record(z3.string(), FileDataSchema.nullable()),\n },\n }\n ),\n});\n\n/**\n * Resolve backend from factory or instance.\n *\n * @param backend - Backend instance or factory function\n * @param stateAndStore - State and store container for backend initialization\n */\nfunction getBackend(\n backend: BackendProtocol | BackendFactory,\n stateAndStore: StateAndStore\n): BackendProtocol {\n if (typeof backend === \"function\") {\n return backend(stateAndStore);\n }\n return backend;\n}\n\n// System prompts\nconst FILESYSTEM_SYSTEM_PROMPT = `You have access to a virtual filesystem. All file paths must start with a /.\n\n- ls: list files in a directory (requires absolute path)\n- read_file: read a file from the filesystem\n- write_file: write to a file in the filesystem\n- edit_file: edit a file in the filesystem\n- glob: find files matching a pattern (e.g., \"**/*.py\")\n- grep: search for text within files`;\n\n// Tool descriptions\nexport const LS_TOOL_DESCRIPTION = \"List files and directories in a directory\";\nexport const READ_FILE_TOOL_DESCRIPTION = \"Read the contents of a file\";\nexport const WRITE_FILE_TOOL_DESCRIPTION =\n \"Write content to a new file. Returns an error if the file already exists\";\nexport const EDIT_FILE_TOOL_DESCRIPTION =\n \"Edit a file by replacing a specific string with a new string\";\nexport const GLOB_TOOL_DESCRIPTION =\n \"Find files matching a glob pattern (e.g., '**/*.py' for all Python files)\";\nexport const GREP_TOOL_DESCRIPTION =\n \"Search for a regex pattern in files. Returns matching files and line numbers\";\n\n/**\n * Create ls tool using backend.\n */\nfunction createLsTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const path = input.path || \"/\";\n const infos = await resolvedBackend.lsInfo(path);\n\n if (infos.length === 0) {\n return `No files found in ${path}`;\n }\n\n // Format output\n const lines: string[] = [];\n for (const info of infos) {\n if (info.is_dir) {\n lines.push(`${info.path} (directory)`);\n } else {\n const size = info.size ? ` (${info.size} bytes)` : \"\";\n lines.push(`${info.path}${size}`);\n }\n }\n return lines.join(\"\\n\");\n },\n {\n name: \"ls\",\n description: customDescription || LS_TOOL_DESCRIPTION,\n schema: z3.object({\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Directory path to list (default: /)\"),\n }),\n }\n );\n}\n\n/**\n * Create read_file tool using backend.\n */\nfunction createReadFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, offset = 0, limit = 2000 } = input;\n return await resolvedBackend.read(file_path, offset, limit);\n },\n {\n name: \"read_file\",\n description: customDescription || READ_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to read\"),\n offset: z3\n .number({ coerce: true })\n .optional()\n .default(0)\n .describe(\"Line offset to start reading from (0-indexed)\"),\n limit: z3\n .number({ coerce: true })\n .optional()\n .default(2000)\n .describe(\"Maximum number of lines to read\"),\n }),\n }\n );\n}\n\n/**\n * Create write_file tool using backend.\n */\nfunction createWriteFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, content } = input;\n const result = await resolvedBackend.write(file_path, content);\n\n if (result.error) {\n return result.error;\n }\n\n // If filesUpdate is present, return Command to update state\n const message = new ToolMessage({\n content: `Successfully wrote to '${file_path}'`,\n tool_call_id: config.toolCall?.id as string,\n name: \"write_file\",\n metadata: result.metadata,\n });\n\n if (result.filesUpdate) {\n return new Command({\n update: { files: result.filesUpdate, messages: [message] },\n });\n }\n\n return message;\n },\n {\n name: \"write_file\",\n description: customDescription || WRITE_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to write\"),\n content: z3.string().describe(\"Content to write to the file\"),\n }),\n }\n );\n}\n\n/**\n * Create edit_file tool using backend.\n */\nfunction createEditFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, old_string, new_string, replace_all = false } = input;\n const result = await resolvedBackend.edit(\n file_path,\n old_string,\n new_string,\n replace_all\n );\n\n if (result.error) {\n return result.error;\n }\n\n const message = new ToolMessage({\n content: `Successfully replaced ${result.occurrences} occurrence(s) in '${file_path}'`,\n tool_call_id: config.toolCall?.id as string,\n name: \"edit_file\",\n metadata: result.metadata,\n });\n\n // If filesUpdate is present, return Command to update state\n if (result.filesUpdate) {\n return new Command({\n update: { files: result.filesUpdate, messages: [message] },\n });\n }\n\n // External storage (filesUpdate is null)\n return message;\n },\n {\n name: \"edit_file\",\n description: customDescription || EDIT_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to edit\"),\n old_string: z3\n .string()\n .describe(\"String to be replaced (must match exactly)\"),\n new_string: z3.string().describe(\"String to replace with\"),\n replace_all: z3\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether to replace all occurrences\"),\n }),\n }\n );\n}\n\n/**\n * Create glob tool using backend.\n */\nfunction createGlobTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { pattern, path = \"/\" } = input;\n const infos = await resolvedBackend.globInfo(pattern, path);\n\n if (infos.length === 0) {\n return `No files found matching pattern '${pattern}'`;\n }\n\n return infos.map((info) => info.path).join(\"\\n\");\n },\n {\n name: \"glob\",\n description: customDescription || GLOB_TOOL_DESCRIPTION,\n schema: z3.object({\n pattern: z3.string().describe(\"Glob pattern (e.g., '*.py', '**/*.ts')\"),\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Base path to search from (default: /)\"),\n }),\n }\n );\n}\n\n/**\n * Create grep tool using backend.\n */\nfunction createGrepTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { pattern, path = \"/\", glob = null } = input;\n const result = await resolvedBackend.grepRaw(pattern, path, glob);\n\n // If string, it's an error\n if (typeof result === \"string\") {\n return result;\n }\n\n if (result.length === 0) {\n return `No matches found for pattern '${pattern}'`;\n }\n\n // Format output: group by file\n const lines: string[] = [];\n let currentFile: string | null = null;\n for (const match of result) {\n if (match.path !== currentFile) {\n currentFile = match.path;\n lines.push(`\\n${currentFile}:`);\n }\n lines.push(` ${match.line}: ${match.text}`);\n }\n\n return lines.join(\"\\n\");\n },\n {\n name: \"grep\",\n description: customDescription || GREP_TOOL_DESCRIPTION,\n schema: z3.object({\n pattern: z3.string().describe(\"Regex pattern to search for\"),\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Base path to search from (default: /)\"),\n glob: z3\n .string()\n .optional()\n .nullable()\n .describe(\"Optional glob pattern to filter files (e.g., '*.py')\"),\n }),\n }\n );\n}\n\n/**\n * Options for creating filesystem middleware.\n */\nexport interface FilesystemMiddlewareOptions {\n /** Backend instance or factory (default: StateBackend) */\n backend?: BackendProtocol | BackendFactory;\n /** Optional custom system prompt override */\n systemPrompt?: string | null;\n /** Optional custom tool descriptions override */\n customToolDescriptions?: Record<string, string> | null;\n /** Optional token limit before evicting a tool result to the filesystem (default: 20000 tokens, ~80KB) */\n toolTokenLimitBeforeEvict?: number | null;\n}\n\n/**\n * Create filesystem middleware with all tools and features.\n */\nexport function createFilesystemMiddleware(\n options: FilesystemMiddlewareOptions = {}\n) {\n const {\n backend = (stateAndStore: StateAndStore) => new StateBackend(stateAndStore),\n systemPrompt: customSystemPrompt = null,\n customToolDescriptions = null,\n toolTokenLimitBeforeEvict = 20000,\n } = options;\n\n const systemPrompt = customSystemPrompt || FILESYSTEM_SYSTEM_PROMPT;\n\n const tools = [\n createLsTool(backend, {\n customDescription: customToolDescriptions?.ls,\n }),\n createReadFileTool(backend, {\n customDescription: customToolDescriptions?.read_file,\n }),\n createWriteFileTool(backend, {\n customDescription: customToolDescriptions?.write_file,\n }),\n createEditFileTool(backend, {\n customDescription: customToolDescriptions?.edit_file,\n }),\n createGlobTool(backend, {\n customDescription: customToolDescriptions?.glob,\n }),\n createGrepTool(backend, {\n customDescription: customToolDescriptions?.grep,\n }),\n ];\n\n return createMiddleware({\n name: \"FilesystemMiddleware\",\n stateSchema: FilesystemStateSchema as any,\n tools,\n wrapModelCall: systemPrompt\n ? async (request, handler: any) => {\n const currentSystemPrompt = request.systemPrompt || \"\";\n const newSystemPrompt = currentSystemPrompt\n ? `${currentSystemPrompt}\\n\\n${systemPrompt}`\n : systemPrompt;\n return handler({ ...request, systemPrompt: newSystemPrompt });\n }\n : undefined,\n wrapToolCall: toolTokenLimitBeforeEvict\n ? ((async (request: any, handler: any) => {\n const result = await handler(request);\n\n async function processToolMessage(msg: ToolMessage) {\n if (\n typeof msg.content === \"string\" &&\n msg.content.length > toolTokenLimitBeforeEvict! * 4\n ) {\n // Build StateAndStore from request\n const stateAndStore: StateAndStore = {\n state: request.state || {},\n store: request.config?.store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const sanitizedId = sanitizeToolCallId(\n request.toolCall?.id || msg.tool_call_id\n );\n const evictPath = `/large_tool_results/${sanitizedId}`;\n\n const writeResult = await resolvedBackend.write(\n evictPath,\n msg.content\n );\n\n if (writeResult.error) {\n return { message: msg, filesUpdate: null };\n }\n\n const truncatedMessage = new ToolMessage({\n content: `Tool result too large (${Math.round(\n msg.content.length / 4\n )} tokens). Content saved to ${evictPath}`,\n tool_call_id: msg.tool_call_id,\n name: msg.name,\n });\n\n return {\n message: truncatedMessage,\n filesUpdate: writeResult.filesUpdate,\n };\n }\n return { message: msg, filesUpdate: null };\n }\n\n if (result instanceof ToolMessage) {\n const processed = await processToolMessage(result);\n\n if (processed.filesUpdate) {\n return new Command({\n update: {\n files: processed.filesUpdate,\n messages: [processed.message],\n },\n });\n }\n\n return processed.message;\n }\n\n if (isCommand(result)) {\n const update = result.update as any;\n if (!update?.messages) {\n return result;\n }\n\n let hasLargeResults = false;\n const accumulatedFiles: Record<string, FileData> = {\n ...(update.files || {}),\n };\n const processedMessages: ToolMessage[] = [];\n\n for (const msg of update.messages) {\n if (msg instanceof ToolMessage) {\n const processed = await processToolMessage(msg);\n processedMessages.push(processed.message);\n\n if (processed.filesUpdate) {\n hasLargeResults = true;\n Object.assign(accumulatedFiles, processed.filesUpdate);\n }\n } else {\n processedMessages.push(msg);\n }\n }\n\n if (hasLargeResults) {\n return new Command({\n update: {\n ...update,\n messages: processedMessages,\n files: accumulatedFiles,\n },\n });\n }\n }\n\n return result;\n }) as any)\n : undefined,\n });\n}\n","/**\n * Shared utility functions for memory backend implementations.\n *\n * This module contains both user-facing string formatters and structured\n * helpers used by backends and the composite router. Structured helpers\n * enable composition without fragile string parsing.\n */\n\nimport micromatch from \"micromatch\";\nimport { basename } from \"path\";\nimport type { FileData, GrepMatch } from \"./protocol.js\";\n\n// Constants\nexport const EMPTY_CONTENT_WARNING =\n \"System reminder: File exists but has empty contents\";\nexport const MAX_LINE_LENGTH = 10000;\nexport const LINE_NUMBER_WIDTH = 6;\nexport const TOOL_RESULT_TOKEN_LIMIT = 20000; // Same threshold as eviction\nexport const TRUNCATION_GUIDANCE =\n \"... [results truncated, try being more specific with your parameters]\";\n\n/**\n * Sanitize tool_call_id to prevent path traversal and separator issues.\n *\n * Replaces dangerous characters (., /, \\) with underscores.\n */\nexport function sanitizeToolCallId(toolCallId: string): string {\n return toolCallId.replace(/\\./g, \"_\").replace(/\\//g, \"_\").replace(/\\\\/g, \"_\");\n}\n\n/**\n * Format file content with line numbers (cat -n style).\n *\n * Chunks lines longer than MAX_LINE_LENGTH with continuation markers (e.g., 5.1, 5.2).\n *\n * @param content - File content as string or list of lines\n * @param startLine - Starting line number (default: 1)\n * @returns Formatted content with line numbers and continuation markers\n */\nexport function formatContentWithLineNumbers(\n content: string | string[],\n startLine: number = 1,\n): string {\n let lines: string[];\n if (typeof content === \"string\") {\n lines = content.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines = lines.slice(0, -1);\n }\n } else {\n lines = content;\n }\n\n const resultLines: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + startLine;\n\n if (line.length <= MAX_LINE_LENGTH) {\n resultLines.push(\n `${lineNum.toString().padStart(LINE_NUMBER_WIDTH)}\\t${line}`,\n );\n } else {\n // Split long line into chunks with continuation markers\n const numChunks = Math.ceil(line.length / MAX_LINE_LENGTH);\n for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {\n const start = chunkIdx * MAX_LINE_LENGTH;\n const end = Math.min(start + MAX_LINE_LENGTH, line.length);\n const chunk = line.substring(start, end);\n if (chunkIdx === 0) {\n // First chunk: use normal line number\n resultLines.push(\n `${lineNum.toString().padStart(LINE_NUMBER_WIDTH)}\\t${chunk}`,\n );\n } else {\n // Continuation chunks: use decimal notation (e.g., 5.1, 5.2)\n const continuationMarker = `${lineNum}.${chunkIdx}`;\n resultLines.push(\n `${continuationMarker.padStart(LINE_NUMBER_WIDTH)}\\t${chunk}`,\n );\n }\n }\n }\n }\n\n return resultLines.join(\"\\n\");\n}\n\n/**\n * Check if content is empty and return warning message.\n *\n * @param content - Content to check\n * @returns Warning message if empty, null otherwise\n */\nexport function checkEmptyContent(content: string): string | null {\n if (!content || content.trim() === \"\") {\n return EMPTY_CONTENT_WARNING;\n }\n return null;\n}\n\n/**\n * Convert FileData to plain string content.\n *\n * @param fileData - FileData object with 'content' key\n * @returns Content as string with lines joined by newlines\n */\nexport function fileDataToString(fileData: FileData): string {\n return fileData.content.join(\"\\n\");\n}\n\n/**\n * Create a FileData object with timestamps.\n *\n * @param content - File content as string\n * @param createdAt - Optional creation timestamp (ISO format)\n * @returns FileData object with content and timestamps\n */\nexport function createFileData(content: string, createdAt?: string): FileData {\n const lines = typeof content === \"string\" ? content.split(\"\\n\") : content;\n const now = new Date().toISOString();\n\n return {\n content: lines,\n created_at: createdAt || now,\n modified_at: now,\n };\n}\n\n/**\n * Update FileData with new content, preserving creation timestamp.\n *\n * @param fileData - Existing FileData object\n * @param content - New content as string\n * @returns Updated FileData object\n */\nexport function updateFileData(fileData: FileData, content: string): FileData {\n const lines = typeof content === \"string\" ? content.split(\"\\n\") : content;\n const now = new Date().toISOString();\n\n return {\n content: lines,\n created_at: fileData.created_at,\n modified_at: now,\n };\n}\n\n/**\n * Format file data for read response with line numbers.\n *\n * @param fileData - FileData object\n * @param offset - Line offset (0-indexed)\n * @param limit - Maximum number of lines\n * @returns Formatted content or error message\n */\nexport function formatReadResponse(\n fileData: FileData,\n offset: number,\n limit: number,\n): string {\n const content = fileDataToString(fileData);\n const emptyMsg = checkEmptyContent(content);\n if (emptyMsg) {\n return emptyMsg;\n }\n\n const lines = content.split(\"\\n\");\n const startIdx = offset;\n const endIdx = Math.min(startIdx + limit, lines.length);\n\n if (startIdx >= lines.length) {\n return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;\n }\n\n const selectedLines = lines.slice(startIdx, endIdx);\n return formatContentWithLineNumbers(selectedLines, startIdx + 1);\n}\n\n/**\n * Perform string replacement with occurrence validation.\n *\n * @param content - Original content\n * @param oldString - String to replace\n * @param newString - Replacement string\n * @param replaceAll - Whether to replace all occurrences\n * @returns Tuple of [new_content, occurrences] on success, or error message string\n */\nexport function performStringReplacement(\n content: string,\n oldString: string,\n newString: string,\n replaceAll: boolean,\n): [string, number] | string {\n // Use split to count occurrences (simpler than regex)\n const occurrences = content.split(oldString).length - 1;\n\n if (occurrences === 0) {\n return `Error: String not found in file: '${oldString}'`;\n }\n\n if (occurrences > 1 && !replaceAll) {\n return `Error: String '${oldString}' appears ${occurrences} times in file. Use replace_all=True to replace all instances, or provide a more specific string with surrounding context.`;\n }\n\n // Python's str.replace() replaces ALL occurrences\n // Use split/join for consistent behavior\n const newContent = content.split(oldString).join(newString);\n\n return [newContent, occurrences];\n}\n\n/**\n * Truncate list or string result if it exceeds token limit (rough estimate: 4 chars/token).\n */\nexport function truncateIfTooLong(\n result: string[] | string,\n): string[] | string {\n if (Array.isArray(result)) {\n const totalChars = result.reduce((sum, item) => sum + item.length, 0);\n if (totalChars > TOOL_RESULT_TOKEN_LIMIT * 4) {\n const truncateAt = Math.floor(\n (result.length * TOOL_RESULT_TOKEN_LIMIT * 4) / totalChars,\n );\n return [...result.slice(0, truncateAt), TRUNCATION_GUIDANCE];\n }\n return result;\n }\n // string\n if (result.length > TOOL_RESULT_TOKEN_LIMIT * 4) {\n return (\n result.substring(0, TOOL_RESULT_TOKEN_LIMIT * 4) +\n \"\\n\" +\n TRUNCATION_GUIDANCE\n );\n }\n return result;\n}\n\n/**\n * Validate and normalize a path.\n *\n * @param path - Path to validate\n * @returns Normalized path starting with / and ending with /\n * @throws Error if path is invalid\n */\nexport function validatePath(path: string | null | undefined): string {\n const pathStr = path || \"/\";\n if (!pathStr || pathStr.trim() === \"\") {\n throw new Error(\"Path cannot be empty\");\n }\n\n let normalized = pathStr.startsWith(\"/\") ? pathStr : \"/\" + pathStr;\n\n if (!normalized.endsWith(\"/\")) {\n normalized += \"/\";\n }\n\n return normalized;\n}\n\n/**\n * Search files dict for paths matching glob pattern.\n *\n * @param files - Dictionary of file paths to FileData\n * @param pattern - Glob pattern (e.g., `*.py`, `**\\/*.ts`)\n * @param path - Base path to search from\n * @returns Newline-separated file paths, sorted by modification time (most recent first).\n * Returns \"No files found\" if no matches.\n *\n * @example\n * ```typescript\n * const files = {\"/src/main.py\": FileData(...), \"/test.py\": FileData(...)};\n * globSearchFiles(files, \"*.py\", \"/\");\n * // Returns: \"/test.py\\n/src/main.py\" (sorted by modified_at)\n * ```\n */\nexport function globSearchFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string = \"/\",\n): string {\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return \"No files found\";\n }\n\n const filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n // Respect standard glob semantics:\n // - Patterns without path separators (e.g., \"*.py\") match only in the current\n // directory (non-recursive) relative to `path`.\n // - Use \"**\" explicitly for recursive matching.\n const effectivePattern = pattern;\n\n const matches: Array<[string, string]> = [];\n for (const [filePath, fileData] of Object.entries(filtered)) {\n let relative = filePath.substring(normalizedPath.length);\n if (relative.startsWith(\"/\")) {\n relative = relative.substring(1);\n }\n if (!relative) {\n const parts = filePath.split(\"/\");\n relative = parts[parts.length - 1] || \"\";\n }\n\n if (\n micromatch.isMatch(relative, effectivePattern, {\n dot: true,\n nobrace: false,\n })\n ) {\n matches.push([filePath, fileData.modified_at]);\n }\n }\n\n matches.sort((a, b) => b[1].localeCompare(a[1])); // Sort by modified_at descending\n\n if (matches.length === 0) {\n return \"No files found\";\n }\n\n return matches.map(([fp]) => fp).join(\"\\n\");\n}\n\n/**\n * Format grep search results based on output mode.\n *\n * @param results - Dictionary mapping file paths to list of [line_num, line_content] tuples\n * @param outputMode - Output format - \"files_with_matches\", \"content\", or \"count\"\n * @returns Formatted string output\n */\nexport function formatGrepResults(\n results: Record<string, Array<[number, string]>>,\n outputMode: \"files_with_matches\" | \"content\" | \"count\",\n): string {\n if (outputMode === \"files_with_matches\") {\n return Object.keys(results).sort().join(\"\\n\");\n }\n if (outputMode === \"count\") {\n const lines: string[] = [];\n for (const filePath of Object.keys(results).sort()) {\n const count = results[filePath].length;\n lines.push(`${filePath}: ${count}`);\n }\n return lines.join(\"\\n\");\n }\n // content mode\n const lines: string[] = [];\n for (const filePath of Object.keys(results).sort()) {\n lines.push(`${filePath}:`);\n for (const [lineNum, line] of results[filePath]) {\n lines.push(` ${lineNum}: ${line}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Search file contents for regex pattern.\n *\n * @param files - Dictionary of file paths to FileData\n * @param pattern - Regex pattern to search for\n * @param path - Base path to search from\n * @param glob - Optional glob pattern to filter files (e.g., \"*.py\")\n * @param outputMode - Output format - \"files_with_matches\", \"content\", or \"count\"\n * @returns Formatted search results. Returns \"No matches found\" if no results.\n *\n * @example\n * ```typescript\n * const files = {\"/file.py\": FileData({content: [\"import os\", \"print('hi')\"], ...})};\n * grepSearchFiles(files, \"import\", \"/\");\n * // Returns: \"/file.py\" (with output_mode=\"files_with_matches\")\n * ```\n */\nexport function grepSearchFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string | null = null,\n glob: string | null = null,\n outputMode: \"files_with_matches\" | \"content\" | \"count\" = \"files_with_matches\",\n): string {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return \"No matches found\";\n }\n\n let filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n if (glob) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([fp]) =>\n micromatch.isMatch(basename(fp), glob, { dot: true, nobrace: false }),\n ),\n );\n }\n\n const results: Record<string, Array<[number, string]>> = {};\n for (const [filePath, fileData] of Object.entries(filtered)) {\n for (let i = 0; i < fileData.content.length; i++) {\n const line = fileData.content[i];\n const lineNum = i + 1;\n if (regex.test(line)) {\n if (!results[filePath]) {\n results[filePath] = [];\n }\n results[filePath].push([lineNum, line]);\n }\n }\n }\n\n if (Object.keys(results).length === 0) {\n return \"No matches found\";\n }\n return formatGrepResults(results, outputMode);\n}\n\n// -------- Structured helpers for composition --------\n\n/**\n * Return structured grep matches from an in-memory files mapping.\n *\n * Returns a list of GrepMatch on success, or a string for invalid inputs\n * (e.g., invalid regex). We deliberately do not raise here to keep backends\n * non-throwing in tool contexts and preserve user-facing error messages.\n */\nexport function grepMatchesFromFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string | null = null,\n glob: string | null = null,\n): GrepMatch[] | string {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return [];\n }\n\n let filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n if (glob) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([fp]) =>\n micromatch.isMatch(basename(fp), glob, { dot: true, nobrace: false }),\n ),\n );\n }\n\n const matches: GrepMatch[] = [];\n for (const [filePath, fileData] of Object.entries(filtered)) {\n for (let i = 0; i < fileData.content.length; i++) {\n const line = fileData.content[i];\n const lineNum = i + 1;\n if (regex.test(line)) {\n matches.push({ path: filePath, line: lineNum, text: line });\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Group structured matches into the legacy dict form used by formatters.\n */\nexport function buildGrepResultsDict(\n matches: GrepMatch[],\n): Record<string, Array<[number, string]>> {\n const grouped: Record<string, Array<[number, string]>> = {};\n for (const m of matches) {\n if (!grouped[m.path]) {\n grouped[m.path] = [];\n }\n grouped[m.path].push([m.line, m.text]);\n }\n return grouped;\n}\n\n/**\n * Format structured grep matches using existing formatting logic.\n */\nexport function formatGrepMatches(\n matches: GrepMatch[],\n outputMode: \"files_with_matches\" | \"content\" | \"count\",\n): string {\n if (matches.length === 0) {\n return \"No matches found\";\n }\n return formatGrepResults(buildGrepResultsDict(matches), outputMode);\n}\n","/**\n * StateBackend: Store files in LangGraph agent state (ephemeral).\n */\n\nimport type {\n BackendProtocol,\n EditResult,\n FileData,\n FileInfo,\n GrepMatch,\n StateAndStore,\n WriteResult,\n} from \"./protocol.js\";\nimport {\n createFileData,\n fileDataToString,\n formatReadResponse,\n globSearchFiles,\n grepMatchesFromFiles,\n performStringReplacement,\n updateFileData,\n} from \"./utils.js\";\n\n/**\n * Backend that stores files in agent state (ephemeral).\n *\n * Uses LangGraph's state management and checkpointing. Files persist within\n * a conversation thread but not across threads. State is automatically\n * checkpointed after each agent step.\n *\n * Special handling: Since LangGraph state must be updated via Command objects\n * (not direct mutation), operations return filesUpdate in WriteResult/EditResult\n * for the middleware to apply via Command.\n */\nexport class StateBackend implements BackendProtocol {\n private stateAndStore: StateAndStore;\n\n constructor(stateAndStore: StateAndStore) {\n this.stateAndStore = stateAndStore;\n }\n\n /**\n * Get files from current state.\n */\n private getFiles(): Record<string, FileData> {\n return (\n ((this.stateAndStore.state as any).files as Record<string, FileData>) ||\n {}\n );\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param path - Absolute path to directory\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n lsInfo(path: string): FileInfo[] {\n const files = this.getFiles();\n const infos: FileInfo[] = [];\n const subdirs = new Set<string>();\n\n // Normalize path to have trailing slash for proper prefix matching\n const normalizedPath = path.endsWith(\"/\") ? path : path + \"/\";\n\n for (const [k, fd] of Object.entries(files)) {\n // Check if file is in the specified directory or a subdirectory\n if (!k.startsWith(normalizedPath)) {\n continue;\n }\n\n // Get the relative path after the directory\n const relative = k.substring(normalizedPath.length);\n\n // If relative path contains '/', it's in a subdirectory\n if (relative.includes(\"/\")) {\n // Extract the immediate subdirectory name\n const subdirName = relative.split(\"/\")[0];\n subdirs.add(normalizedPath + subdirName + \"/\");\n continue;\n }\n\n // This is a file directly in the current directory\n const size = fd.content.join(\"\\n\").length;\n infos.push({\n path: k,\n is_dir: false,\n size: size,\n modified_at: fd.modified_at,\n });\n }\n\n // Add directories to the results\n for (const subdir of Array.from(subdirs).sort()) {\n infos.push({\n path: subdir,\n is_dir: true,\n size: 0,\n modified_at: \"\",\n });\n }\n\n infos.sort((a, b) => a.path.localeCompare(b.path));\n return infos;\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n read(filePath: string, offset: number = 0, limit: number = 2000): string {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) {\n return `Error: File '${filePath}' not found`;\n }\n\n return formatReadResponse(fileData, offset, limit);\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns Raw file content as FileData\n */\n readRaw(filePath: string): FileData {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) throw new Error(`File '${filePath}' not found`);\n return fileData;\n }\n\n /**\n * Create a new file with content.\n * Returns WriteResult with filesUpdate to update LangGraph state.\n */\n write(filePath: string, content: string): WriteResult {\n const files = this.getFiles();\n\n if (filePath in files) {\n return {\n error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`,\n };\n }\n\n const newFileData = createFileData(content);\n return {\n path: filePath,\n filesUpdate: { [filePath]: newFileData },\n };\n }\n\n /**\n * Edit a file by replacing string occurrences.\n * Returns EditResult with filesUpdate and occurrences.\n */\n edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n ): EditResult {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) {\n return { error: `Error: File '${filePath}' not found` };\n }\n\n const content = fileDataToString(fileData);\n const result = performStringReplacement(\n content,\n oldString,\n newString,\n replaceAll,\n );\n\n if (typeof result === \"string\") {\n return { error: result };\n }\n\n const [newContent, occurrences] = result;\n const newFileData = updateFileData(fileData, newContent);\n return {\n path: filePath,\n filesUpdate: { [filePath]: newFileData },\n occurrences: occurrences,\n };\n }\n\n /**\n * Structured search results or error string for invalid input.\n */\n grepRaw(\n pattern: string,\n path: string = \"/\",\n glob: string | null = null,\n ): GrepMatch[] | string {\n const files = this.getFiles();\n return grepMatchesFromFiles(files, pattern, path, glob);\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n */\n globInfo(pattern: string, path: string = \"/\"): FileInfo[] {\n const files = this.getFiles();\n const result = globSearchFiles(files, pattern, path);\n\n if (result === \"No files found\") {\n return [];\n }\n\n const paths = result.split(\"\\n\");\n const infos: FileInfo[] = [];\n for (const p of paths) {\n const fd = files[p];\n const size = fd ? fd.content.join(\"\\n\").length : 0;\n infos.push({\n path: p,\n is_dir: false,\n size: size,\n modified_at: fd?.modified_at || \"\",\n });\n }\n return infos;\n }\n}\n","import { z } from \"zod/v3\";\nimport {\n createMiddleware,\n createAgent,\n AgentMiddleware,\n tool,\n ToolMessage,\n humanInTheLoopMiddleware,\n type InterruptOnConfig,\n type ReactAgent,\n StructuredTool,\n} from \"langchain\";\nimport { Command, getCurrentTaskInput } from \"@langchain/langgraph\";\nimport type { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { AgentClient } from \"@agent_lattice\";\n\nexport type { AgentMiddleware };\n\n// Constants\nconst DEFAULT_SUBAGENT_PROMPT =\n \"In order to complete the objective that the user asks of you, you have access to a number of standard tools.\";\n\n// State keys that should be excluded when passing state to subagents\nconst EXCLUDED_STATE_KEYS = [\"messages\", \"todos\", \"jumpTo\"] as const;\n\nconst DEFAULT_GENERAL_PURPOSE_DESCRIPTION =\n \"General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.\";\n\n// Comprehensive task tool description from Python\nfunction getTaskToolDescription(subagentDescriptions: string[]): string {\n return `\nLaunch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.\n\nAvailable agent types and the tools they have access to:\n${subagentDescriptions.join(\"\\n\")}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n## Usage notes:\n1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n4. The agent's outputs should generally be trusted\n5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.\n\n### Example usage of the general-purpose agent:\n\n<example_agent_descriptions>\n\"general-purpose\": use this agent for general purpose tasks, it has access to all tools as the main agent.\n</example_agent_descriptions>\n\n<example>\nUser: \"I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them.\"\nAssistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*\nAssistant: *Synthesizes the results of the three isolated research tasks and responds to the User*\n<commentary>\nResearch is a complex, multi-step task in it of itself.\nThe research of each individual player is not dependent on the research of the other players.\nThe assistant uses the task tool to break down the complex objective into three isolated tasks.\nEach research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.\nThis means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.\n</commentary>\n</example>\n\n<example>\nUser: \"Analyze a single large code repository for security vulnerabilities and generate a report.\"\nAssistant: *Launches a single \\`task\\` subagent for the repository analysis*\nAssistant: *Receives report and integrates results into final summary*\n<commentary>\nSubagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.\nIf the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.\n</commentary>\n</example>\n\n<example>\nUser: \"Schedule two meetings for me and prepare agendas for each.\"\nAssistant: *Calls the task tool in parallel to launch two \\`task\\` subagents (one per meeting) to prepare agendas*\nAssistant: *Returns final schedules and agendas*\n<commentary>\nTasks are simple individually, but subagents help silo agenda preparation.\nEach subagent only needs to worry about the agenda for one meeting.\n</commentary>\n</example>\n\n<example>\nUser: \"I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\"\nAssistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*\n<commentary>\nThe assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.\nIt is better to just complete the task directly and NOT use the \\`task\\`tool.\n</commentary>\n</example>\n\n### Example usage with custom agents:\n\n<example_agent_descriptions>\n\"content-reviewer\": use this agent after you are done creating significant content or documents\n\"greeting-responder\": use this agent when to respond to user greetings with a friendly joke\n\"research-analyst\": use this agent to conduct thorough research on complex topics\n</example_agent_description>\n\n<example>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: Sure let me write a function that checks if a number is prime\nassistant: First let me use the Write tool to write a function that checks if a number is prime\nassistant: I'm going to use the Write tool to write the following code:\n<code>\nfunction isPrime(n) {\n if (n <= 1) return false\n for (let i = 2; i * i <= n; i++) {\n if (n % i === 0) return false\n }\n return true\n}\n</code>\n<commentary>\nSince significant content was created and the task was completed, now use the content-reviewer agent to review the work\n</commentary>\nassistant: Now let me use the content-reviewer agent to review the code\nassistant: Uses the Task tool to launch with the content-reviewer agent\n</example>\n\n<example>\nuser: \"Can you help me research the environmental impact of different renewable energy sources and create a comprehensive report?\"\n<commentary>\nThis is a complex research task that would benefit from using the research-analyst agent to conduct thorough analysis\n</commentary>\nassistant: I'll help you research the environmental impact of renewable energy sources. Let me use the research-analyst agent to conduct comprehensive research on this topic.\nassistant: Uses the Task tool to launch with the research-analyst agent, providing detailed instructions about what research to conduct and what format the report should take\n</example>\n\n<example>\nuser: \"Hello\"\n<commentary>\nSince the user is greeting, use the greeting-responder agent to respond with a friendly joke\n</commentary>\nassistant: \"I'm going to use the Task tool to launch with the greeting-responder agent\"\n</example>\n `.trim();\n}\n\nconst TASK_SYSTEM_PROMPT = `## \\`task\\` (subagent spawner)\n\nYou have access to a \\`task\\` tool to launch short-lived subagents that handle isolated tasks. These agents are ephemeral — they live only for the duration of the task and return a single result.\n\nWhen to use the task tool:\n- When a task is complex and multi-step, and can be fully delegated in isolation\n- When a task is independent of other tasks and can run in parallel\n- When a task requires focused reasoning or heavy token/context usage that would bloat the orchestrator thread\n- When sandboxing improves reliability (e.g. code execution, structured searches, data formatting)\n- When you only care about the output of the subagent, and not the intermediate steps (ex. performing a lot of research and then returned a synthesized report, performing a series of computations or lookups to achieve a concise, relevant answer.)\n\nSubagent lifecycle:\n1. **Spawn** → Provide clear role, instructions, and expected output\n2. **Run** → The subagent completes the task autonomously\n3. **Return** → The subagent provides a single structured result\n4. **Reconcile** → Incorporate or synthesize the result into the main thread\n\nWhen NOT to use the task tool:\n- If you need to see the intermediate reasoning or steps after the subagent has completed (the task tool hides them)\n- If the task is trivial (a few tool calls or simple lookup)\n- If delegating does not reduce token usage, complexity, or context switching\n- If splitting would add latency without benefit\n\n## Important Task Tool Usage Notes to Remember\n- Whenever possible, parallelize the work that you do. This is true for both tool_calls, and for tasks. Whenever you have independent steps to complete - make tool_calls, or kick off tasks (subagents) in parallel to accomplish them faster. This saves time for the user, which is incredibly important.\n- Remember to use the \\`task\\` tool to silo independent tasks within a multi-part objective.\n- You should use the \\`task\\` tool whenever you have a complex task that will take multiple steps, and is independent from other tasks that the agent needs to complete. These agents are highly competent and efficient.`;\n\n/**\n * Type definitions for pre-compiled agents.\n */\nexport interface CompiledSubAgent {\n /** The name of the agent */\n name: string;\n /** The description of the agent */\n description: string;\n /** The agent instance */\n runnable: AgentClient | Runnable;\n}\n\n/**\n * Type definitions for subagents\n */\nexport interface SubAgent {\n /** The name of the agent */\n name: string;\n /** The description of the agent */\n description: string;\n /** The system prompt to use for the agent */\n systemPrompt: string;\n /** The tools to use for the agent (tool instances, not names). Defaults to defaultTools */\n tools?: StructuredTool[];\n /** The model for the agent. Defaults to default_model */\n model?: LanguageModelLike | string;\n /** Additional middleware to append after default_middleware */\n middleware?: AgentMiddleware[];\n /** The tool configs to use for the agent */\n interruptOn?: Record<string, boolean | InterruptOnConfig>;\n}\n\n/**\n * Filter state to exclude certain keys when passing to subagents\n */\nfunction filterStateForSubagent(\n state: Record<string, unknown>\n): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(state)) {\n if (!EXCLUDED_STATE_KEYS.includes(key as never)) {\n filtered[key] = value;\n }\n }\n return filtered;\n}\n\n/**\n * Create Command with filtered state update from subagent result\n */\nfunction returnCommandWithStateUpdate(\n result: Record<string, unknown>,\n toolCallId: string\n): Command {\n const stateUpdate = filterStateForSubagent(result);\n const messages = result.messages as Array<{ content: string }>;\n const lastMessage = messages?.[messages.length - 1];\n\n return new Command({\n update: {\n ...stateUpdate,\n messages: [\n new ToolMessage({\n content: lastMessage?.content || \"Task completed\",\n tool_call_id: toolCallId,\n name: \"task\",\n }),\n ],\n },\n });\n}\n\n/**\n * Create subagent instances from specifications\n */\nfunction getSubagents(options: {\n defaultModel: LanguageModelLike | string;\n defaultTools: StructuredTool[];\n defaultMiddleware: AgentMiddleware[] | null;\n defaultInterruptOn: Record<string, boolean | InterruptOnConfig> | null;\n subagents: (SubAgent | CompiledSubAgent)[];\n generalPurposeAgent: boolean;\n}): {\n agents: Record<string, ReactAgent<any, any, any, any> | Runnable>;\n descriptions: string[];\n} {\n const {\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n } = options;\n\n const defaultSubagentMiddleware = defaultMiddleware || [];\n const agents: Record<string, ReactAgent<any, any, any, any> | Runnable> = {};\n const subagentDescriptions: string[] = [];\n\n // Create general-purpose agent if enabled\n if (generalPurposeAgent) {\n const generalPurposeMiddleware = [...defaultSubagentMiddleware];\n if (defaultInterruptOn) {\n generalPurposeMiddleware.push(\n humanInTheLoopMiddleware({ interruptOn: defaultInterruptOn })\n );\n }\n\n const generalPurposeSubagent = createAgent({\n model: defaultModel,\n systemPrompt: DEFAULT_SUBAGENT_PROMPT,\n tools: defaultTools as any,\n middleware: generalPurposeMiddleware,\n });\n\n agents[\"general-purpose\"] = generalPurposeSubagent;\n subagentDescriptions.push(\n `- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`\n );\n }\n\n // Process custom subagents\n for (const agentParams of subagents) {\n subagentDescriptions.push(\n `- ${agentParams.name}: ${agentParams.description}`\n );\n\n if (\"runnable\" in agentParams) {\n agents[agentParams.name] = agentParams.runnable;\n } else {\n const middleware = agentParams.middleware\n ? [...defaultSubagentMiddleware, ...agentParams.middleware]\n : [...defaultSubagentMiddleware];\n\n const interruptOn = agentParams.interruptOn || defaultInterruptOn;\n if (interruptOn)\n middleware.push(humanInTheLoopMiddleware({ interruptOn }));\n\n agents[agentParams.name] = createAgent({\n model: agentParams.model ?? defaultModel,\n systemPrompt: agentParams.systemPrompt,\n tools: agentParams.tools ?? defaultTools,\n middleware,\n });\n }\n }\n\n return { agents, descriptions: subagentDescriptions };\n}\n\n/**\n * Create the task tool for invoking subagents\n */\nfunction createTaskTool(options: {\n defaultModel: LanguageModelLike | string;\n defaultTools: StructuredTool[];\n defaultMiddleware: AgentMiddleware[] | null;\n defaultInterruptOn: Record<string, boolean | InterruptOnConfig> | null;\n subagents: (SubAgent | CompiledSubAgent)[];\n generalPurposeAgent: boolean;\n taskDescription: string | null;\n}) {\n const {\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n taskDescription,\n } = options;\n\n const { agents: subagentGraphs, descriptions: subagentDescriptions } =\n getSubagents({\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n });\n\n const finalTaskDescription = taskDescription\n ? taskDescription\n : getTaskToolDescription(subagentDescriptions);\n\n return tool(\n async (\n input: { description: string; subagent_type: string },\n config\n ): Promise<Command | string> => {\n const { description, subagent_type } = input;\n\n // Validate subagent type\n if (!(subagent_type in subagentGraphs)) {\n const allowedTypes = Object.keys(subagentGraphs)\n .map((k) => `\\`${k}\\``)\n .join(\", \");\n throw new Error(\n `Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`\n );\n }\n\n const subagent = subagentGraphs[subagent_type];\n\n // Get current state and filter it for subagent\n const currentState = getCurrentTaskInput<Record<string, unknown>>();\n const subagentState = filterStateForSubagent(currentState);\n subagentState.messages = [new HumanMessage({ content: description })];\n\n // Invoke the subagent\n const result = (await subagent.invoke(subagentState, config)) as Record<\n string,\n unknown\n >;\n\n // Return command with filtered state update\n if (!config.toolCall?.id) {\n throw new Error(\"Tool call ID is required for subagent invocation\");\n }\n\n return returnCommandWithStateUpdate(result, config.toolCall.id);\n },\n {\n name: \"task\",\n description: finalTaskDescription,\n schema: z.object({\n description: z\n .string()\n .describe(\"The task to execute with the selected agent\"),\n subagent_type: z\n .string()\n .describe(\n `Name of the agent to use. Available: ${Object.keys(\n subagentGraphs\n ).join(\", \")}`\n ),\n }),\n }\n );\n}\n\n/**\n * Options for creating subagent middleware\n */\nexport interface SubAgentMiddlewareOptions {\n /** The model to use for subagents */\n defaultModel: LanguageModelLike | string;\n /** The tools to use for the default general-purpose subagent */\n defaultTools?: StructuredTool[];\n /** Default middleware to apply to all subagents */\n defaultMiddleware?: AgentMiddleware[] | null;\n /** The tool configs for the default general-purpose subagent */\n defaultInterruptOn?: Record<string, boolean | InterruptOnConfig> | null;\n /** A list of additional subagents to provide to the agent */\n subagents?: (SubAgent | CompiledSubAgent)[];\n /** Full system prompt override */\n systemPrompt?: string | null;\n /** Whether to include the general-purpose agent */\n generalPurposeAgent?: boolean;\n /** Custom description for the task tool */\n taskDescription?: string | null;\n}\n\n/**\n * Create subagent middleware with task tool\n */\nexport function createSubAgentMiddleware(\n options: SubAgentMiddlewareOptions\n): AgentMiddleware {\n const {\n defaultModel,\n defaultTools = [],\n defaultMiddleware = null,\n defaultInterruptOn = null,\n subagents = [],\n systemPrompt = TASK_SYSTEM_PROMPT,\n generalPurposeAgent = true,\n taskDescription = null,\n } = options;\n\n const taskTool = createTaskTool({\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n taskDescription,\n });\n\n return createMiddleware({\n name: \"subAgentMiddleware\",\n tools: [taskTool],\n wrapModelCall: async (request, handler) => {\n if (systemPrompt !== null) {\n const currentPrompt = request.systemPrompt || \"\";\n const newPrompt = currentPrompt\n ? `${currentPrompt}\\n\\n${systemPrompt}`\n : systemPrompt;\n\n return handler({\n ...request,\n systemPrompt: newPrompt,\n });\n }\n return handler(request);\n },\n });\n}\n","import {\n createMiddleware,\n AgentMiddleware,\n ToolMessage,\n AIMessage,\n} from \"langchain\";\nimport { RemoveMessage } from \"@langchain/core/messages\";\nimport { REMOVE_ALL_MESSAGES } from \"@langchain/langgraph\";\n\n/**\n * Create middleware that patches dangling tool calls in the messages history.\n *\n * When an AI message contains tool_calls but subsequent messages don't include\n * the corresponding ToolMessage responses, this middleware adds synthetic\n * ToolMessages saying the tool call was cancelled.\n *\n * @returns AgentMiddleware that patches dangling tool calls\n *\n * @example\n * ```typescript\n * import { createAgent } from \"langchain\";\n * import { createPatchToolCallsMiddleware } from \"./middleware/patch_tool_calls\";\n *\n * const agent = createAgent({\n * model: \"claude-sonnet-4-5-20250929\",\n * middleware: [createPatchToolCallsMiddleware()],\n * });\n * ```\n */\nexport function createPatchToolCallsMiddleware(): AgentMiddleware {\n return createMiddleware({\n name: \"patchToolCallsMiddleware\",\n beforeAgent: async (state) => {\n const messages = state.messages;\n\n if (!messages || messages.length === 0) {\n return;\n }\n\n const patchedMessages: any[] = [];\n\n // Iterate over the messages and add any dangling tool calls\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n patchedMessages.push(msg);\n\n // Check if this is an AI message with tool calls\n if (AIMessage.isInstance(msg) && msg.tool_calls != null) {\n for (const toolCall of msg.tool_calls) {\n // Look for a corresponding ToolMessage in the messages after this one\n const correspondingToolMsg = messages\n .slice(i)\n .find(\n (m: any) =>\n ToolMessage.isInstance(m) && m.tool_call_id === toolCall.id\n );\n\n if (!correspondingToolMsg) {\n // We have a dangling tool call which needs a ToolMessage\n const toolMsg = `Tool call ${toolCall.name} with id ${toolCall.id} was cancelled - another message came in before it could be completed.`;\n patchedMessages.push(\n new ToolMessage({\n content: toolMsg,\n name: toolCall.name,\n tool_call_id: toolCall.id!,\n })\n );\n }\n }\n }\n }\n\n // Return state update with RemoveMessage followed by patched messages\n return {\n messages: [\n new RemoveMessage({ id: REMOVE_ALL_MESSAGES }),\n ...patchedMessages,\n ],\n };\n },\n });\n}\n","/**\n * FilesystemBackend: Read and write files directly from the filesystem.\n *\n * Security and search upgrades:\n * - Secure path resolution with root containment when in virtual_mode (sandboxed to cwd)\n * - Prevent symlink-following on file I/O using O_NOFOLLOW when available\n * - Ripgrep-powered grep with JSON parsing, plus regex fallback\n * and optional glob include filtering, while preserving virtual path behavior\n */\n\nimport * as fs from \"fs/promises\";\nimport * as fsSync from \"fs\";\nimport * as path from \"path\";\nimport { spawn } from \"child_process\";\nimport fg from \"fast-glob\";\nimport micromatch from \"micromatch\";\nimport type {\n BackendProtocol,\n EditResult,\n FileData,\n FileInfo,\n GrepMatch,\n WriteResult,\n} from \"./protocol.js\";\nimport {\n checkEmptyContent,\n formatContentWithLineNumbers,\n performStringReplacement,\n} from \"./utils.js\";\n\nconst SUPPORTS_NOFOLLOW = fsSync.constants.O_NOFOLLOW !== undefined;\n\n/**\n * Backend that reads and writes files directly from the filesystem.\n *\n * Files are accessed using their actual filesystem paths. Relative paths are\n * resolved relative to the current working directory. Content is read/written\n * as plain text, and metadata (timestamps) are derived from filesystem stats.\n */\nexport class FilesystemBackend implements BackendProtocol {\n private cwd: string;\n private virtualMode: boolean;\n private maxFileSizeBytes: number;\n\n constructor(\n options: {\n rootDir?: string;\n virtualMode?: boolean;\n maxFileSizeMb?: number;\n } = {}\n ) {\n const { rootDir, virtualMode = false, maxFileSizeMb = 10 } = options;\n this.cwd = rootDir ? path.resolve(rootDir) : process.cwd();\n this.virtualMode = virtualMode;\n this.maxFileSizeBytes = maxFileSizeMb * 1024 * 1024;\n }\n\n /**\n * Resolve a file path with security checks.\n *\n * When virtualMode=true, treat incoming paths as virtual absolute paths under\n * this.cwd, disallow traversal (.., ~) and ensure resolved path stays within root.\n * When virtualMode=false, preserve legacy behavior: absolute paths are allowed\n * as-is; relative paths resolve under cwd.\n *\n * @param key - File path (absolute, relative, or virtual when virtualMode=true)\n * @returns Resolved absolute path string\n * @throws Error if path traversal detected or path outside root\n */\n private resolvePath(key: string): string {\n if (this.virtualMode) {\n const vpath = key.startsWith(\"/\") ? key : \"/\" + key;\n if (vpath.includes(\"..\") || vpath.startsWith(\"~\")) {\n throw new Error(\"Path traversal not allowed\");\n }\n const full = path.resolve(this.cwd, vpath.substring(1));\n const relative = path.relative(this.cwd, full);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path: ${full} outside root directory: ${this.cwd}`);\n }\n return full;\n }\n\n if (path.isAbsolute(key)) {\n return key;\n }\n return path.resolve(this.cwd, key);\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param dirPath - Absolute directory path to list files from\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n async lsInfo(dirPath: string): Promise<FileInfo[]> {\n try {\n const resolvedPath = this.resolvePath(dirPath);\n const stat = await fs.stat(resolvedPath);\n\n if (!stat.isDirectory()) {\n return [];\n }\n\n const entries = await fs.readdir(resolvedPath, { withFileTypes: true });\n const results: FileInfo[] = [];\n\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n\n for (const entry of entries) {\n const fullPath = path.join(resolvedPath, entry.name);\n\n try {\n const entryStat = await fs.stat(fullPath);\n const isFile = entryStat.isFile();\n const isDir = entryStat.isDirectory();\n\n if (!this.virtualMode) {\n // Non-virtual mode: use absolute paths\n if (isFile) {\n results.push({\n path: fullPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: fullPath + path.sep,\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n } else {\n let relativePath: string;\n if (fullPath.startsWith(cwdStr)) {\n relativePath = fullPath.substring(cwdStr.length);\n } else if (fullPath.startsWith(this.cwd)) {\n relativePath = fullPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = fullPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virtPath = \"/\" + relativePath;\n\n if (isFile) {\n results.push({\n path: virtPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: virtPath + \"/\",\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n }\n } catch {\n // Skip entries we can't stat\n continue;\n }\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return results;\n } catch {\n return [];\n }\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute or relative file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n async read(\n filePath: string,\n offset: number = 0,\n limit: number = 2000\n ): Promise<string> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return `Error: File '${filePath}' not found`;\n }\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return `Error: Symlinks are not allowed: ${filePath}`;\n }\n if (!stat.isFile()) {\n return `Error: File '${filePath}' not found`;\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const emptyMsg = checkEmptyContent(content);\n if (emptyMsg) {\n return emptyMsg;\n }\n\n const lines = content.split(\"\\n\");\n const startIdx = offset;\n const endIdx = Math.min(startIdx + limit, lines.length);\n\n if (startIdx >= lines.length) {\n return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;\n }\n\n const selectedLines = lines.slice(startIdx, endIdx);\n return formatContentWithLineNumbers(selectedLines, startIdx + 1);\n } catch (e: any) {\n return `Error reading file '${filePath}': ${e.message}`;\n }\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns Raw file content as FileData\n */\n async readRaw(filePath: string): Promise<FileData> {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n let stat: fsSync.Stats;\n\n if (SUPPORTS_NOFOLLOW) {\n stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) throw new Error(`File '${filePath}' not found`);\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n throw new Error(`Symlinks are not allowed: ${filePath}`);\n }\n if (!stat.isFile()) throw new Error(`File '${filePath}' not found`);\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n return {\n content: content.split(\"\\n\"),\n created_at: stat.ctime.toISOString(),\n modified_at: stat.mtime.toISOString(),\n };\n }\n\n /**\n * Create a new file with content.\n * Returns WriteResult. External storage sets filesUpdate=null.\n */\n async write(filePath: string, content: string): Promise<WriteResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n try {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return {\n error: `Cannot write to ${filePath} because it is a symlink. Symlinks are not allowed.`,\n };\n }\n return {\n error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`,\n };\n } catch {\n // File doesn't exist, good to proceed\n }\n\n await fs.mkdir(path.dirname(resolvedPath), { recursive: true });\n\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_CREAT |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags, 0o644);\n try {\n await fd.writeFile(content, \"utf-8\");\n } finally {\n await fd.close();\n }\n } else {\n await fs.writeFile(resolvedPath, content, \"utf-8\");\n }\n\n return { path: filePath, filesUpdate: null };\n } catch (e: any) {\n return { error: `Error writing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Edit a file by replacing string occurrences.\n * Returns EditResult. External storage sets filesUpdate=null.\n */\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false\n ): Promise<EditResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return { error: `Error: Symlinks are not allowed: ${filePath}` };\n }\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const result = performStringReplacement(\n content,\n oldString,\n newString,\n replaceAll\n );\n\n if (typeof result === \"string\") {\n return { error: result };\n }\n\n const [newContent, occurrences] = result;\n\n // Write securely\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags);\n try {\n await fd.writeFile(newContent, \"utf-8\");\n } finally {\n await fd.close();\n }\n } else {\n await fs.writeFile(resolvedPath, newContent, \"utf-8\");\n }\n\n return { path: filePath, filesUpdate: null, occurrences: occurrences };\n } catch (e: any) {\n return { error: `Error editing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Structured search results or error string for invalid input.\n */\n async grepRaw(\n pattern: string,\n dirPath: string = \"/\",\n glob: string | null = null\n ): Promise<GrepMatch[] | string> {\n // Validate regex\n try {\n new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n // Resolve base path\n let baseFull: string;\n try {\n baseFull = this.resolvePath(dirPath || \".\");\n } catch {\n return [];\n }\n\n try {\n await fs.stat(baseFull);\n } catch {\n return [];\n }\n\n // Try ripgrep first, fallback to regex search\n let results = await this.ripgrepSearch(pattern, baseFull, glob);\n if (results === null) {\n results = await this.pythonSearch(pattern, baseFull, glob);\n }\n\n const matches: GrepMatch[] = [];\n for (const [fpath, items] of Object.entries(results)) {\n for (const [lineNum, lineText] of items) {\n matches.push({ path: fpath, line: lineNum, text: lineText });\n }\n }\n return matches;\n }\n\n /**\n * Try to use ripgrep for fast searching.\n * Returns null if ripgrep is not available or fails.\n */\n private async ripgrepSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null\n ): Promise<Record<string, Array<[number, string]>> | null> {\n return new Promise((resolve) => {\n const args = [\"--json\"];\n if (includeGlob) {\n args.push(\"--glob\", includeGlob);\n }\n args.push(\"--\", pattern, baseFull);\n\n const proc = spawn(\"rg\", args, { timeout: 30000 });\n const results: Record<string, Array<[number, string]>> = {};\n let output = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n output += data.toString();\n });\n\n proc.on(\"close\", (code) => {\n if (code !== 0 && code !== 1) {\n // Error (code 1 means no matches, which is ok)\n resolve(null);\n return;\n }\n\n for (const line of output.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const data = JSON.parse(line);\n if (data.type !== \"match\") continue;\n\n const pdata = data.data || {};\n const ftext = pdata.path?.text;\n if (!ftext) continue;\n\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const resolved = path.resolve(ftext);\n const relative = path.relative(this.cwd, resolved);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = ftext;\n }\n\n const ln = pdata.line_number;\n const lt = pdata.lines?.text?.replace(/\\n$/, \"\") || \"\";\n if (ln === undefined) continue;\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([ln, lt]);\n } catch {\n // Skip invalid JSON\n continue;\n }\n }\n\n resolve(results);\n });\n\n proc.on(\"error\", () => {\n resolve(null);\n });\n });\n }\n\n /**\n * Fallback regex search implementation.\n */\n private async pythonSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null\n ): Promise<Record<string, Array<[number, string]>>> {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch {\n return {};\n }\n\n const results: Record<string, Array<[number, string]>> = {};\n const stat = await fs.stat(baseFull);\n const root = stat.isDirectory() ? baseFull : path.dirname(baseFull);\n\n // Use fast-glob to recursively find all files\n const files = await fg(\"**/*\", {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const fp of files) {\n try {\n // Filter by glob if provided\n if (\n includeGlob &&\n !micromatch.isMatch(path.basename(fp), includeGlob)\n ) {\n continue;\n }\n\n // Check file size\n const stat = await fs.stat(fp);\n if (stat.size > this.maxFileSizeBytes) {\n continue;\n }\n\n // Read and search\n const content = await fs.readFile(fp, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (regex.test(line)) {\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const relative = path.relative(this.cwd, fp);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = fp;\n }\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([i + 1, line]);\n }\n }\n } catch {\n // Skip files we can't read\n continue;\n }\n }\n\n return results;\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n */\n async globInfo(\n pattern: string,\n searchPath: string = \"/\"\n ): Promise<FileInfo[]> {\n if (pattern.startsWith(\"/\")) {\n pattern = pattern.substring(1);\n }\n\n const resolvedSearchPath =\n searchPath === \"/\" ? this.cwd : this.resolvePath(searchPath);\n\n try {\n const stat = await fs.stat(resolvedSearchPath);\n if (!stat.isDirectory()) {\n return [];\n }\n } catch {\n return [];\n }\n\n const results: FileInfo[] = [];\n\n try {\n // Use fast-glob for pattern matching\n const matches = await fg(pattern, {\n cwd: resolvedSearchPath,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const matchedPath of matches) {\n try {\n const stat = await fs.stat(matchedPath);\n if (!stat.isFile()) continue;\n\n // Normalize fast-glob paths to platform separators\n // fast-glob returns forward slashes on all platforms, but we need\n // platform-native separators for path comparisons on Windows\n const normalizedPath = matchedPath.split(\"/\").join(path.sep);\n\n if (!this.virtualMode) {\n results.push({\n path: normalizedPath,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n } else {\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n let relativePath: string;\n\n if (normalizedPath.startsWith(cwdStr)) {\n relativePath = normalizedPath.substring(cwdStr.length);\n } else if (normalizedPath.startsWith(this.cwd)) {\n relativePath = normalizedPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = normalizedPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virt = \"/\" + relativePath;\n results.push({\n path: virt,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n }\n } catch {\n // Skip files we can't stat\n continue;\n }\n }\n } catch {\n // Ignore glob errors\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return results;\n }\n}\n","import { Command } from \"@langchain/langgraph\";\nimport { z } from \"zod\";\nimport { createMiddleware, tool, ToolMessage } from \"langchain\";\nimport { genUIMarkdown } from \"../../util/genUIMarkdown\";\n\nconst WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.\nIt also helps the user understand the progress of the task and overall progress of their requests.\nOnly use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.\n\n## When to Use This Tool\nUse this tool in these scenarios:\n\n1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions\n2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations\n3. User explicitly requests todo list - When the user directly asks you to use the todo list\n4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)\n5. The plan may need future revisions or updates based on results from the first few steps. Keeping track of this in a list is helpful.\n\n## How to Use This Tool\n1. When you start working on a task - Mark it as in_progress BEFORE beginning work.\n2. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation.\n3. You can also update future tasks, such as deleting them if they are no longer necessary, or adding new tasks that are necessary. Don't change previously completed tasks.\n4. You can make several updates to the todo list at once. For example, when you complete a task, you can mark the next task you need to start as in_progress.\n\n## When NOT to Use This Tool\nIt is important to skip using this tool when:\n1. There is only a single, straightforward task\n2. The task is trivial and tracking it provides no benefit\n3. The task can be completed in less than 3 trivial steps\n4. The task is purely conversational or informational\n\n## Examples of When to Use the Todo List\n\n<example>\nUser: I want to add a dark mode toggle to the application settings. Make sure you run the tests and build when you're done!\nAssistant: I'll help add a dark mode toggle to your application settings. Let me create a todo list to track this implementation.\n*Creates todo list with the following items:*\n1. Create dark mode toggle component in Settings page\n2. Add dark mode state management (context/store)\n3. Implement CSS-in-JS styles for dark theme\n4. Update existing components to support theme switching\n5. Run tests and build process, addressing any failures or errors that occur\n*Begins working on the first task*\n\n<reasoning>\nThe assistant used the todo list because:\n1. Adding dark mode in it of itself is a multi-step feature requiring UI, state management, and styling changes\n2. The assistant inferred that tests and build need to pass by adding \"Ensure tests and build succeed\" as the final task\n3. Both of the user's requests are complex and require multiple steps to complete.\n</reasoning>\n</example>\n\n<example>\nUser: Help me plan a comprehensive marketing campaign for our new product launch, including social media, email marketing, and press releases.\nAssistant: I'll help you plan a comprehensive marketing campaign for your product launch. Let me create a todo list to organize all the components.\n*Creates todo list with the following items:*\n1. Define target audience and key messaging\n2. Create social media content calendar and posting schedule\n3. Design email marketing sequence and automation flows\n4. Draft press release and identify media contacts\n5. Set up tracking and analytics for campaign performance\n6. Create visual assets and brand materials\n7. Coordinate launch timeline and deliverables\n*Begins working on the first task*\n\n<reasoning>\nThe assistant used the todo list because:\n1. Marketing campaign planning involves multiple distinct channels and activities\n2. Each component requires careful coordination and planning\n3. The systematic approach ensures all aspects of the launch are covered\n</reasoning>\n</example>\n\n<example>\nUser: Help me rename the function getCwd to getCurrentWorkingDirectory across my project\nAssistant: Let me first search through your codebase to find all occurrences of 'getCwd'.\n*Uses search tools to locate all instances of getCwd in the codebase*\nAssistant: I've found 15 instances of 'getCwd' across 8 different files. Let me create a todo list to track these changes.\n*Creates todo list with specific items for each file that needs updating*\n\n<reasoning>\nThe assistant used the todo list because:\n1. The assistant searched to understand the scope of the task\n2. Upon finding multiple occurrences across different files, it determined this was a complex task with multiple steps (>3)\n3. The todo list helps ensure every instance is tracked and updated systematically\n4. This approach prevents missing any occurrences and maintains consistency.\n</reasoning>\n</example>\n\n<example>\nUser: I need help organizing my home office: decluttering the desk, setting up a filing system, organizing digital files, and creating a daily workflow.\nAssistant: I'll help you organize your home office systematically. Let me create a todo list to track each area of organization.\n*Creates todo list with items like: 1) Sort and declutter desk items, 2) Set up physical filing system for documents, 3) Organize digital files and folders, 4) Create daily workflow and productivity systems, 5) Establish maintenance routines*\nLet's start with decluttering your desk space to create a clean foundation for the other organizational systems.\n\n<reasoning>\nThe assistant used the todo list because:\n1. The user provided multiple distinct organizational tasks\n2. Each area requires different approaches and careful planning\n3. Home organization benefits from systematic, step-by-step completion\n4. Progress tracking ensures all areas are addressed thoroughly\n</reasoning>\n</example>\n\n## Examples of When NOT to Use the Todo List\n\n<example>\nUser: How do I print 'Hello World' in Python?\nAssistant: In Python, you can print \"Hello World\" with this simple code:\n\n\\`\\`\\`python\nprint(\"Hello World\")\n\\`\\`\\`\n\nThis will output the text \"Hello World\" to the console when executed.</assistant>\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, trivial task that can be completed in one step. There's no need to track multiple tasks or steps for such a straightforward request.\n</reasoning>\n</example>\n\n<example>\nUser: What's the best way to water houseplants?\nAssistant: The best way to water houseplants depends on the specific plant type, but here are some general guidelines:\n\n- Check soil moisture by inserting your finger about 1-2 inches into the soil\n- Water thoroughly when the top inch feels dry, allowing water to drain from the bottom\n- Use room temperature water and water in the morning when possible\n- Avoid overwatering, which is more harmful than underwatering for most plants\n\nDifferent plants have different needs, so it's important to research your specific varieties for optimal care.\n\n<reasoning>\nThe assistant did not use the todo list because this is an informational request with no actual tasks to complete. The user is simply asking for advice and explanation, not for the assistant to perform multiple steps or activities.\n</reasoning>\n</example>\n\n<example>\nUser: Can you add a comment to the calculateTotal function to explain what it does?\nAssistant: Sure, let me add a comment to the calculateTotal function to explain what it does.\n* Uses the Edit tool to add a comment to the calculateTotal function *\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, straightforward task confined to one location. Adding a comment doesn't require tracking multiple steps or systematic organization.\n</reasoning>\n</example>\n\n<example>\nUser: What time is it in Tokyo right now?\nAssistant: I'll check the current time in Tokyo for you.\n\n*Searches for current time in Tokyo*\n\nThe current time in Tokyo, Japan is [current time]. Tokyo is in the Japan Standard Time (JST) zone, which is UTC+9.\n\n<reasoning>\nThe assistant did not use the todo list because this is a single information lookup with immediate results. There are no multiple steps to track or organize, making the todo list unnecessary for this straightforward request.\n</reasoning>\n</example>\n\n<example>\nUser: I need to write a function that checks if a number is prime and then test it out.\nAssistant: I'll help you write a function that checks if a number is prime and then test it out.\n*Writes function that checks if a number is prime*\n*Tests the function*\n\n<reasoning>\nEven though this is a multi-step task, it is very straightforward and can be completed in two trivial steps (which is less than 3 steps!). Using the todo list here is overkill and wastes time and tokens.\n</reasoning>\n</example>\n\n<example>\nUser: I want you to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\nAssistant: I'll help you order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\n*Orders a pizza from Dominos*\n*Orders a burger from McDonald's*\n*Orders a salad from Subway*\n\n<reasoning>\nEven though this is a multi-step task, assuming the assistant has the ability to order from these restaurants, it is very straightforward and can be completed in three trivial tool calls. \nUsing the todo list here is overkill and wastes time and tokens. These three tool calls should be made in parallel, in fact.\n</reasoning>\n</example>\n\n\n## Task States and Management\n\n1. **Task States**: Use these states to track progress:\n - pending: Task not yet started\n - in_progress: Currently working on (you can have multiple tasks in_progress at a time if they are not related to each other and can be run in parallel)\n - completed: Task finished successfully\n\n2. **Task Management**:\n - Update task status in real-time as you work\n - Mark tasks complete IMMEDIATELY after finishing (don't batch completions)\n - Complete current tasks before starting new ones\n - Remove tasks that are no longer relevant from the list entirely\n - IMPORTANT: When you write this todo list, you should mark your first task (or tasks) as in_progress immediately!.\n - IMPORTANT: Unless all tasks are completed, you should always have at least one task in_progress to show the user that you are working on something.\n\n3. **Task Completion Requirements**:\n - ONLY mark a task as completed when you have FULLY accomplished it\n - If you encounter errors, blockers, or cannot finish, keep the task as in_progress\n - When blocked, create a new task describing what needs to be resolved\n - Never mark a task as completed if:\n - There are unresolved issues or errors\n - Work is partial or incomplete\n - You encountered blockers that prevent completion\n - You couldn't find necessary resources or dependencies\n - Quality standards haven't been met\n\n4. **Task Breakdown**:\n - Create specific, actionable items\n - Break complex tasks into smaller, manageable steps\n - Use clear, descriptive task names\n\nBeing proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully\nRemember: If you only need to make a few tool calls to complete a task, and it is clear what you need to do, it is better to just do the task directly and NOT call this tool at all.`;\nconst TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = `## \\`write_todos\\`\n\nYou have access to the \\`write_todos\\` tool to help you manage and plan complex objectives. \nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\n\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\n\n## Important To-Do List Usage Notes to Remember\n- The \\`write_todos\\` tool should never be called multiple times in parallel.\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;\nconst TodoStatus = z\n .enum([\"pending\", \"in_progress\", \"completed\"])\n .describe(\"Status of the todo\");\nconst TodoSchema = z.object({\n content: z.string().describe(\"Content of the todo item\"),\n status: TodoStatus,\n});\nconst stateSchema = z.object({ todos: z.array(TodoSchema).default([]) });\n\nexport function todoListMiddleware(options?: {\n systemPrompt?: string;\n toolDescription?: string;\n}) {\n /**\n * Write todos tool - manages todo list with Command return\n */\n const writeTodos = tool(\n ({ todos }, config) => {\n return new Command({\n update: {\n todos,\n messages: [\n new ToolMessage({\n content: genUIMarkdown(\"todo_list\", todos),\n tool_call_id: config.toolCall?.id,\n }),\n ],\n },\n });\n },\n {\n name: \"write_todos\",\n description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,\n schema: z.object({\n todos: z.array(TodoSchema).describe(\"List of todo items to update\"),\n }),\n }\n );\n return createMiddleware({\n name: \"todoListMiddleware\",\n stateSchema,\n tools: [writeTodos],\n wrapModelCall: (request, handler) =>\n handler({\n ...request,\n systemPrompt:\n (request.systemPrompt ? `${request.systemPrompt}\\n\\n` : \"\") +\n (options?.systemPrompt ?? TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT),\n }),\n });\n}\n","/**\n * Deep Agent Graph Builder\n *\n * 实现 Deep Agent 类型的 Agent Graph 构建\n */\n\nimport { CompiledStateGraph } from \"@langchain/langgraph\";\nimport { DynamicTool } from \"@langchain/core/tools\";\nimport { createDeepAgent } from \"../../deep_agent_new/agent\";\nimport { AgentLattice, AgentBuildParams, AgentClient } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { getToolClient } from \"../../tool_lattice/ToolLatticeManager\";\nimport { ReactAgent } from \"langchain\";\nimport { createAgentClientFromAgentLattice } from \"@agent_lattice/AgentLatticeManager\";\nimport { getCheckpointSaver } from \"@memory_lattice/MemoryLatticeManager\";\n\nexport class DeepAgentGraphBuilder implements AgentGraphBuilder {\n /**\n * 构建Deep Agent Graph\n *\n * @param agentLattice Agent Lattice对象\n * @param params Agent构建参数\n * @returns 返回CompiledGraph对象\n */\n build(agentLattice: AgentLattice, params: AgentBuildParams): AgentClient {\n const tools = params.tools\n .map((t) => {\n const toolClient = getToolClient(t.key);\n\n return toolClient;\n })\n .filter((tool) => tool !== undefined);\n\n const subagents = params.subAgents.map((sa) => {\n if (sa.client) {\n return {\n name: sa.config.name,\n description: sa.config.description,\n runnable: sa.client,\n };\n } else {\n const subagentClient = createAgentClientFromAgentLattice({\n config: sa.config,\n });\n return {\n name: sa.config.name,\n description: sa.config.description,\n runnable: subagentClient,\n };\n }\n });\n\n const deepAgent = createDeepAgent({\n tools: tools,\n model: params.model,\n contextSchema: params.stateSchema,\n systemPrompt: params.prompt,\n subagents,\n checkpointer: getCheckpointSaver(\"default\"),\n });\n return deepAgent;\n }\n}\n","/**\n * Agent Graph Builder Factory\n *\n * 工厂类,根据Agent类型创建对应的Builder\n */\n\nimport { AgentType } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { ReActAgentGraphBuilder } from \"./ReActAgentGraphBuilder\";\nimport { DeepAgentGraphBuilder } from \"./DeepAgentGraphBuilder\";\n\nexport class AgentGraphBuilderFactory {\n // 单例模式\n private static instance: AgentGraphBuilderFactory;\n\n // Builder缓存\n private builders: Map<AgentType, AgentGraphBuilder>;\n\n private constructor() {\n this.builders = new Map();\n this.registerDefaultBuilders();\n }\n\n /**\n * 获取单例实例\n */\n public static getInstance(): AgentGraphBuilderFactory {\n if (!AgentGraphBuilderFactory.instance) {\n AgentGraphBuilderFactory.instance = new AgentGraphBuilderFactory();\n }\n return AgentGraphBuilderFactory.instance;\n }\n\n /**\n * 注册默认的Builder\n */\n private registerDefaultBuilders(): void {\n this.builders.set(AgentType.REACT, new ReActAgentGraphBuilder());\n this.builders.set(AgentType.DEEP_AGENT, new DeepAgentGraphBuilder());\n }\n\n /**\n * 注册自定义Builder\n *\n * @param type Agent类型\n * @param builder Builder实例\n */\n public registerBuilder(type: AgentType, builder: AgentGraphBuilder): void {\n this.builders.set(type, builder);\n }\n\n /**\n * 获取Builder\n *\n * @param type Agent类型\n * @returns 返回对应的Builder\n */\n public getBuilder(type: AgentType): AgentGraphBuilder {\n const builder = this.builders.get(type);\n if (!builder) {\n throw new Error(`不支持的Agent类型: ${type}`);\n }\n return builder;\n }\n}\n","/**\n * Agent parameters builder\n *\n * responsible for preparing the parameters required for building the Agent\n */\n\nimport { toolLatticeManager } from \"../../tool_lattice/ToolLatticeManager\";\nimport { modelLatticeManager } from \"../../model_lattice/ModelLatticeManager\";\nimport { AgentLattice, AgentBuildParams, GraphBuildOptions } from \"../types\";\nimport {\n getToolsFromConfig,\n getSubAgentsFromConfig,\n isDeepAgentConfig,\n AgentConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Get Agent Lattice function type\n */\nexport type GetAgentLatticeFunction = (key: string) => AgentLattice | undefined;\n\n/**\n * Agent parameters builder\n */\nexport class AgentParamsBuilder {\n private getAgentLatticeFunc: GetAgentLatticeFunction;\n\n /**\n * constructor\n *\n * @param getAgentLatticeFunc get Agent Lattice function\n */\n constructor(getAgentLatticeFunc: GetAgentLatticeFunction) {\n this.getAgentLatticeFunc = getAgentLatticeFunc;\n }\n\n /**\n * build Agent parameters\n *\n * @param agentLattice Agent Lattice object\n * @param options build options\n * @returns Agent build parameters\n */\n public buildParams(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentBuildParams {\n // get tools (use type-safe helper)\n const toolKeys =\n options?.overrideTools || getToolsFromConfig(agentLattice.config);\n const tools = toolKeys.map((toolKey: string) => {\n const toolLattice = toolLatticeManager.getToolLattice(toolKey);\n if (!toolLattice) {\n throw new Error(`Tool \"${toolKey}\" does not exist`);\n }\n return {\n key: toolKey,\n definition: toolLattice.config,\n executor: toolLattice.client,\n };\n });\n\n // get model\n const modelKey = options?.overrideModel || agentLattice.config.modelKey;\n const model = modelKey\n ? modelLatticeManager.getModelLattice(modelKey).client\n : modelLatticeManager.getModelLattice(\"default\").client;\n if (!model) {\n throw new Error(`Model \"${modelKey}\" does not exist`);\n }\n\n // get subAgents (use type-safe helper - only DeepAgentConfig has subAgents)\n const subAgentKeys = getSubAgentsFromConfig(agentLattice.config);\n const subAgents = subAgentKeys.map((agentKey: string) => {\n const subAgentLattice = this.getAgentLatticeFunc(agentKey);\n if (!subAgentLattice) {\n throw new Error(`SubAgent \"${agentKey}\" does not exist`);\n }\n return {\n key: agentKey,\n config: subAgentLattice.config,\n client: subAgentLattice.client,\n };\n });\n let internalSubAgents: any[] = [];\n if (isDeepAgentConfig(agentLattice.config)) {\n internalSubAgents =\n agentLattice.config.internalSubAgents?.map((i) => ({\n key: i.key,\n config: i,\n })) || [];\n }\n\n return {\n tools,\n model,\n subAgents: [...subAgents, ...internalSubAgents],\n prompt: agentLattice.config.prompt,\n stateSchema: agentLattice.config.schema,\n };\n }\n}\n","import { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport {\n AgentConfig,\n AgentClient,\n AgentLattice,\n GraphBuildOptions,\n AgentBuildParams,\n} from \"./types\";\nimport { AgentGraphBuilderFactory } from \"./builders/AgentGraphBuilderFactory\";\nimport { AgentParamsBuilder } from \"./builders/AgentParamsBuilder\";\nimport \"../tool_lattice\";\n// 类型定义已移至 ./types.ts\n\n/**\n * AgentLatticeManager - 单例Agent Lattice管理器\n * 负责注册、管理各种Agent Lattice\n */\nexport class AgentLatticeManager extends BaseLatticeManager<AgentLattice> {\n private static _instance: AgentLatticeManager;\n\n /**\n * 获取AgentLatticeManager单例实例\n */\n public static getInstance(): AgentLatticeManager {\n if (!AgentLatticeManager._instance) {\n AgentLatticeManager._instance = new AgentLatticeManager();\n }\n return AgentLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"agents\";\n }\n\n /**\n * 注册Agent Lattice\n * @param config Agent配置\n */\n public registerLattice(config: AgentConfig): void {\n // 创建Agent Lattice对象\n const agentLattice: AgentLattice = {\n config,\n client: undefined, // 客户端将在需要时由initializeClient创建\n };\n\n // 调用基类的register方法\n this.register(config.key, agentLattice);\n }\n\n /**\n * 获取AgentLattice\n * @param key Lattice键名\n */\n public getAgentLattice(key: string): AgentLattice | undefined {\n return this.get(key);\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): AgentLattice[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 获取Agent配置\n * @param key Lattice键名\n */\n public getAgentConfig(key: string): AgentConfig | undefined {\n return this.getAgentLattice(key)?.config;\n }\n\n /**\n * 获取所有Agent配置\n */\n public getAllAgentConfigs(): AgentConfig[] {\n return this.getAllLattices().map((lattice) => lattice.config);\n }\n\n /**\n * 验证Agent输入参数\n * @param key Lattice键名\n * @param input 输入参数\n */\n public validateAgentInput(key: string, input: any): boolean {\n const agentLattice = this.getAgentLattice(key);\n if (!agentLattice) {\n return false;\n }\n\n try {\n if (agentLattice.config.schema) {\n agentLattice.config.schema.parse(input);\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 构建Agent参数\n *\n * @param agentLattice Agent Lattice对象\n * @param options 构建选项\n * @returns 返回Agent构建参数\n */\n private buildAgentParams(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentBuildParams {\n // 创建参数构建器\n const paramsBuilder = new AgentParamsBuilder((key: string) => {\n this.initializeClient(key);\n return this.getAgentLattice(key);\n });\n\n // 构建参数\n return paramsBuilder.buildParams(agentLattice, options);\n }\n\n /**\n * Create an AgentClient from AgentLattice config\n *\n * @param agentLattice Agent Lattice object\n * @param options Build options\n * @returns AgentClient instance\n */\n public createAgentClientFromConfig(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentClient {\n // Get factory instance\n const factory = AgentGraphBuilderFactory.getInstance();\n\n // Get the builder for the agent type\n const builder = factory.getBuilder(agentLattice.config.type);\n\n // Build params\n const params = this.buildAgentParams(agentLattice, options);\n\n // Use builder to build the graph\n return builder.build(agentLattice, params);\n }\n\n /**\n * 初始化Agent客户端\n *\n * 使用AgentGraphBuilderFactory构建Graph并设置为客户端\n *\n * @param key Lattice键名\n * @param options 构建选项\n * @returns 返回CompiledGraph对象\n */\n public initializeClient(\n key: string,\n options?: GraphBuildOptions\n ): AgentClient {\n const agentLattice = this.getAgentLattice(key);\n if (!agentLattice) {\n throw new Error(`Agent Lattice \"${key}\" 不存在`);\n }\n\n // If client already exists, return it directly\n if (agentLattice.client) {\n return agentLattice.client;\n }\n\n // Create agent client from config\n const graph = this.createAgentClientFromConfig(agentLattice, options);\n\n // Set as client\n agentLattice.client = graph;\n\n return graph;\n }\n}\n\n// 导出单例实例\nexport const agentLatticeManager = AgentLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerAgentLattice = (config: AgentConfig) => {\n agentLatticeManager.registerLattice(config);\n};\n\nexport const registerAgentLattices = (configs: AgentConfig[]) => {\n configs.forEach((config) => {\n agentLatticeManager.registerLattice(config);\n });\n};\n\nexport const getAgentLattice = (key: string) =>\n agentLatticeManager.getAgentLattice(key);\n\nexport const getAgentConfig = (key: string) =>\n agentLatticeManager.getAgentConfig(key);\n\nexport const getAllAgentConfigs = () =>\n agentLatticeManager.getAllAgentConfigs();\n\nexport const validateAgentInput = (key: string, input: any) =>\n agentLatticeManager.validateAgentInput(key, input);\n\n/**\n * 获取或初始化Agent客户端\n *\n * @param key Agent Lattice键名\n * @param options 构建选项\n * @returns 返回CompiledGraph对象\n */\nexport const getAgentClient = (key: string, options?: GraphBuildOptions) =>\n agentLatticeManager.initializeClient(key, options);\n\nexport const createAgentClientFromAgentLattice = (\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);\n","/**\n * ChunkBuffer Abstract Base Class\n *\n * Defines the interface for chunk buffer implementations\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { ThreadStatus, ThreadBuffer } from \"./types\";\n\nexport abstract class ChunkBuffer {\n /**\n * Add a chunk to a thread (creates thread if not exists)\n * Chunks are appended in order\n */\n abstract addChunk(threadId: string, content: MessageChunk): Promise<void>;\n\n /**\n * Mark thread as completed (explicit call)\n */\n abstract completeThread(threadId: string): Promise<void>;\n\n /**\n * Mark thread as aborted (explicit call)\n */\n abstract abortThread(threadId: string): Promise<void>;\n\n /**\n * Check if thread is still active\n */\n abstract isThreadActive(threadId: string): Promise<boolean>;\n\n /**\n * Get thread status (returns undefined if thread doesn't exist)\n */\n abstract getThreadStatus(threadId: string): Promise<ThreadStatus | undefined>;\n\n /**\n * Get thread buffer info including metadata\n */\n abstract getThreadBuffer(threadId: string): Promise<ThreadBuffer | undefined>;\n\n /**\n * Clear specific thread buffer\n */\n abstract clearThread(threadId: string): Promise<void>;\n\n /**\n * Get all active thread IDs\n */\n abstract getActiveThreads(): Promise<string[]>;\n\n /**\n * Get all thread IDs (regardless of status)\n */\n abstract getAllThreads(): Promise<string[]>;\n\n /**\n * Manually trigger cleanup of expired threads\n * Returns number of threads cleaned up\n */\n abstract cleanupExpiredThreads(): Promise<number>;\n\n /**\n * Extend thread TTL (reset expiration time)\n */\n abstract extendThreadTTL(\n threadId: string,\n additionalMs?: number\n ): Promise<void>;\n\n /**\n * Check if a thread exists (valid or expired)\n */\n abstract hasThread(threadId: string): Promise<boolean>;\n\n abstract getNewChunksSinceContentIterator(\n threadId: string,\n messageId: string,\n knownContent: string\n ): AsyncIterable<MessageChunk>;\n}\n","/**\n * ChunkBuffer Types\n *\n * Defines types for managing streaming chunks organized by thread\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { ReplaySubject } from \"rxjs\";\n\n/**\n * Represents a single chunk of data\n * Chunks are identified by their position in the sequence (no unique ID)\n */\nexport interface Chunk {\n messageId: string; // Message this chunk belongs to\n content: MessageChunk; // Chunk content\n}\n\n/**\n * Thread status - requires explicit state transitions\n */\nexport enum ThreadStatus {\n ACTIVE = \"active\",\n COMPLETED = \"completed\",\n ABORTED = \"aborted\",\n}\n\n/**\n * Thread buffer configuration\n */\nexport interface ThreadBufferConfig {\n ttl?: number; // Time-to-live in milliseconds (default: 1 hour)\n cleanupInterval?: number; // Optional: periodic cleanup interval in ms\n}\n\n/**\n * Thread buffer state\n */\nexport interface ThreadBuffer {\n threadId: string;\n chunks$: ReplaySubject<MessageChunk>; // Ordered list of chunks\n status: ThreadStatus;\n createdAt: number;\n updatedAt: number;\n expiresAt: number; // TTL expiration timestamp\n}\n\n/**\n * Buffer statistics\n */\nexport interface BufferStats {\n totalThreads: number;\n activeThreads: number;\n completedThreads: number;\n abortedThreads: number;\n config: Required<ThreadBufferConfig>;\n}\n","/**\n * InMemoryChunkBuffer\n *\n * In-memory implementation of ChunkBuffer with hybrid cleanup strategy:\n * - Lazy cleanup: expired threads are removed on access\n * - Optional periodic cleanup: background timer to clean expired threads\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { EventEmitter, once } from \"events\";\nimport { ChunkBuffer } from \"./ChunkBuffer\";\nimport {\n BufferStats,\n ThreadBuffer,\n ThreadBufferConfig,\n ThreadStatus,\n} from \"./types\";\nimport {\n ReplaySubject,\n Observable,\n Subscription,\n observeOn,\n asyncScheduler,\n} from \"rxjs\";\n\nexport class InMemoryChunkBuffer extends ChunkBuffer {\n private buffers: Map<string, ThreadBuffer>;\n private config: Required<ThreadBufferConfig> & { maxChunks?: number };\n private cleanupTimer?: NodeJS.Timeout;\n\n constructor(config?: ThreadBufferConfig & { maxChunks?: number }) {\n super();\n this.buffers = new Map();\n\n // Default: 1 hour TTL, no periodic cleanup (lazy only)\n this.config = {\n ttl: config?.ttl ?? 60 * 60 * 1000,\n cleanupInterval: config?.cleanupInterval ?? 0,\n maxChunks: config?.maxChunks ?? 1000, // Default max chunks per thread\n };\n\n // Start periodic cleanup only if cleanupInterval is specified\n if (this.config.cleanupInterval > 0) {\n this.startCleanupTimer();\n }\n }\n\n /**\n * Start automatic periodic cleanup timer\n */\n private startCleanupTimer(): void {\n if (this.config.cleanupInterval <= 0) return;\n\n this.cleanupTimer = setInterval(() => {\n this.cleanupExpiredThreads().catch(console.error);\n }, this.config.cleanupInterval);\n\n // Don't prevent process from exiting\n if (this.cleanupTimer.unref) {\n this.cleanupTimer.unref();\n }\n }\n\n /**\n * Stop cleanup timer (for cleanup/shutdown)\n */\n public stopCleanupTimer(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * Check if a buffer is expired (lazy cleanup helper)\n */\n private isExpired(buffer: ThreadBuffer): boolean {\n return buffer.expiresAt <= Date.now();\n }\n\n /**\n * Get buffer if valid, perform lazy cleanup if expired\n */\n private getBufferIfValid(threadId: string): ThreadBuffer | undefined {\n const buffer = this.buffers.get(threadId);\n\n if (buffer && this.isExpired(buffer)) {\n // Lazy cleanup: remove expired buffer on access\n this.buffers.delete(threadId);\n return undefined;\n }\n\n return buffer;\n }\n\n /**\n * Create or get thread buffer\n */\n private getOrCreateBuffer(threadId: string): ThreadBuffer {\n // First check with lazy cleanup\n let buffer = this.getBufferIfValid(threadId);\n if (!buffer) {\n const now = Date.now();\n buffer = {\n threadId,\n chunks$: new ReplaySubject<MessageChunk>(\n this.config.maxChunks ?? 100000\n ),\n status: ThreadStatus.ACTIVE,\n createdAt: now,\n updatedAt: now,\n expiresAt: now + this.config.ttl,\n };\n this.buffers.set(threadId, buffer);\n }\n\n if (buffer.status !== ThreadStatus.ACTIVE) {\n buffer.status = ThreadStatus.ACTIVE;\n buffer.chunks$ = new ReplaySubject<MessageChunk>(\n this.config.maxChunks ?? 100000\n );\n buffer.updatedAt = Date.now();\n buffer.expiresAt = Date.now() + this.config.ttl;\n }\n\n return buffer;\n }\n\n async addChunk(threadId: string, content: MessageChunk): Promise<void> {\n const buffer = this.getOrCreateBuffer(threadId);\n\n const chunk: MessageChunk = content;\n buffer.chunks$.next(chunk);\n buffer.updatedAt = Date.now();\n\n // Auto-extend TTL on activity\n buffer.expiresAt = Date.now() + this.config.ttl;\n buffer.status = ThreadStatus.ACTIVE;\n\n // Notify listeners\n }\n\n async completeThread(threadId: string): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n buffer.status = ThreadStatus.COMPLETED;\n buffer.updatedAt = Date.now();\n buffer.chunks$.complete();\n }\n }\n\n async abortThread(threadId: string): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n buffer.status = ThreadStatus.ABORTED;\n buffer.updatedAt = Date.now();\n buffer.chunks$.error(new Error(\"Thread aborted\"));\n }\n }\n\n async isThreadActive(threadId: string): Promise<boolean> {\n const buffer = this.getBufferIfValid(threadId);\n return buffer?.status === ThreadStatus.ACTIVE;\n }\n\n async getThreadStatus(threadId: string): Promise<ThreadStatus | undefined> {\n return this.getBufferIfValid(threadId)?.status;\n }\n\n async getThreadBuffer(threadId: string): Promise<ThreadBuffer | undefined> {\n const buffer = this.getBufferIfValid(threadId);\n if (!buffer) return undefined;\n return buffer;\n }\n\n async clearThread(threadId: string): Promise<void> {\n this.buffers.delete(threadId);\n }\n\n async getActiveThreads(): Promise<string[]> {\n const activeThreads: string[] = [];\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n // Apply lazy cleanup\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n continue;\n }\n\n if (buffer.status === ThreadStatus.ACTIVE) {\n activeThreads.push(threadId);\n }\n }\n\n return activeThreads;\n }\n\n async getAllThreads(): Promise<string[]> {\n const validThreads: string[] = [];\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n // Apply lazy cleanup\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n } else {\n validThreads.push(threadId);\n }\n }\n\n return validThreads;\n }\n\n async hasThread(threadId: string): Promise<boolean> {\n return this.getBufferIfValid(threadId) !== undefined;\n }\n\n /**\n * Cleanup expired threads based on TTL\n * Returns number of threads cleaned up\n */\n async cleanupExpiredThreads(): Promise<number> {\n const now = Date.now();\n let cleanedCount = 0;\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n if (buffer.expiresAt <= now) {\n this.buffers.delete(threadId);\n cleanedCount++;\n }\n }\n\n return cleanedCount;\n }\n\n async extendThreadTTL(\n threadId: string,\n additionalMs?: number\n ): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n const extension = additionalMs ?? this.config.ttl;\n buffer.expiresAt = Date.now() + extension;\n buffer.updatedAt = Date.now();\n }\n }\n\n async *getNewChunksSinceContentIterator(\n threadId: string,\n messageId: string,\n knownContent: string\n ): AsyncIterable<MessageChunk> {\n const buffer = this.getBufferIfValid(threadId);\n if (!buffer) return;\n\n let accumulatedContent = \"\";\n const queue: MessageChunk[] = [];\n let resolveNext: (() => void) | null = null;\n let errorNext: ((err: any) => void) | null = null;\n let isCompleted = false;\n let pendingError: Error | null = null; // Track errors that occur when not waiting\n\n const subscription = buffer.chunks$\n .pipe(observeOn(asyncScheduler))\n .subscribe({\n next: (chunk) => {\n queue.push(chunk);\n if (resolveNext) {\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n error: (err) => {\n pendingError = err; // Always store the error\n\n if (errorNext) {\n const reject = errorNext;\n errorNext = null;\n reject(err);\n } else if (resolveNext) {\n // If waiting on resolveNext, wake it up to check pendingError\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n complete: () => {\n isCompleted = true;\n if (resolveNext) {\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n });\n let startYieldChunk = false;\n\n try {\n while (true) {\n if (pendingError) {\n throw pendingError;\n }\n if (queue.length === 0) {\n if (isCompleted) break;\n await new Promise<void>((resolve, reject) => {\n resolveNext = resolve;\n errorNext = reject;\n });\n }\n // Check error again after waking up\n if (pendingError) {\n throw pendingError;\n }\n while (queue.length > 0) {\n const chunk = queue.shift();\n if (!chunk) continue;\n\n if (chunk.data?.id === messageId) {\n startYieldChunk = true;\n accumulatedContent += chunk.data?.content || \"\";\n }\n // if (accumulatedContent.length > knownContent.length) {\n // startYieldChunk = true;\n // }\n if (startYieldChunk) {\n yield chunk;\n }\n\n // if (accumulatedContent.length > knownContent.length) {\n // if (accumulatedContent.startsWith(knownContent)) {\n // yield chunk;\n // } else {\n // console.log(\n // \"accumulatedContent not starts with knownContent\",\n // accumulatedContent,\n // knownContent\n // );\n // }\n // }\n }\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n public getStats(): BufferStats {\n let activeCount = 0;\n let completedCount = 0;\n let abortedCount = 0;\n\n const validBuffers: ThreadBuffer[] = [];\n for (const [threadId, buffer] of this.buffers.entries()) {\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n } else {\n validBuffers.push(buffer);\n }\n }\n\n for (const buffer of validBuffers) {\n switch (buffer.status) {\n case ThreadStatus.ACTIVE:\n activeCount++;\n break;\n case ThreadStatus.COMPLETED:\n completedCount++;\n break;\n case ThreadStatus.ABORTED:\n abortedCount++;\n break;\n }\n }\n\n return {\n totalThreads: validBuffers.length,\n activeThreads: activeCount,\n completedThreads: completedCount,\n abortedThreads: abortedCount,\n\n config: this.config,\n };\n }\n\n public dispose(): void {\n this.stopCleanupTimer();\n this.buffers.clear();\n }\n}\n","/**\n * ChunkBufferLatticeManager\n * \n * Manages ChunkBuffer instances following the Lattice pattern\n */\n\nimport { BaseLatticeManager } from '../base/BaseLatticeManager';\nimport { ChunkBuffer } from './ChunkBuffer';\n\n/**\n * ChunkBuffer Lattice Manager\n */\nexport class ChunkBufferLatticeManager extends BaseLatticeManager<ChunkBuffer> {\n private static instance: ChunkBufferLatticeManager;\n \n /**\n * Private constructor for singleton pattern\n */\n private constructor() {\n super();\n }\n \n /**\n * Get singleton instance\n */\n public static getInstance(): ChunkBufferLatticeManager {\n if (!ChunkBufferLatticeManager.instance) {\n ChunkBufferLatticeManager.instance = new ChunkBufferLatticeManager();\n }\n return ChunkBufferLatticeManager.instance;\n }\n \n /**\n * Get Lattice type identifier\n */\n protected getLatticeType(): string {\n return 'chunk_buffer';\n }\n}\n\n// Convenience functions\nexport const getChunkBuffer = (key: string): ChunkBuffer | undefined =>\n ChunkBufferLatticeManager.getInstance().get(key);\n\nexport const registerChunkBuffer = (key: string, buffer: ChunkBuffer): void =>\n ChunkBufferLatticeManager.getInstance().register(key, buffer);\n\nexport const hasChunkBuffer = (key: string): boolean =>\n ChunkBufferLatticeManager.getInstance().has(key);\n\n"],"mappings":"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","names":["z","import_zod","z","import_langgraph","import_protocols","import_zod","import_langgraph","tool","stateSchema","import_langchain","import_langchain","import_langgraph","import_zod","micromatch","micromatch","z3","result","import_v3","import_langchain","import_langgraph","import_langchain","import_messages","import_langgraph","import_micromatch","import_langgraph","import_zod","import_langchain","tool","import_protocols","ThreadStatus"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/base/BaseLatticeManager.ts","../src/model_lattice/ModelLattice.ts","../src/model_lattice/ModelLatticeManager.ts","../src/tool_lattice/get_current_date_time/index.ts","../src/tool_lattice/ToolLatticeManager.ts","../src/util/genUIMarkdown.ts","../src/tool_lattice/createToolApproveWrapper.ts","../src/tool_lattice/internet_search/index.ts","../src/util/genUICard.ts","../src/agent_lattice/types.ts","../src/memory_lattice/DefaultMemorySaver.ts","../src/memory_lattice/MemoryLatticeManager.ts","../src/agent_lattice/builders/state.ts","../src/agent_lattice/builders/ReActAgentGraphBuilder.ts","../src/deep_agent_new/agent.ts","../src/deep_agent_new/middleware/fs.ts","../src/deep_agent_new/backends/utils.ts","../src/deep_agent_new/backends/state.ts","../src/deep_agent_new/middleware/subagents.ts","../src/deep_agent_new/middleware/patch_tool_calls.ts","../src/deep_agent_new/backends/filesystem.ts","../src/deep_agent_new/middleware/todos.ts","../src/agent_lattice/builders/DeepAgentGraphBuilder.ts","../src/agent_lattice/builders/AgentGraphBuilderFactory.ts","../src/agent_lattice/builders/AgentParamsBuilder.ts","../src/agent_lattice/AgentLatticeManager.ts","../src/chunk_buffer_lattice/ChunkBuffer.ts","../src/chunk_buffer_lattice/types.ts","../src/chunk_buffer_lattice/InMemoryChunkBuffer.ts","../src/chunk_buffer_lattice/ChunkBufferLatticeManager.ts"],"sourcesContent":["// 导出核心模块\nexport * from \"./model_lattice\";\nexport * from \"./tool_lattice\";\nexport * from \"./agent_lattice\";\nexport * from \"./memory_lattice\";\nexport * from \"./chunk_buffer_lattice\";\n\n// 重新导出协议接口 - 使用命名导出避免冲突\nimport * as Protocols from \"@axiom-lattice/protocols\";\nexport { Protocols };\n","/**\n * BaseLatticeManager - 抽象基类,为各种Lattice管理器提供通用功能\n * 使用统一的Lattice注册表,不同类型的Lattice通过前缀区分\n * @template TItem - 管理的项目类型\n */\nexport abstract class BaseLatticeManager<TItem = any> {\n // 全局统一的Lattice注册表\n protected static registry: Map<string, any> = new Map();\n\n /**\n * 受保护的构造函数,防止外部直接实例化\n */\n protected constructor() {\n // 空实现\n }\n\n /**\n * 获取管理器实例(由子类实现)\n */\n public static getInstance(): BaseLatticeManager<any> {\n throw new Error(\"必须由子类实现\");\n }\n\n /**\n * 获取Lattice类型,用于构造键前缀\n * 子类必须重写此方法以提供唯一的类型标识符\n */\n protected abstract getLatticeType(): string;\n\n /**\n * 构造完整的键名,包含类型前缀\n * @param key 原始键名\n */\n protected getFullKey(key: string): string {\n return `${this.getLatticeType()}.${key}`;\n }\n\n /**\n * 注册项目\n * @param key 项目键名(不含前缀)\n * @param item 项目实例\n */\n public register(key: string, item: TItem): void {\n const fullKey = this.getFullKey(key);\n if (BaseLatticeManager.registry.has(fullKey)) {\n throw new Error(`项目 \"${fullKey}\" 已经存在,无法重复注册`);\n }\n\n BaseLatticeManager.registry.set(fullKey, item);\n }\n\n /**\n * 获取指定项目\n * @param key 项目键名(不含前缀)\n */\n public get(key: string): TItem | undefined {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.get(fullKey) as TItem | undefined;\n }\n\n /**\n * 获取所有当前类型的项目\n */\n public getAll(): TItem[] {\n const prefix = `${this.getLatticeType()}.`;\n const result: TItem[] = [];\n\n for (const [key, value] of BaseLatticeManager.registry.entries()) {\n if (key.startsWith(prefix)) {\n result.push(value as TItem);\n }\n }\n\n return result;\n }\n\n /**\n * 检查项目是否存在\n * @param key 项目键名(不含前缀)\n */\n public has(key: string): boolean {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.has(fullKey);\n }\n\n /**\n * 移除项目\n * @param key 项目键名(不含前缀)\n */\n public remove(key: string): boolean {\n const fullKey = this.getFullKey(key);\n return BaseLatticeManager.registry.delete(fullKey);\n }\n\n /**\n * 清空当前类型的所有项目\n */\n public clear(): void {\n const prefix = `${this.getLatticeType()}.`;\n const keysToDelete: string[] = [];\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n keysToDelete.push(key);\n }\n }\n\n for (const key of keysToDelete) {\n BaseLatticeManager.registry.delete(key);\n }\n }\n\n /**\n * 获取当前类型的项目数量\n */\n public count(): number {\n const prefix = `${this.getLatticeType()}.`;\n let count = 0;\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n count++;\n }\n }\n\n return count;\n }\n\n /**\n * 获取当前类型的项目键名列表(不含前缀)\n */\n public keys(): string[] {\n const prefix = `${this.getLatticeType()}.`;\n const prefixLength = prefix.length;\n const result: string[] = [];\n\n for (const key of BaseLatticeManager.registry.keys()) {\n if (key.startsWith(prefix)) {\n result.push(key.substring(prefixLength));\n }\n }\n\n return result;\n }\n}\n","import {\n AIMessage,\n BaseMessage,\n BaseMessageLike,\n HumanMessage,\n} from \"@langchain/core/messages\";\nimport { ChatDeepSeek } from \"@langchain/deepseek\";\nimport { AzureChatOpenAI, ChatOpenAI } from \"@langchain/openai\";\nimport { z } from \"zod\";\nimport { ZodType as ZodTypeV3 } from \"zod/v3\";\nimport { $ZodType as ZodTypeV4 } from \"zod/v4/core\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n BaseLanguageModel,\n BaseLanguageModelInput,\n} from \"@langchain/core/language_models/base\";\nimport {\n CallbackManagerForLLMRun,\n Callbacks,\n} from \"@langchain/core/callbacks/manager\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nBaseLanguageModel;\nimport { LLMConfig } from \"@axiom-lattice/protocols\";\n\n/**\n * ModelLattice类,继承自BaseChatModel\n * 简化版本,只保留通过LLMConfig创建LLM实例的功能\n */\nexport class ModelLattice extends BaseChatModel {\n private config: LLMConfig;\n private llm: BaseChatModel;\n\n lc_namespace: string[] = [\"langchain\", \"model_lattice\"];\n\n /**\n * 构造函数\n * @param config LLM配置\n */\n constructor(config: LLMConfig) {\n super({});\n this.config = config;\n this.llm = this.initChatModel(config);\n }\n\n /**\n * 返回模型类型\n */\n _llmType(): string {\n return \"model_lattice\";\n }\n\n /**\n * 返回模型类型\n */\n _modelType(): string {\n return this.llm._modelType();\n }\n\n /**\n * 实现BaseChatModel的_generate方法\n * @param messages 消息数组\n * @param options 调用选项\n * @param runManager 回调管理器\n * @returns 聊天结果\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n return this.llm._generate(messages, options as any, runManager);\n }\n\n /**\n * 将工具绑定到模型\n * @param tools 工具列表\n * @param tool_choice 工具选择选项\n * @returns 绑定工具后的模型\n */\n bindTools(\n tools: any[],\n {\n tool_choice = \"auto\",\n ...kwargs\n }: {\n tool_choice?: \"auto\" | \"none\" | \"required\" | any;\n [key: string]: any;\n } = {}\n ): any {\n // 如果底层LLM实现了bindTools方法,则使用它的实现\n if (typeof this.llm.bindTools === \"function\") {\n return this.llm.bindTools(tools, {\n tool_choice,\n ...kwargs,\n });\n }\n\n // 如果底层LLM没有实现bindTools方法,抛出错误\n throw new Error(\"llm not support bindTools\");\n }\n\n /**\n * 使用结构化输出调用LLM\n * @param input 输入\n * @param schema 结构化输出的schema\n * @param options 调用选项\n * @returns 结构化输出\n */\n async invokeWithStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n input: BaseLanguageModelInput,\n schema: ZodTypeV3<RunOutput> | ZodTypeV4<RunOutput> | Record<string, any>,\n options?: BaseChatModelCallOptions & {\n includeRaw?: boolean;\n name?: string;\n method?: \"functionCalling\" | \"jsonMode\";\n }\n ): Promise<RunOutput | { raw: BaseMessage; parsed: RunOutput }> {\n // 使用LLM的withStructuredOutput方法\n if (this.llm.withStructuredOutput) {\n // 使用类型断言解决类型兼容性问题\n const structuredLLM = this.llm.withStructuredOutput(schema, {\n includeRaw: options?.includeRaw ?? false,\n name: options?.name,\n method: options?.method,\n } as any);\n\n return structuredLLM.invoke(input, options);\n }\n\n // 如果LLM没有withStructuredOutput方法,抛出错误\n throw new Error(\"当前LLM不支持结构化输出\");\n }\n\n /**\n * 创建LLM实例\n * @param config LLM配置\n * @returns LLM实例\n */\n private initChatModel(config: LLMConfig): BaseChatModel {\n if (config.provider === \"azure\") {\n return new AzureChatOpenAI({\n azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,\n azureOpenAIApiInstanceName: \"convertlab-westus\",\n azureOpenAIApiDeploymentName: config.model,\n azureOpenAIApiVersion: \"2024-02-01\",\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n streaming: config.streaming,\n });\n } else if (config.provider === \"deepseek\") {\n return new ChatDeepSeek({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"DEEPSEEK_API_KEY\"],\n streaming: config.streaming,\n });\n } else if (config.provider === \"siliconcloud\") {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"SILICONCLOUD_API_KEY\"],\n configuration: {\n baseURL: \"https://api.siliconflow.cn/v1\",\n },\n streaming: config.streaming,\n });\n } else if (config.provider === \"volcengine\") {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n apiKey: process.env[config.apiKeyEnvName || \"VOLCENGINE_API_KEY\"],\n configuration: {\n baseURL: \"https://ark.cn-beijing.volces.com/api/v3\",\n },\n streaming: config.streaming,\n });\n } else {\n return new ChatOpenAI({\n model: config.model,\n temperature: config.temperature || 0,\n maxTokens: config.maxTokens,\n timeout: config.timeout,\n maxRetries: config.maxRetries || 2,\n streaming: config.streaming,\n apiKey: process.env[config.apiKeyEnvName || \"OPENAI_API_KEY\"],\n configuration: {\n baseURL: config.baseURL,\n },\n });\n }\n }\n}\n","import { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { ModelLattice as LLMModelLattice } from \"./ModelLattice\";\nimport { LLMConfig } from \"@axiom-lattice/protocols\";\n\n// 模型配置接口,直接使用 LLMConfig\nexport type ModelConfig = LLMConfig;\n\n// 模型客户端类型,使用 LLMManager\ntype ModelClient = LLMModelLattice;\n\n// 定义接口\nexport interface ModelLatticeInterface {\n key: string;\n client: ModelClient;\n}\n\n/**\n * ModelLatticeManager - 单例模型Lattice管理器\n * 负责注册、管理各种语言模型Lattice\n */\nexport class ModelLatticeManager extends BaseLatticeManager<ModelLatticeInterface> {\n private static _instance: ModelLatticeManager;\n\n /**\n * 获取ModelLatticeManager单例实例\n */\n public static getInstance(): ModelLatticeManager {\n if (!ModelLatticeManager._instance) {\n ModelLatticeManager._instance = new ModelLatticeManager();\n }\n return ModelLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"models\";\n }\n\n /**\n * 注册模型Lattice\n * @param key Lattice键名\n * @param config 模型配置\n */\n public registerLattice(key: string, config: ModelConfig): void {\n // 使用 LLMManager 创建客户端\n const client = new LLMModelLattice(config);\n\n // 创建模型Lattice对象\n const modelLattice: ModelLatticeInterface = {\n key,\n client,\n };\n\n // 调用基类的register方法\n this.register(key, modelLattice);\n }\n\n /**\n * 获取ModelLattice\n * @param key Lattice键名\n */\n public getModelLattice(key: string): ModelLatticeInterface {\n const modelLattice = this.get(key);\n if (!modelLattice) {\n throw new Error(`ModelLattice ${key} not found`);\n }\n return modelLattice;\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): ModelLatticeInterface[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 清空所有Lattice\n */\n public clearLattices(): void {\n this.clear();\n }\n\n /**\n * 获取Lattice数量\n */\n public getLatticeCount(): number {\n return this.count();\n }\n\n /**\n * 获取Lattice键名列表\n */\n public getLatticeKeys(): string[] {\n return this.keys();\n }\n}\n\n// 导出单例实例\nexport const modelLatticeManager = ModelLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerModelLattice = (key: string, config: ModelConfig) =>\n modelLatticeManager.registerLattice(key, config);\n\nexport const getModelLattice = (key: string) =>\n modelLatticeManager.getModelLattice(key);\n","import z from \"zod\";\nimport { registerToolLattice } from \"../ToolLatticeManager\";\n\nregisterToolLattice(\n \"get_current_date_time\",\n {\n name: \"get_current_date_time\",\n description: \"获取当前日期时间\",\n schema: z.object({}),\n },\n async () => {\n return \"当前日期时间:\" + new Date().toLocaleString();\n }\n);\n","import { StructuredTool, tool } from \"@langchain/core/tools\";\nimport { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { ToolConfig, ToolExecutor } from \"@axiom-lattice/protocols\";\nimport { createToolApproveWrapper } from \"./createToolApproveWrapper\";\n\n// 工具定义接口 - 使用协议中的ToolConfig\nexport type ToolDefinition = ToolConfig;\n\n// Lattice 接口定义\nexport interface ToolLattice {\n key: string;\n config: ToolConfig;\n client: StructuredTool;\n}\n\n/**\n * ToolLatticeManager - 单例工具Lattice管理器\n * 负责注册、管理各种工具Lattice\n */\nexport class ToolLatticeManager extends BaseLatticeManager<ToolLattice> {\n private static _instance: ToolLatticeManager;\n\n /**\n * 获取ToolLatticeManager单例实例\n */\n public static getInstance(): ToolLatticeManager {\n if (!ToolLatticeManager._instance) {\n ToolLatticeManager._instance = new ToolLatticeManager();\n }\n return ToolLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"tools\";\n }\n\n /**\n * 注册工具Lattice\n * @param key Lattice键名\n * @param config 工具配置(定义)\n * @param executor 工具执行函数\n */\n public registerLattice<TInput = any, TOutput = any>(\n key: string,\n config: ToolConfig,\n executor: ToolExecutor<TInput, TOutput>\n ): void {\n // 创建工具Lattice对象\n let toolExecutor;\n\n if (config.needUserApprove) {\n toolExecutor = createToolApproveWrapper<TInput, TOutput>(\n config,\n executor\n );\n } else {\n toolExecutor = async (input: TInput, exe_config: any) => {\n const result = await executor(input, exe_config);\n return result;\n };\n }\n\n const toolLattice: ToolLattice = {\n key,\n config,\n client: tool(toolExecutor as ToolExecutor, config),\n };\n\n // 调用基类的register方法\n this.register(key, toolLattice);\n }\n\n /**\n * 获取ToolLattice\n * @param key Lattice键名\n */\n public getToolLattice(key: string): ToolLattice | undefined {\n return this.get(key);\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): ToolLattice[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 清空所有Lattice\n */\n public clearLattices(): void {\n this.clear();\n }\n\n /**\n * 获取Lattice数量\n */\n public getLatticeCount(): number {\n return this.count();\n }\n\n /**\n * 获取Lattice键名列表\n */\n public getLatticeKeys(): string[] {\n return this.keys();\n }\n\n /**\n * 获取工具定义\n * @param key Lattice键名\n */\n public getToolDefinition(key: string): ToolDefinition {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n throw new Error(`ToolLattice ${key} not found`);\n }\n return toolLattice.config;\n }\n\n /**\n * 获取工具客户端\n * @param key Lattice键名\n */\n public getToolClient(key: string): StructuredTool {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n throw new Error(`ToolLattice ${key} not found`);\n }\n return toolLattice.client;\n }\n\n /**\n * 获取所有工具定义\n */\n public getAllToolDefinitions(): ToolDefinition[] {\n return this.getAllLattices().map((lattice) => lattice.config);\n }\n\n /**\n * 验证工具输入参数\n * @param key Lattice键名\n * @param input 输入参数\n */\n public validateToolInput(key: string, input: any): boolean {\n const toolLattice = this.getToolLattice(key);\n if (!toolLattice) {\n return false;\n }\n\n try {\n if (toolLattice.config.schema) {\n toolLattice.config.schema.parse(input);\n }\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// 导出单例实例\nexport const toolLatticeManager = ToolLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerToolLattice = (\n key: string,\n config: ToolConfig,\n executor: ToolExecutor\n) => toolLatticeManager.registerLattice(key, config, executor);\n\nexport const getToolLattice = (key: string) =>\n toolLatticeManager.getToolLattice(key);\n\nexport const getToolDefinition = (key: string) =>\n toolLatticeManager.getToolDefinition(key);\n\nexport const getToolClient = (key: string) =>\n toolLatticeManager.getToolClient(key);\n\nexport const getAllToolDefinitions = () =>\n toolLatticeManager.getAllToolDefinitions();\n\nexport const validateToolInput = (key: string, input: any) =>\n toolLatticeManager.validateToolInput(key, input);\n","export const genUIMarkdown = (type: string, data: any) => {\n return [\"```\" + type, JSON.stringify(data), \"```\"].join(\"\\n\");\n};\n","import { AIMessage, isAIMessage } from \"@langchain/core/messages\";\nimport { ToolLatticeManager } from \"./ToolLatticeManager\";\nimport { ToolLattice } from \"./ToolLatticeManager\";\nimport { genUIMarkdown } from \"../util/genUIMarkdown\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport { UserFeedbackResponse } from \"../types\";\nimport { END, interrupt } from \"@langchain/langgraph\";\nimport { ToolConfig, ToolExecutor } from \"@axiom-lattice/protocols\";\nexport function createToolApproveWrapper<TInput = any, TOutput = any>(\n tool_config: ToolConfig,\n toolExecutor: ToolExecutor<TInput, TOutput>\n) {\n return async (input: TInput, exe_config: any) => {\n const messagePrefix = \"Tool execution requires approval\";\n const description = `${messagePrefix}\\n\\nTool: ${tool_config.name}\\nArgs: ${JSON.stringify(input, null, 2)}`;\n\n const md = genUIMarkdown(\"confirm\", {\n message: description,\n tool_call: {\n tool_call_id: exe_config.id,\n tool_name: tool_config.name,\n tool_args: input,\n tool_config: tool_config,\n },\n });\n\n const feedback: UserFeedbackResponse = await interrupt(md);\n\n if (feedback.data.action === \"yes\") {\n return await toolExecutor(input, exe_config);\n } else {\n return {\n goto: END,\n };\n }\n };\n}\n","import z from \"zod\";\nimport { registerToolLattice } from \"../ToolLatticeManager\";\nimport { TavilySearch } from \"@langchain/tavily\";\nimport \"dotenv/config\";\nimport { LangGraphRunnableConfig } from \"@langchain/langgraph\";\nimport { genUICard } from \"@util/genUICard\";\n\ntype Topic = \"general\" | \"news\" | \"finance\";\n\nregisterToolLattice(\n \"internet_search\",\n {\n name: \"internet_search\",\n description: \"Run a web search\",\n needUserApprove: true,\n schema: z.object({\n query: z.string().describe(\"The search query\"),\n maxResults: z\n .number()\n .optional()\n .default(5)\n .describe(\"Maximum number of results to return\"),\n topic: z\n .enum([\"general\", \"news\", \"finance\"])\n .optional()\n .default(\"general\")\n .describe(\"Search topic category\"),\n includeRawContent: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether to include raw content\"),\n }),\n },\n async (\n {\n query,\n maxResults = 5,\n topic = \"general\" as Topic,\n includeRawContent = false,\n }: {\n query: string;\n maxResults?: number;\n topic?: Topic;\n includeRawContent?: boolean;\n },\n config: LangGraphRunnableConfig\n ) => {\n /**\n * Run a web search\n */\n console.log(\"[DEBUG][internet_search] Starting search with params:\", {\n query,\n maxResults,\n topic,\n includeRawContent,\n });\n\n // Note: You'll need to install and import tavily-js or similar package\n console.log(\"[DEBUG][internet_search] Creating TavilySearch instance...\");\n const tavilySearch = new TavilySearch({\n maxResults,\n tavilyApiKey: process.env.TAVILY_API_KEY,\n includeRawContent,\n topic,\n });\n\n console.log(\"[DEBUG][internet_search] Invoking search for query:\", query);\n const tavilyResponse = await tavilySearch.invoke({ query });\n console.log(\n \"[DEBUG][internet_search] Search completed. Results count:\",\n tavilyResponse.results?.length ?? 0\n );\n\n const result = genUICard(\"Internet Search:\" + query, \"generic_data_table\", {\n dataSource: tavilyResponse.results,\n });\n console.log(\"[DEBUG][internet_search] Returning UI card result\");\n\n return result;\n }\n);\n","export const genUICard = (title: string, type: string, data: any) => {\n return [title, \"```\" + type, JSON.stringify(data), \"```\"].join(\"\\n\");\n};\n","/**\n * Agent Lattice 类型定义\n *\n * 包含Agent Lattice相关的所有类型定义,供其他模块共享使用\n */\n\nimport { z } from \"zod\";\nimport { ModelLattice } from \"@model_lattice/ModelLattice\";\nimport { CompiledStateGraph } from \"@langchain/langgraph\";\nimport {\n AgentType,\n AgentConfig,\n ReactAgentConfig,\n DeepAgentConfig,\n PlanExecuteAgentConfig,\n SequentialAgentConfig,\n AgentConfigWithTools,\n GraphBuildOptions,\n hasTools,\n isDeepAgentConfig,\n getToolsFromConfig,\n getSubAgentsFromConfig,\n} from \"@axiom-lattice/protocols\";\nimport { ReactAgent } from \"langchain\";\n\n// Re-export types from protocols\nexport {\n AgentType,\n AgentConfig,\n ReactAgentConfig,\n DeepAgentConfig,\n PlanExecuteAgentConfig,\n SequentialAgentConfig,\n AgentConfigWithTools,\n GraphBuildOptions,\n hasTools,\n isDeepAgentConfig,\n getToolsFromConfig,\n getSubAgentsFromConfig,\n};\n\n// Agent客户端类型 - CompiledStateGraph\nexport type AgentClient =\n | CompiledStateGraph<any, any, any, any, any>\n | ReactAgent<any, any, any, any>;\n\n// AgentLattice接口定义\nexport interface AgentLattice {\n config: AgentConfig;\n client?: AgentClient | undefined;\n}\n\n// Agent构建参数接口\nexport interface AgentBuildParams {\n tools: Array<{\n key: string;\n definition: any;\n executor: any;\n }>;\n model: ModelLattice;\n subAgents: Array<{\n key: string;\n config: AgentConfig;\n client: AgentClient | undefined;\n }>;\n prompt: string;\n stateSchema?: z.ZodObject<any, any, any, any, any>;\n}\n","import { MemorySaver } from \"@langchain/langgraph\";\nimport { registerCheckpointSaver } from \"./MemoryLatticeManager\";\nconst memory = new MemorySaver();\nregisterCheckpointSaver(\"default\", memory);\n","/**\n * MemoryLatticeManager\n *\n * 记忆Lattice管理器,负责管理和注册检查点保存器\n */\n\nimport { BaseCheckpointSaver } from \"@langchain/langgraph-checkpoint\";\nimport { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport { MemoryLatticeProtocol, MemoryType } from \"@axiom-lattice/protocols\";\n\n// Re-export types from protocols\nexport { MemoryType };\n\n/**\n * 记忆Lattice管理器类\n */\nexport class MemoryLatticeManager extends BaseLatticeManager {\n private static instance: MemoryLatticeManager;\n\n // 检查点保存器注册表\n private static checkpointSavers: Map<string, BaseCheckpointSaver> = new Map();\n\n /**\n * 私有构造函数,防止外部直接实例化\n */\n private constructor() {\n super();\n }\n\n /**\n * 获取单例实例\n */\n public static getInstance(): MemoryLatticeManager {\n if (!MemoryLatticeManager.instance) {\n MemoryLatticeManager.instance = new MemoryLatticeManager();\n }\n return MemoryLatticeManager.instance;\n }\n\n /**\n * 获取Lattice类型\n */\n protected getLatticeType(): string {\n return \"memory\";\n }\n\n /**\n * 注册检查点保存器\n * @param key 保存器键名\n * @param saver 检查点保存器实例\n */\n public registerCheckpointSaver(\n key: string,\n saver: BaseCheckpointSaver\n ): void {\n if (MemoryLatticeManager.checkpointSavers.has(key)) {\n console.warn(`检查点保存器 \"${key}\" 已经存在,将会覆盖旧的检查点保存器`);\n }\n\n MemoryLatticeManager.checkpointSavers.set(key, saver);\n }\n\n /**\n * 获取检查点保存器\n * @param key 保存器键名\n */\n public getCheckpointSaver(key: string): BaseCheckpointSaver {\n const saver = MemoryLatticeManager.checkpointSavers.get(key);\n if (!saver) {\n throw new Error(`检查点保存器 \"${key}\" 不存在`);\n }\n return saver;\n }\n\n /**\n * 获取所有已注册的检查点保存器键名\n */\n public getCheckpointSaverKeys(): string[] {\n return Array.from(MemoryLatticeManager.checkpointSavers.keys());\n }\n\n /**\n * 检查检查点保存器是否存在\n * @param key 保存器键名\n */\n public hasCheckpointSaver(key: string): boolean {\n return MemoryLatticeManager.checkpointSavers.has(key);\n }\n\n /**\n * 移除检查点保存器\n * @param key 保存器键名\n */\n public removeCheckpointSaver(key: string): boolean {\n return MemoryLatticeManager.checkpointSavers.delete(key);\n }\n}\n\nexport const getCheckpointSaver = (key: string) =>\n MemoryLatticeManager.getInstance().getCheckpointSaver(key);\n\nexport const registerCheckpointSaver = (\n key: string,\n saver: BaseCheckpointSaver\n) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);\n","/**\n * State definitions for Deep Agents\n *\n * TypeScript equivalents of the Python state classes using LangGraph's Annotation.Root() pattern.\n * Defines Todo interface and DeepAgentState using MessagesAnnotation as base with proper reducer functions.\n */\n\nimport \"@langchain/langgraph/zod\";\nimport { MessagesZodState } from \"@langchain/langgraph\";\nimport { withLangGraph } from \"@langchain/langgraph/zod\";\nimport { z } from \"zod\";\n\n/**\n * File reducer function that merges file dictionaries\n * Matches the Python file_reducer function behavior exactly\n */\nexport function fileReducer(\n left: Record<string, string> | null | undefined,\n right: Record<string, string> | null | undefined\n): Record<string, string> {\n if (left == null) {\n return right || {};\n } else if (right == null) {\n return left;\n } else {\n return { ...left, ...right };\n }\n}\n\nexport const createReactAgentSchema = (\n schema?: z.ZodObject<any, any, any, any, any>\n) => {\n return schema ? MessagesZodState.extend(schema.shape) : undefined;\n};\n","/**\n * ReAct Agent Graph Builder\n *\n * 实现 ReAct 类型的 Agent Graph 构建\n */\n\nimport { CompiledStateGraph, MessagesZodState } from \"@langchain/langgraph\";\nimport { DynamicTool } from \"@langchain/core/tools\";\nimport { AgentLattice, AgentBuildParams, AgentClient } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { getToolClient } from \"../../tool_lattice/ToolLatticeManager\";\nimport { createReactAgent } from \"@langchain/langgraph/prebuilt\";\nimport { getCheckpointSaver } from \"@memory_lattice\";\nimport { createReactAgentSchema } from \"./state\";\nimport { createAgent } from \"langchain\";\n\nexport class ReActAgentGraphBuilder implements AgentGraphBuilder {\n /**\n * 构建ReAct Agent Graph\n *\n * @param agentLattice Agent Lattice对象\n * @param params Agent构建参数\n * @returns 返回CompiledGraph对象\n */\n build(agentLattice: AgentLattice, params: AgentBuildParams): AgentClient {\n // 创建符合 DynamicTool 接口的工具对象\n const tools = params.tools\n .map((t) => {\n // 使用 DynamicTool 构造工具对象\n const tool = getToolClient(t.key);\n return tool;\n })\n .filter((tool) => tool !== undefined);\n\n const stateSchema = createReactAgentSchema(params.stateSchema);\n\n return createAgent({\n model: params.model,\n tools: tools,\n systemPrompt: params.prompt,\n name: agentLattice.config.name,\n checkpointer: getCheckpointSaver(\"default\"),\n stateSchema: stateSchema as any,\n });\n }\n}\n","import {\n createAgent,\n humanInTheLoopMiddleware,\n anthropicPromptCachingMiddleware,\n summarizationMiddleware,\n type AgentMiddleware,\n type ReactAgent,\n type InterruptOnConfig,\n} from \"langchain\";\nimport type { StructuredTool } from \"@langchain/core/tools\";\nimport type { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n} from \"@langchain/langgraph-checkpoint\";\n\nimport {\n createFilesystemMiddleware,\n createSubAgentMiddleware,\n createPatchToolCallsMiddleware,\n type SubAgent,\n} from \"./middleware/index.js\";\nimport { StateBackend, type BackendProtocol } from \"./backends/index.js\";\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\nimport { AnnotationRoot } from \"@langchain/langgraph\";\nimport { CompiledSubAgent } from \"./middleware/subagents.js\";\nimport { todoListMiddleware } from \"./middleware/todos.js\";\n/**\n * Configuration parameters for creating a Deep Agent\n * Matches Python's create_deep_agent parameters\n */\nexport interface CreateDeepAgentParams<\n ContextSchema extends\n | AnnotationRoot<any>\n | InteropZodObject = AnnotationRoot<any>\n> {\n /** The model to use (model name string or LanguageModelLike instance). Defaults to claude-sonnet-4-5-20250929 */\n model?: BaseLanguageModel | string;\n /** Tools the agent should have access to */\n tools?: StructuredTool[];\n /** Custom system prompt for the agent. This will be combined with the base agent prompt */\n systemPrompt?: string;\n /** Custom middleware to apply after standard middleware */\n middleware?: AgentMiddleware[];\n /** List of subagent specifications for task delegation */\n subagents?: (SubAgent | CompiledSubAgent)[];\n /** Structured output response format for the agent */\n responseFormat?: any; // ResponseFormat type is complex, using any for now\n /** Optional schema for context (not persisted between invocations) */\n contextSchema?: ContextSchema;\n /** Optional checkpointer for persisting agent state between runs */\n checkpointer?: BaseCheckpointSaver | boolean;\n /** Optional store for persisting longterm memories */\n store?: BaseStore;\n /**\n * Optional backend for filesystem operations.\n * Can be either a backend instance or a factory function that creates one.\n * The factory receives a config object with state and store.\n */\n backend?:\n | BackendProtocol\n | ((config: { state: unknown; store?: BaseStore }) => BackendProtocol);\n /** Optional interrupt configuration mapping tool names to interrupt configs */\n interruptOn?: Record<string, boolean | InterruptOnConfig>;\n /** The name of the agent */\n name?: string;\n}\n\nconst BASE_PROMPT = `In order to complete the objective that the user asks of you, you have access to a number of standard tools.`;\n\n/**\n * Create a Deep Agent with middleware-based architecture.\n *\n * Matches Python's create_deep_agent function, using middleware for all features:\n * - Todo management (todoListMiddleware)\n * - Filesystem tools (createFilesystemMiddleware)\n * - Subagent delegation (createSubAgentMiddleware)\n * - Conversation summarization (summarizationMiddleware)\n * - Prompt caching (anthropicPromptCachingMiddleware)\n * - Tool call patching (createPatchToolCallsMiddleware)\n * - Human-in-the-loop (humanInTheLoopMiddleware) - optional\n *\n * @param params Configuration parameters for the agent\n * @returns ReactAgent instance ready for invocation\n */\nexport function createDeepAgent<\n ContextSchema extends\n | AnnotationRoot<any>\n | InteropZodObject = AnnotationRoot<any>\n>(\n params: CreateDeepAgentParams<ContextSchema> = {}\n): ReactAgent<any, any, ContextSchema, any> {\n const {\n model = \"claude-sonnet-4-5-20250929\",\n tools = [],\n systemPrompt,\n middleware: customMiddleware = [],\n subagents = [],\n responseFormat,\n contextSchema,\n checkpointer,\n store,\n backend,\n interruptOn,\n name,\n } = params;\n\n // Combine system prompt with base prompt like Python implementation\n const finalSystemPrompt = systemPrompt\n ? `${systemPrompt}\\n\\n${BASE_PROMPT}`\n : BASE_PROMPT;\n\n // Create backend configuration for filesystem middleware\n // If no backend is provided, use a factory that creates a StateBackend\n const filesystemBackend = backend\n ? backend\n : (config: { state: unknown; store?: BaseStore }) =>\n new StateBackend(config);\n\n const middleware: AgentMiddleware[] = [\n // Provides todo list management capabilities for tracking tasks\n todoListMiddleware(),\n // Enables filesystem operations and optional long-term memory storage\n createFilesystemMiddleware({ backend: filesystemBackend }),\n // Enables delegation to specialized subagents for complex tasks\n createSubAgentMiddleware({\n defaultModel: model,\n defaultTools: tools,\n defaultMiddleware: [\n // Subagent middleware: Todo list management\n todoListMiddleware(),\n // Subagent middleware: Filesystem operations\n createFilesystemMiddleware({\n backend: filesystemBackend,\n }),\n // Subagent middleware: Automatic conversation summarization when token limits are approached\n summarizationMiddleware({\n model,\n trigger: { tokens: 170_000 },\n keep: { messages: 6 },\n }),\n // Subagent middleware: Anthropic prompt caching for improved performance\n anthropicPromptCachingMiddleware({\n unsupportedModelBehavior: \"ignore\",\n }),\n // Subagent middleware: Patches tool calls for compatibility\n createPatchToolCallsMiddleware(),\n ],\n defaultInterruptOn: interruptOn,\n subagents,\n generalPurposeAgent: true,\n }),\n // Automatically summarizes conversation history when token limits are approached\n summarizationMiddleware({\n model,\n trigger: { tokens: 170_000 },\n keep: { messages: 6 },\n }),\n // Enables Anthropic prompt caching for improved performance and reduced costs\n anthropicPromptCachingMiddleware({\n unsupportedModelBehavior: \"ignore\",\n }),\n // Patches tool calls to ensure compatibility across different model providers\n createPatchToolCallsMiddleware(),\n ];\n\n // Add human-in-the-loop middleware if interrupt config provided\n if (interruptOn) {\n middleware.push(humanInTheLoopMiddleware({ interruptOn }));\n }\n\n // Add custom middleware last (after all built-in middleware)\n middleware.push(...customMiddleware);\n\n return createAgent({\n model,\n systemPrompt: finalSystemPrompt,\n tools,\n middleware,\n responseFormat,\n contextSchema,\n checkpointer,\n store,\n name,\n });\n}\n","/**\n * Middleware for providing filesystem tools to an agent.\n *\n * Provides ls, read_file, write_file, edit_file, glob, and grep tools with support for:\n * - Pluggable backends (StateBackend, StoreBackend, FilesystemBackend, CompositeBackend)\n * - Tool result eviction for large outputs\n */\n\nimport { createMiddleware, tool, ToolMessage } from \"langchain\";\nimport { Command, isCommand, getCurrentTaskInput } from \"@langchain/langgraph\";\nimport { z as z3 } from \"zod/v3\";\nimport { withLangGraph } from \"@langchain/langgraph/zod\";\nimport type {\n BackendProtocol,\n BackendFactory,\n FileData,\n StateAndStore,\n} from \"../backends/protocol.js\";\nimport { StateBackend } from \"../backends/state.js\";\nimport { sanitizeToolCallId } from \"../backends/utils.js\";\n\n/**\n * Zod v3 schema for FileData (re-export from backends)\n */\nconst FileDataSchema = z3.object({\n content: z3.array(z3.string()),\n created_at: z3.string(),\n modified_at: z3.string(),\n});\n\nexport type { FileData };\n\n/**\n * Merge file updates with support for deletions.\n */\nfunction fileDataReducer(\n left: Record<string, FileData> | undefined,\n right: Record<string, FileData | null>\n): Record<string, FileData> {\n if (left === undefined) {\n const result: Record<string, FileData> = {};\n for (const [key, value] of Object.entries(right)) {\n if (value !== null) {\n result[key] = value;\n }\n }\n return result;\n }\n\n const result = { ...left };\n for (const [key, value] of Object.entries(right)) {\n if (value === null) {\n delete result[key];\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Shared filesystem state schema.\n * Defined at module level to ensure the same object identity is used across all agents,\n * preventing \"Channel already exists with different type\" errors when multiple agents\n * use createFilesystemMiddleware.\n */\nconst FilesystemStateSchema = z3.object({\n files: withLangGraph(\n z3.record(z3.string(), FileDataSchema).default({}) as any,\n {\n reducer: {\n fn: fileDataReducer,\n schema: z3.record(z3.string(), FileDataSchema.nullable()),\n },\n }\n ),\n});\n\n/**\n * Resolve backend from factory or instance.\n *\n * @param backend - Backend instance or factory function\n * @param stateAndStore - State and store container for backend initialization\n */\nfunction getBackend(\n backend: BackendProtocol | BackendFactory,\n stateAndStore: StateAndStore\n): BackendProtocol {\n if (typeof backend === \"function\") {\n return backend(stateAndStore);\n }\n return backend;\n}\n\n// System prompts\nconst FILESYSTEM_SYSTEM_PROMPT = `You have access to a virtual filesystem. All file paths must start with a /.\n\n- ls: list files in a directory (requires absolute path)\n- read_file: read a file from the filesystem\n- write_file: write to a file in the filesystem\n- edit_file: edit a file in the filesystem\n- glob: find files matching a pattern (e.g., \"**/*.py\")\n- grep: search for text within files`;\n\n// Tool descriptions\nexport const LS_TOOL_DESCRIPTION = \"List files and directories in a directory\";\nexport const READ_FILE_TOOL_DESCRIPTION = \"Read the contents of a file\";\nexport const WRITE_FILE_TOOL_DESCRIPTION =\n \"Write content to a new file. Returns an error if the file already exists\";\nexport const EDIT_FILE_TOOL_DESCRIPTION =\n \"Edit a file by replacing a specific string with a new string\";\nexport const GLOB_TOOL_DESCRIPTION =\n \"Find files matching a glob pattern (e.g., '**/*.py' for all Python files)\";\nexport const GREP_TOOL_DESCRIPTION =\n \"Search for a regex pattern in files. Returns matching files and line numbers\";\n\n/**\n * Create ls tool using backend.\n */\nfunction createLsTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const path = input.path || \"/\";\n const infos = await resolvedBackend.lsInfo(path);\n\n if (infos.length === 0) {\n return `No files found in ${path}`;\n }\n\n // Format output\n const lines: string[] = [];\n for (const info of infos) {\n if (info.is_dir) {\n lines.push(`${info.path} (directory)`);\n } else {\n const size = info.size ? ` (${info.size} bytes)` : \"\";\n lines.push(`${info.path}${size}`);\n }\n }\n return lines.join(\"\\n\");\n },\n {\n name: \"ls\",\n description: customDescription || LS_TOOL_DESCRIPTION,\n schema: z3.object({\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Directory path to list (default: /)\"),\n }),\n }\n );\n}\n\n/**\n * Create read_file tool using backend.\n */\nfunction createReadFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, offset = 0, limit = 2000 } = input;\n return await resolvedBackend.read(file_path, offset, limit);\n },\n {\n name: \"read_file\",\n description: customDescription || READ_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to read\"),\n offset: z3\n .number({ coerce: true })\n .optional()\n .default(0)\n .describe(\"Line offset to start reading from (0-indexed)\"),\n limit: z3\n .number({ coerce: true })\n .optional()\n .default(2000)\n .describe(\"Maximum number of lines to read\"),\n }),\n }\n );\n}\n\n/**\n * Create write_file tool using backend.\n */\nfunction createWriteFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, content } = input;\n const result = await resolvedBackend.write(file_path, content);\n\n if (result.error) {\n return result.error;\n }\n\n // If filesUpdate is present, return Command to update state\n const message = new ToolMessage({\n content: `Successfully wrote to '${file_path}'`,\n tool_call_id: config.toolCall?.id as string,\n name: \"write_file\",\n metadata: result.metadata,\n });\n\n if (result.filesUpdate) {\n return new Command({\n update: { files: result.filesUpdate, messages: [message] },\n });\n }\n\n return message;\n },\n {\n name: \"write_file\",\n description: customDescription || WRITE_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to write\"),\n content: z3.string().describe(\"Content to write to the file\"),\n }),\n }\n );\n}\n\n/**\n * Create edit_file tool using backend.\n */\nfunction createEditFileTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { file_path, old_string, new_string, replace_all = false } = input;\n const result = await resolvedBackend.edit(\n file_path,\n old_string,\n new_string,\n replace_all\n );\n\n if (result.error) {\n return result.error;\n }\n\n const message = new ToolMessage({\n content: `Successfully replaced ${result.occurrences} occurrence(s) in '${file_path}'`,\n tool_call_id: config.toolCall?.id as string,\n name: \"edit_file\",\n metadata: result.metadata,\n });\n\n // If filesUpdate is present, return Command to update state\n if (result.filesUpdate) {\n return new Command({\n update: { files: result.filesUpdate, messages: [message] },\n });\n }\n\n // External storage (filesUpdate is null)\n return message;\n },\n {\n name: \"edit_file\",\n description: customDescription || EDIT_FILE_TOOL_DESCRIPTION,\n schema: z3.object({\n file_path: z3.string().describe(\"Absolute path to the file to edit\"),\n old_string: z3\n .string()\n .describe(\"String to be replaced (must match exactly)\"),\n new_string: z3.string().describe(\"String to replace with\"),\n replace_all: z3\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether to replace all occurrences\"),\n }),\n }\n );\n}\n\n/**\n * Create glob tool using backend.\n */\nfunction createGlobTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { pattern, path = \"/\" } = input;\n const infos = await resolvedBackend.globInfo(pattern, path);\n\n if (infos.length === 0) {\n return `No files found matching pattern '${pattern}'`;\n }\n\n return infos.map((info) => info.path).join(\"\\n\");\n },\n {\n name: \"glob\",\n description: customDescription || GLOB_TOOL_DESCRIPTION,\n schema: z3.object({\n pattern: z3.string().describe(\"Glob pattern (e.g., '*.py', '**/*.ts')\"),\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Base path to search from (default: /)\"),\n }),\n }\n );\n}\n\n/**\n * Create grep tool using backend.\n */\nfunction createGrepTool(\n backend: BackendProtocol | BackendFactory,\n options: { customDescription: string | undefined }\n) {\n const { customDescription } = options;\n return tool(\n async (input, config) => {\n const stateAndStore: StateAndStore = {\n state: getCurrentTaskInput(config),\n store: (config as any).store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const { pattern, path = \"/\", glob = null } = input;\n const result = await resolvedBackend.grepRaw(pattern, path, glob);\n\n // If string, it's an error\n if (typeof result === \"string\") {\n return result;\n }\n\n if (result.length === 0) {\n return `No matches found for pattern '${pattern}'`;\n }\n\n // Format output: group by file\n const lines: string[] = [];\n let currentFile: string | null = null;\n for (const match of result) {\n if (match.path !== currentFile) {\n currentFile = match.path;\n lines.push(`\\n${currentFile}:`);\n }\n lines.push(` ${match.line}: ${match.text}`);\n }\n\n return lines.join(\"\\n\");\n },\n {\n name: \"grep\",\n description: customDescription || GREP_TOOL_DESCRIPTION,\n schema: z3.object({\n pattern: z3.string().describe(\"Regex pattern to search for\"),\n path: z3\n .string()\n .optional()\n .default(\"/\")\n .describe(\"Base path to search from (default: /)\"),\n glob: z3\n .string()\n .optional()\n .nullable()\n .describe(\"Optional glob pattern to filter files (e.g., '*.py')\"),\n }),\n }\n );\n}\n\n/**\n * Options for creating filesystem middleware.\n */\nexport interface FilesystemMiddlewareOptions {\n /** Backend instance or factory (default: StateBackend) */\n backend?: BackendProtocol | BackendFactory;\n /** Optional custom system prompt override */\n systemPrompt?: string | null;\n /** Optional custom tool descriptions override */\n customToolDescriptions?: Record<string, string> | null;\n /** Optional token limit before evicting a tool result to the filesystem (default: 20000 tokens, ~80KB) */\n toolTokenLimitBeforeEvict?: number | null;\n}\n\n/**\n * Create filesystem middleware with all tools and features.\n */\nexport function createFilesystemMiddleware(\n options: FilesystemMiddlewareOptions = {}\n) {\n const {\n backend = (stateAndStore: StateAndStore) => new StateBackend(stateAndStore),\n systemPrompt: customSystemPrompt = null,\n customToolDescriptions = null,\n toolTokenLimitBeforeEvict = 20000,\n } = options;\n\n const systemPrompt = customSystemPrompt || FILESYSTEM_SYSTEM_PROMPT;\n\n const tools = [\n createLsTool(backend, {\n customDescription: customToolDescriptions?.ls,\n }),\n createReadFileTool(backend, {\n customDescription: customToolDescriptions?.read_file,\n }),\n createWriteFileTool(backend, {\n customDescription: customToolDescriptions?.write_file,\n }),\n createEditFileTool(backend, {\n customDescription: customToolDescriptions?.edit_file,\n }),\n createGlobTool(backend, {\n customDescription: customToolDescriptions?.glob,\n }),\n createGrepTool(backend, {\n customDescription: customToolDescriptions?.grep,\n }),\n ];\n\n return createMiddleware({\n name: \"FilesystemMiddleware\",\n stateSchema: FilesystemStateSchema as any,\n tools,\n wrapModelCall: systemPrompt\n ? async (request, handler: any) => {\n const currentSystemPrompt = request.systemPrompt || \"\";\n const newSystemPrompt = currentSystemPrompt\n ? `${currentSystemPrompt}\\n\\n${systemPrompt}`\n : systemPrompt;\n return handler({ ...request, systemPrompt: newSystemPrompt });\n }\n : undefined,\n wrapToolCall: toolTokenLimitBeforeEvict\n ? ((async (request: any, handler: any) => {\n const result = await handler(request);\n\n async function processToolMessage(msg: ToolMessage) {\n if (\n typeof msg.content === \"string\" &&\n msg.content.length > toolTokenLimitBeforeEvict! * 4\n ) {\n // Build StateAndStore from request\n const stateAndStore: StateAndStore = {\n state: request.state || {},\n store: request.config?.store,\n };\n const resolvedBackend = getBackend(backend, stateAndStore);\n const sanitizedId = sanitizeToolCallId(\n request.toolCall?.id || msg.tool_call_id\n );\n const evictPath = `/large_tool_results/${sanitizedId}`;\n\n const writeResult = await resolvedBackend.write(\n evictPath,\n msg.content\n );\n\n if (writeResult.error) {\n return { message: msg, filesUpdate: null };\n }\n\n const truncatedMessage = new ToolMessage({\n content: `Tool result too large (${Math.round(\n msg.content.length / 4\n )} tokens). Content saved to ${evictPath}`,\n tool_call_id: msg.tool_call_id,\n name: msg.name,\n });\n\n return {\n message: truncatedMessage,\n filesUpdate: writeResult.filesUpdate,\n };\n }\n return { message: msg, filesUpdate: null };\n }\n\n if (result instanceof ToolMessage) {\n const processed = await processToolMessage(result);\n\n if (processed.filesUpdate) {\n return new Command({\n update: {\n files: processed.filesUpdate,\n messages: [processed.message],\n },\n });\n }\n\n return processed.message;\n }\n\n if (isCommand(result)) {\n const update = result.update as any;\n if (!update?.messages) {\n return result;\n }\n\n let hasLargeResults = false;\n const accumulatedFiles: Record<string, FileData> = {\n ...(update.files || {}),\n };\n const processedMessages: ToolMessage[] = [];\n\n for (const msg of update.messages) {\n if (msg instanceof ToolMessage) {\n const processed = await processToolMessage(msg);\n processedMessages.push(processed.message);\n\n if (processed.filesUpdate) {\n hasLargeResults = true;\n Object.assign(accumulatedFiles, processed.filesUpdate);\n }\n } else {\n processedMessages.push(msg);\n }\n }\n\n if (hasLargeResults) {\n return new Command({\n update: {\n ...update,\n messages: processedMessages,\n files: accumulatedFiles,\n },\n });\n }\n }\n\n return result;\n }) as any)\n : undefined,\n });\n}\n","/**\n * Shared utility functions for memory backend implementations.\n *\n * This module contains both user-facing string formatters and structured\n * helpers used by backends and the composite router. Structured helpers\n * enable composition without fragile string parsing.\n */\n\nimport micromatch from \"micromatch\";\nimport { basename } from \"path\";\nimport type { FileData, GrepMatch } from \"./protocol.js\";\n\n// Constants\nexport const EMPTY_CONTENT_WARNING =\n \"System reminder: File exists but has empty contents\";\nexport const MAX_LINE_LENGTH = 10000;\nexport const LINE_NUMBER_WIDTH = 6;\nexport const TOOL_RESULT_TOKEN_LIMIT = 20000; // Same threshold as eviction\nexport const TRUNCATION_GUIDANCE =\n \"... [results truncated, try being more specific with your parameters]\";\n\n/**\n * Sanitize tool_call_id to prevent path traversal and separator issues.\n *\n * Replaces dangerous characters (., /, \\) with underscores.\n */\nexport function sanitizeToolCallId(toolCallId: string): string {\n return toolCallId.replace(/\\./g, \"_\").replace(/\\//g, \"_\").replace(/\\\\/g, \"_\");\n}\n\n/**\n * Format file content with line numbers (cat -n style).\n *\n * Chunks lines longer than MAX_LINE_LENGTH with continuation markers (e.g., 5.1, 5.2).\n *\n * @param content - File content as string or list of lines\n * @param startLine - Starting line number (default: 1)\n * @returns Formatted content with line numbers and continuation markers\n */\nexport function formatContentWithLineNumbers(\n content: string | string[],\n startLine: number = 1,\n): string {\n let lines: string[];\n if (typeof content === \"string\") {\n lines = content.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines = lines.slice(0, -1);\n }\n } else {\n lines = content;\n }\n\n const resultLines: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + startLine;\n\n if (line.length <= MAX_LINE_LENGTH) {\n resultLines.push(\n `${lineNum.toString().padStart(LINE_NUMBER_WIDTH)}\\t${line}`,\n );\n } else {\n // Split long line into chunks with continuation markers\n const numChunks = Math.ceil(line.length / MAX_LINE_LENGTH);\n for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {\n const start = chunkIdx * MAX_LINE_LENGTH;\n const end = Math.min(start + MAX_LINE_LENGTH, line.length);\n const chunk = line.substring(start, end);\n if (chunkIdx === 0) {\n // First chunk: use normal line number\n resultLines.push(\n `${lineNum.toString().padStart(LINE_NUMBER_WIDTH)}\\t${chunk}`,\n );\n } else {\n // Continuation chunks: use decimal notation (e.g., 5.1, 5.2)\n const continuationMarker = `${lineNum}.${chunkIdx}`;\n resultLines.push(\n `${continuationMarker.padStart(LINE_NUMBER_WIDTH)}\\t${chunk}`,\n );\n }\n }\n }\n }\n\n return resultLines.join(\"\\n\");\n}\n\n/**\n * Check if content is empty and return warning message.\n *\n * @param content - Content to check\n * @returns Warning message if empty, null otherwise\n */\nexport function checkEmptyContent(content: string): string | null {\n if (!content || content.trim() === \"\") {\n return EMPTY_CONTENT_WARNING;\n }\n return null;\n}\n\n/**\n * Convert FileData to plain string content.\n *\n * @param fileData - FileData object with 'content' key\n * @returns Content as string with lines joined by newlines\n */\nexport function fileDataToString(fileData: FileData): string {\n return fileData.content.join(\"\\n\");\n}\n\n/**\n * Create a FileData object with timestamps.\n *\n * @param content - File content as string\n * @param createdAt - Optional creation timestamp (ISO format)\n * @returns FileData object with content and timestamps\n */\nexport function createFileData(content: string, createdAt?: string): FileData {\n const lines = typeof content === \"string\" ? content.split(\"\\n\") : content;\n const now = new Date().toISOString();\n\n return {\n content: lines,\n created_at: createdAt || now,\n modified_at: now,\n };\n}\n\n/**\n * Update FileData with new content, preserving creation timestamp.\n *\n * @param fileData - Existing FileData object\n * @param content - New content as string\n * @returns Updated FileData object\n */\nexport function updateFileData(fileData: FileData, content: string): FileData {\n const lines = typeof content === \"string\" ? content.split(\"\\n\") : content;\n const now = new Date().toISOString();\n\n return {\n content: lines,\n created_at: fileData.created_at,\n modified_at: now,\n };\n}\n\n/**\n * Format file data for read response with line numbers.\n *\n * @param fileData - FileData object\n * @param offset - Line offset (0-indexed)\n * @param limit - Maximum number of lines\n * @returns Formatted content or error message\n */\nexport function formatReadResponse(\n fileData: FileData,\n offset: number,\n limit: number,\n): string {\n const content = fileDataToString(fileData);\n const emptyMsg = checkEmptyContent(content);\n if (emptyMsg) {\n return emptyMsg;\n }\n\n const lines = content.split(\"\\n\");\n const startIdx = offset;\n const endIdx = Math.min(startIdx + limit, lines.length);\n\n if (startIdx >= lines.length) {\n return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;\n }\n\n const selectedLines = lines.slice(startIdx, endIdx);\n return formatContentWithLineNumbers(selectedLines, startIdx + 1);\n}\n\n/**\n * Perform string replacement with occurrence validation.\n *\n * @param content - Original content\n * @param oldString - String to replace\n * @param newString - Replacement string\n * @param replaceAll - Whether to replace all occurrences\n * @returns Tuple of [new_content, occurrences] on success, or error message string\n */\nexport function performStringReplacement(\n content: string,\n oldString: string,\n newString: string,\n replaceAll: boolean,\n): [string, number] | string {\n // Use split to count occurrences (simpler than regex)\n const occurrences = content.split(oldString).length - 1;\n\n if (occurrences === 0) {\n return `Error: String not found in file: '${oldString}'`;\n }\n\n if (occurrences > 1 && !replaceAll) {\n return `Error: String '${oldString}' appears ${occurrences} times in file. Use replace_all=True to replace all instances, or provide a more specific string with surrounding context.`;\n }\n\n // Python's str.replace() replaces ALL occurrences\n // Use split/join for consistent behavior\n const newContent = content.split(oldString).join(newString);\n\n return [newContent, occurrences];\n}\n\n/**\n * Truncate list or string result if it exceeds token limit (rough estimate: 4 chars/token).\n */\nexport function truncateIfTooLong(\n result: string[] | string,\n): string[] | string {\n if (Array.isArray(result)) {\n const totalChars = result.reduce((sum, item) => sum + item.length, 0);\n if (totalChars > TOOL_RESULT_TOKEN_LIMIT * 4) {\n const truncateAt = Math.floor(\n (result.length * TOOL_RESULT_TOKEN_LIMIT * 4) / totalChars,\n );\n return [...result.slice(0, truncateAt), TRUNCATION_GUIDANCE];\n }\n return result;\n }\n // string\n if (result.length > TOOL_RESULT_TOKEN_LIMIT * 4) {\n return (\n result.substring(0, TOOL_RESULT_TOKEN_LIMIT * 4) +\n \"\\n\" +\n TRUNCATION_GUIDANCE\n );\n }\n return result;\n}\n\n/**\n * Validate and normalize a path.\n *\n * @param path - Path to validate\n * @returns Normalized path starting with / and ending with /\n * @throws Error if path is invalid\n */\nexport function validatePath(path: string | null | undefined): string {\n const pathStr = path || \"/\";\n if (!pathStr || pathStr.trim() === \"\") {\n throw new Error(\"Path cannot be empty\");\n }\n\n let normalized = pathStr.startsWith(\"/\") ? pathStr : \"/\" + pathStr;\n\n if (!normalized.endsWith(\"/\")) {\n normalized += \"/\";\n }\n\n return normalized;\n}\n\n/**\n * Search files dict for paths matching glob pattern.\n *\n * @param files - Dictionary of file paths to FileData\n * @param pattern - Glob pattern (e.g., `*.py`, `**\\/*.ts`)\n * @param path - Base path to search from\n * @returns Newline-separated file paths, sorted by modification time (most recent first).\n * Returns \"No files found\" if no matches.\n *\n * @example\n * ```typescript\n * const files = {\"/src/main.py\": FileData(...), \"/test.py\": FileData(...)};\n * globSearchFiles(files, \"*.py\", \"/\");\n * // Returns: \"/test.py\\n/src/main.py\" (sorted by modified_at)\n * ```\n */\nexport function globSearchFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string = \"/\",\n): string {\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return \"No files found\";\n }\n\n const filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n // Respect standard glob semantics:\n // - Patterns without path separators (e.g., \"*.py\") match only in the current\n // directory (non-recursive) relative to `path`.\n // - Use \"**\" explicitly for recursive matching.\n const effectivePattern = pattern;\n\n const matches: Array<[string, string]> = [];\n for (const [filePath, fileData] of Object.entries(filtered)) {\n let relative = filePath.substring(normalizedPath.length);\n if (relative.startsWith(\"/\")) {\n relative = relative.substring(1);\n }\n if (!relative) {\n const parts = filePath.split(\"/\");\n relative = parts[parts.length - 1] || \"\";\n }\n\n if (\n micromatch.isMatch(relative, effectivePattern, {\n dot: true,\n nobrace: false,\n })\n ) {\n matches.push([filePath, fileData.modified_at]);\n }\n }\n\n matches.sort((a, b) => b[1].localeCompare(a[1])); // Sort by modified_at descending\n\n if (matches.length === 0) {\n return \"No files found\";\n }\n\n return matches.map(([fp]) => fp).join(\"\\n\");\n}\n\n/**\n * Format grep search results based on output mode.\n *\n * @param results - Dictionary mapping file paths to list of [line_num, line_content] tuples\n * @param outputMode - Output format - \"files_with_matches\", \"content\", or \"count\"\n * @returns Formatted string output\n */\nexport function formatGrepResults(\n results: Record<string, Array<[number, string]>>,\n outputMode: \"files_with_matches\" | \"content\" | \"count\",\n): string {\n if (outputMode === \"files_with_matches\") {\n return Object.keys(results).sort().join(\"\\n\");\n }\n if (outputMode === \"count\") {\n const lines: string[] = [];\n for (const filePath of Object.keys(results).sort()) {\n const count = results[filePath].length;\n lines.push(`${filePath}: ${count}`);\n }\n return lines.join(\"\\n\");\n }\n // content mode\n const lines: string[] = [];\n for (const filePath of Object.keys(results).sort()) {\n lines.push(`${filePath}:`);\n for (const [lineNum, line] of results[filePath]) {\n lines.push(` ${lineNum}: ${line}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Search file contents for regex pattern.\n *\n * @param files - Dictionary of file paths to FileData\n * @param pattern - Regex pattern to search for\n * @param path - Base path to search from\n * @param glob - Optional glob pattern to filter files (e.g., \"*.py\")\n * @param outputMode - Output format - \"files_with_matches\", \"content\", or \"count\"\n * @returns Formatted search results. Returns \"No matches found\" if no results.\n *\n * @example\n * ```typescript\n * const files = {\"/file.py\": FileData({content: [\"import os\", \"print('hi')\"], ...})};\n * grepSearchFiles(files, \"import\", \"/\");\n * // Returns: \"/file.py\" (with output_mode=\"files_with_matches\")\n * ```\n */\nexport function grepSearchFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string | null = null,\n glob: string | null = null,\n outputMode: \"files_with_matches\" | \"content\" | \"count\" = \"files_with_matches\",\n): string {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return \"No matches found\";\n }\n\n let filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n if (glob) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([fp]) =>\n micromatch.isMatch(basename(fp), glob, { dot: true, nobrace: false }),\n ),\n );\n }\n\n const results: Record<string, Array<[number, string]>> = {};\n for (const [filePath, fileData] of Object.entries(filtered)) {\n for (let i = 0; i < fileData.content.length; i++) {\n const line = fileData.content[i];\n const lineNum = i + 1;\n if (regex.test(line)) {\n if (!results[filePath]) {\n results[filePath] = [];\n }\n results[filePath].push([lineNum, line]);\n }\n }\n }\n\n if (Object.keys(results).length === 0) {\n return \"No matches found\";\n }\n return formatGrepResults(results, outputMode);\n}\n\n// -------- Structured helpers for composition --------\n\n/**\n * Return structured grep matches from an in-memory files mapping.\n *\n * Returns a list of GrepMatch on success, or a string for invalid inputs\n * (e.g., invalid regex). We deliberately do not raise here to keep backends\n * non-throwing in tool contexts and preserve user-facing error messages.\n */\nexport function grepMatchesFromFiles(\n files: Record<string, FileData>,\n pattern: string,\n path: string | null = null,\n glob: string | null = null,\n): GrepMatch[] | string {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n let normalizedPath: string;\n try {\n normalizedPath = validatePath(path);\n } catch {\n return [];\n }\n\n let filtered = Object.fromEntries(\n Object.entries(files).filter(([fp]) => fp.startsWith(normalizedPath)),\n );\n\n if (glob) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([fp]) =>\n micromatch.isMatch(basename(fp), glob, { dot: true, nobrace: false }),\n ),\n );\n }\n\n const matches: GrepMatch[] = [];\n for (const [filePath, fileData] of Object.entries(filtered)) {\n for (let i = 0; i < fileData.content.length; i++) {\n const line = fileData.content[i];\n const lineNum = i + 1;\n if (regex.test(line)) {\n matches.push({ path: filePath, line: lineNum, text: line });\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Group structured matches into the legacy dict form used by formatters.\n */\nexport function buildGrepResultsDict(\n matches: GrepMatch[],\n): Record<string, Array<[number, string]>> {\n const grouped: Record<string, Array<[number, string]>> = {};\n for (const m of matches) {\n if (!grouped[m.path]) {\n grouped[m.path] = [];\n }\n grouped[m.path].push([m.line, m.text]);\n }\n return grouped;\n}\n\n/**\n * Format structured grep matches using existing formatting logic.\n */\nexport function formatGrepMatches(\n matches: GrepMatch[],\n outputMode: \"files_with_matches\" | \"content\" | \"count\",\n): string {\n if (matches.length === 0) {\n return \"No matches found\";\n }\n return formatGrepResults(buildGrepResultsDict(matches), outputMode);\n}\n","/**\n * StateBackend: Store files in LangGraph agent state (ephemeral).\n */\n\nimport type {\n BackendProtocol,\n EditResult,\n FileData,\n FileInfo,\n GrepMatch,\n StateAndStore,\n WriteResult,\n} from \"./protocol.js\";\nimport {\n createFileData,\n fileDataToString,\n formatReadResponse,\n globSearchFiles,\n grepMatchesFromFiles,\n performStringReplacement,\n updateFileData,\n} from \"./utils.js\";\n\n/**\n * Backend that stores files in agent state (ephemeral).\n *\n * Uses LangGraph's state management and checkpointing. Files persist within\n * a conversation thread but not across threads. State is automatically\n * checkpointed after each agent step.\n *\n * Special handling: Since LangGraph state must be updated via Command objects\n * (not direct mutation), operations return filesUpdate in WriteResult/EditResult\n * for the middleware to apply via Command.\n */\nexport class StateBackend implements BackendProtocol {\n private stateAndStore: StateAndStore;\n\n constructor(stateAndStore: StateAndStore) {\n this.stateAndStore = stateAndStore;\n }\n\n /**\n * Get files from current state.\n */\n private getFiles(): Record<string, FileData> {\n return (\n ((this.stateAndStore.state as any).files as Record<string, FileData>) ||\n {}\n );\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param path - Absolute path to directory\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n lsInfo(path: string): FileInfo[] {\n const files = this.getFiles();\n const infos: FileInfo[] = [];\n const subdirs = new Set<string>();\n\n // Normalize path to have trailing slash for proper prefix matching\n const normalizedPath = path.endsWith(\"/\") ? path : path + \"/\";\n\n for (const [k, fd] of Object.entries(files)) {\n // Check if file is in the specified directory or a subdirectory\n if (!k.startsWith(normalizedPath)) {\n continue;\n }\n\n // Get the relative path after the directory\n const relative = k.substring(normalizedPath.length);\n\n // If relative path contains '/', it's in a subdirectory\n if (relative.includes(\"/\")) {\n // Extract the immediate subdirectory name\n const subdirName = relative.split(\"/\")[0];\n subdirs.add(normalizedPath + subdirName + \"/\");\n continue;\n }\n\n // This is a file directly in the current directory\n const size = fd.content.join(\"\\n\").length;\n infos.push({\n path: k,\n is_dir: false,\n size: size,\n modified_at: fd.modified_at,\n });\n }\n\n // Add directories to the results\n for (const subdir of Array.from(subdirs).sort()) {\n infos.push({\n path: subdir,\n is_dir: true,\n size: 0,\n modified_at: \"\",\n });\n }\n\n infos.sort((a, b) => a.path.localeCompare(b.path));\n return infos;\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n read(filePath: string, offset: number = 0, limit: number = 2000): string {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) {\n return `Error: File '${filePath}' not found`;\n }\n\n return formatReadResponse(fileData, offset, limit);\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns Raw file content as FileData\n */\n readRaw(filePath: string): FileData {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) throw new Error(`File '${filePath}' not found`);\n return fileData;\n }\n\n /**\n * Create a new file with content.\n * Returns WriteResult with filesUpdate to update LangGraph state.\n */\n write(filePath: string, content: string): WriteResult {\n const files = this.getFiles();\n\n if (filePath in files) {\n return {\n error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`,\n };\n }\n\n const newFileData = createFileData(content);\n return {\n path: filePath,\n filesUpdate: { [filePath]: newFileData },\n };\n }\n\n /**\n * Edit a file by replacing string occurrences.\n * Returns EditResult with filesUpdate and occurrences.\n */\n edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n ): EditResult {\n const files = this.getFiles();\n const fileData = files[filePath];\n\n if (!fileData) {\n return { error: `Error: File '${filePath}' not found` };\n }\n\n const content = fileDataToString(fileData);\n const result = performStringReplacement(\n content,\n oldString,\n newString,\n replaceAll,\n );\n\n if (typeof result === \"string\") {\n return { error: result };\n }\n\n const [newContent, occurrences] = result;\n const newFileData = updateFileData(fileData, newContent);\n return {\n path: filePath,\n filesUpdate: { [filePath]: newFileData },\n occurrences: occurrences,\n };\n }\n\n /**\n * Structured search results or error string for invalid input.\n */\n grepRaw(\n pattern: string,\n path: string = \"/\",\n glob: string | null = null,\n ): GrepMatch[] | string {\n const files = this.getFiles();\n return grepMatchesFromFiles(files, pattern, path, glob);\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n */\n globInfo(pattern: string, path: string = \"/\"): FileInfo[] {\n const files = this.getFiles();\n const result = globSearchFiles(files, pattern, path);\n\n if (result === \"No files found\") {\n return [];\n }\n\n const paths = result.split(\"\\n\");\n const infos: FileInfo[] = [];\n for (const p of paths) {\n const fd = files[p];\n const size = fd ? fd.content.join(\"\\n\").length : 0;\n infos.push({\n path: p,\n is_dir: false,\n size: size,\n modified_at: fd?.modified_at || \"\",\n });\n }\n return infos;\n }\n}\n","import { z } from \"zod/v3\";\nimport {\n createMiddleware,\n createAgent,\n AgentMiddleware,\n tool,\n ToolMessage,\n humanInTheLoopMiddleware,\n type InterruptOnConfig,\n type ReactAgent,\n StructuredTool,\n} from \"langchain\";\nimport { Command, getCurrentTaskInput } from \"@langchain/langgraph\";\nimport type { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { AgentClient } from \"@agent_lattice\";\n\nexport type { AgentMiddleware };\n\n// Constants\nconst DEFAULT_SUBAGENT_PROMPT =\n \"In order to complete the objective that the user asks of you, you have access to a number of standard tools.\";\n\n// State keys that should be excluded when passing state to subagents\nconst EXCLUDED_STATE_KEYS = [\"messages\", \"todos\", \"jumpTo\"] as const;\n\nconst DEFAULT_GENERAL_PURPOSE_DESCRIPTION =\n \"General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.\";\n\n// Comprehensive task tool description from Python\nfunction getTaskToolDescription(subagentDescriptions: string[]): string {\n return `\nLaunch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.\n\nAvailable agent types and the tools they have access to:\n${subagentDescriptions.join(\"\\n\")}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n## Usage notes:\n1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n4. The agent's outputs should generally be trusted\n5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.\n\n### Example usage of the general-purpose agent:\n\n<example_agent_descriptions>\n\"general-purpose\": use this agent for general purpose tasks, it has access to all tools as the main agent.\n</example_agent_descriptions>\n\n<example>\nUser: \"I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them.\"\nAssistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*\nAssistant: *Synthesizes the results of the three isolated research tasks and responds to the User*\n<commentary>\nResearch is a complex, multi-step task in it of itself.\nThe research of each individual player is not dependent on the research of the other players.\nThe assistant uses the task tool to break down the complex objective into three isolated tasks.\nEach research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.\nThis means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.\n</commentary>\n</example>\n\n<example>\nUser: \"Analyze a single large code repository for security vulnerabilities and generate a report.\"\nAssistant: *Launches a single \\`task\\` subagent for the repository analysis*\nAssistant: *Receives report and integrates results into final summary*\n<commentary>\nSubagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.\nIf the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.\n</commentary>\n</example>\n\n<example>\nUser: \"Schedule two meetings for me and prepare agendas for each.\"\nAssistant: *Calls the task tool in parallel to launch two \\`task\\` subagents (one per meeting) to prepare agendas*\nAssistant: *Returns final schedules and agendas*\n<commentary>\nTasks are simple individually, but subagents help silo agenda preparation.\nEach subagent only needs to worry about the agenda for one meeting.\n</commentary>\n</example>\n\n<example>\nUser: \"I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\"\nAssistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*\n<commentary>\nThe assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.\nIt is better to just complete the task directly and NOT use the \\`task\\`tool.\n</commentary>\n</example>\n\n### Example usage with custom agents:\n\n<example_agent_descriptions>\n\"content-reviewer\": use this agent after you are done creating significant content or documents\n\"greeting-responder\": use this agent when to respond to user greetings with a friendly joke\n\"research-analyst\": use this agent to conduct thorough research on complex topics\n</example_agent_description>\n\n<example>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: Sure let me write a function that checks if a number is prime\nassistant: First let me use the Write tool to write a function that checks if a number is prime\nassistant: I'm going to use the Write tool to write the following code:\n<code>\nfunction isPrime(n) {\n if (n <= 1) return false\n for (let i = 2; i * i <= n; i++) {\n if (n % i === 0) return false\n }\n return true\n}\n</code>\n<commentary>\nSince significant content was created and the task was completed, now use the content-reviewer agent to review the work\n</commentary>\nassistant: Now let me use the content-reviewer agent to review the code\nassistant: Uses the Task tool to launch with the content-reviewer agent\n</example>\n\n<example>\nuser: \"Can you help me research the environmental impact of different renewable energy sources and create a comprehensive report?\"\n<commentary>\nThis is a complex research task that would benefit from using the research-analyst agent to conduct thorough analysis\n</commentary>\nassistant: I'll help you research the environmental impact of renewable energy sources. Let me use the research-analyst agent to conduct comprehensive research on this topic.\nassistant: Uses the Task tool to launch with the research-analyst agent, providing detailed instructions about what research to conduct and what format the report should take\n</example>\n\n<example>\nuser: \"Hello\"\n<commentary>\nSince the user is greeting, use the greeting-responder agent to respond with a friendly joke\n</commentary>\nassistant: \"I'm going to use the Task tool to launch with the greeting-responder agent\"\n</example>\n `.trim();\n}\n\nconst TASK_SYSTEM_PROMPT = `## \\`task\\` (subagent spawner)\n\nYou have access to a \\`task\\` tool to launch short-lived subagents that handle isolated tasks. These agents are ephemeral — they live only for the duration of the task and return a single result.\n\nWhen to use the task tool:\n- When a task is complex and multi-step, and can be fully delegated in isolation\n- When a task is independent of other tasks and can run in parallel\n- When a task requires focused reasoning or heavy token/context usage that would bloat the orchestrator thread\n- When sandboxing improves reliability (e.g. code execution, structured searches, data formatting)\n- When you only care about the output of the subagent, and not the intermediate steps (ex. performing a lot of research and then returned a synthesized report, performing a series of computations or lookups to achieve a concise, relevant answer.)\n\nSubagent lifecycle:\n1. **Spawn** → Provide clear role, instructions, and expected output\n2. **Run** → The subagent completes the task autonomously\n3. **Return** → The subagent provides a single structured result\n4. **Reconcile** → Incorporate or synthesize the result into the main thread\n\nWhen NOT to use the task tool:\n- If you need to see the intermediate reasoning or steps after the subagent has completed (the task tool hides them)\n- If the task is trivial (a few tool calls or simple lookup)\n- If delegating does not reduce token usage, complexity, or context switching\n- If splitting would add latency without benefit\n\n## Important Task Tool Usage Notes to Remember\n- Whenever possible, parallelize the work that you do. This is true for both tool_calls, and for tasks. Whenever you have independent steps to complete - make tool_calls, or kick off tasks (subagents) in parallel to accomplish them faster. This saves time for the user, which is incredibly important.\n- Remember to use the \\`task\\` tool to silo independent tasks within a multi-part objective.\n- You should use the \\`task\\` tool whenever you have a complex task that will take multiple steps, and is independent from other tasks that the agent needs to complete. These agents are highly competent and efficient.`;\n\n/**\n * Type definitions for pre-compiled agents.\n */\nexport interface CompiledSubAgent {\n /** The name of the agent */\n name: string;\n /** The description of the agent */\n description: string;\n /** The agent instance */\n runnable: AgentClient | Runnable;\n}\n\n/**\n * Type definitions for subagents\n */\nexport interface SubAgent {\n /** The name of the agent */\n name: string;\n /** The description of the agent */\n description: string;\n /** The system prompt to use for the agent */\n systemPrompt: string;\n /** The tools to use for the agent (tool instances, not names). Defaults to defaultTools */\n tools?: StructuredTool[];\n /** The model for the agent. Defaults to default_model */\n model?: LanguageModelLike | string;\n /** Additional middleware to append after default_middleware */\n middleware?: AgentMiddleware[];\n /** The tool configs to use for the agent */\n interruptOn?: Record<string, boolean | InterruptOnConfig>;\n}\n\n/**\n * Filter state to exclude certain keys when passing to subagents\n */\nfunction filterStateForSubagent(\n state: Record<string, unknown>\n): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(state)) {\n if (!EXCLUDED_STATE_KEYS.includes(key as never)) {\n filtered[key] = value;\n }\n }\n return filtered;\n}\n\n/**\n * Create Command with filtered state update from subagent result\n */\nfunction returnCommandWithStateUpdate(\n result: Record<string, unknown>,\n toolCallId: string\n): Command {\n const stateUpdate = filterStateForSubagent(result);\n const messages = result.messages as Array<{ content: string }>;\n const lastMessage = messages?.[messages.length - 1];\n\n return new Command({\n update: {\n ...stateUpdate,\n messages: [\n new ToolMessage({\n content: lastMessage?.content || \"Task completed\",\n tool_call_id: toolCallId,\n name: \"task\",\n }),\n ],\n },\n });\n}\n\n/**\n * Create subagent instances from specifications\n */\nfunction getSubagents(options: {\n defaultModel: LanguageModelLike | string;\n defaultTools: StructuredTool[];\n defaultMiddleware: AgentMiddleware[] | null;\n defaultInterruptOn: Record<string, boolean | InterruptOnConfig> | null;\n subagents: (SubAgent | CompiledSubAgent)[];\n generalPurposeAgent: boolean;\n}): {\n agents: Record<string, ReactAgent<any, any, any, any> | Runnable>;\n descriptions: string[];\n} {\n const {\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n } = options;\n\n const defaultSubagentMiddleware = defaultMiddleware || [];\n const agents: Record<string, ReactAgent<any, any, any, any> | Runnable> = {};\n const subagentDescriptions: string[] = [];\n\n // Create general-purpose agent if enabled\n if (generalPurposeAgent) {\n const generalPurposeMiddleware = [...defaultSubagentMiddleware];\n if (defaultInterruptOn) {\n generalPurposeMiddleware.push(\n humanInTheLoopMiddleware({ interruptOn: defaultInterruptOn })\n );\n }\n\n const generalPurposeSubagent = createAgent({\n model: defaultModel,\n systemPrompt: DEFAULT_SUBAGENT_PROMPT,\n tools: defaultTools as any,\n middleware: generalPurposeMiddleware,\n });\n\n agents[\"general-purpose\"] = generalPurposeSubagent;\n subagentDescriptions.push(\n `- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`\n );\n }\n\n // Process custom subagents\n for (const agentParams of subagents) {\n subagentDescriptions.push(\n `- ${agentParams.name}: ${agentParams.description}`\n );\n\n if (\"runnable\" in agentParams) {\n agents[agentParams.name] = agentParams.runnable;\n } else {\n const middleware = agentParams.middleware\n ? [...defaultSubagentMiddleware, ...agentParams.middleware]\n : [...defaultSubagentMiddleware];\n\n const interruptOn = agentParams.interruptOn || defaultInterruptOn;\n if (interruptOn)\n middleware.push(humanInTheLoopMiddleware({ interruptOn }));\n\n agents[agentParams.name] = createAgent({\n model: agentParams.model ?? defaultModel,\n systemPrompt: agentParams.systemPrompt,\n tools: agentParams.tools ?? defaultTools,\n middleware,\n });\n }\n }\n\n return { agents, descriptions: subagentDescriptions };\n}\n\n/**\n * Create the task tool for invoking subagents\n */\nfunction createTaskTool(options: {\n defaultModel: LanguageModelLike | string;\n defaultTools: StructuredTool[];\n defaultMiddleware: AgentMiddleware[] | null;\n defaultInterruptOn: Record<string, boolean | InterruptOnConfig> | null;\n subagents: (SubAgent | CompiledSubAgent)[];\n generalPurposeAgent: boolean;\n taskDescription: string | null;\n}) {\n const {\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n taskDescription,\n } = options;\n\n const { agents: subagentGraphs, descriptions: subagentDescriptions } =\n getSubagents({\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n });\n\n const finalTaskDescription = taskDescription\n ? taskDescription\n : getTaskToolDescription(subagentDescriptions);\n\n return tool(\n async (\n input: { description: string; subagent_type: string },\n config\n ): Promise<Command | string> => {\n const { description, subagent_type } = input;\n\n // Validate subagent type\n if (!(subagent_type in subagentGraphs)) {\n const allowedTypes = Object.keys(subagentGraphs)\n .map((k) => `\\`${k}\\``)\n .join(\", \");\n throw new Error(\n `Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`\n );\n }\n\n const subagent = subagentGraphs[subagent_type];\n\n // Get current state and filter it for subagent\n const currentState = getCurrentTaskInput<Record<string, unknown>>();\n const subagentState = filterStateForSubagent(currentState);\n subagentState.messages = [new HumanMessage({ content: description })];\n\n // Invoke the subagent\n const result = (await subagent.invoke(subagentState, config)) as Record<\n string,\n unknown\n >;\n\n // Return command with filtered state update\n if (!config.toolCall?.id) {\n throw new Error(\"Tool call ID is required for subagent invocation\");\n }\n\n return returnCommandWithStateUpdate(result, config.toolCall.id);\n },\n {\n name: \"task\",\n description: finalTaskDescription,\n schema: z.object({\n description: z\n .string()\n .describe(\"The task to execute with the selected agent\"),\n subagent_type: z\n .string()\n .describe(\n `Name of the agent to use. Available: ${Object.keys(\n subagentGraphs\n ).join(\", \")}`\n ),\n }),\n }\n );\n}\n\n/**\n * Options for creating subagent middleware\n */\nexport interface SubAgentMiddlewareOptions {\n /** The model to use for subagents */\n defaultModel: LanguageModelLike | string;\n /** The tools to use for the default general-purpose subagent */\n defaultTools?: StructuredTool[];\n /** Default middleware to apply to all subagents */\n defaultMiddleware?: AgentMiddleware[] | null;\n /** The tool configs for the default general-purpose subagent */\n defaultInterruptOn?: Record<string, boolean | InterruptOnConfig> | null;\n /** A list of additional subagents to provide to the agent */\n subagents?: (SubAgent | CompiledSubAgent)[];\n /** Full system prompt override */\n systemPrompt?: string | null;\n /** Whether to include the general-purpose agent */\n generalPurposeAgent?: boolean;\n /** Custom description for the task tool */\n taskDescription?: string | null;\n}\n\n/**\n * Create subagent middleware with task tool\n */\nexport function createSubAgentMiddleware(\n options: SubAgentMiddlewareOptions\n): AgentMiddleware {\n const {\n defaultModel,\n defaultTools = [],\n defaultMiddleware = null,\n defaultInterruptOn = null,\n subagents = [],\n systemPrompt = TASK_SYSTEM_PROMPT,\n generalPurposeAgent = true,\n taskDescription = null,\n } = options;\n\n const taskTool = createTaskTool({\n defaultModel,\n defaultTools,\n defaultMiddleware,\n defaultInterruptOn,\n subagents,\n generalPurposeAgent,\n taskDescription,\n });\n\n return createMiddleware({\n name: \"subAgentMiddleware\",\n tools: [taskTool],\n wrapModelCall: async (request, handler) => {\n if (systemPrompt !== null) {\n const currentPrompt = request.systemPrompt || \"\";\n const newPrompt = currentPrompt\n ? `${currentPrompt}\\n\\n${systemPrompt}`\n : systemPrompt;\n\n return handler({\n ...request,\n systemPrompt: newPrompt,\n });\n }\n return handler(request);\n },\n });\n}\n","import {\n createMiddleware,\n AgentMiddleware,\n ToolMessage,\n AIMessage,\n} from \"langchain\";\nimport { RemoveMessage } from \"@langchain/core/messages\";\nimport { REMOVE_ALL_MESSAGES } from \"@langchain/langgraph\";\n\n/**\n * Create middleware that patches dangling tool calls in the messages history.\n *\n * When an AI message contains tool_calls but subsequent messages don't include\n * the corresponding ToolMessage responses, this middleware adds synthetic\n * ToolMessages saying the tool call was cancelled.\n *\n * @returns AgentMiddleware that patches dangling tool calls\n *\n * @example\n * ```typescript\n * import { createAgent } from \"langchain\";\n * import { createPatchToolCallsMiddleware } from \"./middleware/patch_tool_calls\";\n *\n * const agent = createAgent({\n * model: \"claude-sonnet-4-5-20250929\",\n * middleware: [createPatchToolCallsMiddleware()],\n * });\n * ```\n */\nexport function createPatchToolCallsMiddleware(): AgentMiddleware {\n return createMiddleware({\n name: \"patchToolCallsMiddleware\",\n beforeAgent: async (state) => {\n const messages = state.messages;\n\n if (!messages || messages.length === 0) {\n return;\n }\n\n const patchedMessages: any[] = [];\n\n // Iterate over the messages and add any dangling tool calls\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n patchedMessages.push(msg);\n\n // Check if this is an AI message with tool calls\n if (AIMessage.isInstance(msg) && msg.tool_calls != null) {\n for (const toolCall of msg.tool_calls) {\n // Look for a corresponding ToolMessage in the messages after this one\n const correspondingToolMsg = messages\n .slice(i)\n .find(\n (m: any) =>\n ToolMessage.isInstance(m) && m.tool_call_id === toolCall.id\n );\n\n if (!correspondingToolMsg) {\n // We have a dangling tool call which needs a ToolMessage\n const toolMsg = `Tool call ${toolCall.name} with id ${toolCall.id} was cancelled - another message came in before it could be completed.`;\n patchedMessages.push(\n new ToolMessage({\n content: toolMsg,\n name: toolCall.name,\n tool_call_id: toolCall.id!,\n })\n );\n }\n }\n }\n }\n\n // Return state update with RemoveMessage followed by patched messages\n return {\n messages: [\n new RemoveMessage({ id: REMOVE_ALL_MESSAGES }),\n ...patchedMessages,\n ],\n };\n },\n });\n}\n","/**\n * FilesystemBackend: Read and write files directly from the filesystem.\n *\n * Security and search upgrades:\n * - Secure path resolution with root containment when in virtual_mode (sandboxed to cwd)\n * - Prevent symlink-following on file I/O using O_NOFOLLOW when available\n * - Ripgrep-powered grep with JSON parsing, plus regex fallback\n * and optional glob include filtering, while preserving virtual path behavior\n */\n\nimport * as fs from \"fs/promises\";\nimport * as fsSync from \"fs\";\nimport * as path from \"path\";\nimport { spawn } from \"child_process\";\nimport fg from \"fast-glob\";\nimport micromatch from \"micromatch\";\nimport type {\n BackendProtocol,\n EditResult,\n FileData,\n FileInfo,\n GrepMatch,\n WriteResult,\n} from \"./protocol.js\";\nimport {\n checkEmptyContent,\n formatContentWithLineNumbers,\n performStringReplacement,\n} from \"./utils.js\";\n\nconst SUPPORTS_NOFOLLOW = fsSync.constants.O_NOFOLLOW !== undefined;\n\n/**\n * Backend that reads and writes files directly from the filesystem.\n *\n * Files are accessed using their actual filesystem paths. Relative paths are\n * resolved relative to the current working directory. Content is read/written\n * as plain text, and metadata (timestamps) are derived from filesystem stats.\n */\nexport class FilesystemBackend implements BackendProtocol {\n private cwd: string;\n private virtualMode: boolean;\n private maxFileSizeBytes: number;\n\n constructor(\n options: {\n rootDir?: string;\n virtualMode?: boolean;\n maxFileSizeMb?: number;\n } = {}\n ) {\n const { rootDir, virtualMode = false, maxFileSizeMb = 10 } = options;\n this.cwd = rootDir ? path.resolve(rootDir) : process.cwd();\n this.virtualMode = virtualMode;\n this.maxFileSizeBytes = maxFileSizeMb * 1024 * 1024;\n }\n\n /**\n * Resolve a file path with security checks.\n *\n * When virtualMode=true, treat incoming paths as virtual absolute paths under\n * this.cwd, disallow traversal (.., ~) and ensure resolved path stays within root.\n * When virtualMode=false, preserve legacy behavior: absolute paths are allowed\n * as-is; relative paths resolve under cwd.\n *\n * @param key - File path (absolute, relative, or virtual when virtualMode=true)\n * @returns Resolved absolute path string\n * @throws Error if path traversal detected or path outside root\n */\n private resolvePath(key: string): string {\n if (this.virtualMode) {\n const vpath = key.startsWith(\"/\") ? key : \"/\" + key;\n if (vpath.includes(\"..\") || vpath.startsWith(\"~\")) {\n throw new Error(\"Path traversal not allowed\");\n }\n const full = path.resolve(this.cwd, vpath.substring(1));\n const relative = path.relative(this.cwd, full);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path: ${full} outside root directory: ${this.cwd}`);\n }\n return full;\n }\n\n if (path.isAbsolute(key)) {\n return key;\n }\n return path.resolve(this.cwd, key);\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param dirPath - Absolute directory path to list files from\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n async lsInfo(dirPath: string): Promise<FileInfo[]> {\n try {\n const resolvedPath = this.resolvePath(dirPath);\n const stat = await fs.stat(resolvedPath);\n\n if (!stat.isDirectory()) {\n return [];\n }\n\n const entries = await fs.readdir(resolvedPath, { withFileTypes: true });\n const results: FileInfo[] = [];\n\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n\n for (const entry of entries) {\n const fullPath = path.join(resolvedPath, entry.name);\n\n try {\n const entryStat = await fs.stat(fullPath);\n const isFile = entryStat.isFile();\n const isDir = entryStat.isDirectory();\n\n if (!this.virtualMode) {\n // Non-virtual mode: use absolute paths\n if (isFile) {\n results.push({\n path: fullPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: fullPath + path.sep,\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n } else {\n let relativePath: string;\n if (fullPath.startsWith(cwdStr)) {\n relativePath = fullPath.substring(cwdStr.length);\n } else if (fullPath.startsWith(this.cwd)) {\n relativePath = fullPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = fullPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virtPath = \"/\" + relativePath;\n\n if (isFile) {\n results.push({\n path: virtPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: virtPath + \"/\",\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n }\n } catch {\n // Skip entries we can't stat\n continue;\n }\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return results;\n } catch {\n return [];\n }\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute or relative file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n async read(\n filePath: string,\n offset: number = 0,\n limit: number = 2000\n ): Promise<string> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return `Error: File '${filePath}' not found`;\n }\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return `Error: Symlinks are not allowed: ${filePath}`;\n }\n if (!stat.isFile()) {\n return `Error: File '${filePath}' not found`;\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const emptyMsg = checkEmptyContent(content);\n if (emptyMsg) {\n return emptyMsg;\n }\n\n const lines = content.split(\"\\n\");\n const startIdx = offset;\n const endIdx = Math.min(startIdx + limit, lines.length);\n\n if (startIdx >= lines.length) {\n return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;\n }\n\n const selectedLines = lines.slice(startIdx, endIdx);\n return formatContentWithLineNumbers(selectedLines, startIdx + 1);\n } catch (e: any) {\n return `Error reading file '${filePath}': ${e.message}`;\n }\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns Raw file content as FileData\n */\n async readRaw(filePath: string): Promise<FileData> {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n let stat: fsSync.Stats;\n\n if (SUPPORTS_NOFOLLOW) {\n stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) throw new Error(`File '${filePath}' not found`);\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n throw new Error(`Symlinks are not allowed: ${filePath}`);\n }\n if (!stat.isFile()) throw new Error(`File '${filePath}' not found`);\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n return {\n content: content.split(\"\\n\"),\n created_at: stat.ctime.toISOString(),\n modified_at: stat.mtime.toISOString(),\n };\n }\n\n /**\n * Create a new file with content.\n * Returns WriteResult. External storage sets filesUpdate=null.\n */\n async write(filePath: string, content: string): Promise<WriteResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n try {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return {\n error: `Cannot write to ${filePath} because it is a symlink. Symlinks are not allowed.`,\n };\n }\n return {\n error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`,\n };\n } catch {\n // File doesn't exist, good to proceed\n }\n\n await fs.mkdir(path.dirname(resolvedPath), { recursive: true });\n\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_CREAT |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags, 0o644);\n try {\n await fd.writeFile(content, \"utf-8\");\n } finally {\n await fd.close();\n }\n } else {\n await fs.writeFile(resolvedPath, content, \"utf-8\");\n }\n\n return { path: filePath, filesUpdate: null };\n } catch (e: any) {\n return { error: `Error writing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Edit a file by replacing string occurrences.\n * Returns EditResult. External storage sets filesUpdate=null.\n */\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false\n ): Promise<EditResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return { error: `Error: Symlinks are not allowed: ${filePath}` };\n }\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const result = performStringReplacement(\n content,\n oldString,\n newString,\n replaceAll\n );\n\n if (typeof result === \"string\") {\n return { error: result };\n }\n\n const [newContent, occurrences] = result;\n\n // Write securely\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags);\n try {\n await fd.writeFile(newContent, \"utf-8\");\n } finally {\n await fd.close();\n }\n } else {\n await fs.writeFile(resolvedPath, newContent, \"utf-8\");\n }\n\n return { path: filePath, filesUpdate: null, occurrences: occurrences };\n } catch (e: any) {\n return { error: `Error editing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Structured search results or error string for invalid input.\n */\n async grepRaw(\n pattern: string,\n dirPath: string = \"/\",\n glob: string | null = null\n ): Promise<GrepMatch[] | string> {\n // Validate regex\n try {\n new RegExp(pattern);\n } catch (e: any) {\n return `Invalid regex pattern: ${e.message}`;\n }\n\n // Resolve base path\n let baseFull: string;\n try {\n baseFull = this.resolvePath(dirPath || \".\");\n } catch {\n return [];\n }\n\n try {\n await fs.stat(baseFull);\n } catch {\n return [];\n }\n\n // Try ripgrep first, fallback to regex search\n let results = await this.ripgrepSearch(pattern, baseFull, glob);\n if (results === null) {\n results = await this.pythonSearch(pattern, baseFull, glob);\n }\n\n const matches: GrepMatch[] = [];\n for (const [fpath, items] of Object.entries(results)) {\n for (const [lineNum, lineText] of items) {\n matches.push({ path: fpath, line: lineNum, text: lineText });\n }\n }\n return matches;\n }\n\n /**\n * Try to use ripgrep for fast searching.\n * Returns null if ripgrep is not available or fails.\n */\n private async ripgrepSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null\n ): Promise<Record<string, Array<[number, string]>> | null> {\n return new Promise((resolve) => {\n const args = [\"--json\"];\n if (includeGlob) {\n args.push(\"--glob\", includeGlob);\n }\n args.push(\"--\", pattern, baseFull);\n\n const proc = spawn(\"rg\", args, { timeout: 30000 });\n const results: Record<string, Array<[number, string]>> = {};\n let output = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n output += data.toString();\n });\n\n proc.on(\"close\", (code) => {\n if (code !== 0 && code !== 1) {\n // Error (code 1 means no matches, which is ok)\n resolve(null);\n return;\n }\n\n for (const line of output.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const data = JSON.parse(line);\n if (data.type !== \"match\") continue;\n\n const pdata = data.data || {};\n const ftext = pdata.path?.text;\n if (!ftext) continue;\n\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const resolved = path.resolve(ftext);\n const relative = path.relative(this.cwd, resolved);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = ftext;\n }\n\n const ln = pdata.line_number;\n const lt = pdata.lines?.text?.replace(/\\n$/, \"\") || \"\";\n if (ln === undefined) continue;\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([ln, lt]);\n } catch {\n // Skip invalid JSON\n continue;\n }\n }\n\n resolve(results);\n });\n\n proc.on(\"error\", () => {\n resolve(null);\n });\n });\n }\n\n /**\n * Fallback regex search implementation.\n */\n private async pythonSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null\n ): Promise<Record<string, Array<[number, string]>>> {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch {\n return {};\n }\n\n const results: Record<string, Array<[number, string]>> = {};\n const stat = await fs.stat(baseFull);\n const root = stat.isDirectory() ? baseFull : path.dirname(baseFull);\n\n // Use fast-glob to recursively find all files\n const files = await fg(\"**/*\", {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const fp of files) {\n try {\n // Filter by glob if provided\n if (\n includeGlob &&\n !micromatch.isMatch(path.basename(fp), includeGlob)\n ) {\n continue;\n }\n\n // Check file size\n const stat = await fs.stat(fp);\n if (stat.size > this.maxFileSizeBytes) {\n continue;\n }\n\n // Read and search\n const content = await fs.readFile(fp, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (regex.test(line)) {\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const relative = path.relative(this.cwd, fp);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = fp;\n }\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([i + 1, line]);\n }\n }\n } catch {\n // Skip files we can't read\n continue;\n }\n }\n\n return results;\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n */\n async globInfo(\n pattern: string,\n searchPath: string = \"/\"\n ): Promise<FileInfo[]> {\n if (pattern.startsWith(\"/\")) {\n pattern = pattern.substring(1);\n }\n\n const resolvedSearchPath =\n searchPath === \"/\" ? this.cwd : this.resolvePath(searchPath);\n\n try {\n const stat = await fs.stat(resolvedSearchPath);\n if (!stat.isDirectory()) {\n return [];\n }\n } catch {\n return [];\n }\n\n const results: FileInfo[] = [];\n\n try {\n // Use fast-glob for pattern matching\n const matches = await fg(pattern, {\n cwd: resolvedSearchPath,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const matchedPath of matches) {\n try {\n const stat = await fs.stat(matchedPath);\n if (!stat.isFile()) continue;\n\n // Normalize fast-glob paths to platform separators\n // fast-glob returns forward slashes on all platforms, but we need\n // platform-native separators for path comparisons on Windows\n const normalizedPath = matchedPath.split(\"/\").join(path.sep);\n\n if (!this.virtualMode) {\n results.push({\n path: normalizedPath,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n } else {\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n let relativePath: string;\n\n if (normalizedPath.startsWith(cwdStr)) {\n relativePath = normalizedPath.substring(cwdStr.length);\n } else if (normalizedPath.startsWith(this.cwd)) {\n relativePath = normalizedPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = normalizedPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virt = \"/\" + relativePath;\n results.push({\n path: virt,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n }\n } catch {\n // Skip files we can't stat\n continue;\n }\n }\n } catch {\n // Ignore glob errors\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return results;\n }\n}\n","import { Command } from \"@langchain/langgraph\";\nimport { z } from \"zod\";\nimport { createMiddleware, tool, ToolMessage } from \"langchain\";\nimport { genUIMarkdown } from \"../../util/genUIMarkdown\";\n\nconst WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.\nIt also helps the user understand the progress of the task and overall progress of their requests.\nOnly use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.\n\n## When to Use This Tool\nUse this tool in these scenarios:\n\n1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions\n2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations\n3. User explicitly requests todo list - When the user directly asks you to use the todo list\n4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)\n5. The plan may need future revisions or updates based on results from the first few steps. Keeping track of this in a list is helpful.\n\n## How to Use This Tool\n1. When you start working on a task - Mark it as in_progress BEFORE beginning work.\n2. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation.\n3. You can also update future tasks, such as deleting them if they are no longer necessary, or adding new tasks that are necessary. Don't change previously completed tasks.\n4. You can make several updates to the todo list at once. For example, when you complete a task, you can mark the next task you need to start as in_progress.\n\n## When NOT to Use This Tool\nIt is important to skip using this tool when:\n1. There is only a single, straightforward task\n2. The task is trivial and tracking it provides no benefit\n3. The task can be completed in less than 3 trivial steps\n4. The task is purely conversational or informational\n\n## Examples of When to Use the Todo List\n\n<example>\nUser: I want to add a dark mode toggle to the application settings. Make sure you run the tests and build when you're done!\nAssistant: I'll help add a dark mode toggle to your application settings. Let me create a todo list to track this implementation.\n*Creates todo list with the following items:*\n1. Create dark mode toggle component in Settings page\n2. Add dark mode state management (context/store)\n3. Implement CSS-in-JS styles for dark theme\n4. Update existing components to support theme switching\n5. Run tests and build process, addressing any failures or errors that occur\n*Begins working on the first task*\n\n<reasoning>\nThe assistant used the todo list because:\n1. Adding dark mode in it of itself is a multi-step feature requiring UI, state management, and styling changes\n2. The assistant inferred that tests and build need to pass by adding \"Ensure tests and build succeed\" as the final task\n3. Both of the user's requests are complex and require multiple steps to complete.\n</reasoning>\n</example>\n\n<example>\nUser: Help me plan a comprehensive marketing campaign for our new product launch, including social media, email marketing, and press releases.\nAssistant: I'll help you plan a comprehensive marketing campaign for your product launch. Let me create a todo list to organize all the components.\n*Creates todo list with the following items:*\n1. Define target audience and key messaging\n2. Create social media content calendar and posting schedule\n3. Design email marketing sequence and automation flows\n4. Draft press release and identify media contacts\n5. Set up tracking and analytics for campaign performance\n6. Create visual assets and brand materials\n7. Coordinate launch timeline and deliverables\n*Begins working on the first task*\n\n<reasoning>\nThe assistant used the todo list because:\n1. Marketing campaign planning involves multiple distinct channels and activities\n2. Each component requires careful coordination and planning\n3. The systematic approach ensures all aspects of the launch are covered\n</reasoning>\n</example>\n\n<example>\nUser: Help me rename the function getCwd to getCurrentWorkingDirectory across my project\nAssistant: Let me first search through your codebase to find all occurrences of 'getCwd'.\n*Uses search tools to locate all instances of getCwd in the codebase*\nAssistant: I've found 15 instances of 'getCwd' across 8 different files. Let me create a todo list to track these changes.\n*Creates todo list with specific items for each file that needs updating*\n\n<reasoning>\nThe assistant used the todo list because:\n1. The assistant searched to understand the scope of the task\n2. Upon finding multiple occurrences across different files, it determined this was a complex task with multiple steps (>3)\n3. The todo list helps ensure every instance is tracked and updated systematically\n4. This approach prevents missing any occurrences and maintains consistency.\n</reasoning>\n</example>\n\n<example>\nUser: I need help organizing my home office: decluttering the desk, setting up a filing system, organizing digital files, and creating a daily workflow.\nAssistant: I'll help you organize your home office systematically. Let me create a todo list to track each area of organization.\n*Creates todo list with items like: 1) Sort and declutter desk items, 2) Set up physical filing system for documents, 3) Organize digital files and folders, 4) Create daily workflow and productivity systems, 5) Establish maintenance routines*\nLet's start with decluttering your desk space to create a clean foundation for the other organizational systems.\n\n<reasoning>\nThe assistant used the todo list because:\n1. The user provided multiple distinct organizational tasks\n2. Each area requires different approaches and careful planning\n3. Home organization benefits from systematic, step-by-step completion\n4. Progress tracking ensures all areas are addressed thoroughly\n</reasoning>\n</example>\n\n## Examples of When NOT to Use the Todo List\n\n<example>\nUser: How do I print 'Hello World' in Python?\nAssistant: In Python, you can print \"Hello World\" with this simple code:\n\n\\`\\`\\`python\nprint(\"Hello World\")\n\\`\\`\\`\n\nThis will output the text \"Hello World\" to the console when executed.</assistant>\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, trivial task that can be completed in one step. There's no need to track multiple tasks or steps for such a straightforward request.\n</reasoning>\n</example>\n\n<example>\nUser: What's the best way to water houseplants?\nAssistant: The best way to water houseplants depends on the specific plant type, but here are some general guidelines:\n\n- Check soil moisture by inserting your finger about 1-2 inches into the soil\n- Water thoroughly when the top inch feels dry, allowing water to drain from the bottom\n- Use room temperature water and water in the morning when possible\n- Avoid overwatering, which is more harmful than underwatering for most plants\n\nDifferent plants have different needs, so it's important to research your specific varieties for optimal care.\n\n<reasoning>\nThe assistant did not use the todo list because this is an informational request with no actual tasks to complete. The user is simply asking for advice and explanation, not for the assistant to perform multiple steps or activities.\n</reasoning>\n</example>\n\n<example>\nUser: Can you add a comment to the calculateTotal function to explain what it does?\nAssistant: Sure, let me add a comment to the calculateTotal function to explain what it does.\n* Uses the Edit tool to add a comment to the calculateTotal function *\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, straightforward task confined to one location. Adding a comment doesn't require tracking multiple steps or systematic organization.\n</reasoning>\n</example>\n\n<example>\nUser: What time is it in Tokyo right now?\nAssistant: I'll check the current time in Tokyo for you.\n\n*Searches for current time in Tokyo*\n\nThe current time in Tokyo, Japan is [current time]. Tokyo is in the Japan Standard Time (JST) zone, which is UTC+9.\n\n<reasoning>\nThe assistant did not use the todo list because this is a single information lookup with immediate results. There are no multiple steps to track or organize, making the todo list unnecessary for this straightforward request.\n</reasoning>\n</example>\n\n<example>\nUser: I need to write a function that checks if a number is prime and then test it out.\nAssistant: I'll help you write a function that checks if a number is prime and then test it out.\n*Writes function that checks if a number is prime*\n*Tests the function*\n\n<reasoning>\nEven though this is a multi-step task, it is very straightforward and can be completed in two trivial steps (which is less than 3 steps!). Using the todo list here is overkill and wastes time and tokens.\n</reasoning>\n</example>\n\n<example>\nUser: I want you to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\nAssistant: I'll help you order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\n*Orders a pizza from Dominos*\n*Orders a burger from McDonald's*\n*Orders a salad from Subway*\n\n<reasoning>\nEven though this is a multi-step task, assuming the assistant has the ability to order from these restaurants, it is very straightforward and can be completed in three trivial tool calls. \nUsing the todo list here is overkill and wastes time and tokens. These three tool calls should be made in parallel, in fact.\n</reasoning>\n</example>\n\n\n## Task States and Management\n\n1. **Task States**: Use these states to track progress:\n - pending: Task not yet started\n - in_progress: Currently working on (you can have multiple tasks in_progress at a time if they are not related to each other and can be run in parallel)\n - completed: Task finished successfully\n\n2. **Task Management**:\n - Update task status in real-time as you work\n - Mark tasks complete IMMEDIATELY after finishing (don't batch completions)\n - Complete current tasks before starting new ones\n - Remove tasks that are no longer relevant from the list entirely\n - IMPORTANT: When you write this todo list, you should mark your first task (or tasks) as in_progress immediately!.\n - IMPORTANT: Unless all tasks are completed, you should always have at least one task in_progress to show the user that you are working on something.\n\n3. **Task Completion Requirements**:\n - ONLY mark a task as completed when you have FULLY accomplished it\n - If you encounter errors, blockers, or cannot finish, keep the task as in_progress\n - When blocked, create a new task describing what needs to be resolved\n - Never mark a task as completed if:\n - There are unresolved issues or errors\n - Work is partial or incomplete\n - You encountered blockers that prevent completion\n - You couldn't find necessary resources or dependencies\n - Quality standards haven't been met\n\n4. **Task Breakdown**:\n - Create specific, actionable items\n - Break complex tasks into smaller, manageable steps\n - Use clear, descriptive task names\n\nBeing proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully\nRemember: If you only need to make a few tool calls to complete a task, and it is clear what you need to do, it is better to just do the task directly and NOT call this tool at all.`;\nconst TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = `## \\`write_todos\\`\n\nYou have access to the \\`write_todos\\` tool to help you manage and plan complex objectives. \nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\n\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\n\n## Important To-Do List Usage Notes to Remember\n- The \\`write_todos\\` tool should never be called multiple times in parallel.\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;\nconst TodoStatus = z\n .enum([\"pending\", \"in_progress\", \"completed\"])\n .describe(\"Status of the todo\");\nconst TodoSchema = z.object({\n content: z.string().describe(\"Content of the todo item\"),\n status: TodoStatus,\n});\nconst stateSchema = z.object({ todos: z.array(TodoSchema).default([]) });\n\nexport function todoListMiddleware(options?: {\n systemPrompt?: string;\n toolDescription?: string;\n}) {\n /**\n * Write todos tool - manages todo list with Command return\n */\n const writeTodos = tool(\n ({ todos }, config) => {\n return new Command({\n update: {\n todos,\n messages: [\n new ToolMessage({\n content: genUIMarkdown(\"todo_list\", todos),\n tool_call_id: config.toolCall?.id,\n }),\n ],\n },\n });\n },\n {\n name: \"write_todos\",\n description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,\n schema: z.object({\n todos: z.array(TodoSchema).describe(\"List of todo items to update\"),\n }),\n }\n );\n return createMiddleware({\n name: \"todoListMiddleware\",\n stateSchema,\n tools: [writeTodos],\n wrapModelCall: (request, handler) =>\n handler({\n ...request,\n systemPrompt:\n (request.systemPrompt ? `${request.systemPrompt}\\n\\n` : \"\") +\n (options?.systemPrompt ?? TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT),\n }),\n });\n}\n","/**\n * Deep Agent Graph Builder\n *\n * 实现 Deep Agent 类型的 Agent Graph 构建\n */\n\nimport { CompiledStateGraph } from \"@langchain/langgraph\";\nimport { DynamicTool } from \"@langchain/core/tools\";\nimport { createDeepAgent } from \"../../deep_agent_new/agent\";\nimport { AgentLattice, AgentBuildParams, AgentClient } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { getToolClient } from \"../../tool_lattice/ToolLatticeManager\";\nimport { ReactAgent } from \"langchain\";\nimport { createAgentClientFromAgentLattice } from \"@agent_lattice/AgentLatticeManager\";\nimport { getCheckpointSaver } from \"@memory_lattice/MemoryLatticeManager\";\n\nexport class DeepAgentGraphBuilder implements AgentGraphBuilder {\n /**\n * 构建Deep Agent Graph\n *\n * @param agentLattice Agent Lattice对象\n * @param params Agent构建参数\n * @returns 返回CompiledGraph对象\n */\n build(agentLattice: AgentLattice, params: AgentBuildParams): AgentClient {\n const tools = params.tools\n .map((t) => {\n const toolClient = getToolClient(t.key);\n\n return toolClient;\n })\n .filter((tool) => tool !== undefined);\n\n const subagents = params.subAgents.map((sa) => {\n if (sa.client) {\n return {\n name: sa.config.name,\n description: sa.config.description,\n runnable: sa.client,\n };\n } else {\n const subagentClient = createAgentClientFromAgentLattice({\n config: sa.config,\n });\n return {\n name: sa.config.name,\n description: sa.config.description,\n runnable: subagentClient,\n };\n }\n });\n\n const deepAgent = createDeepAgent({\n tools: tools,\n model: params.model,\n contextSchema: params.stateSchema,\n systemPrompt: params.prompt,\n subagents,\n checkpointer: getCheckpointSaver(\"default\"),\n });\n return deepAgent;\n }\n}\n","/**\n * Agent Graph Builder Factory\n *\n * 工厂类,根据Agent类型创建对应的Builder\n */\n\nimport { AgentType } from \"../types\";\nimport { AgentGraphBuilder } from \"./AgentGraphBuilder\";\nimport { ReActAgentGraphBuilder } from \"./ReActAgentGraphBuilder\";\nimport { DeepAgentGraphBuilder } from \"./DeepAgentGraphBuilder\";\n\nexport class AgentGraphBuilderFactory {\n // 单例模式\n private static instance: AgentGraphBuilderFactory;\n\n // Builder缓存\n private builders: Map<AgentType, AgentGraphBuilder>;\n\n private constructor() {\n this.builders = new Map();\n this.registerDefaultBuilders();\n }\n\n /**\n * 获取单例实例\n */\n public static getInstance(): AgentGraphBuilderFactory {\n if (!AgentGraphBuilderFactory.instance) {\n AgentGraphBuilderFactory.instance = new AgentGraphBuilderFactory();\n }\n return AgentGraphBuilderFactory.instance;\n }\n\n /**\n * 注册默认的Builder\n */\n private registerDefaultBuilders(): void {\n this.builders.set(AgentType.REACT, new ReActAgentGraphBuilder());\n this.builders.set(AgentType.DEEP_AGENT, new DeepAgentGraphBuilder());\n }\n\n /**\n * 注册自定义Builder\n *\n * @param type Agent类型\n * @param builder Builder实例\n */\n public registerBuilder(type: AgentType, builder: AgentGraphBuilder): void {\n this.builders.set(type, builder);\n }\n\n /**\n * 获取Builder\n *\n * @param type Agent类型\n * @returns 返回对应的Builder\n */\n public getBuilder(type: AgentType): AgentGraphBuilder {\n const builder = this.builders.get(type);\n if (!builder) {\n throw new Error(`不支持的Agent类型: ${type}`);\n }\n return builder;\n }\n}\n","/**\n * Agent parameters builder\n *\n * responsible for preparing the parameters required for building the Agent\n */\n\nimport { toolLatticeManager } from \"../../tool_lattice/ToolLatticeManager\";\nimport { modelLatticeManager } from \"../../model_lattice/ModelLatticeManager\";\nimport { AgentLattice, AgentBuildParams, GraphBuildOptions } from \"../types\";\nimport {\n getToolsFromConfig,\n getSubAgentsFromConfig,\n isDeepAgentConfig,\n AgentConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Get Agent Lattice function type\n */\nexport type GetAgentLatticeFunction = (key: string) => AgentLattice | undefined;\n\n/**\n * Agent parameters builder\n */\nexport class AgentParamsBuilder {\n private getAgentLatticeFunc: GetAgentLatticeFunction;\n\n /**\n * constructor\n *\n * @param getAgentLatticeFunc get Agent Lattice function\n */\n constructor(getAgentLatticeFunc: GetAgentLatticeFunction) {\n this.getAgentLatticeFunc = getAgentLatticeFunc;\n }\n\n /**\n * build Agent parameters\n *\n * @param agentLattice Agent Lattice object\n * @param options build options\n * @returns Agent build parameters\n */\n public buildParams(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentBuildParams {\n // get tools (use type-safe helper)\n const toolKeys =\n options?.overrideTools || getToolsFromConfig(agentLattice.config);\n const tools = toolKeys.map((toolKey: string) => {\n const toolLattice = toolLatticeManager.getToolLattice(toolKey);\n if (!toolLattice) {\n throw new Error(`Tool \"${toolKey}\" does not exist`);\n }\n return {\n key: toolKey,\n definition: toolLattice.config,\n executor: toolLattice.client,\n };\n });\n\n // get model\n const modelKey = options?.overrideModel || agentLattice.config.modelKey;\n const model = modelKey\n ? modelLatticeManager.getModelLattice(modelKey).client\n : modelLatticeManager.getModelLattice(\"default\").client;\n if (!model) {\n throw new Error(`Model \"${modelKey}\" does not exist`);\n }\n\n // get subAgents (use type-safe helper - only DeepAgentConfig has subAgents)\n const subAgentKeys = getSubAgentsFromConfig(agentLattice.config);\n const subAgents = subAgentKeys.map((agentKey: string) => {\n const subAgentLattice = this.getAgentLatticeFunc(agentKey);\n if (!subAgentLattice) {\n throw new Error(`SubAgent \"${agentKey}\" does not exist`);\n }\n return {\n key: agentKey,\n config: subAgentLattice.config,\n client: subAgentLattice.client,\n };\n });\n let internalSubAgents: any[] = [];\n if (isDeepAgentConfig(agentLattice.config)) {\n internalSubAgents =\n agentLattice.config.internalSubAgents?.map((i) => ({\n key: i.key,\n config: i,\n })) || [];\n }\n\n return {\n tools,\n model,\n subAgents: [...subAgents, ...internalSubAgents],\n prompt: agentLattice.config.prompt,\n stateSchema: agentLattice.config.schema,\n };\n }\n}\n","import { BaseLatticeManager } from \"../base/BaseLatticeManager\";\nimport {\n AgentConfig,\n AgentClient,\n AgentLattice,\n GraphBuildOptions,\n AgentBuildParams,\n} from \"./types\";\nimport { AgentGraphBuilderFactory } from \"./builders/AgentGraphBuilderFactory\";\nimport { AgentParamsBuilder } from \"./builders/AgentParamsBuilder\";\nimport \"../tool_lattice\";\n// 类型定义已移至 ./types.ts\n\n/**\n * AgentLatticeManager - 单例Agent Lattice管理器\n * 负责注册、管理各种Agent Lattice\n */\nexport class AgentLatticeManager extends BaseLatticeManager<AgentLattice> {\n private static _instance: AgentLatticeManager;\n\n /**\n * 获取AgentLatticeManager单例实例\n */\n public static getInstance(): AgentLatticeManager {\n if (!AgentLatticeManager._instance) {\n AgentLatticeManager._instance = new AgentLatticeManager();\n }\n return AgentLatticeManager._instance;\n }\n\n /**\n * 获取Lattice类型前缀\n */\n protected getLatticeType(): string {\n return \"agents\";\n }\n\n /**\n * 注册Agent Lattice\n * @param config Agent配置\n */\n public registerLattice(config: AgentConfig): void {\n // 创建Agent Lattice对象\n const agentLattice: AgentLattice = {\n config,\n client: undefined, // 客户端将在需要时由initializeClient创建\n };\n\n // 调用基类的register方法\n this.register(config.key, agentLattice);\n }\n\n /**\n * 获取AgentLattice\n * @param key Lattice键名\n */\n public getAgentLattice(key: string): AgentLattice | undefined {\n return this.get(key);\n }\n\n /**\n * 获取所有Lattice\n */\n public getAllLattices(): AgentLattice[] {\n return this.getAll();\n }\n\n /**\n * 检查Lattice是否存在\n * @param key Lattice键名\n */\n public hasLattice(key: string): boolean {\n return this.has(key);\n }\n\n /**\n * 移除Lattice\n * @param key Lattice键名\n */\n public removeLattice(key: string): boolean {\n return this.remove(key);\n }\n\n /**\n * 获取Agent配置\n * @param key Lattice键名\n */\n public getAgentConfig(key: string): AgentConfig | undefined {\n return this.getAgentLattice(key)?.config;\n }\n\n /**\n * 获取所有Agent配置\n */\n public getAllAgentConfigs(): AgentConfig[] {\n return this.getAllLattices().map((lattice) => lattice.config);\n }\n\n /**\n * 验证Agent输入参数\n * @param key Lattice键名\n * @param input 输入参数\n */\n public validateAgentInput(key: string, input: any): boolean {\n const agentLattice = this.getAgentLattice(key);\n if (!agentLattice) {\n return false;\n }\n\n try {\n if (agentLattice.config.schema) {\n agentLattice.config.schema.parse(input);\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 构建Agent参数\n *\n * @param agentLattice Agent Lattice对象\n * @param options 构建选项\n * @returns 返回Agent构建参数\n */\n private buildAgentParams(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentBuildParams {\n // 创建参数构建器\n const paramsBuilder = new AgentParamsBuilder((key: string) => {\n this.initializeClient(key);\n return this.getAgentLattice(key);\n });\n\n // 构建参数\n return paramsBuilder.buildParams(agentLattice, options);\n }\n\n /**\n * Create an AgentClient from AgentLattice config\n *\n * @param agentLattice Agent Lattice object\n * @param options Build options\n * @returns AgentClient instance\n */\n public createAgentClientFromConfig(\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n ): AgentClient {\n // Get factory instance\n const factory = AgentGraphBuilderFactory.getInstance();\n\n // Get the builder for the agent type\n const builder = factory.getBuilder(agentLattice.config.type);\n\n // Build params\n const params = this.buildAgentParams(agentLattice, options);\n\n // Use builder to build the graph\n return builder.build(agentLattice, params);\n }\n\n /**\n * 初始化Agent客户端\n *\n * 使用AgentGraphBuilderFactory构建Graph并设置为客户端\n *\n * @param key Lattice键名\n * @param options 构建选项\n * @returns 返回CompiledGraph对象\n */\n public initializeClient(\n key: string,\n options?: GraphBuildOptions\n ): AgentClient {\n const agentLattice = this.getAgentLattice(key);\n if (!agentLattice) {\n throw new Error(`Agent Lattice \"${key}\" 不存在`);\n }\n\n // If client already exists, return it directly\n if (agentLattice.client) {\n return agentLattice.client;\n }\n\n // Create agent client from config\n const graph = this.createAgentClientFromConfig(agentLattice, options);\n\n // Set as client\n agentLattice.client = graph;\n\n return graph;\n }\n}\n\n// 导出单例实例\nexport const agentLatticeManager = AgentLatticeManager.getInstance();\n\n// 导出便捷方法\nexport const registerAgentLattice = (config: AgentConfig) => {\n agentLatticeManager.registerLattice(config);\n};\n\nexport const registerAgentLattices = (configs: AgentConfig[]) => {\n configs.forEach((config) => {\n agentLatticeManager.registerLattice(config);\n });\n};\n\nexport const getAgentLattice = (key: string) =>\n agentLatticeManager.getAgentLattice(key);\n\nexport const getAgentConfig = (key: string) =>\n agentLatticeManager.getAgentConfig(key);\n\nexport const getAllAgentConfigs = () =>\n agentLatticeManager.getAllAgentConfigs();\n\nexport const validateAgentInput = (key: string, input: any) =>\n agentLatticeManager.validateAgentInput(key, input);\n\n/**\n * 获取或初始化Agent客户端\n *\n * @param key Agent Lattice键名\n * @param options 构建选项\n * @returns 返回CompiledGraph对象\n */\nexport const getAgentClient = (key: string, options?: GraphBuildOptions) =>\n agentLatticeManager.initializeClient(key, options);\n\nexport const createAgentClientFromAgentLattice = (\n agentLattice: AgentLattice,\n options?: GraphBuildOptions\n) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);\n","/**\n * ChunkBuffer Abstract Base Class\n *\n * Defines the interface for chunk buffer implementations\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { ThreadStatus, ThreadBuffer } from \"./types\";\n\nexport abstract class ChunkBuffer {\n /**\n * Add a chunk to a thread (creates thread if not exists)\n * Chunks are appended in order\n */\n abstract addChunk(threadId: string, content: MessageChunk): Promise<void>;\n\n /**\n * Mark thread as completed (explicit call)\n */\n abstract completeThread(threadId: string): Promise<void>;\n\n /**\n * Mark thread as aborted (explicit call)\n */\n abstract abortThread(threadId: string): Promise<void>;\n\n /**\n * Check if thread is still active\n */\n abstract isThreadActive(threadId: string): Promise<boolean>;\n\n /**\n * Get thread status (returns undefined if thread doesn't exist)\n */\n abstract getThreadStatus(threadId: string): Promise<ThreadStatus | undefined>;\n\n /**\n * Get thread buffer info including metadata\n */\n abstract getThreadBuffer(threadId: string): Promise<ThreadBuffer | undefined>;\n\n /**\n * Clear specific thread buffer\n */\n abstract clearThread(threadId: string): Promise<void>;\n\n /**\n * Get all active thread IDs\n */\n abstract getActiveThreads(): Promise<string[]>;\n\n /**\n * Get all thread IDs (regardless of status)\n */\n abstract getAllThreads(): Promise<string[]>;\n\n /**\n * Manually trigger cleanup of expired threads\n * Returns number of threads cleaned up\n */\n abstract cleanupExpiredThreads(): Promise<number>;\n\n /**\n * Extend thread TTL (reset expiration time)\n */\n abstract extendThreadTTL(\n threadId: string,\n additionalMs?: number\n ): Promise<void>;\n\n /**\n * Check if a thread exists (valid or expired)\n */\n abstract hasThread(threadId: string): Promise<boolean>;\n\n abstract getNewChunksSinceContentIterator(\n threadId: string,\n messageId: string,\n knownContent: string\n ): AsyncIterable<MessageChunk>;\n}\n","/**\n * ChunkBuffer Types\n *\n * Defines types for managing streaming chunks organized by thread\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { ReplaySubject } from \"rxjs\";\n\n/**\n * Represents a single chunk of data\n * Chunks are identified by their position in the sequence (no unique ID)\n */\nexport interface Chunk {\n messageId: string; // Message this chunk belongs to\n content: MessageChunk; // Chunk content\n}\n\n/**\n * Thread status - requires explicit state transitions\n */\nexport enum ThreadStatus {\n ACTIVE = \"active\",\n COMPLETED = \"completed\",\n ABORTED = \"aborted\",\n}\n\n/**\n * Thread buffer configuration\n */\nexport interface ThreadBufferConfig {\n ttl?: number; // Time-to-live in milliseconds (default: 1 hour)\n cleanupInterval?: number; // Optional: periodic cleanup interval in ms\n}\n\n/**\n * Thread buffer state\n */\nexport interface ThreadBuffer {\n threadId: string;\n chunks$: ReplaySubject<MessageChunk>; // Ordered list of chunks\n status: ThreadStatus;\n createdAt: number;\n updatedAt: number;\n expiresAt: number; // TTL expiration timestamp\n}\n\n/**\n * Buffer statistics\n */\nexport interface BufferStats {\n totalThreads: number;\n activeThreads: number;\n completedThreads: number;\n abortedThreads: number;\n config: Required<ThreadBufferConfig>;\n}\n","/**\n * InMemoryChunkBuffer\n *\n * In-memory implementation of ChunkBuffer with hybrid cleanup strategy:\n * - Lazy cleanup: expired threads are removed on access\n * - Optional periodic cleanup: background timer to clean expired threads\n */\n\nimport { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { EventEmitter, once } from \"events\";\nimport { ChunkBuffer } from \"./ChunkBuffer\";\nimport {\n BufferStats,\n ThreadBuffer,\n ThreadBufferConfig,\n ThreadStatus,\n} from \"./types\";\nimport {\n ReplaySubject,\n Observable,\n Subscription,\n observeOn,\n asyncScheduler,\n} from \"rxjs\";\n\nexport class InMemoryChunkBuffer extends ChunkBuffer {\n private buffers: Map<string, ThreadBuffer>;\n private config: Required<ThreadBufferConfig> & { maxChunks?: number };\n private cleanupTimer?: NodeJS.Timeout;\n\n constructor(config?: ThreadBufferConfig & { maxChunks?: number }) {\n super();\n this.buffers = new Map();\n\n // Default: 1 hour TTL, no periodic cleanup (lazy only)\n this.config = {\n ttl: config?.ttl ?? 60 * 60 * 1000,\n cleanupInterval: config?.cleanupInterval ?? 0,\n maxChunks: config?.maxChunks ?? 1000, // Default max chunks per thread\n };\n\n // Start periodic cleanup only if cleanupInterval is specified\n if (this.config.cleanupInterval > 0) {\n this.startCleanupTimer();\n }\n }\n\n /**\n * Start automatic periodic cleanup timer\n */\n private startCleanupTimer(): void {\n if (this.config.cleanupInterval <= 0) return;\n\n this.cleanupTimer = setInterval(() => {\n this.cleanupExpiredThreads().catch(console.error);\n }, this.config.cleanupInterval);\n\n // Don't prevent process from exiting\n if (this.cleanupTimer.unref) {\n this.cleanupTimer.unref();\n }\n }\n\n /**\n * Stop cleanup timer (for cleanup/shutdown)\n */\n public stopCleanupTimer(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * Check if a buffer is expired (lazy cleanup helper)\n */\n private isExpired(buffer: ThreadBuffer): boolean {\n return buffer.expiresAt <= Date.now();\n }\n\n /**\n * Get buffer if valid, perform lazy cleanup if expired\n */\n private getBufferIfValid(threadId: string): ThreadBuffer | undefined {\n const buffer = this.buffers.get(threadId);\n\n if (buffer && this.isExpired(buffer)) {\n // Lazy cleanup: remove expired buffer on access\n this.buffers.delete(threadId);\n return undefined;\n }\n\n return buffer;\n }\n\n /**\n * Create or get thread buffer\n */\n private getOrCreateBuffer(threadId: string): ThreadBuffer {\n // First check with lazy cleanup\n let buffer = this.getBufferIfValid(threadId);\n if (!buffer) {\n const now = Date.now();\n buffer = {\n threadId,\n chunks$: new ReplaySubject<MessageChunk>(\n this.config.maxChunks ?? 100000\n ),\n status: ThreadStatus.ACTIVE,\n createdAt: now,\n updatedAt: now,\n expiresAt: now + this.config.ttl,\n };\n this.buffers.set(threadId, buffer);\n }\n\n if (buffer.status !== ThreadStatus.ACTIVE) {\n buffer.status = ThreadStatus.ACTIVE;\n buffer.chunks$ = new ReplaySubject<MessageChunk>(\n this.config.maxChunks ?? 100000\n );\n buffer.updatedAt = Date.now();\n buffer.expiresAt = Date.now() + this.config.ttl;\n }\n\n return buffer;\n }\n\n async addChunk(threadId: string, content: MessageChunk): Promise<void> {\n const buffer = this.getOrCreateBuffer(threadId);\n\n const chunk: MessageChunk = content;\n buffer.chunks$.next(chunk);\n buffer.updatedAt = Date.now();\n\n // Auto-extend TTL on activity\n buffer.expiresAt = Date.now() + this.config.ttl;\n buffer.status = ThreadStatus.ACTIVE;\n\n // Notify listeners\n }\n\n async completeThread(threadId: string): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n buffer.status = ThreadStatus.COMPLETED;\n buffer.updatedAt = Date.now();\n buffer.chunks$.complete();\n }\n }\n\n async abortThread(threadId: string): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n buffer.status = ThreadStatus.ABORTED;\n buffer.updatedAt = Date.now();\n buffer.chunks$.error(new Error(\"Thread aborted\"));\n }\n }\n\n async isThreadActive(threadId: string): Promise<boolean> {\n const buffer = this.getBufferIfValid(threadId);\n return buffer?.status === ThreadStatus.ACTIVE;\n }\n\n async getThreadStatus(threadId: string): Promise<ThreadStatus | undefined> {\n return this.getBufferIfValid(threadId)?.status;\n }\n\n async getThreadBuffer(threadId: string): Promise<ThreadBuffer | undefined> {\n const buffer = this.getBufferIfValid(threadId);\n if (!buffer) return undefined;\n return buffer;\n }\n\n async clearThread(threadId: string): Promise<void> {\n this.buffers.delete(threadId);\n }\n\n async getActiveThreads(): Promise<string[]> {\n const activeThreads: string[] = [];\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n // Apply lazy cleanup\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n continue;\n }\n\n if (buffer.status === ThreadStatus.ACTIVE) {\n activeThreads.push(threadId);\n }\n }\n\n return activeThreads;\n }\n\n async getAllThreads(): Promise<string[]> {\n const validThreads: string[] = [];\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n // Apply lazy cleanup\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n } else {\n validThreads.push(threadId);\n }\n }\n\n return validThreads;\n }\n\n async hasThread(threadId: string): Promise<boolean> {\n return this.getBufferIfValid(threadId) !== undefined;\n }\n\n /**\n * Cleanup expired threads based on TTL\n * Returns number of threads cleaned up\n */\n async cleanupExpiredThreads(): Promise<number> {\n const now = Date.now();\n let cleanedCount = 0;\n\n for (const [threadId, buffer] of this.buffers.entries()) {\n if (buffer.expiresAt <= now) {\n this.buffers.delete(threadId);\n cleanedCount++;\n }\n }\n\n return cleanedCount;\n }\n\n async extendThreadTTL(\n threadId: string,\n additionalMs?: number\n ): Promise<void> {\n const buffer = this.getBufferIfValid(threadId);\n if (buffer) {\n const extension = additionalMs ?? this.config.ttl;\n buffer.expiresAt = Date.now() + extension;\n buffer.updatedAt = Date.now();\n }\n }\n\n async *getNewChunksSinceContentIterator(\n threadId: string,\n messageId: string,\n knownContent: string\n ): AsyncIterable<MessageChunk> {\n const buffer = this.getBufferIfValid(threadId);\n if (!buffer) return;\n\n let accumulatedContent = \"\";\n const queue: MessageChunk[] = [];\n let resolveNext: (() => void) | null = null;\n let errorNext: ((err: any) => void) | null = null;\n let isCompleted = false;\n let pendingError: Error | null = null; // Track errors that occur when not waiting\n\n const subscription = buffer.chunks$\n .pipe(observeOn(asyncScheduler))\n .subscribe({\n next: (chunk) => {\n queue.push(chunk);\n if (resolveNext) {\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n error: (err) => {\n pendingError = err; // Always store the error\n\n if (errorNext) {\n const reject = errorNext;\n errorNext = null;\n reject(err);\n } else if (resolveNext) {\n // If waiting on resolveNext, wake it up to check pendingError\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n complete: () => {\n isCompleted = true;\n if (resolveNext) {\n const resolve = resolveNext;\n resolveNext = null;\n resolve();\n }\n },\n });\n let startYieldChunk = false;\n\n try {\n while (true) {\n if (pendingError) {\n throw pendingError;\n }\n if (queue.length === 0) {\n if (isCompleted) break;\n await new Promise<void>((resolve, reject) => {\n resolveNext = resolve;\n errorNext = reject;\n });\n }\n // Check error again after waking up\n if (pendingError) {\n throw pendingError;\n }\n while (queue.length > 0) {\n const chunk = queue.shift();\n if (!chunk) continue;\n\n if (chunk.data?.id === messageId) {\n startYieldChunk = true;\n accumulatedContent += chunk.data?.content || \"\";\n }\n // if (accumulatedContent.length > knownContent.length) {\n // startYieldChunk = true;\n // }\n if (startYieldChunk) {\n yield chunk;\n }\n\n // if (accumulatedContent.length > knownContent.length) {\n // if (accumulatedContent.startsWith(knownContent)) {\n // yield chunk;\n // } else {\n // console.log(\n // \"accumulatedContent not starts with knownContent\",\n // accumulatedContent,\n // knownContent\n // );\n // }\n // }\n }\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n public getStats(): BufferStats {\n let activeCount = 0;\n let completedCount = 0;\n let abortedCount = 0;\n\n const validBuffers: ThreadBuffer[] = [];\n for (const [threadId, buffer] of this.buffers.entries()) {\n if (this.isExpired(buffer)) {\n this.buffers.delete(threadId);\n } else {\n validBuffers.push(buffer);\n }\n }\n\n for (const buffer of validBuffers) {\n switch (buffer.status) {\n case ThreadStatus.ACTIVE:\n activeCount++;\n break;\n case ThreadStatus.COMPLETED:\n completedCount++;\n break;\n case ThreadStatus.ABORTED:\n abortedCount++;\n break;\n }\n }\n\n return {\n totalThreads: validBuffers.length,\n activeThreads: activeCount,\n completedThreads: completedCount,\n abortedThreads: abortedCount,\n\n config: this.config,\n };\n }\n\n public dispose(): void {\n this.stopCleanupTimer();\n this.buffers.clear();\n }\n}\n","/**\n * ChunkBufferLatticeManager\n * \n * Manages ChunkBuffer instances following the Lattice pattern\n */\n\nimport { BaseLatticeManager } from '../base/BaseLatticeManager';\nimport { ChunkBuffer } from './ChunkBuffer';\n\n/**\n * ChunkBuffer Lattice Manager\n */\nexport class ChunkBufferLatticeManager extends BaseLatticeManager<ChunkBuffer> {\n private static instance: ChunkBufferLatticeManager;\n \n /**\n * Private constructor for singleton pattern\n */\n private constructor() {\n super();\n }\n \n /**\n * Get singleton instance\n */\n public static getInstance(): ChunkBufferLatticeManager {\n if (!ChunkBufferLatticeManager.instance) {\n ChunkBufferLatticeManager.instance = new ChunkBufferLatticeManager();\n }\n return ChunkBufferLatticeManager.instance;\n }\n \n /**\n * Get Lattice type identifier\n */\n protected getLatticeType(): string {\n return 'chunk_buffer';\n }\n}\n\n// Convenience functions\nexport const getChunkBuffer = (key: string): ChunkBuffer | undefined =>\n ChunkBufferLatticeManager.getInstance().get(key);\n\nexport const registerChunkBuffer = (key: string, buffer: ChunkBuffer): void =>\n ChunkBufferLatticeManager.getInstance().register(key, buffer);\n\nexport const hasChunkBuffer = (key: string): boolean =>\n ChunkBufferLatticeManager.getInstance().has(key);\n\n"],"mappings":"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","names":["z","import_zod","z","import_langgraph","import_protocols","import_zod","import_langgraph","tool","stateSchema","import_langchain","import_langchain","import_langgraph","import_zod","micromatch","micromatch","z3","result","import_v3","import_langchain","import_langgraph","import_langchain","import_messages","import_langgraph","import_micromatch","import_langgraph","import_zod","import_langchain","tool","import_protocols","ThreadStatus"]}
|