@faapi/agent 4.3.0 → 4.5.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/README.md CHANGED
@@ -44,12 +44,13 @@ import type { FaapiConfig } from '@faapi/faapi';
44
44
 
45
45
  export default {
46
46
  agent: {
47
- llm: {
48
- provider: 'openai',
49
- apiKey: process.env.OPENAI_API_KEY,
50
- model: 'gpt-4o',
47
+ llms: {
48
+ openai: {
49
+ provider: 'openai',
50
+ apiKey: process.env.OPENAI_API_KEY,
51
+ models: { 'gpt-4o': {} },
52
+ },
51
53
  },
52
- defaultAgent: 'researcher',
53
54
  maxTurns: 10,
54
55
  maxAgentDepth: 3,
55
56
  },
@@ -57,6 +58,18 @@ export default {
57
58
  } satisfies FaapiConfig;
58
59
  ```
59
60
 
61
+ 无默认 agent / 默认 provider——handler 调用时显式指定 agent 名与 model/provider:
62
+
63
+ ```ts
64
+ // src/api/chat/handler.ts
65
+ import type { AgentHandle } from '@faapi/agent';
66
+
67
+ export async function POST(agent: AgentHandle, body: { input: string }) {
68
+ const result = await agent.run(body.input, { agent: 'researcher', model: 'gpt-4o' });
69
+ return { content: result.content, turns: result.turns };
70
+ }
71
+ ```
72
+
60
73
  CLI 启动时动态加载——未安装时自动跳过,不影响核心功能。需单独安装:`pnpm add @faapi/agent`。
61
74
 
62
75
  ## 多 agent 组织
package/dist/index.d.ts CHANGED
@@ -510,21 +510,23 @@ declare function reactLoopStream(input: string | undefined, config: ReactLoopCon
510
510
  *
511
511
  * // src/api/chat/handler.ts
512
512
  * export function POST(agent: AgentHandle, body: { input: string }) {
513
- * const result = await agent.run(body.input);
513
+ * const result = await agent.run(body.input, { agent: 'researcher', model: 'gpt-4o' });
514
514
  * return { content: result.content, turns: result.turns };
515
515
  * }
516
516
  * ```
517
517
  *
518
- * 工厂未注册(`@faapi/agent` 插件未加载或 `config.agent.llm` / `defaultAgent` 未配置)
519
- * 时注入 `undefined`,handler 需自行处理。
518
+ * 仅在 `@faapi/agent` 插件未加载时注入 `undefined`,handler 需自行处理。
519
+ * `config.agent.llms` 未配置时工厂照常注册(外部 provider 模式)——
520
+ * `agent.run/stream` 需调用方传 `options.provider` 才能调用 LLM。
521
+ * 无默认 agent——每次 `run` / `stream` 必须显式传 `options.agent`。
520
522
  *
521
523
  * 详见 [agentHandle.md](./agentHandle.md)。
522
524
  */
523
525
  /**
524
- * `agent.run` / `agent.stream` 的 options 参数——临时覆盖本次调用的 LLM 配置
526
+ * `agent.run` / `agent.stream` 的 options 参数——本次调用的 LLM 配置
525
527
  *
526
- * 所有字段可选,不传或 `undefined` 时回落到下一优先级(agent 元数据 → 全局配置)。
527
- * **不修改 agent 自身状态**——下一次调用仍用默认配置。
528
+ * `agent` 必须显式传(无默认 agent);其余字段可选,不传或 `undefined` 时回落到
529
+ * 下一优先级(agent 元数据 → 全局配置)。**不修改 agent 自身状态**。
528
530
  *
529
531
  * `model` 是字符串 key,支持三种形式(解析规则见 [agentHandle.md](./agentHandle.md) 的
530
532
  * 「`options.model` 字符串 key 解析规则」):
@@ -532,23 +534,20 @@ declare function reactLoopStream(input: string | undefined, config: ReactLoopCon
532
534
  * - `provider/model` 一体化(如 `'openai/gpt-4o'`)
533
535
  * - 纯 model 名(如 `'gpt-4o'`)—— 在所有 provider 的 `models` 里查找,唯一时切到对应 provider
534
536
  *
537
+ * 不传 `model` 时用 agent 元数据 `config.model` 作为缺省 key 参与同一套解析。
535
538
  * 优先级(高 → 低):`options` > agent 元数据(`config.model` / `config.maxTurns`)> 全局
536
- * `AgentRuntimeConfig` / `defaultLlm` provider。详见 [agentHandle.md](./agentHandle.md) 的
537
- * Run-level 覆盖优先级表。
538
- *
539
- * `agent` 字段覆盖本次调用的 agent 名(不传时用 `config.agent.defaultAgent`,
540
- * 未设 defaultAgent 时必须显式传入)。
539
+ * `AgentRuntimeConfig`。详见 [agentHandle.md](./agentHandle.md) 的 Run-level 覆盖优先级表。
541
540
  *
542
541
  * @example
543
542
  * ```ts
543
+ * // 指定 agent(必须——无默认 agent)
544
+ * await agent.run(input, { agent: 'researcher' });
545
+ *
544
546
  * // 按请求切模型(纯 model 名,在 llms 里唯一时切到对应 provider)
545
- * await agent.run(input, { model: 'gpt-4o-mini' });
547
+ * await agent.run(input, { agent: 'researcher', model: 'gpt-4o-mini' });
546
548
  *
547
549
  * // provider/model 一体化形式(精确切换)
548
- * await agent.run(input, { model: 'anthropic/claude-3-5-sonnet' });
549
- *
550
- * // 指定 agent(不依赖 defaultAgent 配置)
551
- * await agent.run(input, { agent: 'researcher' });
550
+ * await agent.run(input, { agent: 'researcher', model: 'anthropic/claude-3-5-sonnet' });
552
551
  * ```
553
552
  */
554
553
  interface AgentRunOptions {
@@ -560,18 +559,41 @@ interface AgentRunOptions {
560
559
  */
561
560
  signal?: AbortSignal;
562
561
  /**
563
- * 覆盖本次调用的 agent 名(从 agentRegistry 查找对应元数据 / tools / sub-agents)
562
+ * 本次调用的 agent 名(必须显式传——config.agent defaultAgent 默认值)
564
563
  *
565
- * 不传时用 `config.agent.defaultAgent`。`defaultAgent` 未设时必须显式传入,
566
- * 否则抛 `AgentError`。
564
+ * agentRegistry 查找对应元数据 / tools / sub-agents。
565
+ * 不传抛 `AgentError`。
567
566
  */
568
567
  agent?: string;
569
568
  /**
570
569
  * 切换 provider + model 的字符串 key(支持 llms key / `provider/model` / 纯 model 名)
571
570
  *
572
- * 不传时用 `defaultLlm` provider + agent 元数据 `config.model`。
571
+ * 不传时用 agent 元数据 `config.model` 作为缺省 key 参与解析;
572
+ * 两者皆无且未传 `provider` 时抛 `AgentError`(无默认 provider)。
573
+ * `provider` 字段存在时本字段变为「原始 model 名」原样透传给外部 provider
574
+ * (不做 llms key 解析,支持带 / 的 model id),详见 {@link AgentRunOptions.provider}。
573
575
  */
574
576
  model?: string;
577
+ /**
578
+ * 外部 provider(本次调用临时使用,优先级最高——完全不查 `config.agent.llms`)
579
+ *
580
+ * 两种形式(运行时按形状判别,两者皆非抛 `AgentError`):
581
+ * - `LlmConfig` 对象(含字符串 `provider` 字段)→ 现场调 `createProvider` 创建适配器
582
+ * (浅拷贝 + `models` 兜底 `{}`,不改调用方对象),适用于 BYOK(用户自带 apiKey)/
583
+ * 按请求指定 baseURL 网关
584
+ * - `LLMProvider` 实例(有 `complete` / `stream` 方法)→ 直接使用,适用于框架未内置
585
+ * 适配器的 LLM 服务(内部自研模型网关等)
586
+ *
587
+ * 传入时 `options.model` 语义变为「原始 model 名」——不做 llms key 解析、不拆 `/`,
588
+ * 原样透传给该 provider(支持 OpenRouter 等带 `/` 的 model id)。
589
+ * LlmConfig 形式下 `options.model` 缺省时回落该 config 的 `models` 第一个 key,
590
+ * 两者皆无抛 `AgentError`;LLMProvider 实例形式下可为 `undefined`(自定义 provider 自决)。
591
+ *
592
+ * 仅影响本次调用——不进 providers Map、不修改 agent 状态。
593
+ * **sub-agent 递归继承父调用解析出的 provider**(sub 的 model 用其元数据声明的
594
+ * `config.model`,未声明时沿用父 model),不继承 options 对象本身。
595
+ */
596
+ provider?: LlmConfig | LLMProvider;
575
597
  /** 采样温度(透传给 LLM API,覆盖 provider/model 级 temperature) */
576
598
  temperature?: number;
577
599
  /** 最大生成 token 数(透传给 LLM API) */
@@ -635,14 +657,15 @@ interface AgentHandle {
635
657
  */
636
658
  stream(input?: string, options?: AgentRunOptions): AsyncIterable<ReactLoopStreamChunk>;
637
659
  /**
638
- * 把自身包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
660
+ * 把指定 agent 包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
639
661
  *
640
- * 用于 agent-as-tool 场景:父 agent 把子 agent 包装为 tool,
662
+ * 用于 agent-as-tool 场景:把 agent 包装为 tool,
641
663
  * 加入 LLM 可见 tool 列表,LLM 调用时触发 sub-agent 递归执行。
642
664
  *
665
+ * @param name agent 名(显式指定——无默认 agent)
643
666
  * @returns `AgentToolDescriptor` 或 `undefined`(agent 未注册)
644
667
  */
645
- asTool(): AgentToolDescriptor | undefined;
668
+ asTool(name: string): AgentToolDescriptor | undefined;
646
669
  }
647
670
 
648
671
  /**
@@ -735,16 +758,10 @@ interface ToolSchemaResolution {
735
758
  * 访问器签名与 faapi 核心对称(见 [agent.md](./agent.md) 依赖注入章节)。
736
759
  */
737
760
  interface AgentDeps {
738
- /** LLM provider 实例映射(key 是 provider 名,来自 config.agent.llms) */
761
+ /** LLM provider 实例映射(key 是 provider 名,来自 config.agent.llms;未配置时为空 Map) */
739
762
  providers: Map<string, LLMProvider>;
740
- /** 默认 provider 实例(config.agent.defaultLlm 对应,或 llms 第一个 key) */
741
- defaultProvider: LLMProvider;
742
- /** LLM provider 配置映射(含 models,用于 options.model key 解析) */
763
+ /** LLM provider 配置映射(含 models,用于 options.model key 解析;llms 未配置时为空对象) */
743
764
  llms: Record<string, LlmConfig>;
744
- /** 默认 provider key(config.agent.defaultLlm,或 llms 第一个 key) */
745
- defaultLlm: string;
746
- /** 当前 agent 名 */
747
- agentName: string;
748
765
  /** 项目根目录(Phase 3.5 接线时用于加载器) */
749
766
  rootDir: string;
750
767
  /** 全局 agent 配置覆盖 */
@@ -815,7 +832,7 @@ declare class Agent {
815
832
  */
816
833
  private readonly schemaCache;
817
834
  /**
818
- * @param deps 运行时依赖(访问器 + providers Map + defaultProvider + llms + config)
835
+ * @param deps 运行时依赖(访问器 + providers Map + llms + config)
819
836
  * @param depth 递归深度(默认 1 = 根 agent;sub-agent 递归时传入 depth+1)
820
837
  */
821
838
  constructor(deps: AgentDeps, depth?: number);
@@ -823,15 +840,17 @@ declare class Agent {
823
840
  * 非流式执行——组装 config 调 [reactLoop](./reactLoop.md)
824
841
  *
825
842
  * reactLoop 不知 agent 名(只关心循环逻辑),返回的 `result.trace.agentName` 为空字符串。
826
- * 本方法在 reactLoop 返回后填充 `this.deps.agentName`,让顶层 trace 标识"是哪个 agent 跑的"。
843
+ * 本方法在 reactLoop 返回后填充 `options.agent`,让顶层 trace 标识"是哪个 agent 跑的"。
827
844
  *
828
845
  * @param input 用户输入(可选——续跑场景不传新输入;input 与 `options.messages`
829
846
  * 都为空时抛 `AgentError`)
830
- * @param options 临时覆盖本次调用的 model(字符串 key)/ temperature / maxTokens /
831
- * messages / enableTracing
847
+ * @param options 本次调用配置——`agent`(agent 名,必须显式传,无默认 agent)/
848
+ * provider(外部 provider)/ model(字符串 key)/ temperature /
849
+ * maxTokens / messages / enableTracing
832
850
  * (不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
833
851
  * @returns 最终结果(content + messages + turns + stopReason + usage + trace?)
834
- * @throws {AgentError} agent 未注册;input 与 messages 都为空;续跑历史结构非法
852
+ * @throws {AgentError} 未传 options.agent;agent 未注册;input 与 messages 都为空;
853
+ * 续跑历史结构非法;provider/model 无法解析
835
854
  * @throws {ReactLoopError} 超出 maxTurns(`error.messages` 携带完整历史,可续跑)
836
855
  * @throws {AgentAbortError} 中断(`error.messages` 携带断点历史,可续跑)
837
856
  * @throws {Error} provider.complete 抛错时立即传播
@@ -842,24 +861,27 @@ declare class Agent {
842
861
  *
843
862
  * @param input 用户输入(可选——续跑场景不传新输入;input 与 `options.messages`
844
863
  * 都为空时抛 `AgentError`)
845
- * @param options 临时覆盖本次调用的 model(字符串 key)/ temperature / maxTokens /
846
- * messages(不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
864
+ * @param options 本次调用配置——`agent`(必须显式传)/ provider / model /
865
+ * temperature / maxTokens / messages
866
+ * (不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
847
867
  * @yields 流式 chunk(deltaContent / toolCall / toolResult / done)
848
- * @throws {AgentError} agent 未注册;input 与 messages 都为空;续跑历史结构非法
868
+ * @throws {AgentError} 未传 options.agent;agent 未注册;input 与 messages 都为空;
869
+ * 续跑历史结构非法;provider/model 无法解析
849
870
  * @throws {ReactLoopError} 超出 maxTurns(`error.messages` 携带完整历史,可续跑)
850
871
  * @throws {AgentAbortError} 中断(`error.messages` 携带断点历史,可续跑)
851
872
  * @throws {Error} provider.stream 抛错时立即传播
852
873
  */
853
874
  stream(input?: string, options?: AgentRunOptions): AsyncIterable<ReactLoopStreamChunk>;
854
875
  /**
855
- * 把自身包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
876
+ * 把指定 agent 包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
856
877
  *
857
878
  * 与 [agentRegistry.asTool](../../faapi/src/injection/agentRegistry.md) 同构——
858
879
  * Agent 类自带此方法便于在注入器场景直接调用(不必再过注册表)。
859
880
  *
881
+ * @param name agent 名(显式指定——无默认 agent)
860
882
  * @returns `AgentToolDescriptor` 或 `undefined`(agent 未注册)
861
883
  */
862
- asTool(): AgentToolDescriptor | undefined;
884
+ asTool(name: string): AgentToolDescriptor | undefined;
863
885
  /**
864
886
  * 查询 tool schema(带缓存)
865
887
  *
@@ -873,41 +895,57 @@ declare class Agent {
873
895
  /**
874
896
  * 组装 ReactLoopConfig
875
897
  *
876
- * 1. 解析有效 agent 名:`options.agent` > `deps.agentName`(`config.agent.defaultAgent`)
898
+ * 1. 解析有效 agent 名:`options.agent`(必须显式传——无默认 agent,不传抛 AgentError)
877
899
  * 2. 查 agent 元数据(未注册抛 AgentError)——用 `getAgent` 拿 AgentCore
878
900
  * (LLM-facing 字段:systemPrompt / model / maxTurns)
879
901
  * 3. buildToolDefinitions 组装 tool 列表(用有效 agent 名查 tools / sub-agents)
880
- * 4. config 字段优先级(高 → 低):`options` > agent 元数据 > 全局 AgentRuntimeConfig / deps.defaultProvider
902
+ * 4. config 字段优先级(高 → 低):`options` > agent 元数据 > 全局 AgentRuntimeConfig
881
903
  *
882
- * `options.model` 是字符串 key,由 {@link resolveModelKey} 解析为 provider + model
883
- * (支持 llms key 精确匹配 / `provider/model` 一体化 / model 名模糊匹配)。
884
- * 不传 `options.model` 时用 `deps.defaultProvider` + agent 元数据 `config.model`。
904
+ * `options.provider`(外部 provider)存在时由 {@link resolveExternalProvider} 物化,
905
+ * 优先级最高——`options.model` 变为原始 model 名原样透传(不解析 llms key)。
906
+ * 否则 `options.model` 是字符串 key,由 {@link resolveModelKey} 解析为 provider + model
907
+ * (支持 llms key 精确匹配 / `provider/model` 一体化 / 纯 model 名模糊匹配;
908
+ * 未传 `options.model` 时用 agent 元数据 `config.model` 作为缺省 key)。
885
909
  * 详见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」。
886
910
  *
887
- * `options.agent` 覆盖本次调用的 agent 名——不传时用 `deps.agentName`(来自
888
- * `config.agent.defaultAgent`)。`defaultAgent` 未设且 `options.agent` 未传时抛
889
- * `AgentError`。
890
- *
891
911
  * **输入守卫**(续跑入口,见 [reactLoop.md](./reactLoop.md) 中断恢复章节):
892
912
  * `input` 与 `options.messages` 都为空时抛 `AgentError`(不发送空请求);
893
913
  * `options.messages` 提供时先经 `validateResumeHistory` 结构校验,非法抛
894
914
  * `AgentError`,不发起 LLM 请求。
895
915
  */
896
916
  private buildLoopConfig;
917
+ /**
918
+ * 解析外部 provider(`options.provider`)→ provider + model
919
+ *
920
+ * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.provider` 外部 provider」章节:
921
+ * - `LLMProvider` 实例 → 直接使用,`modelKey` 原样透传(可为 `undefined`,自定义 provider 自决)
922
+ * - `LlmConfig` 配置对象 → `createProvider` 现场创建,`modelKey` 原样透传;
923
+ * 缺省回落该 config `models` 第一个 key,两者皆无抛 `AgentError`(早失败,不发请求)
924
+ * - `modelKey` 不做 llms key 解析、不拆 `/`(支持 OpenRouter 等带斜杠的 model id)
925
+ *
926
+ * 仅本次调用生效:不进 providers Map、sub-agent 递归不继承(executeSubAgent 构造
927
+ * subDeps 时不携带 options,sub-agent 走默认解析链路)。
928
+ *
929
+ * @throws {AgentError} provider 形式非法;LlmConfig 形式下 model 缺失
930
+ */
931
+ private resolveExternalProvider;
897
932
  /**
898
933
  * 解析 `options.model` 字符串 key → provider + model
899
934
  *
900
- * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」:
901
- * 1. `undefined` `deps.defaultProvider` + `meta.model`
902
- * 2. 精确匹配 `deps.providers` key → 该 provider + 其 `models` 第一个 key
903
- * 3. `/` → `provider/model` 形式,`deps.providers.get(provider)` +model
935
+ * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」。
936
+ * 无默认 provider——`key` 未传时用 agent 元数据 `config.model` 作为缺省 key;
937
+ * 两者皆无抛 `AgentError`(要求调用方传 `options.model` `options.provider`)。
938
+ * 1. 精确匹配 `deps.providers` key → provider + 其 `models` 第一个 key
939
+ * (该 provider 未声明 `models` 时回落 `meta.model`)
940
+ * 2. 含 `/` → `provider/model` 形式,`deps.providers.get(provider)` + 该 model
904
941
  * (要求该 model 在 `deps.llms[provider].models` 里)
905
- * 4. 不含 `/` 且非 provider key → 在所有 provider 的 `models` 里按 model 名查找
942
+ * 3. 不含 `/` 且非 provider key → 在所有 provider 的 `models` 里按 model 名查找
906
943
  * - 唯一 → 该 provider + 该 model
907
944
  * - 多个 → 抛 `AgentError`(要求用 `provider/model` 消歧)
908
945
  * - 无 → 抛 `AgentError`
909
946
  *
910
- * @throws {AgentError} key 解析失败(provider/model 不存在或歧义)
947
+ * @throws {AgentError} key 与 `meta.model` 均缺省;key 解析失败(provider/model
948
+ * 不存在或歧义)
911
949
  */
912
950
  private resolveModelKey;
913
951
  /**
@@ -930,8 +968,9 @@ declare class Agent {
930
968
  * - `agent.` 前缀 → {@link executeSubAgent} 递归(含 enableTracing + TracingToolResult 包装)
931
969
  * - 常规 tool → `loadToolModule` 加载 handler + 可选 input 校验 → 调用
932
970
  *
933
- * `enableTracing` 由 [buildLoopConfig](#buildLoopConfig) 闭包捕获传入,用于 sub-agent
934
- * 调用时决定是否包装 [TracingToolResult](./trace.md) 携带 sub-trace。
971
+ * `callCtx` 由 [buildLoopConfig](#buildLoopConfig) 闭包捕获传入——本次调用的有效
972
+ * agent 名(白名单校验)、enableTracing(sub-agent tracing 包装)与解析出的
973
+ * provider/model(sub-agent 递归继承)。常规 tool 不需要 tracing 包装,直接返回结果。
935
974
  *
936
975
  * **常规 tool 校验失败**:不抛错,返回 `{ error }` 对象——reactLoop stringify 后
937
976
  * 作为 tool 结果回传 LLM,LLM 可据此修正参数重试。
@@ -944,7 +983,9 @@ declare class Agent {
944
983
  *
945
984
  * 1. `maxAgentDepth` 防护——超限抛 {@link AgentRecursionError}
946
985
  * 2. sub-agent handler 导出 `run` 时调自定义 `mod.run(args)`(无 trace,与常规 tool 一致)
947
- * 3. 无 `run` 时调 `subAgent.run(stringify(args), { enableTracing })` 走默认 reactLoop
986
+ * 3. 无 `run` 时调 `subAgent.run(stringify(args), { agent, provider, model, enableTracing })`
987
+ * 走默认 reactLoop——继承父调用的 provider,sub 元数据声明 `model` 时优先用自身的,
988
+ * 未声明时沿用父 model
948
989
  *
949
990
  * **tracing 路径**:`enableTracing=true` 时,subAgent.run 返回的 `result.trace`(agentName
950
991
  * 已被 `Agent.run` 填为 subName)被包装为 [TracingToolResult](./trace.md) 返回给 reactLoop。
@@ -982,8 +1023,6 @@ declare class Agent {
982
1023
  * models: { 'gpt-4o': {}, 'gpt-4o-mini': { temperature: 0.5 } },
983
1024
  * },
984
1025
  * },
985
- * defaultLlm: 'openai',
986
- * defaultAgent: 'researcher',
987
1026
  * maxTurns: 10,
988
1027
  * },
989
1028
  * plugins: ['@faapi/agent'],
@@ -991,19 +1030,18 @@ declare class Agent {
991
1030
  * ```
992
1031
  *
993
1032
  * 插件 setup 时:
994
- * 1. 遍历 `config.agent.llms` 每项调 `createProvider` → `Map<providerKey, LLMProvider>`
995
- * 2. 读 `config.agent.defaultLlm` `defaultProvider`(未设时用 `llms` 第一个 key)
996
- * 3. `config.agent.defaultAgent`(可选) / `maxTurns` / `maxAgentDepth`
997
- * 4. 从 `@faapi/faapi` import 注册表/加载器访问器(getAgent / getTool / resolveAgentTools /
1033
+ * 1. 遍历 `config.agent.llms`(可选)→ 每项调 `createProvider` → `Map<providerKey, LLMProvider>`
1034
+ * 2. 读 `config.agent.maxTurns` / `maxAgentDepth`
1035
+ * 3. `@faapi/faapi` import 注册表/加载器访问器(getAgent / getTool / resolveAgentTools /
998
1036
  * resolveSubAgents / loadAgentModule / loadToolModule)
999
- * 5. `registerAgentHandleFactory` 注册工厂——每次请求时构造 [Agent](./agent.md) 实例注入到
1037
+ * 4. `registerAgentHandleFactory` 注册工厂——每次请求时构造 [Agent](./agent.md) 实例注入到
1000
1038
  * handler 的 `agent` 参数
1001
1039
  *
1002
- * 配置缺失时(`agent.llms` 未设置)跳过工厂注册并打印警告,
1003
- * handler 的 `agent` 参数注入 `undefined`。
1040
+ * 无默认 agent / 默认 provider——`agent.run/stream` 每次调用显式传 `options.agent` +
1041
+ * `options.model` / `options.provider`。
1004
1042
  *
1005
- * `defaultAgent` 可选——未设时 handler 需通过 `agent.run(input, { agent: 'name' })`
1006
- * 显式指定 agent 名。
1043
+ * `agent.llms` 可选——未配置时工厂照常注册(外部 provider 模式),`agent.run/stream`
1044
+ * 需调用方传 `options.provider` 才能调用 LLM。只有插件未加载时 `agent` 参数才注入 `undefined`。
1007
1045
  *
1008
1046
  * 详见 [plugin.md](./plugin.md)。
1009
1047
  */