Skip to content

feat: cooperative proxy mode — forward native tools to billion-context proxy (内外呼应) - #154

Open
ranxianglei wants to merge 4 commits into
masterfrom
2026-08-16_cooperative-proxy-mode
Open

feat: cooperative proxy mode — forward native tools to billion-context proxy (内外呼应)#154
ranxianglei wants to merge 4 commits into
masterfrom
2026-08-16_cooperative-proxy-mode

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

What

The "inside" half of the cooperative plugin protocol (billion-context issue dog/billion-context#1, gitea; protocol half = ranxianglei/billion-context#161). When pi's model baseUrl routes through a billion-context proxy (the /bili/ zero-config prefix), the extension automatically switches to cooperative mode — 有外用外:

  • Tools stay native, execution forwards: compress / decompress / search_context / acp_status keep their native pi registration (native UX, permissions, audit), but execute POSTs to the proxy's /__bili/plugin/tool, which runs them under its session lock against the same view the model saw. Result text returns as the native tool result.
  • Real session identity: every provider request carries x-bili-plugin: pi + x-bili-plugin-conversation: <pi session id> (via the SDK's before_provider_headers hook). The proxy keys state by pi's real session id — no more content-fingerprint collisions — and suppresses its own wire tool injection (no double compression).
  • In-process pipeline skipped: context returns pi's messages untouched (the proxy runs processTurn — tags, folding, nudges — at the wire level); before_agent_start drops the local philosophy prompt (proxy injects it) while keeping the delegate prompt (pi-side feature).

Detection

Stateless per-call check: bili path segment in ctx.model.baseUrl → proxy origin. Model switches mid-session are picked up on the next call; nothing is cached. ACP_COOPERATIVE_PROXY=0 disables entirely.

Compatibility

Without a /bili/ baseUrl every path is byte-identical to before (early-return branches only). MITM-mode (transparent proxy, no prefix) is NOT detected — documented; use the /bili/ prefix baseURL for cooperative mode.

Verification

  • npm run typecheck
  • New suite tests/cooperative.test.ts 7/7 (URL matrix, header injection + absence, context identity passthrough, prompt ownership, live HTTP forward with conversation-id/args/result assertions, error propagation, kill switch)
  • npm test: 300 tests — 299 pass + 1 pre-existing failure on pristine master (e2e-compress-config.test.ts "2w limit fires nudge" — verified failing on a clean master checkout before these changes; unrelated)
  • npm run build

Files

  • src/cooperative.ts (new) — detection + forwardToolToProxy / tryForwardTool
  • src/index.tswireProviderHeaders + cooperative early-returns in context/system-prompt wiring
  • 4 tool files — tryForwardTool branch at top of execute
  • tests/cooperative.test.ts, README.md section, CONFIGURATION.md ACP_COOPERATIVE_PROXY
  • devlog/2026-08-16_cooperative-proxy-mode/ — REQ + DESIGN + WORKLOG

Ordering note

No code-level coupling, but the endpoints this forwards to land with ranxianglei/billion-context#161 — merge that first for the combination to work end-to-end.

Refs: dog/billion-context#1 (gitea)

awork added 4 commits August 16, 2026 02:21
…t proxy (内外呼应)

When the model baseUrl routes through a billion-context proxy (/bili/
zero-config prefix), the extension switches to cooperative mode per the
protocol shipped in ranxianglei/billion-context#161: the 4 native tools
forward to POST /__bili/plugin/tool under the proxy's session lock,
every request announces x-bili-plugin: pi + x-bili-plugin-conversation
(pi's real session id), and the in-process pipeline (processTurn, nudges,
philosophy prompt) is skipped - the proxy owns compression end-to-end.
Detection is a stateless per-call URL check; without a proxy (or with
ACP_COOPERATIVE_PROXY=0) behavior is byte-identical. Tests 7/7 new.
…w reporting

proxyBaseForContext falls back to BILLION_CONTEXT_PROXY (exported by the
billion-context launcher next to HTTPS_PROXY), so bili pi in MITM
transparent mode gets the same native-tool cooperative experience as the
/bili/ prefix. before_provider_headers now also reports the model's
contextWindow (x-bili-plugin-context-window) - the agent-side value
becomes the authoritative nudge denominator on the proxy. Tests 8/8 new
(300 pass total; 1 pre-existing master failure unchanged).
…ressRange since #148 viable-ranges

The '2w limit fires the nudge' assertion (from #145) broke when #148 landed
viable-ranges: the kernel now only counts merged ranges with tokens*4 >=
minCompressRange (5000 chars) as effective T1 content. The 12x2000-char
fixture's ranges all stayed under the gate, so the EMERGENCY nudge was
correctly suppressed. Enlarge bulk text to 3000 chars/msg so the merged
range clears the gate; the 100w-limit idle assertion is unaffected (2%
usage, no pressure). Kernel behavior is intentional — fixture was stale.
@ranxianglei

Copy link
Copy Markdown
Owner Author

已更新:

  1. 合并 master(symlink-hardening fix(decompress): harden toFile against symlink path-escape #140 后续,BEHIND 已消)
  2. 修复 pre-existing master CI 红灯e2e-compress-config 的 2w-limit 断言(feat(config): three-level compress cascade (global > provider > model) #145 引入)被 fix: recommend only viable compressible ranges (>=200 tokens) on all surfaces #148 的 viable-ranges 行为打破 —— kernel 现在只把 tokens*4 >= minCompressRange(5000) 的合并区间计入有效 T1 内容,12×2000-char fixture 全部低于门槛,EMERGENCY nudge 被正确压制。fixture 加大到 3000 chars/msg(内核行为是有意的防碎片设计,不该改内核)。本地 303/303,typecheck/build 绿。

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