Skip to content

feat(agent-core-v2): add KIMI_CODE_LLM_HEADERS_TIMEOUT_MS for llm headers timeout - #4092

Open
sailist wants to merge 2 commits into
mainfrom
feat-280-09-30-llm-headers-timeout
Open

sailist wants to merge 2 commits into
mainfrom
feat-280-09-30-llm-headers-timeout

Conversation

@sailist

@sailist sailist commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Requirement or Bug

新增环境变量 KIMI_CODE_LLM_HEADERS_TIMEOUT_MS,可配置 LLM 请求等待响应头的最长时间(替代 HTTP 客户端默认的 300 秒),避免长时间不返回响应头的非流式 thinking 请求在 300s 被掐断后陷入退避重试循环。

Bug Reproduction Steps

N/A

Root Cause

N/A

Code Changes

 packages/agent-core-v2/src/human/llm/requester/
+├── timeout.ts                          # resolveLlmHeadersTimeoutMs + 代理感知的 memoized dispatcher 工厂
 └── bases/
     ├── openai/requester.ts             # createClient:解析到值时传 fetchOptions.dispatcher
     ├── openai-responses/requester.ts   # 同上
     └── anthropic/requester.ts          # 同上
 docs/en|zh/configuration/env-vars.md    # 各新增一行变量说明
 createClient(model, headers)
+  headersTimeoutMs = resolveLlmHeadersTimeoutMs()
+  # 未设置/空串 → undefined;非正整数 → 抛错(经 convertOpenAIError 归为 llm.failed.remote,消息含变量名)
+  dispatcher = headersTimeoutMs === undefined ? undefined : getLlmHeadersTimeoutDispatcher(headersTimeoutMs)
+  # 无代理 → undici Agent({headersTimeout})
+  # HTTP(S) 代理 → EnvHttpProxyAgent(解析 http/https/all_proxy 优先级,no_proxy 追加回环保护)
+  # SOCKS 代理 → undefined + stderr 一次性警告(请求走全局 dispatcher)
   return new SDK({
     ...existingOptions,
+    fetchOptions: dispatcher === undefined ? undefined : { dispatcher },
   })

只放宽 undici 的 headersTimeout(headers-only 语义),SDK 总超时仍为默认 10 分钟:单次尝试实际上限为 min(变量值, 10 分钟)。不设 bodyTimeout,不碰全局 dispatcher,不影响进程内其他 fetch 用户。google-genai 的 SDK 无 dispatcher/fetchOptions 接缝,无法支持,文档已如实标注。

Behavior Changes and Affected Users

Behavior Before After Who relies on the old behavior Escape hatch
未设置 KIMI_CODE_LLM_HEADERS_TIMEOUT_MS(全部现有用户) 不传 fetchOptions,undici 默认 300s headers 超时 完全一致(不传 fetchOptions,RequestInit 无 dispatcher) 全部现有用户 无需
设置为正整数 变量不存在 openai / openai-responses / anthropic 三个协议的请求以该值为 undici headers 超时 无(新变量) 不设置即恢复默认
设置为非正整数等非法值 变量不存在 请求失败,llm.failed.remote,错误消息含变量名 无(新变量) 修正或取消该变量
设置变量 + HTTP(S) 代理环境变量 变量不存在 请求仍经代理(EnvHttpProxyAgent 携带同样的 headersTimeout) 无(新变量) 同上
设置变量 + SOCKS 代理环境变量 变量不存在 变量不生效,stderr 一次性警告,请求仍走代理的全局 dispatcher 无(新变量) 同上
google-genai 协议请求 无 dispatcher 配置 不变(SDK 无接缝,不支持) 全部 google-genai 用户 无需

受影响模块与测试覆盖:

  • llm/requester/timeout.ts(新增)与三个 base 的 createClient 接线:test/llm/headers-timeout.test.ts 新增 1 个用例——stub 全局 fetch 走真实 SDK,逐协议(openai / openai-responses / anthropic)断言未设置时 RequestInit 无 dispatcher、设置后有;HTTP 代理下有;SOCKS 下无;非法值时请求以 llm.failed.remote 失败且消息含变量名。
  • test/llm/errors.test.ts:413 用例并入「maps remaining status errors」,测试总数净增 0(根规则:加 1 删 1)。

Checklist

  • I have read the CONTRIBUTING document.
  • I have added tests that prove my feature works.
  • The behavior-change table above is complete, and every removed behavior or flipped default is named in the changeset and either has an escape hatch or was explicitly approved by a maintainer in this PR.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5ac3cd0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@5ac3cd0
npx https://pkg.pr.new/@moonshot-ai/kimi-code@5ac3cd0

commit: 5ac3cd0

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7ae5076a1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +89 to +95
if (httpProxyUrls !== undefined) {
dispatcher = new EnvHttpProxyAgent({
httpProxy: httpProxyUrls.httpProxy ?? '',
httpsProxy: httpProxyUrls.httpsProxy ?? '',
noProxy: resolveNoProxy(env),
headersTimeout: timeoutMs,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the invalid-proxy fallback

When a CLI user sets KIMI_CODE_LLM_HEADERS_TIMEOUT_MS while an HTTP(S) proxy URL is malformed, this construction is outside the existing proxy factory's error handling, so the LLM request now fails with llm.failed.remote. Previously createProxyDispatcher caught invalid proxy configurations, warned, and continued with a direct connection (packages/agent-core-v2/src/_base/utils/proxy.ts:201-204). Reuse that fallback or catch this construction error so enabling the new timeout does not break users whose invalid proxy setting was already being tolerated.

Useful? React with 👍 / 👎.

Comment on lines +10 to +11
const value = Number(raw);
if (!Number.isInteger(value) || value <= 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject timeout values outside Node's timer range

Values such as 3000000000 satisfy this validation and are documented as valid positive integers, but Undici schedules its header deadline with a Node timer, whose maximum delay is 2^31 - 1; Node clamps larger delays to 1 ms. As a result, a user attempting to set a very large timeout instead gets immediate headers-timeout failures on every supported LLM request, rather than the documented ten-minute SDK cap. Reject or clamp values above the timer limit (preferably to the total-request timeout) before constructing the dispatcher.

Useful? React with 👍 / 👎.

Comment thread docs/en/configuration/env-vars.md Outdated
| `KIMI_MODEL_TOP_P` | Nucleus-sampling `top_p` for every request; `kimi` provider only (global) | Number, e.g. `0.95` |
| `KIMI_MODEL_THINKING_EFFORT` | Force a thinking effort (`thinking.effort`), bypassing the model's declared `support_efforts`; `kimi` provider only | An effort value, e.g. `max` |
| `KIMI_MODEL_THINKING_KEEP` | Preserved-thinking passthrough: `thinking.keep` on `kimi`, a `clear_thinking_20251015` edit on `anthropic`; overrides `[thinking] keep` | A value the API accepts, e.g. `all`; an off-value (`false`/`0`/`no`/`off`/`none`/`null`) disables it |
| `KIMI_CODE_LLM_HEADERS_TIMEOUT_MS` | Max time (ms) an LLM request on the `openai` / `openai-responses` / `anthropic` protocols may wait for the response headers (first byte), replacing the HTTP client's default 300 s headers timeout — raise it for long non-streaming thinking; unset keeps the default; the SDK's own total request timeout (default 10 minutes) still caps each attempt; not supported for `google-genai` (its SDK exposes no dispatcher option) or behind a SOCKS proxy (requests still go through the proxy) | Positive integer; invalid values fail the request |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the required CLI changeset

This adds a documented, user-perceivable CLI environment variable, but the commit does not add a .changeset file. The next release's curated CLI changelog will therefore omit how users can configure longer LLM header waits. Add an @moonshot-ai/kimi-code changeset with a short user-facing sentence for this setting.

AGENTS.md reference: AGENTS.md:L85-L86

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant