乐于分享
好东西不私藏

OpenClaw Gateway 启动完整调用链

OpenClaw Gateway 启动完整调用链

从配置文件读取 → 自定义LLM API配置 → Gateway启动 → 实际AI调用的完整函数调用链


目录

  1. 完整调用链总览图
  1. 第一阶段:Setup Wizard(用户交互)
  1. 第二阶段:收集自定义API信息
  1. 第三阶段:生成并保存配置
  1. 第四阶段:Gateway启动加载配置
  1. 第五阶段:注册内置API Provider
  1. 第六阶段:Agent运行时调用模型
  1. 第七阶段:解析并创建StreamFn
  1. 第八阶段:实际AI调用(核心回调)
  1. 关键文件和函数总结

完整调用链总览图

┌─────────────────────────────────────────────────────────────────────────────────────┐
│                              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()`**

核心设计要点

  1. custom-api-key 不创建新的API协议实现,而是复用已有的内置协议(openai-completionsanthropic-messages 等)
  1. 只替换三个关键参数
  • baseUrl → 指向自定义端点
  • apiKey → 自定义密钥
  • modelId → 自定义模型ID
  1. 自定义Provider使用与OpenAI/Anthropic完全相同的代码路径,通过 model.baseUrlmodel.apiKey 实现端点切换

生成时间: 2026-06-22