@faapi/faapi 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -177,6 +177,101 @@ interface ResponseConfig {
177
177
  message: string;
178
178
  }) => unknown;
179
179
  }
180
+ /**
181
+ * LLM 提供方配置(Phase 2.4)
182
+ *
183
+ * 定义如何连接 LLM 服务(OpenAI 兼容 API),由 Phase 3.2 的 `@faapi/agent` 插件读取。
184
+ * 支持 `provider` 标识 + OpenAI 兼容字段(apiKey / model / baseURL),
185
+ * 额外字段透传给 LLM API(如 temperature / max_tokens)。
186
+ *
187
+ * `model` 是默认模型,agent 自身 `config.model` 可覆盖。
188
+ */
189
+ interface LlmConfig {
190
+ /**
191
+ * LLM 提供方标识(如 'openai' / 'anthropic')
192
+ *
193
+ * Phase 3.2 的 provider 模块按此值选择对应的 LLM 适配器。
194
+ */
195
+ provider: string;
196
+ /**
197
+ * API key(从 `process.env` 读取,避免硬编码)
198
+ *
199
+ * 如 `process.env.OPENAI_API_KEY`。
200
+ */
201
+ apiKey?: string;
202
+ /**
203
+ * 默认模型(如 'gpt-4o'),agent 自身 `config.model` 优先
204
+ */
205
+ model?: string;
206
+ /**
207
+ * API 基础 URL(可选,用于 OpenAI 兼容 API 如 Azure OpenAI / 中转服务)
208
+ *
209
+ * 未设置时用 provider 对应的官方默认值(如 'https://api.openai.com/v1')。
210
+ */
211
+ baseURL?: string;
212
+ /**
213
+ * 其他透传参数(如 temperature / max_tokens / top_p)
214
+ *
215
+ * 这些字段原样传给 LLM API,由 provider 适配器处理。
216
+ */
217
+ [key: string]: unknown;
218
+ }
219
+ /**
220
+ * agent 子系统全局配置(Phase 2.4)
221
+ *
222
+ * 提供 agent 子系统的全局默认值,所有字段均可选,未设置时用框架默认值。
223
+ * agent 自身 `config.maxTurns` / `config.model` 优先于全局配置。
224
+ *
225
+ * ```ts
226
+ * import type { FaapiConfig } from '@faapi/faapi';
227
+ * export default {
228
+ * agent: {
229
+ * llm: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
230
+ * defaultAgent: 'researcher',
231
+ * maxTurns: 10,
232
+ * maxAgentDepth: 3,
233
+ * defaultTools: ['weather.getWeather'],
234
+ * },
235
+ * } satisfies FaapiConfig;
236
+ * ```
237
+ *
238
+ * 详见 `src/config/configTypes.md` agent 配置块章节。
239
+ */
240
+ interface AgentConfig {
241
+ /**
242
+ * LLM 提供方配置(Phase 3.2 由 @faapi/agent 插件使用)
243
+ *
244
+ * 未设置时 Phase 3.x 插件无法调用 LLM,agent 的 `run` 函数仍可手动实现。
245
+ */
246
+ llm?: LlmConfig;
247
+ /**
248
+ * 默认 agent 名,用于 `agent` 参数注入([injectParams](../injection/injectParams.md) Phase 2.3)
249
+ *
250
+ * Phase 2.3 的 `agent` 参数注入暂返回 `undefined`,Phase 3.x 的 @faapi/agent 插件
251
+ * 读取此值从 [agentRegistry](../injection/agentRegistry.md) 查找对应 agent 元数据,
252
+ * 注入 `AgentHandle`(含可调用 `run`)。
253
+ */
254
+ defaultAgent?: string;
255
+ /**
256
+ * 默认 tool 列表,所有 agent 都可用(无需在每个 agent 的 `tools` 重复声明)
257
+ *
258
+ * 与 agent 自身 `tools` 合并(都加入可用 tool 集合,去重)。
259
+ * 由 `@faapi/agent` 插件在 setup 时合并到 agent 的 tool 引用列表。
260
+ */
261
+ defaultTools?: string[];
262
+ /**
263
+ * 默认最大对话轮数(覆盖 agent 自身 `config.maxTurns`,agent 自身配置优先)
264
+ *
265
+ * Phase 3.3 的 reactLoop 使用此值作为递归深度防护。
266
+ */
267
+ maxTurns?: number;
268
+ /**
269
+ * agent 调用 agent 的最大递归深度(防护无限递归,Phase 3.3 reactLoop 使用)
270
+ *
271
+ * 默认值由 Phase 3.x 的 @faapi/agent 插件定义(如 3)。
272
+ */
273
+ maxAgentDepth?: number;
274
+ }
180
275
  /**
181
276
  * faapi 配置文件类型
182
277
  *
@@ -305,6 +400,31 @@ interface FaapiConfig {
305
400
  * ```
306
401
  */
307
402
  plugins?: PluginDeclaration[];
403
+ /**
404
+ * agent 子系统全局配置(Phase 2.4)
405
+ *
406
+ * 提供 agent 子系统的全局默认值:LLM 提供方、默认 agent、默认共享 tool、
407
+ * 最大对话轮数、agent 调用 agent 的最大递归深度。
408
+ *
409
+ * agent 自身 `config.maxTurns` / `config.model` 优先于全局配置。
410
+ * `defaultTools` 与 agent 自身 `tools` 合并(去重)。
411
+ *
412
+ * ```ts
413
+ * import type { FaapiConfig } from '@faapi/faapi';
414
+ * export default {
415
+ * agent: {
416
+ * llm: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
417
+ * defaultAgent: 'researcher',
418
+ * defaultTools: ['weather.getWeather'],
419
+ * maxTurns: 10,
420
+ * maxAgentDepth: 3,
421
+ * },
422
+ * } satisfies FaapiConfig;
423
+ * ```
424
+ *
425
+ * 详见 `src/config/configTypes.md` agent 配置块章节。
426
+ */
427
+ agent?: AgentConfig;
308
428
  /**
309
429
  * 扩展 ctx:在每次请求创建上下文后调用,可挂载自定义方法(如 ctx.xml、ctx.stream)
310
430
  *
@@ -654,6 +774,327 @@ declare function collectRouteSchemaSources(routes: RouteManifest, rootDir?: stri
654
774
  mergedAllTypes: Map<string, HandlerTypeInfo>;
655
775
  };
656
776
 
777
+ /**
778
+ * Agent 完整元数据
779
+ *
780
+ * 由 [extractAgentMetadata](./extractAgentMetadata.md) 产出,合并路径推导字段
781
+ * (来自 [scanAgents](../agents/scanAgents.md) 的 `AgentManifest`)与 AST 提取字段
782
+ * (JSDoc 描述、`@agent` 覆盖名、config 块字段)。
783
+ *
784
+ * 与 [ToolMetadata](./extractToolMetadata.md) 对称——一个从函数导出提取 JSDoc + 参数类型,
785
+ * 一个从 config 导出提取 JSDoc + 配置块。
786
+ *
787
+ * 字段来源:
788
+ * - `name` — `@agent` JSDoc 覆盖值,或 `pathMeta.name`(目录推导)
789
+ * - `filePath` / `hasConfig` / `hasRun` — 由 `pathMeta` 透传
790
+ * - `description` — JSDoc 注释块自由文本(对 LLM 可见)
791
+ * - `systemPrompt` / `tools` / `agents` / `model` / `maxTurns` — config 块字面量提取
792
+ */
793
+ interface AgentMetadata {
794
+ /** agent 名(`@agent` JSDoc 覆盖值 或 目录推导值) */
795
+ name: string;
796
+ /** JSDoc 描述(agent 描述,对 LLM 可见),无 JSDoc 或 JSDoc 无自由文本时为 `undefined` */
797
+ description?: string;
798
+ /** 源码相对路径(从 `pathMeta` 透传) */
799
+ filePath: string;
800
+ /** 是否导出 config 块(从 `pathMeta` 透传) */
801
+ hasConfig: boolean;
802
+ /** 是否导出 run 函数(从 `pathMeta` 透传) */
803
+ hasRun: boolean;
804
+ /** 系统提示词(config 块字面量提取),无/非字面量时为 `undefined` */
805
+ systemPrompt?: string;
806
+ /** agent 显式声明可用的 tool 引用列表(config 块字面量提取),无/含非字面量元素时为 `undefined` */
807
+ tools?: string[];
808
+ /** 可调用的其他 agent 名列表(config 块字面量提取),无/含非字面量元素时为 `undefined` */
809
+ agents?: string[];
810
+ /** LLM 模型名(config 块字面量提取),无/非字面量时为 `undefined` */
811
+ model?: string;
812
+ /** 最大对话轮数(config 块字面量提取),无/非字面量时为 `undefined` */
813
+ maxTurns?: number;
814
+ }
815
+ /**
816
+ * 路径推导的 agent 元数据(由 [scanAgents](../agents/scanAgents.ts) 计算)
817
+ *
818
+ * 透传到 [AgentMetadata](./extractAgentMetadata.ts) 输出,与 AST 提取字段合并。
819
+ * 与 [ToolPathMeta](./extractToolMetadata.md) 对称。
820
+ */
821
+ interface AgentPathMeta {
822
+ /** 目录推导的 agent 名(如 `researcher`) */
823
+ name: string;
824
+ /** 源码相对路径(如 `src/agents/researcher/handler.ts`) */
825
+ filePath: string;
826
+ /** 是否导出 config 块(scanAgents 正则检测) */
827
+ hasConfig: boolean;
828
+ /** 是否导出 run 函数(scanAgents 正则检测) */
829
+ hasRun: boolean;
830
+ }
831
+
832
+ /**
833
+ * Tool 完整元数据
834
+ *
835
+ * 由 [extractToolMetadata](./extractToolMetadata.md) 产出,合并路径推导字段
836
+ * (来自 [scanTools](../tools/scanTools.md) 的 `ToolManifest`)与 AST 提取字段
837
+ * (JSDoc 描述、`@tool` 覆盖名、第一个参数 interface 名)。
838
+ *
839
+ * 字段来源:
840
+ * - `name` — `@tool` JSDoc 覆盖值,或 `pathMeta.name`(路径推导)
841
+ * - `filePath` / `functionName` — 由 `pathMeta` 透传
842
+ * - `description` — JSDoc 注释块自由文本(对 LLM 可见)
843
+ * - `inputTypeName` — 第一个参数的 TypeReference 名(供 [extractTypeInfo](./extractHandlerTypes.md) 生成 zod schema)
844
+ */
845
+ interface ToolMetadata {
846
+ /** tool 名(`@tool` JSDoc 覆盖值 或 路径推导值) */
847
+ name: string;
848
+ /** JSDoc 描述(tool 描述,对 LLM 可见),无 JSDoc 或 JSDoc 无自由文本时为 `undefined` */
849
+ description?: string;
850
+ /** 第一个参数的 interface/type 名(用于生成 zod schema),
851
+ * 无参数/参数无类型标注/参数为内联类型字面量时为 `undefined` */
852
+ inputTypeName?: string;
853
+ /** 源码相对路径(从 `pathMeta` 透传) */
854
+ filePath: string;
855
+ /** 源码中的导出函数名(从 `pathMeta` 透传,AST 定位用,不受 `@tool` 覆盖影响) */
856
+ functionName: string;
857
+ }
858
+ /**
859
+ * 路径推导的 tool 元数据(由 [scanTools](../tools/scanTools.ts) 计算)
860
+ *
861
+ * 透传到 [ToolMetadata](./extractToolMetadata.ts) 输出,与 AST 提取字段合并。
862
+ */
863
+ interface ToolPathMeta {
864
+ /** 路径推导的 tool 名(如 `weather.getWeather`) */
865
+ name: string;
866
+ /** 源码相对路径(如 `src/tools/weather/handler.ts`) */
867
+ filePath: string;
868
+ }
869
+
870
+ /**
871
+ * 按名查找单个 agent
872
+ *
873
+ * @param name agent 名(如 `researcher`,含 `@agent` 覆盖值)
874
+ * @returns `AgentMetadata` 或 `undefined`(未注册)
875
+ */
876
+ declare function getAgent(name: string): AgentMetadata | undefined;
877
+ /**
878
+ * agent 包装为 tool 的描述符
879
+ *
880
+ * 与 [ToolMetadata](../ast/extractToolMetadata.md) 平行结构,供 reactLoop 把
881
+ * agent 当作 tool 发给 LLM。reactLoop 按 `kind` 字段路由执行:
882
+ * - `'tool'` → `loadToolModule` 加载 handler 函数
883
+ * - `'agent'` → `loadAgentModule` 加载 agent handler + 递归 reactLoop
884
+ *
885
+ * `name` 加 `agent.` 前缀避免与常规 tool 冲突,reactLoop 据此识别 sub-agent 递归。
886
+ * 不含 input schema——agent `run` 函数参数为开放式(任意 JSON),无类型约束。
887
+ */
888
+ interface AgentToolDescriptor {
889
+ /** 标识此 tool 实际是 agent(reactLoop 据此走 sub-agent 递归) */
890
+ kind: 'agent';
891
+ /** tool 名(默认 `agent.<agentName>`,避免与常规 tool 冲突) */
892
+ name: string;
893
+ /** agent 名(不含前缀,用于按名查找 agent 元数据) */
894
+ agentName: string;
895
+ /** 描述(对 LLM 可见,来自 `agent.description`),无 JSDoc 描述时为 `undefined` */
896
+ description?: string;
897
+ /** agent 元数据引用(reactLoop 取 `systemPrompt` / `model` / `maxTurns` / `filePath` 等) */
898
+ metadata: AgentMetadata;
899
+ }
900
+ /**
901
+ * 解析 agent 可用 tool 集合
902
+ *
903
+ * 只返回 agent 显式声明的 tool(agent config 块的 `tools` 字段)。
904
+ * 不在此处合并全局 `defaultTools`——`defaultTools` 的合并由 `@faapi/agent` 的
905
+ * `Agent.buildToolDefinitions` 在更上层完成(与 sub-agent 一起按 `name` 去重)。
906
+ * `resolveAgentTools` 只关心 agent 自身显式声明的部分,职责单一。
907
+ *
908
+ * agent 必须显式声明用哪些 tool,显式优于隐式。
909
+ *
910
+ * `tools` 中未在 toolRegistry 找到的 tool 名静默跳过(tool 可选可用,不强制存在)。
911
+ *
912
+ * 跨注册表依赖 [toolRegistry](./toolRegistry.ts) 的 `getTool`,
913
+ * 两个注册表由 `createAppBase` 在同一启动阶段水合。
914
+ *
915
+ * @param name agent 名
916
+ * @returns `ToolMetadata[]`(agent 未注册返回空数组)
917
+ */
918
+ declare function resolveAgentTools(name: string): ToolMetadata[];
919
+ /**
920
+ * 解析 agent 可调用的子 agent 集合
921
+ *
922
+ * 读 `agent.agents` 字段([extractAgentMetadata](../ast/extractAgentMetadata.md)
923
+ * 提取的 `config.agents` 字面量列表),按名查找已注册 agent。
924
+ *
925
+ * reactLoop 组装 LLM tool 列表:
926
+ * ```ts
927
+ * const tools = [
928
+ * ...resolveAgentTools(name), // 常规 tool
929
+ * ...resolveSubAgents(name).map((a) => asTool(a.name)!), // agent-as-tool
930
+ * ];
931
+ * ```
932
+ *
933
+ * @param name agent 名
934
+ * @returns `AgentMetadata[]`(`agents` 未设置 / agent 未注册返回空数组)
935
+ */
936
+ declare function resolveSubAgents(name: string): AgentMetadata[];
937
+
938
+ /**
939
+ * 加载后的 agent 模块
940
+ *
941
+ * 与 [ToolModule](./loadToolModule.md) 对称——agent 不像 tool 只有一个 handler 函数,
942
+ * 它导出 `config` 块(对象,含运行时可能动态求值的字段)和可选的 `run` 函数。
943
+ *
944
+ * - `config`:agent 配置对象(含 systemPrompt / tools / agents / model / maxTurns 等,
945
+ * 以及任何非字面量字段——AST 阶段仅提取字面量,动态值需运行时加载)
946
+ * - `run`:自定义 agent 运行逻辑(可选,替代默认 reactLoop)
947
+ *
948
+ * `AgentMetadata`(从 `faapi-agents.js` 水合)已含字面量字段,`loadAgentModule`
949
+ * 用于在运行时拿到完整 config 对象(含动态字段)和 run 函数引用。
950
+ */
951
+ interface AgentModule {
952
+ /**
953
+ * agent 配置对象(含运行时字段)
954
+ *
955
+ * `hasConfig` 为 true 时一定存在;为 false 时为 `undefined`。
956
+ * 可能是对象字面量(`export const config = {...}`)或函数返回值(`export function config() { return {...} }`)。
957
+ *
958
+ * 函数形式:本模块调用 `config()` 拿到返回值(无参调用,与 AST 阶段的字面量提取不同——
959
+ * 运行时可拿到动态求值结果)。
960
+ */
961
+ config: Record<string, unknown> | undefined;
962
+ /**
963
+ * 自定义 agent 运行函数(可选)
964
+ *
965
+ * `hasRun` 为 true 时一定为 function;为 false 时为 `undefined`。
966
+ * 调用方式由 `@faapi/agent` 子包的 Agent 类定义(Phase 3.x)。
967
+ */
968
+ run: ((...args: unknown[]) => unknown) | undefined;
969
+ }
970
+ /**
971
+ * 动态 import agent handler 文件并提取 `config` 和 `run` 导出
972
+ *
973
+ * Dev 按需编译模式(Vite 风格):先 `ensureCompiled` 确保产物存在再 import,
974
+ * 避免 import 不存在的文件污染 Vite SSR 内部状态(详见 [loadRouteModule](./loadRouteModule.md))。
975
+ * Prod 模式:产物在 build 阶段已固化,直接 import,失败即报错。
976
+ *
977
+ * 与 [loadToolModule](./loadToolModule.md) 的差异:
978
+ * - tool 按 `functionName` 提取单个函数(校验为 function)
979
+ * - agent 提取 `config`(对象或函数返回对象)和 `run`(函数,可选)
980
+ * - agent 的 config 可能为函数形式(`export function config() { return {...} }`),
981
+ * 本模块自动调用拿到返回值(与 AST 阶段仅提字面量不同——运行时拿动态值)
982
+ *
983
+ * 错误传递:
984
+ * - 编译失败 → 抛 "Failed to compile agent module"
985
+ * - import 失败 → 抛 "Failed to load agent module"
986
+ *
987
+ * @param filePath agent handler 文件的绝对路径(产物形式,如 `dist/agents/researcher/handler.js`)
988
+ * @param hasConfig 是否应提取 config 导出(来自 `AgentMetadata.hasConfig`)
989
+ * @param hasRun 是否应提取 run 导出(来自 `AgentMetadata.hasRun`)
990
+ * @param rootDir 项目根目录(按需编译模式用,可选)
991
+ */
992
+ declare function loadAgentModule(filePath: string, hasConfig: boolean, hasRun: boolean, rootDir?: string): Promise<AgentModule>;
993
+
994
+ /**
995
+ * 加载后的 tool 模块
996
+ *
997
+ * 与 `RouteModule` 对称——`functionName` 替代 `method`(tool 没有HTTP方法维度)。
998
+ * `handler` 是从模块解析出的 tool 函数,可直接调用。
999
+ */
1000
+ interface ToolModule {
1001
+ /** tool 函数(已校验为 function 类型) */
1002
+ handler: (...args: unknown[]) => unknown;
1003
+ /** 源码导出名(如 `getWeather`,用于日志/调试,与 `method` 对应) */
1004
+ functionName: string;
1005
+ }
1006
+ /**
1007
+ * 动态 import tool handler 文件并提取指定函数名的导出
1008
+ *
1009
+ * Dev 按需编译模式(Vite 风格):先 `ensureCompiled` 确保产物存在再 import,
1010
+ * 避免 import 不存在的文件污染 Vite SSR 内部状态(详见 [loadRouteModule](./loadRouteModule.md))。
1011
+ * Prod 模式:产物在 build 阶段已固化,直接 import,失败即报错。
1012
+ *
1013
+ * 错误传递:
1014
+ * - 编译失败 → 抛 "Failed to compile tool module"
1015
+ * - import 失败 → 抛 "Failed to load tool module"
1016
+ * - 导出不是函数 → 抛 "does not export a valid function"
1017
+ *
1018
+ * @param filePath tool handler 文件的绝对路径(产物形式,如 `dist/tools/weather/handler.js`)
1019
+ * @param functionName 源码导出函数名(如 `getWeather`,由 `ToolManifest.functionName` 提供)
1020
+ * @param rootDir 项目根目录(按需编译模式用,可选)
1021
+ */
1022
+ declare function loadToolModule(filePath: string, functionName: string, rootDir?: string): Promise<ToolModule>;
1023
+
1024
+ /**
1025
+ * 加载后的 tool schema 模块
1026
+ *
1027
+ * 与 [ToolModule](./loadToolModule.md) 对称——`schema` 替代 `handler`。
1028
+ *
1029
+ * `schema` 是 `unknown` 类型——faapi 核心不依赖 zod(zod 是 peerDep),
1030
+ * `zod.js` 由业务方安装的 zod 创建,`@faapi/agent` 负责断言为 zod schema 后
1031
+ * 调 `z.toJSONSchema` / `safeParse`。
1032
+ */
1033
+ interface ToolSchemaModule {
1034
+ /** zod schema 对象(由业务方安装的 zod 创建) */
1035
+ schema: unknown;
1036
+ /** schema 导出名(如 `WeatherInputSchema`,用于日志/调试) */
1037
+ schemaName: string;
1038
+ }
1039
+ /**
1040
+ * 动态加载 tool 的 zod.js schema 模块
1041
+ *
1042
+ * 与 [loadToolModule](./loadToolModule.md) 对称——一个加载 handler.js(tool 函数),
1043
+ * 一个加载 zod.js(tool schema)。
1044
+ *
1045
+ * 行为:
1046
+ * - `tool.inputTypeName` 为 `undefined` → 返回 `undefined`(无 schema,用自由 schema)
1047
+ * - zod.js 文件不存在 → 返回 `undefined`(schema 可选,缺失用自由 schema)
1048
+ * - import 失败 / 导出名不匹配 → 返回 `undefined`
1049
+ *
1050
+ * 与 route schema 不同(route schema 缺失抛 `InternalError`),tool schema 是可选的——
1051
+ * `@faapi/agent` 的 `resolveToolSchema` 未提供时用自由 schema `{ type: 'object' }`,
1052
+ * LLM 自由传参,handler 内部自行处理参数合法性。
1053
+ *
1054
+ * @param tool tool 元数据(含 `filePath` + `inputTypeName`)
1055
+ * @param rootDir 项目根目录(用于计算 zod.js 绝对路径,`tool.filePath` 是相对路径时拼接)
1056
+ */
1057
+ declare function loadToolSchema(tool: ToolMetadata, rootDir?: string): Promise<ToolSchemaModule | undefined>;
1058
+
1059
+ /**
1060
+ * 按全名查找单个 tool
1061
+ *
1062
+ * @param tool 全名(如 `weather.getWeather`)
1063
+ * @returns `ToolMetadata` 或 `undefined`(未注册)
1064
+ */
1065
+ declare function getTool(name: string): ToolMetadata | undefined;
1066
+
1067
+ /**
1068
+ * agent handle 工厂注册表(单例)
1069
+ *
1070
+ * 让 `@faapi/agent` 插件在启动时注册「请求级 agent handle 工厂」,
1071
+ * [injectParams](./injectParams.md) 在 `agent` 参数注入时调工厂拿到 `AgentHandle` 实例。
1072
+ *
1073
+ * 解耦设计:faapi 核心不依赖 `@faapi/agent`——核心只提供注册 / 查询点,
1074
+ * 工厂返回 `unknown`,具体类型由 `@faapi/agent` 的 `AgentHandle` 接口定义。
1075
+ *
1076
+ * 详见 [agentHandle.md](./agentHandle.md)。
1077
+ */
1078
+ /** agent handle 工厂函数(由 `@faapi/agent` 插件注册) */
1079
+ type AgentHandleFactory = (ctx: FaapiContext) => unknown;
1080
+ /**
1081
+ * 注册 agent handle 工厂
1082
+ *
1083
+ * 由 `@faapi/agent` 插件在 `setup()` 时调用,传入创建 `AgentHandle` 的工厂函数。
1084
+ * 二次注册覆盖第一次(与 `hydrateAgentRegistry` 全量替换同构)。
1085
+ *
1086
+ * 传入 `null` 等效于 [clearAgentHandleFactory](#clearAgentHandleFactory)。
1087
+ *
1088
+ * @param factory 工厂函数或 `null`(清理)
1089
+ */
1090
+ declare function registerAgentHandleFactory(factory: AgentHandleFactory | null): void;
1091
+ /**
1092
+ * 清空工厂注册(app close / 测试清理时调用)
1093
+ *
1094
+ * 与 `clearAgentRegistry` / `clearToolRegistry` 对称,避免测试间状态泄漏。
1095
+ */
1096
+ declare function clearAgentHandleFactory(): void;
1097
+
657
1098
  /**
658
1099
  * 加载 faapi 配置文件
659
1100
  *
@@ -822,10 +1263,14 @@ interface AppBase {
822
1263
  inject(options?: InjectOptions): Promise<InjectResponse>;
823
1264
  }
824
1265
 
825
- /** dev 应用接口(AppBase + reloadRoutes 热替换) */
1266
+ /** dev 应用接口(AppBase + reloadRoutes/reloadTools/reloadAgents 热替换) */
826
1267
  interface DevApp extends AppBase {
827
1268
  /** 重新水合路由清单 + 清 schema 缓存 + 更新 server 路由引用(dev 热替换用) */
828
1269
  reloadRoutes(): Promise<void>;
1270
+ /** 重新扫描 tools + 重生成 faapi-tools.js + 清缓存(dev 热替换用) */
1271
+ reloadTools(): Promise<void>;
1272
+ /** 重新扫描 agents + 重生成 faapi-agents.js + 清缓存(dev 热替换用) */
1273
+ reloadAgents(): Promise<void>;
829
1274
  }
830
1275
  /**
831
1276
  * dev 模式应用启动 API
@@ -872,4 +1317,4 @@ type ProdApp = AppBase;
872
1317
  */
873
1318
  declare function createProdApp(options?: CreateAppOptions): Promise<ProdApp>;
874
1319
 
875
- export { type ProdApp as App, CorsOptions, type CreateAppOptions, type DevApp, type FaapiConfig, FaapiContext, FaapiError, FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, HelmetOptions, type InjectOptions, type InjectResponse, InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type ResponseConfig, RouteManifest, RouteNotFoundError, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, collectRouteSchemaSources, createProdApp as createApp, createDevApp, createProdApp, createProgram, extractTypeInfo, getApp, getInputTypeForMethod, invalidateProgramCache, loadConfig, loadEnv, resolveTypeNode };
1320
+ export { type AgentConfig, type AgentHandleFactory, type AgentMetadata, type AgentModule, type AgentPathMeta, type AgentToolDescriptor, type ProdApp as App, CorsOptions, type CreateAppOptions, type DevApp, type FaapiConfig, FaapiContext, FaapiError, FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, HelmetOptions, type InjectOptions, type InjectResponse, InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, type LlmConfig, LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type ResponseConfig, RouteManifest, RouteNotFoundError, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, type ToolMetadata, type ToolModule, type ToolPathMeta, type ToolSchemaModule, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, clearAgentHandleFactory, collectRouteSchemaSources, createProdApp as createApp, createDevApp, createProdApp, createProgram, extractTypeInfo, getAgent, getApp, getInputTypeForMethod, getTool, invalidateProgramCache, loadAgentModule, loadConfig, loadEnv, loadToolModule, loadToolSchema, registerAgentHandleFactory, resolveAgentTools, resolveSubAgents, resolveTypeNode };