Skip to content

[opencode 请求流程分析] OpenCode 请求流程与请求 Header 分析(2026-07-17) #6

Description

@github-actions

近期相关变更

  • fix(provider): restore Azure Cognitive Services endpoints (#37340) — 修复 Azure 端点配置
  • chore: generate — SDK 代码重新生成(含 provider 配置更新)

1. 请求流程

架构概览

OpenCode 的 LLM 请求分两条路径:

  1. AI SDK 路径(默认):通过 @ai-sdk/* npm 包发送请求
  2. Native Route 路径:仅 OpenAI、Anthropic、opencode 自有 provider 可用,直接使用 packages/llmLLMClient

路径选择在 native-runtime.ts:status() 中判断。

关键步骤

sequenceDiagram
    participant Session
    participant LLMRequestPrep as session/llm/request.ts
    participant NativeRuntime as native-runtime.ts
    participant LLMClient as route/client.ts
    participant Auth as route/auth.ts
    participant Executor as route/executor.ts
    participant Provider as LLM Provider

    Session->>LLMRequestPrep: prepare() — 构造 headers/params
    LLMRequestPrep-->>Session: Prepared{headers, messages, tools...}
    Session->>NativeRuntime: stream()/generateText
    NativeRuntime->>LLMClient: LLMClient.stream(request)
    LLMClient->>LLMClient: compile() → route.body.from() 构造 body
    LLMClient->>Auth: route.prepareTransport() → Auth.apply() 注入鉴权 header
    Auth-->>LLMClient: Headers (Authorization/x-api-key/SigV4...)
    LLMClient->>Executor: RequestExecutor.execute(httpRequest)
    Executor->>Provider: POST JSON + headers
    Provider-->>Executor: SSE / Event-stream
    Executor->>Executor: retryStatusFailures() 自动重试
    Executor-->>LLMClient: Stream<LLMEvent>
Loading
# 环节 关键文件 & 函数
1 请求构造 session/llm/request.tsLLMRequestPrep.prepare()
2 凭据获取 provider/auth.tsProviderAuth.Service (OAuth/API key)
3 路径选择 native-runtime.tsstatus()
4 消息降格 native-request.tsLLMNative.from() (AI SDK → LLMRequest)
5 Body 构造 route/client.tscompile()route.body.from()
6 Body 验证 route/client.tsProviderShared.validateWith()
7 Header 组装 route/transport/http.tsjsonRequestParts()
8 鉴权注入 route/auth.tsAuth.apply()
9 HTTP 构造 protocols/shared.ts:322jsonPost() 设置 content-type
10 发送&重试 route/executor.tsretryStatusFailures() (最多 2 次)
11 流解析 各 Protocol 的 stream.step() → LLMEvent[]

2. 请求 Header 明细

通用 Headers

Header 取值来源 说明
content-type protocols/shared.ts:322 固定 application/json
User-Agent session/llm/request.ts:21 opencode/<version>
x-session-affinity session/llm/request.ts:197 会话亲和性路由
X-Session-Id session/llm/request.ts:198 会话 ID

Anthropic

Header 取值来源 说明
x-api-key providers/anthropic.ts:14Auth.header("x-api-key") API key;env 回退 ANTHROPIC_API_KEY
anthropic-version protocols/anthropic-messages.ts:852 固定 2023-06-01
content-type protocols/shared.ts:322 application/json

OpenAI / OpenAI Compatible

Header 取值来源 说明
Authorization providers/openai.ts:20AuthOptions.bearer() Bearer <key>;env 回退 OPENAI_API_KEY
content-type protocols/shared.ts:322 application/json

Azure OpenAI

Header 取值来源 说明
api-key providers/azure.ts:72Auth.header("api-key") Azure API key;env 回退 AZURE_OPENAI_API_KEY
Authorization providers/azure.ts:10Auth.remove("authorization") 主动移除,避免与 api-key 冲突
api-version(URL 参数) providers/azure.ts:33,81 URL 查询参数,默认 v1

Amazon Bedrock(SigV4)

Header 取值来源 说明
Authorization protocols/utils/bedrock-auth.ts:27AwsV4Signer.sign() AWS SigV4 签名
x-amz-date protocols/utils/bedrock-auth.tsAwsV4Signer.sign() SigV4 时间戳
x-amz-security-token protocols/utils/bedrock-auth.ts STS 临时 token(有 sessionToken 时)
content-type protocols/utils/bedrock-auth.ts:40 签名前设置,纳入签名范围

Bedrock 也支持 Bearer API key(providers/amazon-bedrock.ts 传入 apiKey 时)。

Google Gemini

Header 取值来源 说明
x-goog-api-key providers/google.ts:17Auth.header("x-goog-api-key") Google API key;env 回退 GOOGLE_GENERATIVE_AI_API_KEY

URL 动态嵌入模型 ID:/models/${model.id}:streamGenerateContent?alt=sse(protocols/gemini.ts:505)

GitHub Copilot

Header 取值来源 说明
Authorization providers/github-copilot.ts:40,46AuthOptions.bearer() Bearer <token>;无默认 env var,baseURL 必须外部配置

opencode 自有 Provider

Header 取值来源 说明
x-opencode-project session/llm/request.ts:190 项目 ID
x-opencode-session session/llm/request.ts:191 会话 ID
x-opencode-request session/llm/request.ts:192 请求 ID
x-opencode-client session/llm/request.ts:193 客户端类型

3. 鉴权机制

Provider 机制 实现位置
Anthropic x-api-key: <key> providers/anthropic.ts:14
OpenAI / Compatible Authorization: Bearer <key> route/auth-options.ts:bearer()
Azure api-key: <key>(移除 Authorization) providers/azure.ts:68-76
Bedrock AWS SigV4(AwsV4Signer) protocols/utils/bedrock-auth.ts:sigV4()
Google Gemini x-goog-api-key: <key> providers/google.ts:17
GitHub Copilot Authorization: Bearer <OAuth token> providers/github-copilot.ts:40
OpenRouter Authorization: Bearer <key> providers/openrouter.ts

凭据解析链(route/auth-options.ts:bearer()):

显式传入 auth → 显式传入 apiKey → Config.redacted(ENV_VAR_NAME) → MissingCredentialError

4. 关键代码位置索引

文件 作用
packages/llm/src/route/client.ts Route.make() / LLMClient / compile()
packages/llm/src/route/auth.ts Auth 抽象(bearer/header/custom)
packages/llm/src/route/auth-options.ts AuthOptions.bearer() 标准解析链
packages/llm/src/route/executor.ts HTTP 发送 / 错误分类 / 指数退避重试
packages/llm/src/route/transport/http.ts jsonRequestParts() / httpJson()
packages/llm/src/protocols/shared.ts:322 jsonPost() — 设置 content-type
packages/llm/src/protocols/anthropic-messages.ts:845 Anthropic 路由(anthropic-version header)
packages/llm/src/protocols/openai-chat.ts:497 OpenAI Chat Completions 路由
packages/llm/src/protocols/openai-responses.ts:984 OpenAI Responses API 路由
packages/llm/src/protocols/gemini.ts:500 Gemini 路由(URL 嵌入模型 ID)
packages/llm/src/protocols/bedrock-converse.ts:658 Bedrock Converse 路由
packages/llm/src/protocols/utils/bedrock-auth.ts AWS SigV4 签名(AwsV4Signer)
packages/opencode/src/session/llm/request.ts session 级 headers 构造
packages/opencode/src/session/llm/native-request.ts AI SDK → LLMRequest 降格
packages/opencode/src/session/llm/native-runtime.ts Native 路径选择与执行
packages/opencode/src/provider/auth.ts OAuth / API key 凭据管理

5. 重试策略

  • 最大重试:2 次(executor.ts:MAX_RETRIES)
  • 可重试状态码:429503504529
  • 退避策略:优先 retry-after-ms/retry-after header,否则指数退避(基础 500ms,上限 10s,±20% 抖动)

Generated by Daily Upstream Sync + Request-Flow Analysis · 96 AIC · ⌖ 7.04 AIC · ⊞ 5.9K ·

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions