@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/dist/index.js CHANGED
@@ -849,6 +849,21 @@ async function* reactLoopStream(input, config) {
849
849
  // src/agent.ts
850
850
  var DEFAULT_MAX_AGENT_DEPTH = 3;
851
851
  var VALID_MESSAGE_ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool"]);
852
+ function isProviderInstance(value) {
853
+ return typeof value === "object" && value !== null && typeof value.complete === "function" && typeof value.stream === "function";
854
+ }
855
+ function isProviderConfig(value) {
856
+ return typeof value === "object" && value !== null && typeof value.provider === "string";
857
+ }
858
+ function materializeProvider(external) {
859
+ if (isProviderInstance(external)) return external;
860
+ if (isProviderConfig(external)) {
861
+ return createProvider({ ...external, models: external.models ?? {} });
862
+ }
863
+ throw new AgentError(
864
+ 'options.provider must be an LlmConfig object (with a string "provider" field) or an LLMProvider instance (with complete/stream methods)'
865
+ );
866
+ }
852
867
  function validateResumeHistory(messages) {
853
868
  messages.forEach((message, index) => {
854
869
  if (!VALID_MESSAGE_ROLES.has(message.role)) {
@@ -904,7 +919,7 @@ var Agent = class _Agent {
904
919
  */
905
920
  schemaCache = /* @__PURE__ */ new Map();
906
921
  /**
907
- * @param deps 运行时依赖(访问器 + providers Map + defaultProvider + llms + config)
922
+ * @param deps 运行时依赖(访问器 + providers Map + llms + config)
908
923
  * @param depth 递归深度(默认 1 = 根 agent;sub-agent 递归时传入 depth+1)
909
924
  */
910
925
  constructor(deps, depth = 1) {
@@ -915,15 +930,17 @@ var Agent = class _Agent {
915
930
  * 非流式执行——组装 config 调 [reactLoop](./reactLoop.md)
916
931
  *
917
932
  * reactLoop 不知 agent 名(只关心循环逻辑),返回的 `result.trace.agentName` 为空字符串。
918
- * 本方法在 reactLoop 返回后填充 `this.deps.agentName`,让顶层 trace 标识"是哪个 agent 跑的"。
933
+ * 本方法在 reactLoop 返回后填充 `options.agent`,让顶层 trace 标识"是哪个 agent 跑的"。
919
934
  *
920
935
  * @param input 用户输入(可选——续跑场景不传新输入;input 与 `options.messages`
921
936
  * 都为空时抛 `AgentError`)
922
- * @param options 临时覆盖本次调用的 model(字符串 key)/ temperature / maxTokens /
923
- * messages / enableTracing
937
+ * @param options 本次调用配置——`agent`(agent 名,必须显式传,无默认 agent)/
938
+ * provider(外部 provider)/ model(字符串 key)/ temperature /
939
+ * maxTokens / messages / enableTracing
924
940
  * (不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
925
941
  * @returns 最终结果(content + messages + turns + stopReason + usage + trace?)
926
- * @throws {AgentError} agent 未注册;input 与 messages 都为空;续跑历史结构非法
942
+ * @throws {AgentError} 未传 options.agent;agent 未注册;input 与 messages 都为空;
943
+ * 续跑历史结构非法;provider/model 无法解析
927
944
  * @throws {ReactLoopError} 超出 maxTurns(`error.messages` 携带完整历史,可续跑)
928
945
  * @throws {AgentAbortError} 中断(`error.messages` 携带断点历史,可续跑)
929
946
  * @throws {Error} provider.complete 抛错时立即传播
@@ -932,7 +949,7 @@ var Agent = class _Agent {
932
949
  const config = await this.buildLoopConfig(input, options);
933
950
  const result = await reactLoop(input, config);
934
951
  if (result.trace) {
935
- result.trace.agentName = options?.agent ?? this.deps.agentName;
952
+ result.trace.agentName = options?.agent ?? "";
936
953
  }
937
954
  return result;
938
955
  }
@@ -941,10 +958,12 @@ var Agent = class _Agent {
941
958
  *
942
959
  * @param input 用户输入(可选——续跑场景不传新输入;input 与 `options.messages`
943
960
  * 都为空时抛 `AgentError`)
944
- * @param options 临时覆盖本次调用的 model(字符串 key)/ temperature / maxTokens /
945
- * messages(不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
961
+ * @param options 本次调用配置——`agent`(必须显式传)/ provider / model /
962
+ * temperature / maxTokens / messages
963
+ * (不修改 agent 自身状态,详见 [agentHandle](./agentHandle.md))
946
964
  * @yields 流式 chunk(deltaContent / toolCall / toolResult / done)
947
- * @throws {AgentError} agent 未注册;input 与 messages 都为空;续跑历史结构非法
965
+ * @throws {AgentError} 未传 options.agent;agent 未注册;input 与 messages 都为空;
966
+ * 续跑历史结构非法;provider/model 无法解析
948
967
  * @throws {ReactLoopError} 超出 maxTurns(`error.messages` 携带完整历史,可续跑)
949
968
  * @throws {AgentAbortError} 中断(`error.messages` 携带断点历史,可续跑)
950
969
  * @throws {Error} provider.stream 抛错时立即传播
@@ -954,15 +973,16 @@ var Agent = class _Agent {
954
973
  yield* reactLoopStream(input, config);
955
974
  }
956
975
  /**
957
- * 把自身包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
976
+ * 把指定 agent 包装为 `AgentToolDescriptor` 供 LLM 当 tool 调用
958
977
  *
959
978
  * 与 [agentRegistry.asTool](../../faapi/src/injection/agentRegistry.md) 同构——
960
979
  * Agent 类自带此方法便于在注入器场景直接调用(不必再过注册表)。
961
980
  *
981
+ * @param name agent 名(显式指定——无默认 agent)
962
982
  * @returns `AgentToolDescriptor` 或 `undefined`(agent 未注册)
963
983
  */
964
- asTool() {
965
- const meta = this.deps.getAgent(this.deps.agentName);
984
+ asTool(name) {
985
+ const meta = this.deps.getAgent(name);
966
986
  if (!meta) return void 0;
967
987
  return {
968
988
  kind: "agent",
@@ -994,21 +1014,19 @@ var Agent = class _Agent {
994
1014
  /**
995
1015
  * 组装 ReactLoopConfig
996
1016
  *
997
- * 1. 解析有效 agent 名:`options.agent` > `deps.agentName`(`config.agent.defaultAgent`)
1017
+ * 1. 解析有效 agent 名:`options.agent`(必须显式传——无默认 agent,不传抛 AgentError)
998
1018
  * 2. 查 agent 元数据(未注册抛 AgentError)——用 `getAgent` 拿 AgentCore
999
1019
  * (LLM-facing 字段:systemPrompt / model / maxTurns)
1000
1020
  * 3. buildToolDefinitions 组装 tool 列表(用有效 agent 名查 tools / sub-agents)
1001
- * 4. config 字段优先级(高 → 低):`options` > agent 元数据 > 全局 AgentRuntimeConfig / deps.defaultProvider
1021
+ * 4. config 字段优先级(高 → 低):`options` > agent 元数据 > 全局 AgentRuntimeConfig
1002
1022
  *
1003
- * `options.model` 是字符串 key,由 {@link resolveModelKey} 解析为 provider + model
1004
- * (支持 llms key 精确匹配 / `provider/model` 一体化 / model 名模糊匹配)。
1005
- * 不传 `options.model` 时用 `deps.defaultProvider` + agent 元数据 `config.model`。
1023
+ * `options.provider`(外部 provider)存在时由 {@link resolveExternalProvider} 物化,
1024
+ * 优先级最高——`options.model` 变为原始 model 名原样透传(不解析 llms key)。
1025
+ * 否则 `options.model` 是字符串 key,由 {@link resolveModelKey} 解析为 provider + model
1026
+ * (支持 llms key 精确匹配 / `provider/model` 一体化 / 纯 model 名模糊匹配;
1027
+ * 未传 `options.model` 时用 agent 元数据 `config.model` 作为缺省 key)。
1006
1028
  * 详见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」。
1007
1029
  *
1008
- * `options.agent` 覆盖本次调用的 agent 名——不传时用 `deps.agentName`(来自
1009
- * `config.agent.defaultAgent`)。`defaultAgent` 未设且 `options.agent` 未传时抛
1010
- * `AgentError`。
1011
- *
1012
1030
  * **输入守卫**(续跑入口,见 [reactLoop.md](./reactLoop.md) 中断恢复章节):
1013
1031
  * `input` 与 `options.messages` 都为空时抛 `AgentError`(不发送空请求);
1014
1032
  * `options.messages` 提供时先经 `validateResumeHistory` 结构校验,非法抛
@@ -1023,14 +1041,20 @@ var Agent = class _Agent {
1023
1041
  if (options?.messages?.length) {
1024
1042
  validateResumeHistory(options.messages);
1025
1043
  }
1026
- const agentName = options?.agent ?? this.deps.agentName;
1044
+ const agentName = options?.agent;
1045
+ if (!agentName) {
1046
+ throw new AgentError(
1047
+ 'agent.run/stream requires options.agent (no default agent) \u2014 pass { agent: "name" } to specify which agent to run'
1048
+ );
1049
+ }
1027
1050
  const meta = this.deps.getAgent(agentName);
1028
1051
  if (!meta) {
1029
1052
  throw new AgentError(`Agent "${agentName}" is not registered`);
1030
1053
  }
1031
1054
  const tools = await this.buildToolDefinitions(agentName);
1032
- const { provider, model } = this.resolveModelKey(options?.model, meta);
1055
+ const { provider, model } = options?.provider !== void 0 ? this.resolveExternalProvider(options.provider, options?.model) : this.resolveModelKey(options?.model, meta);
1033
1056
  const enableTracing = options?.enableTracing ?? this.deps.config?.enableTracing ?? false;
1057
+ const callCtx = { agentName, enableTracing, provider, model };
1034
1058
  return {
1035
1059
  provider,
1036
1060
  systemPrompt: meta.systemPrompt,
@@ -1042,41 +1066,77 @@ var Agent = class _Agent {
1042
1066
  signal: options?.signal,
1043
1067
  messages: options?.messages,
1044
1068
  enableTracing,
1045
- executeTool: async (name, args) => this.executeTool(name, args, enableTracing)
1069
+ executeTool: async (name, args) => this.executeTool(name, args, callCtx)
1046
1070
  };
1047
1071
  }
1072
+ /**
1073
+ * 解析外部 provider(`options.provider`)→ provider + model
1074
+ *
1075
+ * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.provider` 外部 provider」章节:
1076
+ * - `LLMProvider` 实例 → 直接使用,`modelKey` 原样透传(可为 `undefined`,自定义 provider 自决)
1077
+ * - `LlmConfig` 配置对象 → `createProvider` 现场创建,`modelKey` 原样透传;
1078
+ * 缺省回落该 config `models` 第一个 key,两者皆无抛 `AgentError`(早失败,不发请求)
1079
+ * - `modelKey` 不做 llms key 解析、不拆 `/`(支持 OpenRouter 等带斜杠的 model id)
1080
+ *
1081
+ * 仅本次调用生效:不进 providers Map、sub-agent 递归不继承(executeSubAgent 构造
1082
+ * subDeps 时不携带 options,sub-agent 走默认解析链路)。
1083
+ *
1084
+ * @throws {AgentError} provider 形式非法;LlmConfig 形式下 model 缺失
1085
+ */
1086
+ resolveExternalProvider(external, modelKey) {
1087
+ const provider = materializeProvider(external);
1088
+ if (isProviderInstance(external)) {
1089
+ return { provider, model: modelKey };
1090
+ }
1091
+ const firstModel = Object.keys(external.models ?? {})[0];
1092
+ const model = modelKey ?? firstModel;
1093
+ if (model === void 0) {
1094
+ throw new AgentError(
1095
+ "External provider requires a model: pass options.model or declare models in the provider config"
1096
+ );
1097
+ }
1098
+ return { provider, model };
1099
+ }
1048
1100
  /**
1049
1101
  * 解析 `options.model` 字符串 key → provider + model
1050
1102
  *
1051
- * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」:
1052
- * 1. `undefined` `deps.defaultProvider` + `meta.model`
1053
- * 2. 精确匹配 `deps.providers` key → 该 provider + 其 `models` 第一个 key
1054
- * 3. `/` → `provider/model` 形式,`deps.providers.get(provider)` +model
1103
+ * 规则见 [agentHandle.md](./agentHandle.md) 的「`options.model` 字符串 key 解析规则」。
1104
+ * 无默认 provider——`key` 未传时用 agent 元数据 `config.model` 作为缺省 key;
1105
+ * 两者皆无抛 `AgentError`(要求调用方传 `options.model` `options.provider`)。
1106
+ * 1. 精确匹配 `deps.providers` key → provider + 其 `models` 第一个 key
1107
+ * (该 provider 未声明 `models` 时回落 `meta.model`)
1108
+ * 2. 含 `/` → `provider/model` 形式,`deps.providers.get(provider)` + 该 model
1055
1109
  * (要求该 model 在 `deps.llms[provider].models` 里)
1056
- * 4. 不含 `/` 且非 provider key → 在所有 provider 的 `models` 里按 model 名查找
1110
+ * 3. 不含 `/` 且非 provider key → 在所有 provider 的 `models` 里按 model 名查找
1057
1111
  * - 唯一 → 该 provider + 该 model
1058
1112
  * - 多个 → 抛 `AgentError`(要求用 `provider/model` 消歧)
1059
1113
  * - 无 → 抛 `AgentError`
1060
1114
  *
1061
- * @throws {AgentError} key 解析失败(provider/model 不存在或歧义)
1115
+ * @throws {AgentError} key 与 `meta.model` 均缺省;key 解析失败(provider/model
1116
+ * 不存在或歧义)
1062
1117
  */
1063
1118
  resolveModelKey(key, meta) {
1064
- if (key === void 0) {
1065
- return { provider: this.deps.defaultProvider, model: meta.model };
1119
+ const effectiveKey = key ?? meta.model;
1120
+ if (effectiveKey === void 0) {
1121
+ throw new AgentError(
1122
+ 'No LLM provider resolved: pass options.model (a provider key / "provider/model" / model name from config.agent.llms), options.provider (external provider), or declare model in the agent config'
1123
+ );
1066
1124
  }
1067
- const byProviderKey = this.deps.providers.get(key);
1125
+ const byProviderKey = this.deps.providers.get(effectiveKey);
1068
1126
  if (byProviderKey) {
1069
- const llmConfig = this.deps.llms[key];
1127
+ const llmConfig = this.deps.llms[effectiveKey];
1070
1128
  const firstModel = llmConfig ? Object.keys(llmConfig.models)[0] : void 0;
1071
1129
  return { provider: byProviderKey, model: firstModel ?? meta.model };
1072
1130
  }
1073
- if (key.includes("/")) {
1074
- const slashIdx = key.indexOf("/");
1075
- const providerName = key.slice(0, slashIdx);
1076
- const modelName = key.slice(slashIdx + 1);
1131
+ if (effectiveKey.includes("/")) {
1132
+ const slashIdx = effectiveKey.indexOf("/");
1133
+ const providerName = effectiveKey.slice(0, slashIdx);
1134
+ const modelName = effectiveKey.slice(slashIdx + 1);
1077
1135
  const provider = this.deps.providers.get(providerName);
1078
1136
  if (!provider) {
1079
- throw new AgentError(`Unknown provider "${providerName}" in model key "${key}"`);
1137
+ throw new AgentError(
1138
+ `Unknown provider "${providerName}" in model key "${effectiveKey}". Declare it in config.agent.llms, or pass options.provider to use an external provider.`
1139
+ );
1080
1140
  }
1081
1141
  const llmConfig = this.deps.llms[providerName];
1082
1142
  if (!llmConfig || !llmConfig.models[modelName]) {
@@ -1089,20 +1149,20 @@ var Agent = class _Agent {
1089
1149
  const matches = [];
1090
1150
  for (const [providerName, provider] of this.deps.providers) {
1091
1151
  const llmConfig = this.deps.llms[providerName];
1092
- if (llmConfig && llmConfig.models[key]) {
1152
+ if (llmConfig && llmConfig.models[effectiveKey]) {
1093
1153
  matches.push({ provider, providerName });
1094
1154
  }
1095
1155
  }
1096
1156
  if (matches.length === 1) {
1097
- return { provider: matches[0].provider, model: key };
1157
+ return { provider: matches[0].provider, model: effectiveKey };
1098
1158
  }
1099
1159
  if (matches.length > 1) {
1100
1160
  throw new AgentError(
1101
- `Model "${key}" is ambiguous (found in providers: ${matches.map((m) => m.providerName).join(", ")}). Use "provider/model" to disambiguate.`
1161
+ `Model "${effectiveKey}" is ambiguous (found in providers: ${matches.map((m) => m.providerName).join(", ")}). Use "provider/model" to disambiguate.`
1102
1162
  );
1103
1163
  }
1104
1164
  throw new AgentError(
1105
- `Model "${key}" not found in any provider. Declare it in config.agent.llms.*.models.`
1165
+ `Model "${effectiveKey}" not found in any provider. Declare it in config.agent.llms.*.models, or pass options.provider to use an external provider.`
1106
1166
  );
1107
1167
  }
1108
1168
  /**
@@ -1148,15 +1208,16 @@ var Agent = class _Agent {
1148
1208
  * - `agent.` 前缀 → {@link executeSubAgent} 递归(含 enableTracing + TracingToolResult 包装)
1149
1209
  * - 常规 tool → `loadToolModule` 加载 handler + 可选 input 校验 → 调用
1150
1210
  *
1151
- * `enableTracing` 由 [buildLoopConfig](#buildLoopConfig) 闭包捕获传入,用于 sub-agent
1152
- * 调用时决定是否包装 [TracingToolResult](./trace.md) 携带 sub-trace。
1211
+ * `callCtx` 由 [buildLoopConfig](#buildLoopConfig) 闭包捕获传入——本次调用的有效
1212
+ * agent 名(白名单校验)、enableTracing(sub-agent tracing 包装)与解析出的
1213
+ * provider/model(sub-agent 递归继承)。常规 tool 不需要 tracing 包装,直接返回结果。
1153
1214
  *
1154
1215
  * **常规 tool 校验失败**:不抛错,返回 `{ error }` 对象——reactLoop stringify 后
1155
1216
  * 作为 tool 结果回传 LLM,LLM 可据此修正参数重试。
1156
1217
  *
1157
1218
  * **tool 未找到 / 加载失败**:抛错,被 reactLoop catch 后同样回传 LLM。
1158
1219
  */
1159
- async executeTool(rawName, rawArgs, enableTracing) {
1220
+ async executeTool(rawName, rawArgs, callCtx) {
1160
1221
  const name = rawName;
1161
1222
  let args = rawArgs;
1162
1223
  const guard = this.deps.config?.beforeToolCall?.(name, args, this.deps.ctx);
@@ -1165,19 +1226,19 @@ var Agent = class _Agent {
1165
1226
  if ("args" in guard) args = guard.args;
1166
1227
  }
1167
1228
  const declared = /* @__PURE__ */ new Set();
1168
- for (const tool2 of this.deps.resolveAgentTools(this.deps.agentName)) {
1229
+ for (const tool2 of this.deps.resolveAgentTools(callCtx.agentName)) {
1169
1230
  declared.add(tool2.name);
1170
1231
  }
1171
- for (const sub of this.deps.resolveSubAgents(this.deps.agentName)) {
1232
+ for (const sub of this.deps.resolveSubAgents(callCtx.agentName)) {
1172
1233
  declared.add(`agent.${sub.name}`);
1173
1234
  }
1174
1235
  if (!declared.has(name)) {
1175
1236
  return {
1176
- error: `Tool "${name}" is not declared by agent "${this.deps.agentName}" (add it to the agent's tools/agents declaration)`
1237
+ error: `Tool "${name}" is not declared by agent "${callCtx.agentName}" (add it to the agent's tools/agents declaration)`
1177
1238
  };
1178
1239
  }
1179
1240
  if (name.startsWith("agent.")) {
1180
- return await this.executeSubAgent(name.slice(6), args, enableTracing);
1241
+ return await this.executeSubAgent(name.slice(6), args, callCtx);
1181
1242
  }
1182
1243
  const tool = this.deps.getTool(name);
1183
1244
  if (!tool) {
@@ -1202,7 +1263,9 @@ var Agent = class _Agent {
1202
1263
  *
1203
1264
  * 1. `maxAgentDepth` 防护——超限抛 {@link AgentRecursionError}
1204
1265
  * 2. sub-agent handler 导出 `run` 时调自定义 `mod.run(args)`(无 trace,与常规 tool 一致)
1205
- * 3. 无 `run` 时调 `subAgent.run(stringify(args), { enableTracing })` 走默认 reactLoop
1266
+ * 3. 无 `run` 时调 `subAgent.run(stringify(args), { agent, provider, model, enableTracing })`
1267
+ * 走默认 reactLoop——继承父调用的 provider,sub 元数据声明 `model` 时优先用自身的,
1268
+ * 未声明时沿用父 model
1206
1269
  *
1207
1270
  * **tracing 路径**:`enableTracing=true` 时,subAgent.run 返回的 `result.trace`(agentName
1208
1271
  * 已被 `Agent.run` 填为 subName)被包装为 [TracingToolResult](./trace.md) 返回给 reactLoop。
@@ -1220,14 +1283,13 @@ var Agent = class _Agent {
1220
1283
  * 而非 `getAgent`(返回 AgentCore,无代码加载细节)。DB skill 无文件,
1221
1284
  * `getAgentEntry` 返回 `undefined`,走默认 reactLoop。
1222
1285
  */
1223
- async executeSubAgent(subName, args, enableTracing) {
1286
+ async executeSubAgent(subName, args, callCtx) {
1224
1287
  const newDepth = this.depth + 1;
1225
1288
  const maxDepth = this.deps.config?.maxAgentDepth ?? DEFAULT_MAX_AGENT_DEPTH;
1226
1289
  if (newDepth > maxDepth) {
1227
1290
  throw new AgentRecursionError(maxDepth, newDepth);
1228
1291
  }
1229
- const subDeps = { ...this.deps, agentName: subName };
1230
- const subAgent = new _Agent(subDeps, newDepth);
1292
+ const subAgent = new _Agent(this.deps, newDepth);
1231
1293
  const entry = this.deps.getAgentEntry(subName);
1232
1294
  if (entry?.hasRun) {
1233
1295
  const mod = await this.deps.loadAgentModule(entry.filePath, entry.hasRun);
@@ -1237,11 +1299,15 @@ var Agent = class _Agent {
1237
1299
  return result2;
1238
1300
  }
1239
1301
  }
1302
+ const subMeta = this.deps.getAgent(subName);
1240
1303
  const result = await subAgent.run(typeof args === "string" ? args : JSON.stringify(args), {
1241
- enableTracing
1304
+ agent: subName,
1305
+ provider: callCtx.provider,
1306
+ model: subMeta?.model ?? callCtx.model,
1307
+ enableTracing: callCtx.enableTracing
1242
1308
  });
1243
1309
  this.deps.config?.afterToolCall?.(`agent.${subName}`, args, result.content, this.deps.ctx);
1244
- if (enableTracing && result.trace) {
1310
+ if (callCtx.enableTracing && result.trace) {
1245
1311
  return {
1246
1312
  __trace: true,
1247
1313
  result: result.content,
@@ -1286,14 +1352,12 @@ var agentPlugin = {
1286
1352
  setup(ctx) {
1287
1353
  const registries = ctx.registries;
1288
1354
  const agentConfig = readAgentConfig(ctx);
1289
- if (!agentConfig?.llms) {
1290
- console.warn(
1291
- "! @faapi/agent: config.agent.llms not configured, agent parameter injection disabled"
1355
+ const llms = agentConfig?.llms ?? {};
1356
+ if (Object.keys(llms).length === 0) {
1357
+ console.log(
1358
+ "- @faapi/agent: no llms configured \u2014 use agent.run(input, { agent, provider }) to pass an external provider per call"
1292
1359
  );
1293
- return;
1294
1360
  }
1295
- const defaultAgent = agentConfig.defaultAgent ?? "";
1296
- const llms = agentConfig.llms;
1297
1361
  const providers = /* @__PURE__ */ new Map();
1298
1362
  for (const [name, llmConfig] of Object.entries(llms)) {
1299
1363
  if (!llmConfig.apiKey || llmConfig.apiKey.trim() === "") {
@@ -1303,22 +1367,14 @@ var agentPlugin = {
1303
1367
  }
1304
1368
  providers.set(name, createProvider(llmConfig));
1305
1369
  }
1306
- const defaultLlm = agentConfig.defaultLlm ?? Object.keys(llms)[0];
1307
- const defaultProvider = providers.get(defaultLlm);
1308
- if (!defaultProvider) {
1309
- console.warn(
1310
- `! @faapi/agent: config.agent.defaultLlm "${defaultLlm}" not found in llms, agent parameter injection disabled`
1311
- );
1312
- return;
1313
- }
1314
1370
  const runtimeConfig = {
1315
- maxTurns: agentConfig.maxTurns,
1316
- maxAgentDepth: agentConfig.maxAgentDepth,
1317
- maxHistoryTokens: agentConfig.maxHistoryTokens,
1371
+ maxTurns: agentConfig?.maxTurns,
1372
+ maxAgentDepth: agentConfig?.maxAgentDepth,
1373
+ maxHistoryTokens: agentConfig?.maxHistoryTokens,
1318
1374
  // 鉴权钩子(authHooks,见 ./authHooks.md)——业务方在 config.agent 声明
1319
- beforeToolCall: agentConfig.beforeToolCall,
1320
- afterToolCall: agentConfig.afterToolCall,
1321
- filterTools: agentConfig.filterTools
1375
+ beforeToolCall: agentConfig?.beforeToolCall,
1376
+ afterToolCall: agentConfig?.afterToolCall,
1377
+ filterTools: agentConfig?.filterTools
1322
1378
  };
1323
1379
  const rootDir = ctx.rootDir;
1324
1380
  const schemaCache = /* @__PURE__ */ new Map();
@@ -1341,10 +1397,7 @@ var agentPlugin = {
1341
1397
  ctx.registries.agentHandle.register((ctx2) => {
1342
1398
  return new Agent({
1343
1399
  providers,
1344
- defaultProvider,
1345
1400
  llms,
1346
- defaultLlm,
1347
- agentName: defaultAgent ?? "",
1348
1401
  rootDir,
1349
1402
  config: runtimeConfig,
1350
1403
  // ctx 传递链(authHooks):捕获请求上下文,tool handler / sub-agent /
@@ -1365,7 +1418,7 @@ var agentPlugin = {
1365
1418
  });
1366
1419
  });
1367
1420
  console.log(
1368
- defaultAgent ? `- @faapi/agent: default agent "${defaultAgent}" (provider: ${defaultLlm}) available via agent parameter injection` : `- @faapi/agent: no defaultAgent set \u2014 use agent.run(input, { agent: 'name' }) to specify agent (provider: ${defaultLlm})`
1421
+ Object.keys(llms).length > 0 ? `- @faapi/agent: providers [${Object.keys(llms).join(", ")}] \u2014 call agent.run(input, { agent, model }) to execute (no default agent/provider)` : "- @faapi/agent: no llms configured \u2014 use agent.run(input, { agent, provider }) to pass an external provider per call"
1369
1422
  );
1370
1423
  }
1371
1424
  };