Skip to content

fix(opencode-web): force explicit loopback entries in child no_proxy (issue #75) - #76

Open
linletian wants to merge 1 commit into
developfrom
fix/opencode-web-loopback-noproxy
Open

fix(opencode-web): force explicit loopback entries in child no_proxy (issue #75)#76
linletian wants to merge 1 commit into
developfrom
fix/opencode-web-loopback-noproxy

Conversation

@linletian

Copy link
Copy Markdown
Owner

问题(#75

opencode web/serve 入口下 oh-my-openagent 的 task 工具 100% 崩溃:messages.map is not a function;切到 CLI TUI 即恢复。

根因(已在 127.0.0.1 实测复现并验证)

  1. 宿主环境配置了局域网代理(HTTP_PROXY=http://192.168.1.254:6268),no_proxy 使用 CIDR 写法 127.0.0.0/8
  2. opencode 内嵌 Bun 运行时:Bun 的 fetch 会读代理环境变量,但 no_proxy 不匹配 CIDR 网段(只认显式主机名/IP)。于是插件进程内对 http://127.0.0.1:<port>(opencode 自身服务)的 SDK 调用被送进局域网代理 → 代理无法连接 → 502
  3. 插件 normalizeSDKResponse(..., {preferResponseOnMissingData: true}) 在错误响应下返回非数组对象,下游 messages.map 直接崩溃。
  4. TUI 不受影响:该模式下插件走进程内 fetch,不经过网络/代理。

对照实验(opencode 1.18.18 内嵌 Bun 1.3.14 实测):

环境 Bun fetch → 127.0.0.1:port
代理 + CIDR-only no_proxy(现状) 502
no_proxy 追加显式 127.0.0.1 直连(401 无 auth / 200 带 auth)✅
Node 同款调用(对照) 始终正常(Node 不读代理 env)

修复

opencode_web.buildEnv 合并 NO_PROXY/no_proxy(大小写两种)并追加字面 loopback 条目 localhost,127.0.0.1,::1

  • 仅在配置了代理时生效;* 通配时不动;已有条目(含 CIDR)全部保留、去重。
  • 远程 LLM provider 流量照常走代理(仅 loopback 绕过);本地 provider(ollama 等)顺带修好。
  • LAN / Tailscale 远程访问不受影响:mw→opencode 的 Go 反向代理本就支持 CIDR no_proxy,且该改动只作用于 opencode 子进程环境。

测试

  • 新增 TestWithLoopbackNoProxy(6 个子用例:无代理 no-op / 新建 / CIDR 保留+追加 / 双写合并去重 / 通配跳过 / 幂等)与 TestBuildEnv_LoopbackNoProxy(端到端,含代理变量保留断言)。
  • gofmt 干净、go test ./... 全过、两个二进制构建通过。
  • 实机 E2E:以修复后 env 启动 opencode serve,Bun 探针 401/200(修复前 502)。

Closes #75(myworktree 侧)。上游层面另见 issue 评论:Bun 的 no_proxy CIDR 支持、opencode 插件 client 的 loopback 代理绕行、oh-my-openagent 的数组容错。

…(issue #75)

opencode embeds the Bun runtime, whose fetch honors HTTP(S)_PROXY but
does not match CIDR ranges in no_proxy (e.g. the common 127.0.0.0/8).
With a LAN proxy configured, in-process plugin SDK calls to the
loopback server were routed through the proxy and failed with 502,
surfacing in oh-my-openagent as 'messages.map is not a function' and a
100% task-tool failure in web/serve mode (TUI is unaffected because
plugins use in-process fetch there).

buildEnv now merges NO_PROXY/no_proxy (both cases) and appends the
literal hosts localhost, 127.0.0.1, ::1 so every no_proxy matcher
bypasses loopback. No-op without a configured proxy or with a '*'
wildcard; existing entries (CIDR included) are preserved; remote LLM
provider traffic still goes through the proxy.

Verified live: opencode serve + Bun probe returns 502 with CIDR-only
no_proxy, and 401/200 (direct) after the fix. Unit tests cover append,
merge/dedupe across cases, wildcard, and no-proxy no-op.
@linletian

Copy link
Copy Markdown
Owner Author

CI 备注:test-build (ubuntu-latest) 的失败是 internal/framework.TestRestartCreatesNewID 的 TempDir 清理竞态(unlinkat ... directory not empty),在 origin/develop(648af1d)本地复跑同样失败,属预存 flake,与本 PR 无关(本 PR 只改 internal/instance/opencode_web,该包测试全过)。建议另行修复。

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