从配置文件读取 → 自定义LLM API配置 → Gateway启动 → 实际AI调用的完整函数调用链
目录
- 完整调用链总览图
- 第一阶段:Setup Wizard(用户交互)
- 第二阶段:收集自定义API信息
- 第三阶段:生成并保存配置
- 第四阶段:Gateway启动加载配置
- 第五阶段:注册内置API Provider
- 第六阶段:Agent运行时调用模型
- 第七阶段:解析并创建StreamFn
- 第八阶段:实际AI调用(核心回调)
- 关键文件和函数总结
完整调用链总览图
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 1. Setup Wizard(用户交互) │
│ src/wizard/setup.ts:runSetupWizard() │
│ ↓ │
│ src/wizard/setup.ts:promptAuthChoiceGrouped() │
│ ↓ │
│ [用户选择 "custom-api-key"] │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 2. 收集自定义API信息(交互式) │
│ src/commands/onboard-custom.ts:promptCustomApiConfig() │
│ ↓ │
│ src/commands/onboard-custom.ts:promptBaseUrlAndKey() │
│ ↓ │
│ src/commands/onboard-custom.ts:ensureApiKeyFromEnvOrPrompt() │
│ ↓ │
│ src/commands/onboard-custom.ts:requestOpenAiVerification() │
│ ↓ │
│ src/commands/onboard-custom.ts:buildOpenAiVerificationProbeRequest() │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 3. 生成并保存配置 │
│ src/commands/onboard-custom-config.ts:applyCustomApiConfig() │
│ ↓ │
│ src/commands/onboard-custom-config.ts:resolveCustomProviderId() │
│ ↓ │
│ src/commands/onboard-custom-config.ts:resolveProviderApi() │
│ ↓ │
│ src/commands/onboard-custom-config.ts:buildEndpointIdFromUrl() │
│ ↓ │
│ src/wizard/setup.ts:writeWizardConfigFile() │
│ ↓ │
│ → 保存到 openclaw.json │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 4. Gateway启动加载配置 │
│ src/cli/gateway-cli/run.ts:runGatewayCommand() │
│ ↓ │
│ src/cli/gateway-cli/run-loop.ts:runGatewayLoop() │
│ ↓ │
│ src/gateway/server.impl.ts:startGatewayServer() │
│ ↓ │
│ src/gateway/server.impl.ts:loadGatewayStartupConfigSnapshot() │
│ ↓ │
│ src/config/io.ts:loadConfig() │
│ src/config/io.ts:readConfigFileSnapshotWithPluginMetadata() │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 5. 注册内置API Provider │
│ src/llm/providers/register-builtins.ts:registerBuiltInApiProviders() │
│ ↓ │
│ registerApiProvider({ │
│ api: "openai-completions", │
│ stream: streamOpenAICompletions, │
│ streamSimple: streamSimpleOpenAICompletions │
│ }) │
│ ↓ │
│ src/llm/api-registry.ts:registerApiProvider() │
│ ↓ │
│ → 存入 apiProviderRegistry │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 6. Agent运行时调用模型 │
│ src/agents/agent-command.ts:agentCommandInternal() │
│ ↓ │
│ src/agents/embedded-agent-runner/run.ts:runEmbeddedAgent() │
│ ↓ │
│ src/agents/embedded-agent-runner/run/attempt.ts:runEmbeddedAttemptWithBackend() │
│ ↓ │
│ src/agents/embedded-agent-runner/run/attempt.ts:registerProviderStreamForModel() │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 7. 解析并创建StreamFn │
│ src/agents/provider-stream.ts:registerProviderStreamForModel() │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ 尝试Provider插件方式: │ │
│ │ src/plugins/provider-runtime.ts:resolveProviderStreamFn() │ │
│ │ ↓ │ │
│ │ src/plugins/provider-hook-runtime.ts:resolveProviderRuntimePlugin() │ │
│ │ ↓ │ │
│ │ [custom-api-key没有Provider插件,返回undefined] │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ 回退到通用API方式: │
│ src/agents/provider-stream.ts:createTransportAwareStreamFnForModel() │
│ ↓ │
│ src/agents/provider-stream.ts:ensureCustomApiRegistered(model.api, streamFn) │
│ ↓ │
│ → 注册到 apiProviderRegistry["openai-completions"] │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 8. 实际AI调用(核心回调!) │
│ src/agents/embedded-agent-runner/run/attempt.ts:activeSession.agent.streamFn() │
│ ↓ │
│ src/llm/api-registry.ts:getApiProvider("openai-completions") │
│ ↓ │
│ src/llm/api-registry.ts:provider.stream(model, context, options) │
│ ↓ │
│ src/llm/providers/register-builtins.ts:streamOpenAICompletions() (懒加载包装) │
│ ↓ │
│ import("./openai-completions.js") │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ src/llm/providers/openai-completions.ts:streamOpenAICompletions() │ │
│ │ ========================== 实际AI回调函数 ========================== │ │
│ │ │ │
│ │ 1. const apiKey = getEnvApiKey(model.provider) || "" │ │
│ │ 2. const client = createClient(model, context, apiKey, ...) │ │
│ │ → new OpenAI({ │ │
│ │ baseURL: model.baseUrl, // "https://api.example.com/v1" │ │
│ │ apiKey: apiKey, // 自定义API Key │ │
│ │ }) │ │
│ │ 3. const params = buildParams(model, context, options, ...) │ │
│ │ 4. client.chat.completions.create(params, {stream: true}) │ │
│ │ → 发送HTTP请求到自定义端点! │ │
│ │ 5. 处理流式响应,推送事件到stream │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────┘
第一阶段:Setup Wizard(用户交互)
src/wizard/setup.ts:runSetupWizard()
↓
src/wizard/setup.ts:promptAuthChoiceGrouped()
↓
[用户选择 "custom-api-key"]
关键函数
| 文件 |
函数 |
作用 |
| `src/wizard/setup.ts` |
`runSetupWizard()` |
Setup Wizard主入口 |
| `src/wizard/setup.ts` |
`promptAuthChoiceGrouped()` |
显示认证选项列表 |
第二阶段:收集自定义API信息
src/commands/onboard-custom.ts:promptCustomApiConfig()
↓
src/commands/onboard-custom.ts:promptBaseUrlAndKey()
↓
src/commands/onboard-custom.ts:ensureApiKeyFromEnvOrPrompt()
↓
src/commands/onboard-custom.ts:requestOpenAiVerification()
↓
src/commands/onboard-custom.ts:buildOpenAiVerificationProbeRequest()
关键函数
| 文件 |
函数 |
作用 |
| `src/commands/onboard-custom.ts` |
`promptCustomApiConfig()` |
交互式收集自定义API信息 |
| `src/commands/onboard-custom.ts` |
`promptBaseUrlAndKey()` |
提示输入baseUrl和API Key |
| `src/commands/onboard-custom.ts` |
`ensureApiKeyFromEnvOrPrompt()` |
从环境变量或提示获取API Key |
| `src/commands/onboard-custom.ts` |
`requestOpenAiVerification()` |
验证端点可用性 |
| `src/commands/onboard-custom.ts` |
`buildOpenAiVerificationProbeRequest()` |
构建验证探测请求 |
第三阶段:生成并保存配置
src/commands/onboard-custom-config.ts:applyCustomApiConfig()
↓
src/commands/onboard-custom-config.ts:resolveCustomProviderId()
↓
src/commands/onboard-custom-config.ts:resolveProviderApi()
↓
src/commands/onboard-custom-config.ts:buildEndpointIdFromUrl()
↓
src/wizard/setup.ts:writeWizardConfigFile()
↓
→ 保存到 openclaw.json
生成的配置示例
{
"models": {
"providers": {
"custom-api-example-com": {
"baseUrl": "https://api.example.com/v1",
"api": "openai-completions",
"apiKey": "${env:CUSTOM_API_KEY}",
"models": [
{
"id": "gpt-4",
"name": "gpt-4 (Custom Provider)",
"contextWindow": 128000,
"maxTokens": 4096,
"input": ["text", "image"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
},
"agents": {
"defaults": {
"model": "custom-api-example-com/gpt-4"
}
}
}
关键函数
| 文件 |
函数 |
作用 |
| `src/commands/onboard-custom-config.ts` |
`applyCustomApiConfig()` |
**核心:生成配置** |
| `src/commands/onboard-custom-config.ts` |
`resolveCustomProviderId()` |
生成Provider ID |
| `src/commands/onboard-custom-config.ts` |
`resolveProviderApi()` |
映射兼容性到API类型 |
| `src/commands/onboard-custom-config.ts` |
`buildEndpointIdFromUrl()` |
从URL生成建议ID |
| `src/wizard/setup.ts` |
`writeWizardConfigFile()` |
保存配置到文件 |
第四阶段:Gateway启动加载配置
src/cli/gateway-cli/run.ts:runGatewayCommand()
↓
src/cli/gateway-cli/run-loop.ts:runGatewayLoop()
↓
src/gateway/server.impl.ts:startGatewayServer()
↓
src/gateway/server.impl.ts:loadGatewayStartupConfigSnapshot()
↓
src/config/io.ts:loadConfig()
src/config/io.ts:readConfigFileSnapshotWithPluginMetadata()
关键函数
| 文件 |
函数 |
作用 |
| `src/cli/gateway-cli/run.ts` |
`runGatewayCommand()` |
CLI入口 |
| `src/cli/gateway-cli/run-loop.ts` |
`runGatewayLoop()` |
运行循环 |
| `src/gateway/server.impl.ts` |
`startGatewayServer()` |
启动Gateway服务器 |
| `src/gateway/server.impl.ts` |
`loadGatewayStartupConfigSnapshot()` |
加载配置快照 |
| `src/config/io.ts` |
`loadConfig()` |
加载配置 |
| `src/config/io.ts` |
`readConfigFileSnapshotWithPluginMetadata()` |
读取配置快照 |
第五阶段:注册内置API Provider
src/llm/providers/register-builtins.ts:registerBuiltInApiProviders()
↓
src/llm/providers/register-builtins.ts:registerApiProvider({
api: "openai-completions",
stream: streamOpenAICompletions,
streamSimple: streamSimpleOpenAICompletions
})
↓
src/llm/api-registry.ts:registerApiProvider()
↓
→ 存入 apiProviderRegistry
注册的8个内置API Provider
| API |
Stream函数 |
文件 |
| `anthropic-messages` |
`streamAnthropic` |
`src/llm/providers/anthropic.ts` |
| `openai-completions` |
`streamOpenAICompletions` |
`src/llm/providers/openai-completions.ts` |
| `mistral-conversations` |
`streamMistral` |
`src/llm/providers/mistral.ts` |
| `openai-responses` |
`streamOpenAIResponses` |
`src/llm/providers/openai-responses.ts` |
| `azure-openai-responses` |
`streamAzureOpenAIResponses` |
`src/llm/providers/azure-openai.ts` |
| `openai-chatgpt-responses` |
`streamOpenAICodexResponses` |
`src/llm/providers/openai-codex.ts` |
| `google-generative-ai` |
`streamGoogle` |
`src/llm/providers/google.ts` |
| `google-vertex` |
`streamGoogleVertex` |
`src/llm/providers/google-vertex.ts` |
关键函数
| 文件 |
函数 |
作用 |
| `src/llm/providers/register-builtins.ts` |
`registerBuiltInApiProviders()` |
注册所有内置API Provider |
| `src/llm/api-registry.ts` |
`registerApiProvider()` |
存入API注册表 |
第六阶段:Agent运行时调用模型
src/agents/agent-command.ts:agentCommandInternal()
↓
src/agents/embedded-agent-runner/run.ts:runEmbeddedAgent()
↓
src/agents/embedded-agent-runner/run/attempt.ts:runEmbeddedAttemptWithBackend()
↓
src/agents/embedded-agent-runner/run/attempt.ts:registerProviderStreamForModel()
关键函数
| 文件 |
函数 |
作用 |
| `src/agents/agent-command.ts` |
`agentCommandInternal()` |
Agent命令入口 |
| `src/agents/embedded-agent-runner/run.ts` |
`runEmbeddedAgent()` |
运行嵌入式Agent |
| `src/agents/embedded-agent-runner/run/attempt.ts` |
`runEmbeddedAttemptWithBackend()` |
尝试执行 |
| `src/agents/embedded-agent-runner/run/attempt.ts` |
`registerProviderStreamForModel()` |
注册模型的StreamFn |
第七阶段:解析并创建StreamFn
src/agents/provider-stream.ts:registerProviderStreamForModel()
↓
┌─────────────────────────────────────────────────────────┐
│ 尝试Provider插件方式: │
│ src/plugins/provider-runtime.ts:resolveProviderStreamFn()│
│ ↓ │
│ src/plugins/provider-hook-runtime.ts:resolveProviderRuntimePlugin()│
│ ↓ │
│ [custom-api-key没有Provider插件,返回undefined] │
└─────────────────────────────────────────────────────────┘
↓
回退到通用API方式:
src/agents/provider-stream.ts:createTransportAwareStreamFnForModel()
↓
src/agents/provider-stream.ts:ensureCustomApiRegistered(model.api, streamFn)
↓
→ 注册到 apiProviderRegistry["openai-completions"]
关键函数
| 文件 |
函数 |
作用 |
| `src/agents/provider-stream.ts` |
`registerProviderStreamForModel()` |
为模型注册StreamFn |
| `src/plugins/provider-runtime.ts` |
`resolveProviderStreamFn()` |
尝试从Provider插件获取 |
| `src/plugins/provider-hook-runtime.ts` |
`resolveProviderRuntimePlugin()` |
解析Provider运行时插件 |
| `src/agents/provider-stream.ts` |
`createTransportAwareStreamFnForModel()` |
创建基于通用API的StreamFn |
| `src/agents/provider-stream.ts` |
`ensureCustomApiRegistered()` |
注册到API注册表 |
第八阶段:实际AI调用(核心回调)
src/agents/embedded-agent-runner/run/attempt.ts:activeSession.agent.streamFn()
↓
src/llm/api-registry.ts:getApiProvider("openai-completions")
↓
src/llm/api-registry.ts:provider.stream(model, context, options)
↓
src/llm/providers/register-builtins.ts:streamOpenAICompletions() (懒加载包装)
↓
import("./openai-completions.js")
↓
src/llm/providers/openai-completions.ts:streamOpenAICompletions()
├─ 1. const apiKey = getEnvApiKey(model.provider) || ""
├─ 2. const client = createClient(model, context, apiKey, ...)
│ → new OpenAI({
│ baseURL: model.baseUrl, // "https://api.example.com/v1"
│ apiKey: apiKey, // 自定义API Key
│ })
├─ 3. const params = buildParams(model, context, options, ...)
├─ 4. client.chat.completions.create(params, {stream: true})
│ → 发送HTTP请求到自定义端点!
└─ 5. 处理流式响应,推送事件到stream
核心AI回调函数
// src/llm/providers/openai-completions.ts:123
export const streamOpenAICompletions: StreamFunction<
"openai-completions",
OpenAICompletionsOptions
> = (model: Model<"openai-completions">, context: Context, options?: OpenAICompletionsOptions) => {
const stream = new AssistantMessageEventStream();
void (async () => {
// 1. 获取API Key
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
// 2. 创建OpenAI客户端(使用自定义baseUrl)
const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
// 3. 构建请求参数
let params = buildParams(model, context, options, compat, cacheRetention);
// 4. 发送请求(实际HTTP调用)
const { data: openaiStream, response } = await client.chat.completions
.create(params as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming, requestOptions)
.withResponse();
// 5. 处理流式响应
stream.push({ type: "start", partial: output });
// ... 解析chunk、推事件
})();
return stream;
};
关键函数
| 文件 |
函数 |
作用 |
| `src/agents/embedded-agent-runner/run/attempt.ts` |
`activeSession.agent.streamFn()` |
调用StreamFn |
| `src/llm/api-registry.ts` |
`getApiProvider()` |
从注册表获取Provider |
| `src/llm/providers/register-builtins.ts` |
`streamOpenAICompletions()` |
懒加载包装器 |
| `src/llm/providers/openai-completions.ts` |
**`streamOpenAICompletions()`** |
**实际的AI回调函数** |
| `src/llm/providers/openai-completions.ts` |
`createClient()` |
创建OpenAI客户端 |
| `src/llm/providers/openai-completions.ts` |
`buildParams()` |
构建请求参数 |
关键文件和函数总结
按阶段汇总
| 阶段 |
关键文件 |
关键函数 |
| **配置收集** |
`src/commands/onboard-custom.ts` |
`promptCustomApiConfig()` |
| **配置生成** |
`src/commands/onboard-custom-config.ts` |
`applyCustomApiConfig()` |
| **配置保存** |
`src/wizard/setup.ts` |
`writeWizardConfigFile()` |
| **配置加载** |
`src/config/io.ts` |
`loadConfig()` |
| **Provider注册** |
`src/llm/providers/register-builtins.ts` |
`registerBuiltInApiProviders()` |
| **API注册表** |
`src/llm/api-registry.ts` |
`registerApiProvider()` / `getApiProvider()` |
| **StreamFn创建** |
`src/agents/provider-stream.ts` |
`registerProviderStreamForModel()` |
| **实际AI调用** |
`src/llm/providers/openai-completions.ts` |
**`streamOpenAICompletions()`** |
核心设计要点
custom-api-key 不创建新的API协议实现,而是复用已有的内置协议(openai-completions、anthropic-messages 等)
- 只替换三个关键参数:
- 自定义Provider使用与OpenAI/Anthropic完全相同的代码路径,通过
model.baseUrl 和 model.apiKey 实现端点切换
生成时间: 2026-06-22