Skip to content

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

Description

@github-actions

本次变更提示

近期同步的 20 条提交主要涉及 TUI 交互、子 Agent 嵌套深度限制和 UI 修复,不直接影响请求流程或 Header 构造


1. 请求流程

opencode 存在两条并行的 LLM 请求路径:

  • Native 路径(@opencode/llm,Effect 体系):OpenAI、Anthropic、Bedrock、Google 等原生协议。
  • AI SDK 路径(ai / @ai-sdk/*):GitHub Copilot、Azure、OpenRouter、xAI 等。

1.1 Native 路径时序(Mermaid)

sequenceDiagram
    participant S as Session/prompt
    participant NR as native-runtime.ts
    participant NRQ as native-request.ts
    participant LC as LLMClient (client.ts)
    participant P as Protocol
    participant HT as HttpTransport (http.ts)
    participant Auth as Auth (auth.ts)
    participant EX as RequestExecutor (executor.ts)
    participant API as LLM Provider

    S->>NR: stream(input)
    NR->>NRQ: model() 按 api.npm 选 provider 工厂
    NRQ->>NRQ: request() 构造 LLMRequest
    NR->>LC: LLMClient.stream(request)
    LC->>LC: compile() → resolveRequestOptions()
    LC->>P: route.body.from(request) 构造请求体
    LC->>HT: prepareTransport() → jsonRequestParts()
    HT->>Auth: Auth.toEffect(auth)(authInput)
    Auth-->>HT: 返回已鉴权 Headers
    HT->>HT: ProviderShared.jsonPost() 设置 content-type
    LC->>EX: execute(httpRequest)
    EX->>EX: retryStatusFailures()(最多重试 2 次)
    EX->>API: HTTP POST(SSE/JSON 流)
    API-->>EX: 响应流
    EX-->>LC: HttpClientResponse
    LC->>P: streamPrepared() 解帧→解码 LLMEvent
    LC-->>S: Stream<LLMEvent>
Loading

1.2 关键步骤

# 步骤 文件 / 函数
1 Session 调用 stream(input) session/llm/native-runtime.ts
2 model.api.npm 分派 provider 工厂,构造 LLMRequest session/llm/native-request.ts:model() L153-175
3 compile() 合并 route/model/request 三层默认值 llm/src/route/client.ts:compile
4 Protocol body.from(request) 构造 provider-native JSON 体 各协议文件
5 jsonRequestParts() 渲染 URL、合并静态 header、调用 Auth llm/src/route/transport/http.ts:jsonRequestParts
6 ProviderShared.jsonPost() 强制设置 content-type: application/json llm/src/protocols/shared.ts:322
7 遇到 429/503/504/529 按指数退避重试(最多 2 次) llm/src/route/executor.ts:retryStatusFailures
8 响应经 Framing 解帧后由 Protocol 状态机解析为 LLMEvent llm/src/route/client.ts:streamPrepared

2. 请求 Header 明细

通用(所有 Native 路径)

Header 取值来源 说明
content-type shared.ts:322 application/json,jsonPost() 强制设置

Anthropic

Header 取值来源 说明
anthropic-version anthropic-messages.ts:852"2023-06-01" 路由静态注入,每次请求携带
x-api-key providers/anthropic.ts:17apiKey || ANTHROPIC_API_KEY 鉴权(非 Bearer 格式)

OpenAI / OpenAI-Compatible

Header 取值来源 说明
Authorization auth-options.ts:bearer()"Bearer <apiKey || OPENAI_API_KEY>" 标准 Bearer Token

Azure OpenAI

Header 取值来源 说明
api-key providers/azure.ts:70apiKey || AZURE_OPENAI_API_KEY Azure 专用(同时移除 Authorization)

URL 附加 ?api-version=<version> 查询参数。

Amazon Bedrock(SigV4)

Header 取值来源 说明
Authorization bedrock-auth.ts:signRequest()AwsV4Signer.sign() AWS4-HMAC-SHA256 签名串
x-amz-date AwsV4Signer 自动 UTC 时间戳
x-amz-security-token AwsV4Signer(有 sessionToken 时) STS 临时凭证令牌

若提供 apiKey 则退化为 Authorization: Bearer <apiKey>

Google / Gemini

Header 取值来源 说明
x-goog-api-key providers/google.ts:16apiKey || GOOGLE_GENERATIVE_AI_API_KEY Google API Key

GitHub Copilot(AI SDK 路径)

Header 取值来源 说明
Authorization core/github-copilot/copilot-provider.ts:62"Bearer <apiKey>" OAuth Token 或 API Key
User-Agent 后缀 withUserAgentSuffix(..., "ai-sdk/openai-compatible/0.1.0") SDK 版本标识

OpenRouter

Header 取值来源 说明
Authorization providers/openrouter.ts"Bearer <apiKey || OPENROUTER_API_KEY>" Bearer Token

Cloudflare AI Gateway / Workers AI

Header 取值来源 说明
Authorization providers/cloudflare.ts:45 → Bearer from CLOUDFLARE_API_TOKEN / CF_AIG_TOKEN(Gateway)或 CLOUDFLARE_API_KEY / CLOUDFLARE_WORKERS_AI_TOKEN(Workers AI) Bearer Token

3. 鉴权机制

3.1 API Key

apiKey 参数优先 → 回退到 Auth.config("ENV_VAR")(读取环境变量)
→ Auth.header("x-api-key")    Anthropic
→ Auth.bearer()                OpenAI / OpenRouter 等
→ Auth.header("x-goog-api-key")  Google
→ Auth.remove("authorization") + Auth.header("api-key")  Azure

核心抽象:auth.ts:credential() / auth.ts:fromCredential() / auth-options.ts:bearer()

3.2 AWS SigV4(Bedrock)

protocols/utils/bedrock-auth.ts:signRequest() 使用 aws4fetchAwsV4Signer 对每请求签名。凭据在路由构造时静态注入;STS 凭据过期需调用方手动重建 model。

3.3 OAuth(GitHub Copilot 等)

packages/opencode/src/provider/auth.ts 管理 OAuth 流程(authorize()callback() → 存储 { type: "oauth", access: "<token>" }),运行时以 Bearer Token 形式注入。

3.4 自定义 Auth

Auth.custom((input: AuthInput) => Effect.Effect<Headers, LLMError>) 允许完全自定义 header 注入,Bedrock SigV4 即此方式。


4. 关键代码位置索引

文件 说明
packages/llm/src/route/client.ts 核心路由、compile()LLMClient
packages/llm/src/route/auth.ts Auth/Credential 抽象,header 注入接口
packages/llm/src/route/auth-options.ts AuthOptions.bearer() 标准 Bearer 解析
packages/llm/src/route/transport/http.ts jsonRequestParts() URL/header/auth 组装
packages/llm/src/route/executor.ts HTTP 执行、重试、错误分类、日志脱敏
packages/llm/src/protocols/shared.ts:320 jsonPost()content-type: application/json
packages/llm/src/protocols/anthropic-messages.ts:852 anthropic-version: 2023-06-01
packages/llm/src/protocols/openai-chat.ts:497 OpenAI Chat 路由
packages/llm/src/protocols/openai-responses.ts:984 OpenAI Responses 路由
packages/llm/src/protocols/bedrock-converse.ts:658 Bedrock 路由,SigV4 auth
packages/llm/src/protocols/gemini.ts:500 Gemini 路由
packages/llm/src/protocols/utils/bedrock-auth.ts AWS SigV4 实现(aws4fetch)
packages/llm/src/providers/anthropic.ts x-api-key 注入
packages/llm/src/providers/azure.ts api-key,移除 Authorization
packages/llm/src/providers/google.ts x-goog-api-key
packages/llm/src/providers/amazon-bedrock.ts SigV4 / Bearer 二选一
packages/llm/src/providers/github-copilot.ts Copilot provider facade
packages/llm/src/providers/cloudflare.ts Cloudflare AI Gateway / Workers AI
packages/opencode/src/session/llm/native-request.ts model() 分派,request() 构造
packages/opencode/src/session/llm/native-runtime.ts Native 路径入口
packages/opencode/src/provider/provider.ts BUNDLED_PROVIDERS,AI SDK 工厂
packages/opencode/src/provider/auth.ts OAuth 流程管理
packages/core/src/github-copilot/copilot-provider.ts:62 Copilot Authorization: Bearer

Generated by Daily Upstream Sync + Request-Flow Analysis · 152.6 AIC · ⌖ 7.06 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