feat: support custom headers in LLM runner (EVOLVER_LLM_HEADERS)
问题
内置的 llm runner(llmRunner.js)在 complete() 函数中硬编码了 HTTP 请求头:
- "" + + "" + + "javascript headers: { 'content-type': 'application/json', authorization: Bearer \ },
- "" + + "" + + "" +
某些 OpenAI 兼容的 API 提供商需要额外的请求头来进行路由/认证。例如,OpenCode Go 需要 + "" + x-opencode-session + "" + 头来进行请求路由:
- "" + + "" + + "json { "error": { "type": "MissingSessionID", "message": "Request is missing x-opencode-session and cannot be routed efficiently." } }
- "" + + "" + + "" +
没有这个头,API 会返回 400 Bad Request。
建议方案
通过环境变量 + "" + EVOLVER_LLM_HEADERS + "" + 支持自定义请求头:
简单格式(单个头):
- "" + + "" + + "ash export EVOLVER_LLM_HEADERS='x-opencode-session:evolver-autoexec-12345'
- "" + + "" + + "" +
JSON 格式(多个头):
- "" + + "" + + "ash export EVOLVER_LLM_HEADERS='{"x-opencode-session":"evolver-12345","user-agent":"my-agent/1.0"}'
- "" + + "" + + "" +
实现建议
在 + "" + eadLlmRunnerConfig() + "" + 中解析 + "" + EVOLVER_LLM_HEADERS + "" + 并合并到请求头:
- "" + + "" + + "javascript // readLlmRunnerConfig const rawHeaders = env['EVOLVER_LLM_HEADERS'] ?? ''; const extraHeaders = rawHeaders.startsWith('{') ? JSON.parse(rawHeaders) : Object.fromEntries(rawHeaders.split(',').map(h => h.split(':').map(s => s.trim())));
return { apiKey, baseUrl, model, maxTurns, maxFileBytes, extraHeaders };
// complete() const response = await fetchFn(\/chat/completions, { method: 'POST', headers: { 'content-type': 'application/json', authorization: \Bearer \, ...config.extraHeaders, }, body: JSON.stringify({ model: config.model, messages, tools: TOOLS, tool_choice: 'auto' }), signal, });
- "" + + "" + + "" +
临时解决方案
目前使用本地代理来添加所需的请求头,然后转发到上游 API。这虽然可行,但增加了一个额外的进程和网络跳转。
环境信息
- Evolver: 2.0.37
- OS: Windows 11
- Node: v24.18.1
- API 提供商: OpenCode Go ( + "" + https://opencode.ai/zen/go/v1 + "" + )
Problem
The built-in llm runner (llmRunner.js) hardcodes HTTP headers in the complete() function:
- "" + + "" + + "javascript headers: { 'content-type': 'application/json', authorization: \Bearer \ },
- "" + + "" + + "" +
Some OpenAI-compatible API providers require additional headers for routing/authentication. For example, OpenCode Go requires + "" + x-opencode-session + "" + for request routing:
- "" + + "" + + "json { "error": { "type": "MissingSessionID", "message": "Request is missing x-opencode-session and cannot be routed efficiently." } }
- "" + + "" + + "" +
Without this header, the API returns 400 Bad Request.
Proposed Solution
Add support for custom headers via environment variable + "" + EVOLVER_LLM_HEADERS + "" + :
Simple format (single header):
- "" + + "" + + "ash export EVOLVER_LLM_HEADERS='x-opencode-session:evolver-autoexec-12345'
- "" + + "" + + "" +
JSON format (multiple headers):
- "" + + "" + + "ash export EVOLVER_LLM_HEADERS='{"x-opencode-session":"evolver-12345","user-agent":"my-agent/1.0"}'
- "" + + "" + + "" +
Implementation
In + "" + eadLlmRunnerConfig() + "" + , parse + "" + EVOLVER_LLM_HEADERS + "" + and merge into request headers:
- "" + + "" + + "javascript // readLlmRunnerConfig const rawHeaders = env['EVOLVER_LLM_HEADERS'] ?? ''; const extraHeaders = rawHeaders.startsWith('{') ? JSON.parse(rawHeaders) : Object.fromEntries(rawHeaders.split(',').map(h => h.split(':').map(s => s.trim())));
return { apiKey, baseUrl, model, maxTurns, maxFileBytes, extraHeaders };
// complete() const response = await fetchFn(\/chat/completions, { method: 'POST', headers: { 'content-type': 'application/json', authorization: \Bearer \, ...config.extraHeaders, }, body: JSON.stringify({ model: config.model, messages, tools: TOOLS, tool_choice: 'auto' }), signal, });
- "" + + "" + + "" +
Workaround
Currently using a local proxy that adds the required header before forwarding to the upstream API. This works but adds an extra process and network hop.
Environment
- Evolver: 2.0.37
- OS: Windows 11
- Node: v24.18.1
- API Provider: OpenCode Go ( + "" + https://opencode.ai/zen/go/v1 + "" + )
Source: EvoMap/evolver