Skip to content

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

Description

@github-actions

本次变更提示

近期同步提交主要为模型元数据和 UI 修正,不影响请求流程或 Header 构造


1. 请求流程(时序)

分层结构

session/llm.ts           ← 会话调度(AI SDK / Native 路径选择)
session/llm/request.ts   ← 准备层(system/Header/ProviderOptions)
session/llm/native-request.ts ← 会话数据→LLMRequest 适配
session/llm/native-runtime.ts ← 执行层
route/client.ts          ← 请求编译(compile/stream/generate)
route/executor.ts        ← HTTP 发送、错误映射、重试
route/auth.ts            ← 凭据加载与 Header 注入
route/transport/http.ts  ← POST 构造、URL 拼装
protocols/*              ← 各协议实现
providers/*              ← Provider 门面

关键步骤

# 步骤 关键文件:符号
1 Provider/Model 解析:按 model.api.npm 选 facade native-request.ts:LLMNative.model
2 Header 准备:聚合 system、options、插件 chat.headers hook request.ts:LLMRequestPrep.prepare
3 Body 构造:protocol.body.from(request) → provider-native JSON protocols/*/fromRequest
4 Body 验证/编码:Effect Schema encode/decode route/client.ts:compile
5 鉴权注入:Auth.apply() 加载 key/SigV4 → Headers.setAll route/auth.ts:Auth.apply
6 HTTP POST 构造:jsonRequestParts() 拼 URL+headers transport/http.ts:jsonRequestParts
7 发送+重试:429/503/504/529 最多 2 次,退避 500ms–10s executor.ts:retryStatusFailures
8 流解析:framing 切帧 → Schema decode → step 状态机 route/client.ts:streamPrepared

2. 请求 Header 明细

通用 Header(所有 Provider,request.ts 注入)

Header 取值来源 说明
User-Agent opencode/${InstallationVersion}(L19) 客户端版本
x-session-affinity sessionID 路由亲和性
X-Session-Id sessionID 会话追踪
x-parent-session-id parentSessionID(可选) 父会话

providerID.startsWith("opencode") 时,额外注入:x-opencode-projectx-opencode-sessionx-opencode-requestx-opencode-client

Anthropic

Header 取值来源 说明
x-api-key options.apiKey > env ANTHROPIC_API_KEY(anthropic.ts:17) API 鉴权
anthropic-version 硬编码 "2023-06-01"(anthropic-messages.ts:852) API 版本锁定

OpenAI(Responses / Chat)

Header 取值来源 说明
Authorization Bearer <key>,env OPENAI_API_KEY(openai.ts:24) API 鉴权

Azure OpenAI

Header 取值来源 说明
api-key options.apiKey > env AZURE_OPENAI_API_KEY(azure.ts:67) 非 Bearer,Azure 专属
api-version(URL query) options.apiVersion(默认 "v1") API 版本

Auth.remove("authorization") 后再注入 api-key(azure.ts:67)。

Amazon Bedrock(SigV4)

Header 取值来源 说明
Authorization AWS SigV4(aws4fetch,bedrock-auth.ts:signRequest) AWS4-HMAC-SHA256 Credential=...
x-amz-date SigV4 自动生成 请求时间戳
x-amz-security-token credentials.sessionToken(STS) 临时凭证令牌
content-type 签名前设为 application/json(bedrock-auth.ts:51) 必须纳入签名

若配置 apiKey,改走 Auth.bearer(apiKey) 路径,跳过 SigV4(amazon-bedrock.ts:29)。

Google Gemini

Header 取值来源 说明
x-goog-api-key options.apiKey > env GOOGLE_GENERATIVE_AI_API_KEY(google.ts:17) API 鉴权(非 Bearer)

URL 动态:/models/${modelId}:streamGenerateContent?alt=sse(gemini.ts:505)。

GitHub Copilot

Header 取值来源 说明
Authorization Bearer <key>,无默认 env var(github-copilot.ts:40) 必须显式提供

OpenAI 兼容 / OpenRouter / xAI

Provider Header env var
OpenAI-compat Authorization: Bearer 无默认(openai-compatible.ts:29)
OpenRouter Authorization: Bearer OPENROUTER_API_KEY(openrouter.ts:84)
xAI Authorization: Bearer XAI_API_KEY(xai.ts:17)

Cloudflare AI Gateway / Workers AI

Header 取值来源 说明
cf-aig-authorization Bearer <gatewayApiKey>,env CLOUDFLARE_API_TOKEN(cloudflare.ts:47) Gateway 鉴权
Authorization Bearer <apiKey>(cloudflare.ts:50) 下游 provider
Workers AI Authorization Bearer,env CLOUDFLARE_API_KEY(cloudflare.ts:60) Workers AI 鉴权

3. 鉴权机制

凭据加载统一由 Auth 抽象(route/auth.ts)处理:

Auth.optional(options.apiKey)
  .orElse(Auth.config("ENV_VAR"))   // Effect Config,缺失时抛 AuthenticationReason
  .bearer()                         // → Authorization: Bearer <key>
  // 或 .header("x-api-key")        // → x-api-key: <key>
Provider 机制 代码位置
Anthropic Header x-api-key providers/anthropic.ts:12-18
OpenAI Bearer Token providers/openai.ts:24
Azure Header api-key(移除 Authorization) providers/azure.ts:67-72
Bedrock AWS SigV4 / Bearer protocols/utils/bedrock-auth.ts:sigV4
Google Header x-goog-api-key providers/google.ts:13-18
Copilot Bearer Token(无默认 env) providers/github-copilot.ts:40

OpenAI OAuth:注入自定义 fetch(FetchHttpClient.Fetch),绕过标准 Auth.apply(native-runtime.ts:statusWithFetch)。


4. 关键代码位置索引

文件 关键符号
session/llm/request.ts LLMRequestPrep.prepare(L19 User-Agent; L134 chat.headers hook; L187 headers 构造)
session/llm/native-request.ts LLMNative.model(L153), LLMNative.request(L186)
session/llm/native-runtime.ts LLMNativeRuntime.stream(L57), statusWithFetch(L64)
route/client.ts Route.make(L258), compile(L310), LLMClient.layer(L355)
route/auth.ts Auth.bearer(L97), Auth.header(L103), Auth.custom(L117)
route/executor.ts retryStatusFailures(L207), layer(L230)
route/transport/http.ts jsonRequestParts(L61), httpJson(L97)
protocols/anthropic-messages.ts route(L842-L856)(含 anthropic-version 静态 header)
protocols/openai-chat.ts route(L497-L504)
protocols/openai-responses.ts route(L984), webSocketRoute(L1011)
protocols/bedrock-converse.ts route(L658-L672)(动态 URL)
protocols/utils/bedrock-auth.ts sigV4(L43), signRequest(L20)
protocols/gemini.ts route(L500-L509)(动态 URL 含 modelId)

5. 重试与 Body Overlay

重试:对 429/503/504/529 最多 2 次重试,退避 500ms–10s,尊重 Retry-After/Retry-After-Ms。解析 OpenAI(x-ratelimit-*)和 Anthropic(anthropic-ratelimit-*)速率限制响应 Header。

Body Overlay:request.http.body 可追加字段,PROTOCOL_BODY_OVERLAY_DENYLIST(transport/http.ts:30)保护 messages/model/tools 等协议保留字段不可覆盖。

协议复用:DeepSeek、TogetherAI、Cerebras 等均复用 OpenAIChat.protocol,协议修复自动传播。

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