sequenceDiagram
participant S as Session/Prompt
participant C as LLMClient (client.ts)
participant P as Protocol (anthropic-messages 等)
participant T as HttpTransport (transport/http.ts)
participant A as Auth (auth.ts)
participant E as RequestExecutor (executor.ts)
participant LLM as LLM Provider
S->>C: stream(request) / generate(request)
C->>C: resolveRequestOptions() 合并 defaults
C->>C: applyCachePolicy()
C->>P: route.body.from(request) 构造 body
P-->>C: validated body
C->>T: route.prepareTransport(body, request)
T->>T: jsonRequestParts() 渲染 URL & headers
T->>A: Auth.toEffect()(authInput) 注入凭据
A-->>T: headers (含鉴权 header)
T-->>C: HttpPrepared { request, framing }
C->>E: RequestExecutor.execute(httpRequest)
E->>LLM: POST /endpoint
LLM-->>E: SSE/HTTP stream
E->>E: retryStatusFailures() 最多重试 2 次
E-->>S: Stream<LLMEvent>
本次变更提示
近 20 条同步提交(stats 回退、config 字段容错、UI 修复、i18n 等)与请求流程/Header 无直接关联。
1. 请求流程(时序)
sequenceDiagram participant S as Session/Prompt participant C as LLMClient (client.ts) participant P as Protocol (anthropic-messages 等) participant T as HttpTransport (transport/http.ts) participant A as Auth (auth.ts) participant E as RequestExecutor (executor.ts) participant LLM as LLM Provider S->>C: stream(request) / generate(request) C->>C: resolveRequestOptions() 合并 defaults C->>C: applyCachePolicy() C->>P: route.body.from(request) 构造 body P-->>C: validated body C->>T: route.prepareTransport(body, request) T->>T: jsonRequestParts() 渲染 URL & headers T->>A: Auth.toEffect()(authInput) 注入凭据 A-->>T: headers (含鉴权 header) T-->>C: HttpPrepared { request, framing } C->>E: RequestExecutor.execute(httpRequest) E->>LLM: POST /endpoint LLM-->>E: SSE/HTTP stream E->>E: retryStatusFailures() 最多重试 2 次 E-->>S: Stream<LLMEvent>分步说明
route/client.ts→LLMClient.stream()/generate()client.ts→resolveRequestOptions()src/cache-policy.ts→applyCachePolicy()protocols/*/→protocol.body.from()client.ts:compile()→Schema.decodeUnknownEffecttransport/http.ts→jsonRequestParts()route/auth.ts→Auth.toEffect()route/executor.ts→RequestExecutor.execute()executor.ts→retryStatusFailures()(429/503/504/529, 最多 2 次)client.ts→route.streamPrepared()→ Protocol 状态机2. 请求 Header 明细
Anthropic (
protocols/anthropic-messages.ts)content-typeshared.ts:322application/jsonx-api-keyproviders/anthropic.ts:14–19apiKey选项或ANTHROPIC_API_KEY环境变量)anthropic-versionprotocols/anthropic-messages.ts:8522023-06-01anthropic-betaopencode/provider.ts:174–177interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14OpenAI (
protocols/openai-chat.ts/openai-responses.ts)content-typeshared.ts:322application/jsonAuthorizationproviders/openai.ts→AuthOptions.bearer()Bearer <OPENAI_API_KEY>Amazon Bedrock (
protocols/bedrock-converse.ts)content-typebedrock-auth.ts:37Authorizationprotocols/utils/bedrock-auth.ts→AwsV4Signerx-amz-dateAwsV4Signer自动生成x-amz-security-tokenAwsV4Signer(含 sessionToken 时)Authorizationproviders/amazon-bedrock.ts:39Bearer <apiKey>(配置了 apiKey 时)Google Gemini (
protocols/gemini.ts)content-typeshared.ts:322application/jsonx-goog-api-keyproviders/google.ts:14–19GOOGLE_GENERATIVE_AI_API_KEY)Azure OpenAI (
providers/azure.ts)content-typeshared.ts:322application/jsonapi-keyproviders/azure.ts:61–66AZURE_OPENAI_API_KEY); 移除了Authorizationapi-versionproviders/azure.ts:75–79GitHub Copilot (
providers/github-copilot.ts)content-typeshared.ts:322application/jsonAuthorizationproviders/github-copilot.ts:44–48Bearer <copilot-oauth-token>OpenRouter / OpenAI-Compatible
content-typeshared.ts:322application/jsonAuthorizationproviders/openrouter.ts:85/openai-compatible.ts:26Bearer <API_KEY>(OPENROUTER_API_KEY)HTTP-Refereropencode/provider.ts:458,470,479,490,601X-Titleopencode/provider.ts:459,471,492,603opencodeX-Sourceopencode/provider.ts:472opencode(llmgateway)X-BILLING-INVOKE-ORIGINopencode/provider.ts:483OpenCode(nvidia)Google Vertex AI
Authorizationopencode/provider.ts:538–541Bearer (gcloud_access_token)(ADC 动态获取)GitLab AI Gateway
User-Agentopencode/provider.ts:621opencode/(ver) gitlab-ai-provider/(ver) ((os))anthropic-betaopencode/provider.ts:622context-1m-2025-08-07PRIVATE-TOKEN/Authorizationopencode/provider.ts:669PRIVATE-TOKEN,OAuth token 用Bearer3. 鉴权机制
x-api-keyproviders/anthropic.ts:9–19Authorization: Bearerroute/auth-options.ts:43–52protocols/utils/bedrock-auth.ts→AwsV4SignerAuthorization: Bearerproviders/amazon-bedrock.ts:39x-goog-api-keyproviders/google.ts:14–19api-keyproviders/azure.ts:61–66Authorization: Bearerproviders/github-copilot.ts:44–48Authorization: Bearerproviders/openrouter.ts:85Authorization: Beareropencode/provider.ts:532–541Bearer) 或 PAT(PRIVATE-TOKEN)opencode/provider.ts:669凭据解析优先级(以 Anthropic 为例):
auth: Auth对象apiKeyANTHROPIC_API_KEY)MissingCredentialError→LLMError(AuthenticationReason)4. 关键代码位置索引
packages/llm/src/route/client.tscompile(),resolveRequestOptions()packages/llm/src/route/auth.tsAuth,bearer(),header(),custom()packages/llm/src/route/auth-options.tsAuthOptions.bearer()封装packages/llm/src/route/transport/http.tsjsonRequestParts(),httpJson()packages/llm/src/route/executor.tspackages/llm/src/protocols/anthropic-messages.ts:852anthropic-version: 2023-06-01packages/llm/src/protocols/openai-chat.ts:497–503packages/llm/src/protocols/bedrock-converse.ts:658–672packages/llm/src/protocols/utils/bedrock-auth.tspackages/llm/src/protocols/gemini.ts:500–509packages/llm/src/protocols/shared.ts:314–323jsonPost()统一设置 content-typepackages/llm/src/providers/anthropic.tspackages/llm/src/providers/azure.tsapi-keyheaderpackages/llm/src/providers/openrouter.tspackages/opencode/src/provider/provider.ts