billion-context 0.1.122 → 0.1.123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -143
- package/README.zh-CN.md +71 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,8 +150,7 @@ Pick by your client:
|
|
|
150
150
|
| Client | Use |
|
|
151
151
|
|---|---|
|
|
152
152
|
| **pi** | [`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi) (in-process extension) |
|
|
153
|
-
| **opencode 1.x
|
|
154
|
-
| **opencode 2.0+** | `bili opencode` (built-in V2 plugin — native tools, no separate package) or `bili plugin install opencode` (self-spawning native plugin, no launcher) |
|
|
153
|
+
| **opencode** (1.x / 2.x) | [`billion-context`](https://github.com/ranxianglei/billion-context) — `bili opencode` (launcher) or `bili plugin install opencode` (native, no launcher); standalone [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) remains usable on 1.x. Full guide: [OpenCode](#opencode) |
|
|
155
154
|
| **omp** | [`billion-context`](https://github.com/ranxianglei/billion-context) via `bili omp` (built-in plugin) or `bili plugin install omp` (self-spawning native plugin, no launcher) |
|
|
156
155
|
| **dsh** | `bili dsh` (launcher — full native plugin via `--patch`: tools, session-bound `/acp`, fetch intercept) or `bili plugin install dsh` ≡ `dsh plugin --profile <name> add billion-context` (one unified lane — pnpm-installs the package into each profile so dsh mounts the bundled patch layer; the bili form just drives dsh's own channel per profile and migrates legacy managed blocks) |
|
|
157
156
|
| **kimi** | `bili plugin install kimi` (self-spawning native plugin, no launcher — Kimi Code ≥ 2.0.0; per-session routing block in `~/.kimi-code/config.toml`) or `bili kimi` (launcher, cert-MITM) or `/bili/` prefix |
|
|
@@ -160,12 +159,6 @@ Pick by your client:
|
|
|
160
159
|
|
|
161
160
|
**Native mode vs standalone extensions.** The host-native plugins (`bili plugin install pi` / `opencode` — they spawn the proxy inside the host process) and the standalone in-process extensions (`billion-context-pi`, `opencode-acp`) are **mutually exclusive**: both active means double compression. The installer makes the switch: `bili plugin install pi` replaces the legacy `npm:billion-context-pi` entry (with a reminder that a project-scope entry in `<project>/.pi/settings.json` from `pi install -l` lives outside the global settings), and `bili plugin install opencode` strips legacy `opencode-acp` entries from the global opencode.json — bare name, `npm:` alias, versioned (`opencode-acp@stable`), or path form, array or object shape; the original config is snapshotted to `.bili-bak` once. A **project-local** install (`opencode plugin opencode-acp` writes `<project>/.opencode/opencode.json`, not the global config) is not touched — remove it by hand; the installer note reminds you. As a runtime safety net for manual installs, the native entries set `BILLION_CONTEXT_NATIVE=<host>` synchronously at load so a standalone extension can stand down at action time — its own load-time `BILLION_CONTEXT_PROXY` check cannot see a proxy that native mode spawns asynchronously, and its `/bili/` baseUrl check never sees the fetch-layer rewrite. On the pi side the marker needs `billion-context-pi` **0.1.72+** (the per-event re-check landed after 0.1.71); the pi-native entry additionally scans both pi settings files once its proxy is up and warns loudly when it spots a co-resident legacy entry the installer never saw — that warning is the only visible signal while an old `billion-context-pi` silently double-compresses.
|
|
162
161
|
|
|
163
|
-
**Legacy sessions from opencode-acp (v1 lane routing).** On OpenCode 1.x, `bili plugin install opencode` keeps pre-migration sessions WORKING: the native entry absorbs the installed `opencode-acp` package (imported directly from `node_modules` — `.opencode/node_modules`, project `node_modules`, global npm root, or opencode's config-scope modules, first hit wins) and routes per session. A session is legacy iff opencode-acp's persisted state file exists (`<XDG_DATA_HOME>/opencode/storage/plugin/acp/<sessionID>.json`):
|
|
164
|
-
|
|
165
|
-
- **Legacy session** — compression runs through the absorbed opencode-acp (its own `<dcp-message-id>` refs and block store keep working: `compress` / `decompress` / `search_context` / `acp_status` / `acp_context_recap` all execute in it). Its model requests carry `x-bili-plugin-bypass: 1`, and the proxy forwards them VERBATIM — no wire injection, no nudge, no session binding.
|
|
166
|
-
- **New session** — bili owns it: tool calls forward to the proxy's plugin endpoints (plugin mode). The tool slots the model sees carry the DCP schemas (one def per name process-wide on v1), but the executor routes by session lane, so a new session's `compress` reaches the proxy while a legacy session's reaches opencode-acp. `acp_context_recap` has no proxy counterpart — on new sessions the proxy answers it with its unknown-tool message.
|
|
167
|
-
|
|
168
|
-
`/acp` and `/dcp` route the same way. Adoption of new sessions into opencode-acp's registry is prevented by gating its transforms (system / messages / text.complete) on the legacy predicate. Degradation: when the opencode-acp package is absent or fails to import, bili runs alone and legacy sessions behave as read-only archives (old `<acp>` tags render, `decompress` returns `[Block … not found]`, new refs restart from m00001).
|
|
169
162
|
|
|
170
163
|
## Install
|
|
171
164
|
|
|
@@ -202,10 +195,26 @@ bili plugin install kimi # writes $KIMI_CODE_HOME/plugins/managed/billion
|
|
|
202
195
|
bili plugin remove <client> # undo (dsh removes through the same channel; config snapshots go to .bili-bak)
|
|
203
196
|
```
|
|
204
197
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
198
|
+
Where a client has its own plugin channel you can also install natively,
|
|
199
|
+
skipping bili commands entirely:
|
|
200
|
+
|
|
201
|
+
- **dsh:** `dsh plugin --profile <name> add billion-context` is the very
|
|
202
|
+
command `bili plugin install dsh` drives per profile — same end state
|
|
203
|
+
either way (pnpm into the profile, bundled patch layer mounted by dsh
|
|
204
|
+
itself); remove through the same channel. See the dsh section below.
|
|
205
|
+
- **opencode:** add the bare npm name to your real config's plugin list —
|
|
206
|
+
`"plugin": ["billion-context"]` (npm form only; a git checkout has no
|
|
207
|
+
published entry). The package publishes `exports["./server"]` →
|
|
208
|
+
`dist/agent/opencode-native.js`, so opencode loads it through its own
|
|
209
|
+
Npm.add machinery and the plugin self-spawns exactly like the
|
|
210
|
+
bili-installed form. Do the two things the bili installer would have done
|
|
211
|
+
for you too: set `"compaction": { "auto": false }` in the same config
|
|
212
|
+
(otherwise OpenCode's native auto-compaction double-compresses) and keep a
|
|
213
|
+
manual backup of the file first.
|
|
214
|
+
|
|
215
|
+
For pi / omp / kimi / claude there is no client-side channel — `bili plugin
|
|
216
|
+
install <client>` writes their config entries for you (kimi's declarative
|
|
217
|
+
`kimi.plugin.json` + registry record, claude's managed settings block, …).
|
|
209
218
|
|
|
210
219
|
At load the plugin **spawns its own proxy** (or attaches to a healthy
|
|
211
220
|
running one — a parent-pid watchdog tears it down when the client exits),
|
|
@@ -261,8 +270,7 @@ Notes:
|
|
|
261
270
|
the entries and snapshots the original config (`.bili-bak`); migration
|
|
262
271
|
details in the client table above (pi needs `billion-context-pi` 0.1.72+
|
|
263
272
|
to stand down cleanly).
|
|
264
|
-
-
|
|
265
|
-
(v1 lane routing, #920) — see "OpenCode 1.x" below.
|
|
273
|
+
- OpenCode: legacy `opencode-acp` sessions, the V1/V2 plugin shapes, and all caveats are consolidated in the [OpenCode](#opencode) section.
|
|
266
274
|
- `kimi` reports runtime-info at bootstrap only (static `custom_headers` can't
|
|
267
275
|
carry per-request window/model headers without going stale on model switch)
|
|
268
276
|
and binds subagent conversations by per-call `conversation_id` — full
|
|
@@ -319,7 +327,7 @@ bili pi # launch pi through the proxy — file-fre
|
|
|
319
327
|
bili codex # launch codex through the proxy
|
|
320
328
|
bili claude # launch claude through the proxy
|
|
321
329
|
bili omp # pi-style, file-free (#535): env + extension registerProvider + compaction cancel, real ~/.omp untouched
|
|
322
|
-
bili opencode #
|
|
330
|
+
bili opencode # OpenCode (1.x & 2.x): full guide in the [OpenCode](#opencode) section below
|
|
323
331
|
bili hermes # file-free (#535): hermes proxy env (HTTPS_PROXY + HERMES_CA_BUNDLE) — https via CONNECT MITM, http via absolute-form forward proxy; real ~/.hermes untouched
|
|
324
332
|
bili dsh # deepseek-harness: full native plugin injected via --patch (#941) — compress/decompress/acp_status registered as real dsh tools, requests stamped with the dsh session id (plugin mode), /acp session-bound; non-loopback upstreams ride proxy envs (https MITM, http absolute-form), loopback keeps the overlay DSH_HOME (~/.dsh-bili) rewrite (#535), built-in deepseek route via DEEPSEEK_BASE_URL; dsh native auto-compaction disabled (compaction-basic auto:false)
|
|
325
333
|
bili codebuddy # Tencent CodeBuddy Code CLI: CODEBUDDY_BASE_URL /bili/ rewrite (OpenAI chat completions wire), budget aligned via CODEBUDDY_AUTO_COMPACT_WINDOW; real ~/.codebuddy untouched
|
|
@@ -355,133 +363,7 @@ automatically.
|
|
|
355
363
|
For per-client configuration examples (OpenCode, Codex, Pi, login-client
|
|
356
364
|
MITM, …) see the web UI guide at [http://localhost:8787](http://localhost:8787).
|
|
357
365
|
|
|
358
|
-
###
|
|
359
|
-
|
|
360
|
-
On a 1.x host, `bili opencode` runs **new sessions through the bili proxy** and
|
|
361
|
-
keeps **existing `opencode-acp` ("legacy") sessions working with their own
|
|
362
|
-
machinery** (#920). The launcher strips the `opencode-acp` entry from its temp
|
|
363
|
-
config clone (the host never loads it armed), and the thin bili plugin imports
|
|
364
|
-
the installed package as a library instead:
|
|
365
|
-
|
|
366
|
-
- every acp hook is gated on "an acp store file exists for this session"
|
|
367
|
-
(`~/.local/share/opencode/storage/plugin/acp/<sessionID>.json`, or the dir
|
|
368
|
-
from `storagePath` in `acp.jsonc`) — legacy sessions keep their DCP compress /
|
|
369
|
-
decompress / search_context / acp_status tools and the `/dcp` command; new
|
|
370
|
-
sessions are never adopted and run plain proxy mode.
|
|
371
|
-
- legacy LLM requests are stamped `x-bili-plugin-bypass: 1`, which the proxy
|
|
372
|
-
honors as raw passthrough (no injection, no compression, no session state).
|
|
373
|
-
- in proxy mode the proxy owns the compression tool names: same-named client
|
|
374
|
-
tools in the body are dropped before injection, so upstream sees one
|
|
375
|
-
definition per name.
|
|
376
|
-
|
|
377
|
-
Graceful degradation: if the package can't be found/imported or isn't v1, the
|
|
378
|
-
plugin behaves exactly as before this change — legacy sessions degrade the way
|
|
379
|
-
they did when `opencode-acp` self-disabled on `/bili/` baseURLs.
|
|
380
|
-
|
|
381
|
-
### OpenCode 2.0
|
|
382
|
-
|
|
383
|
-
OpenCode 2.0 ships a new plugin API (`@opencode/plugin`); the standalone
|
|
384
|
-
`opencode-acp` extension is V1-only and does not load under 2.0. Both bili
|
|
385
|
-
modes work on 2.0. The 2.x plugin API surface is still moving between builds
|
|
386
|
-
(adjacent npm `dev`-channel builds expose different `ctx` shapes), so the
|
|
387
|
-
hook/tool details below are version-specific observations, not a stable
|
|
388
|
-
contract:
|
|
389
|
-
|
|
390
|
-
- **Launcher:** `bili opencode` works unchanged. On a 2.x host it injects the
|
|
391
|
-
built-in V2 plugin (`dist/agent/opencode.js`) into the temp config as a temp
|
|
392
|
-
wrapper directory whose `index.js` re-exports the plugin file — 2.x rejects
|
|
393
|
-
bare file paths in the config `plugin` array (directory entries use
|
|
394
|
-
`index.js` as entrypoint); 1.x hosts get the bare file path. Host generation
|
|
395
|
-
is detected with a `--version` probe (a failed probe defaults to the 1.x
|
|
396
|
-
shape). The V2 plugin registers the bili tools natively in-host — compress /
|
|
397
|
-
decompress / search_context / acp_status (+ absorb), JSON-Schema inputs — and
|
|
398
|
-
stamps the proxy headers on every outgoing provider request, so compression
|
|
399
|
-
runs in plugin mode with no wire-level tool injection. Native auto-compaction
|
|
400
|
-
is disabled automatically (`compaction.auto: false`). Every registration is
|
|
401
|
-
defensive (optional chaining): on any 2.x build where a seam is missing or
|
|
402
|
-
never fires, the plugin stays inert and the session transparently runs in
|
|
403
|
-
plain proxy mode (wire-level tool injection) instead of breaking — observed
|
|
404
|
-
on two adjacent `dev` builds (2026-09-13 / 2026-09-14) whose API surfaces
|
|
405
|
-
differ from each other (#754 review probes); conversely verified end-to-end
|
|
406
|
-
on `@opencode/cli` 2.0.3 (native `acp_status` executed through the plugin
|
|
407
|
-
endpoint, zero wire-level injection).
|
|
408
|
-
- **Native (no launcher):** with the package installed from npm, run
|
|
409
|
-
`bili plugin install opencode` — it registers a self-spawning plugin in your
|
|
410
|
-
real opencode config and sets `compaction.auto: false`, after which plain
|
|
411
|
-
`opencode` works as-is. No `mcp.bili` MCP face is added by default (the
|
|
412
|
-
native plugin already provides the bili tools, session-bound); pass
|
|
413
|
-
`--with-mcp` to add one — the entry then carries no origin pin, so it
|
|
414
|
-
survives the plugin's ephemeral-port proxy restarts (#926). The entry form
|
|
415
|
-
depends on how THIS bili was installed: an **npm install** writes the bare
|
|
416
|
-
package name (`"plugin":
|
|
417
|
-
["billion-context"]`) — the package publishes `exports["./server"]` →
|
|
418
|
-
`dist/agent/opencode-native.js`, so opencode loads it through its own
|
|
419
|
-
Npm.add machinery and manages install/upgrade itself; zero absolute paths,
|
|
420
|
-
portable across machines. A **git checkout / dev build** has no published
|
|
421
|
-
entry and falls back to a local shim dir
|
|
422
|
-
(`<configDir>/plugins/billion-context/index.js` → this checkout's
|
|
423
|
-
`dist/agent/opencode-native.js`) — machine-local by construction, not
|
|
424
|
-
portable; re-running install from an npm install migrates the entry back to
|
|
425
|
-
the bare name. At load the plugin bootstraps its own
|
|
426
|
-
proxy (attaches to a healthy instance instead of doubling; parent-pid
|
|
427
|
-
watchdog kills it when opencode exits), routes model-API traffic to
|
|
428
|
-
`<proxy>/bili/<upstream-url>`, and exposes the same native bili tools as
|
|
429
|
-
launcher mode — no fixed port, no env var, no launcher.
|
|
430
|
-
Opt-out: `BILI_NATIVE_OPENCODE=0`. If no proxy can be made healthy, requests
|
|
431
|
-
go direct (uncompressed) with a one-time warning and recover automatically.
|
|
432
|
-
Under a `bili opencode` launch this entry is skipped entirely (the launcher
|
|
433
|
-
owns the proxy).
|
|
434
|
-
|
|
435
|
-
The same wrapper serves **OpenCode 1.x** through the V1 `.server()` hooks
|
|
436
|
-
(verified on 1.14.46 and 1.18.31): the `config` hook mutates the shared
|
|
437
|
-
config object in-process to rewrite every provider `options.baseURL` to
|
|
438
|
-
`<proxy>/bili/…` and sets `compaction.auto: false`; `chat.headers` stamps
|
|
439
|
-
the plugin headers per request; `tool` registers the bili tools with real
|
|
440
|
-
zod shapes (zod is a runtime dependency — when it cannot be resolved the
|
|
441
|
-
plugin degrades to plain proxy mode: rewrite only, wire-injected tools);
|
|
442
|
-
the `/acp` command renders the same status panel. Providers **without**
|
|
443
|
-
an explicit `baseURL` (SDK defaults, e.g. bare `@ai-sdk/openai` →
|
|
444
|
-
api.openai.com) are caught by a global `fetch` patch (the pi-native
|
|
445
|
-
mechanism) that reroutes model-API calls to the proxy — verified end-to-end
|
|
446
|
-
on 1.14.46 and 1.18.31 (log: `v1: fetch patch installed`), including the
|
|
447
|
-
OpenAI Responses endpoint. The patch is idempotent and passes
|
|
448
|
-
`/bili/`-wrapped URLs through untouched.
|
|
449
|
-
- **Pure proxy:** point the provider baseURL at the proxy like any other
|
|
450
|
-
client:
|
|
451
|
-
|
|
452
|
-
```json
|
|
453
|
-
{
|
|
454
|
-
"provider": {
|
|
455
|
-
"myprovider": {
|
|
456
|
-
"npm": "@ai-sdk/openai-compatible",
|
|
457
|
-
"options": {
|
|
458
|
-
"baseURL": "http://localhost:8787/bili/http://upstream.example/v1",
|
|
459
|
-
"apiKey": "sk-any"
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
Note: 2.0 AI-SDK providers require an `apiKey` field even for local
|
|
467
|
-
endpoints that never check it — set any non-empty value.
|
|
468
|
-
|
|
469
|
-
Caveats: the 2.x line publishes as npm package `@opencode/cli`. Command
|
|
470
|
-
support is build-dependent: one pre-release exposed only
|
|
471
|
-
list/get/update/remove, while 2.0.x stable lets plugins ADD commands via
|
|
472
|
-
`ctx.command.transform((editor) => editor.add(...))` — invocable in the TUI by
|
|
473
|
-
accepting the slash-menu completion (Tab + Enter); note `opencode run` mode
|
|
474
|
-
dispatches no slash commands at all (they pass through to the model). The
|
|
475
|
-
bundled plugin deliberately registers no commands on either shape — call the
|
|
476
|
-
`acp_status` tool instead of an `/acp` command. The bundled agent file keeps
|
|
477
|
-
the V1 `server()` export alongside the V2 `setup()`, so the same artifact also
|
|
478
|
-
loads on hosts ≥ 1.18.29 that support dual-shape plugins. Design note: the V2 plugin is a thin protocol client (no
|
|
479
|
-
acp-kernel inside) because the proxy stays the single compression authority,
|
|
480
|
-
which eliminates kernel-version drift between agent and proxy — it does not
|
|
481
|
-
rely on the plugin API being unable to mutate context (that capability varies
|
|
482
|
-
by 2.x build).
|
|
483
|
-
|
|
484
|
-
#### dsh (deepseek-harness)
|
|
366
|
+
### dsh (deepseek-harness)
|
|
485
367
|
|
|
486
368
|
Two lanes, same plugin (#941):
|
|
487
369
|
|
|
@@ -525,7 +407,7 @@ untouched except for header stamping. Known limitation: manual
|
|
|
525
407
|
`/compact` has no dsh-side event hook, so its boundary is left to the
|
|
526
408
|
kernel's natural ingest diff (auto-compaction is off, so this is rare).
|
|
527
409
|
|
|
528
|
-
|
|
410
|
+
### Kimi Code (Moonshot)
|
|
529
411
|
|
|
530
412
|
Three aligned modes: `bili kimi` (launcher, cert-MITM — Option 2), `/bili/`
|
|
531
413
|
URL prefix, and native plugin mode (`bili plugin install kimi`, #963). Kimi
|
|
@@ -610,6 +492,155 @@ This failure mode is now loud instead of silent:
|
|
|
610
492
|
|
|
611
493
|
To actually compress such a client: add its model domain to `"mitm".domains` in `billion-context.json` (e.g. `"mitm": { "domains": ["copilot.tencent.com"] }`) or via `BILI_MITM_DOMAINS`, restart bili, and make the client trust bili's root CA (`NODE_EXTRA_CA_CERTS=~/.local/share/billion-context/ca/root-ca.pem` for Node-based clients, or the client's own CA-path setting). The `/bili/` prefix trick does not apply here — there is no URL to change. Details: [CONFIGURATION.md → MITM](CONFIGURATION.md#mitm-transparent-proxy-login-clients).
|
|
612
494
|
|
|
495
|
+
## OpenCode
|
|
496
|
+
|
|
497
|
+
One bundled plugin serves **both** OpenCode generations: the agent file keeps
|
|
498
|
+
the V1 `server()` export alongside the V2 `setup()`, so hosts ≥ 1.18.29 load
|
|
499
|
+
the V1 shape and 2.x hosts load the V2 `setup()`. The standalone
|
|
500
|
+
[`opencode-acp`](https://github.com/ranxianglei/opencode-acp) extension is
|
|
501
|
+
V1-only and does **not** load under 2.x — for OpenCode 2.x, billion-context
|
|
502
|
+
is the recommended context manager. Everything below is verified end-to-end
|
|
503
|
+
on `@opencode/cli` 2.0.3 (V1 lane: 1.14.46 and 1.18.31).
|
|
504
|
+
|
|
505
|
+
| Path | Command | When |
|
|
506
|
+
|---|---|---|
|
|
507
|
+
| Launcher (easiest) | `bili opencode` | one command brings up proxy + client; real config untouched |
|
|
508
|
+
| Native (no launcher) | `bili plugin install opencode` | self-spawning plugin in your real config; start `opencode` as usual |
|
|
509
|
+
| Pure proxy (fallback) | baseURL `/bili/` prefix | no plugin — wire-level tool injection |
|
|
510
|
+
|
|
511
|
+
### Launcher — `bili opencode`
|
|
512
|
+
|
|
513
|
+
HTTPS rides cert-MITM, HTTP a temp `opencode.json` clone with `/bili/`
|
|
514
|
+
(JSONC comments accepted, merged the way opencode itself merges them;
|
|
515
|
+
relative local plugin specs re-anchored to absolute paths in the clone —
|
|
516
|
+
opencode resolves them against the declaring config file's dir, #826). Host
|
|
517
|
+
generation is detected with a `--version` probe (failed probe defaults to
|
|
518
|
+
1.x): on a **2.x** host the built-in V2 plugin (`dist/agent/opencode.js`) is
|
|
519
|
+
injected as a temp wrapper directory whose `index.js` re-exports the plugin
|
|
520
|
+
file (2.x rejects bare file paths in the config `plugin` array); **1.x**
|
|
521
|
+
hosts get the bare file path.
|
|
522
|
+
|
|
523
|
+
What the plugin does (both generations): registers the bili tools natively
|
|
524
|
+
in-host — compress / decompress / search_context / acp_status (+ absorb) —
|
|
525
|
+
and stamps the proxy headers on every outgoing provider request, including
|
|
526
|
+
context-window / max-output read from the host's own model catalog
|
|
527
|
+
(`ctx.catalog.model.list()`, refreshed every 60s) and reported to the proxy
|
|
528
|
+
as runtime-info (#955) — compression runs in plugin mode with **no**
|
|
529
|
+
wire-level tool injection. Native auto-compaction is disabled automatically
|
|
530
|
+
(`compaction.auto: false`). Every registration is defensive (optional
|
|
531
|
+
chaining): on any 2.x build where a seam is missing or never fires, the
|
|
532
|
+
plugin stays inert and the session transparently runs in plain proxy mode
|
|
533
|
+
instead of breaking — observed across adjacent `dev` builds whose API
|
|
534
|
+
surfaces differ from each other (#754 review probes).
|
|
535
|
+
|
|
536
|
+
1.x specifics (verified 1.14.46 + 1.18.31): the V1 `.server()` hooks rewrite
|
|
537
|
+
every provider `options.baseURL` to `<proxy>/bili/…` in-process and set
|
|
538
|
+
`compaction.auto: false`; `chat.headers` stamps the plugin headers per
|
|
539
|
+
request; `tool` registers the bili tools with real zod shapes (zod is a
|
|
540
|
+
runtime dependency — when it cannot be resolved the plugin degrades to
|
|
541
|
+
rewrite-only). Providers **without** an explicit `baseURL` (SDK defaults,
|
|
542
|
+
e.g. bare `@ai-sdk/openai` → api.openai.com) are caught by a global `fetch`
|
|
543
|
+
patch (log: `v1: fetch patch installed`) — idempotent, passes
|
|
544
|
+
`/bili/`-wrapped URLs through untouched; verified including the OpenAI
|
|
545
|
+
Responses endpoint.
|
|
546
|
+
|
|
547
|
+
### Native (no launcher) — `bili plugin install opencode`
|
|
548
|
+
|
|
549
|
+
Registers a self-spawning plugin in your real opencode config and sets
|
|
550
|
+
`compaction.auto: false`; afterwards plain `opencode` works as-is. No MCP
|
|
551
|
+
face is added by default (the native plugin already provides the bili tools,
|
|
552
|
+
session-bound); pass `--with-mcp` to add one — the entry then carries no
|
|
553
|
+
origin pin, so it survives the plugin's ephemeral-port proxy restarts (#926).
|
|
554
|
+
Entry form depends on how THIS bili was installed: an **npm install** writes
|
|
555
|
+
the bare package name (`"plugin": ["billion-context"]`) — the package
|
|
556
|
+
publishes `exports["./server"]` → `dist/agent/opencode-native.js`, so
|
|
557
|
+
opencode loads it through its own Npm.add machinery; zero absolute paths, portable. (That exact bare-name entry doubles as a hand-install without bili — see Option 1.) A **git checkout / dev build** falls back to a local shim dir
|
|
558
|
+
(`<configDir>/plugins/billion-context/index.js` → this checkout's
|
|
559
|
+
`dist/agent/opencode-native.js`) — machine-local by construction; re-running
|
|
560
|
+
install from an npm install migrates the entry back to the bare name.
|
|
561
|
+
|
|
562
|
+
At load the plugin bootstraps its own proxy (attaches to a healthy instance
|
|
563
|
+
instead of doubling; parent-pid watchdog kills it when opencode exits),
|
|
564
|
+
routes model-API traffic to `<proxy>/bili/<upstream-url>`, and exposes the
|
|
565
|
+
same native bili tools as launcher mode — no fixed port, no env var, no
|
|
566
|
+
launcher. Opt-out: `BILI_NATIVE_OPENCODE=0`. If no proxy can be made
|
|
567
|
+
healthy, requests go direct (uncompressed) with a one-time warning and
|
|
568
|
+
recover automatically. Under a `bili opencode` launch this entry is skipped
|
|
569
|
+
entirely (the launcher owns the proxy).
|
|
570
|
+
|
|
571
|
+
### Pure proxy (no plugin)
|
|
572
|
+
|
|
573
|
+
Point the provider baseURL at the proxy like any other client:
|
|
574
|
+
|
|
575
|
+
```json
|
|
576
|
+
{
|
|
577
|
+
"provider": {
|
|
578
|
+
"myprovider": {
|
|
579
|
+
"npm": "@ai-sdk/openai-compatible",
|
|
580
|
+
"options": {
|
|
581
|
+
"baseURL": "http://localhost:8787/bili/http://upstream.example/v1",
|
|
582
|
+
"apiKey": "sk-any"
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
Note: 2.0 AI-SDK providers require an `apiKey` field even for local
|
|
590
|
+
endpoints that never check it — set any non-empty value.
|
|
591
|
+
|
|
592
|
+
### Status: `/acp` and `acp_status`
|
|
593
|
+
|
|
594
|
+
The `/acp` panel is session-bound in all modes, and the `acp_status` tool is
|
|
595
|
+
its in-host equivalent everywhere. On 2.0.x stable, where the command editor
|
|
596
|
+
supports adding entries (`editor.add`), the V2 plugin additionally registers
|
|
597
|
+
an `/acp` slash command — rendered as a synthetic non-model message,
|
|
598
|
+
panel-first like the `acp_status` tool; on older shapes the registration
|
|
599
|
+
stays inert. Note `opencode run` mode dispatches no slash commands at all
|
|
600
|
+
(they pass through to the model) — use the TUI.
|
|
601
|
+
|
|
602
|
+
### Legacy opencode-acp sessions (#920)
|
|
603
|
+
|
|
604
|
+
On 1.x hosts, pre-migration [`opencode-acp`](https://github.com/ranxianglei/opencode-acp)
|
|
605
|
+
sessions keep working under both lanes: the launcher strips the
|
|
606
|
+
`opencode-acp` entry from its temp config clone (the host never loads it
|
|
607
|
+
armed), and each lane absorbs the installed package (imported directly from
|
|
608
|
+
`node_modules` — `.opencode/node_modules`, project `node_modules`, global npm
|
|
609
|
+
root, or opencode's config-scope modules, first hit wins). A session is
|
|
610
|
+
legacy iff opencode-acp's persisted state file exists
|
|
611
|
+
(`<XDG_DATA_HOME>/opencode/storage/plugin/acp/<sessionID>.json`, or the dir
|
|
612
|
+
from `storagePath` in `acp.jsonc`):
|
|
613
|
+
|
|
614
|
+
- **Legacy session** — compression runs through the absorbed opencode-acp
|
|
615
|
+
(its own refs and block store keep working: `compress` / `decompress` /
|
|
616
|
+
`search_context` / `acp_status` / `acp_context_recap` all execute in it).
|
|
617
|
+
Its model requests carry `x-bili-plugin-bypass: 1`; the proxy forwards
|
|
618
|
+
them VERBATIM — no wire injection, no nudge, no session binding.
|
|
619
|
+
- **New session** — bili owns it: tool calls forward to the proxy's plugin
|
|
620
|
+
endpoints (plugin mode). The executor routes by session lane, so a new
|
|
621
|
+
session's `compress` reaches the proxy while a legacy session's reaches
|
|
622
|
+
opencode-acp. `acp_context_recap` has no proxy counterpart — on new
|
|
623
|
+
sessions the proxy answers with its unknown-tool message.
|
|
624
|
+
|
|
625
|
+
`/acp` and `/dcp` route the same way. Adoption of new sessions into
|
|
626
|
+
opencode-acp's registry is prevented by gating its transforms (system /
|
|
627
|
+
messages / text.complete) on the legacy predicate. Degradation: when the
|
|
628
|
+
package is absent or fails to import (or isn't v1), bili runs alone and
|
|
629
|
+
legacy sessions behave as read-only archives (old tags render, `decompress`
|
|
630
|
+
returns `[Block … not found]`, new refs restart from m00001).
|
|
631
|
+
|
|
632
|
+
### Caveats
|
|
633
|
+
|
|
634
|
+
- The 2.x line publishes as npm package `@opencode/cli`, and its plugin API
|
|
635
|
+
surface is still moving between builds (adjacent `dev`-channel builds
|
|
636
|
+
expose different `ctx` shapes) — the hook/tool details above are
|
|
637
|
+
version-specific observations, not a stable contract.
|
|
638
|
+
- Design note: the V2 plugin is a thin protocol client (no acp-kernel
|
|
639
|
+
inside) because the proxy stays the single compression authority — that
|
|
640
|
+
eliminates kernel-version drift between agent and proxy; it does not rely
|
|
641
|
+
on the plugin API being unable to mutate context (that capability varies
|
|
642
|
+
by 2.x build).
|
|
643
|
+
|
|
613
644
|
## Running the proxy
|
|
614
645
|
|
|
615
646
|
### Flags
|
package/README.zh-CN.md
CHANGED
|
@@ -78,9 +78,7 @@ AI 编程助手的<strong>通用上下文压缩代理</strong>
|
|
|
78
78
|
| 客户端 | 用这个 |
|
|
79
79
|
|---|---|
|
|
80
80
|
| **pi** | [`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi)(进程内扩展) |
|
|
81
|
-
| **opencode
|
|
82
|
-
| **opencode 2.0+** | `bili opencode`(内置 V2 插件 —— 原生工具,无需另装包)或 `bili plugin install opencode`(自拉起原生插件,免启动器) |
|
|
83
|
-
| **opencode** | [`billion-context`](https://github.com/ranxianglei/billion-context),`bili opencode`(新会话走 bili 代理;现有 [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) 会话继续可用,见下文「OpenCode 1.x」) |
|
|
81
|
+
| **opencode**(1.x / 2.x) | [`billion-context`](https://github.com/ranxianglei/billion-context) —— `bili opencode`(启动器)或 `bili plugin install opencode`(原生,免启动器);独立 [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) 在 1.x 上仍可用。完整指南:[OpenCode](#opencode) |
|
|
84
82
|
| **omp** | [`billion-context`](https://github.com/ranxianglei/billion-context),`bili omp`(内置插件)或 `bili plugin install omp`(自拉起原生插件,免启动器) |
|
|
85
83
|
| **dsh** | [`billion-context`](https://github.com/ranxianglei/billion-context) —— `bili dsh`(启动器,经 `--patch` 注入完整原生插件:工具、会话绑定 `/acp`、fetch 拦截)或 `bili plugin install dsh` ≡ `dsh plugin --profile <name> add billion-context`(统一泳道 —— pnpm 把包装进各 profile、由 dsh 挂载包内 patch 层;bili 形式只是替你按 profile 驱动 dsh 自己的通道,并顺带迁移旧版受管块) |
|
|
86
84
|
| **kimi** | `bili plugin install kimi`(自拉起原生插件,免启动器 —— 需 Kimi Code ≥ 2.0.0;每会话在 `~/.kimi-code/config.toml` 写入路由块)或 `bili kimi`(启动器,证书 MITM)或 `/bili/` 前缀 |
|
|
@@ -89,12 +87,6 @@ AI 编程助手的<strong>通用上下文压缩代理</strong>
|
|
|
89
87
|
|
|
90
88
|
**原生模式 vs 独立扩展。** 宿主原生插件(`bili plugin install pi` / `opencode` —— 代理在宿主进程内拉起)与独立进程内扩展(`billion-context-pi`、`opencode-acp`)**互斥**:两者同时生效意味着双重压缩。安装器负责切换:`bili plugin install pi` 会替换旧的 `npm:billion-context-pi` 条目;`bili plugin install opencode` 会从全局 opencode.json 里剔除旧的 `opencode-acp` 条目 —— 裸名、`npm:` 别名、带版本号(`opencode-acp@stable`)、路径形式都认,数组/对象两种形态都处理;原配置会快照到 `opencode.json.bili-bak`。**项目级**安装(`opencode plugin opencode-acp` 写的是 `<project>/.opencode/opencode.json`,不是全局配置)不会被碰 —— 需手动移除,安装器输出里会提醒。作为手动安装的运行期安全网,原生入口在加载时同步设置 `BILLION_CONTEXT_NATIVE=<host>`,让独立扩展在动作时自动退出 —— 它自己的加载期 `BILLION_CONTEXT_PROXY` 检查看不见原生模式异步拉起的代理,`/bili/` baseURL 检查也看不见 fetch 层改写。
|
|
91
89
|
|
|
92
|
-
**从 opencode-acp 迁移旧会话(v1 泳道路由)。** 在 OpenCode 1.x 上,`bili plugin install opencode` 让迁移前的旧会话继续可用:原生入口会吸收已安装的 `opencode-acp` 包(直接从 `node_modules` 导入 —— `.opencode/node_modules`、项目 `node_modules`、全局 npm root、opencode 配置级 modules,先到先得),并按会话路由。会话属于 legacy ⟺ opencode-acp 的持久化状态文件存在(`<XDG_DATA_HOME>/opencode/storage/plugin/acp/<sessionID>.json`):
|
|
93
|
-
|
|
94
|
-
- **旧会话** —— 压缩由被吸收的 opencode-acp 执行(它自己的 `<dcp-message-id>` 引用号与块存储照常工作:`compress` / `decompress` / `search_context` / `acp_status` / `acp_context_recap` 全部在它里面执行)。其模型请求带 `x-bili-plugin-bypass: 1`,代理原样转发 —— 不注入 wire 工具、不注 nudge、不绑定会话。
|
|
95
|
-
- **新会话** —— bili 接管:工具调用转发到代理的 plugin 端点(plugin 模式)。模型看到的工具槽位带 DCP schema(v1 进程级每个名字仅一份定义),但执行器按会话分泳道:新会话的 `compress` 发到代理,旧会话的发给 opencode-acp。`acp_context_recap` 没有代理端对应 —— 新会话调用会收到代理的 unknown-tool 消息。
|
|
96
|
-
|
|
97
|
-
`/acp` 与 `/dcp` 同样路由。新会话被 opencode-acp 注册表收编的可能被其 transform 门控(system / messages / text.complete 都过 legacy 谓词)阻断。退化路径:opencode-acp 包缺失或导入失败时 bili 单独运行,旧会话退化为只读存档(旧 `<acp>` 标签照常渲染、`decompress` 返回 `[Block … not found]`、新引用号从 m00001 重新开始)。
|
|
98
90
|
|
|
99
91
|
## 安装
|
|
100
92
|
|
|
@@ -127,7 +119,12 @@ bili plugin install kimi # 写 $KIMI_CODE_HOME/plugins/managed/billion-co
|
|
|
127
119
|
bili plugin remove <client> # 卸载(dsh 经同一通道移除;配置快照存 .bili-bak)
|
|
128
120
|
```
|
|
129
121
|
|
|
130
|
-
|
|
122
|
+
客户端有自己的插件通道时,也可以原生安装、完全不用 bili 命令:
|
|
123
|
+
|
|
124
|
+
- **dsh:** `dsh plugin --profile <name> add billion-context` 正是 `bili plugin install dsh` 按 profile 驱动的那条命令 —— 两种走法终态一致(pnpm 装进 profile、patch 层由 dsh 自己挂载);经同一通道卸载。见下文 dsh 段。
|
|
125
|
+
- **opencode:** 把裸 npm 包名直接写进你真实配置的插件列表 —— `"plugin": ["billion-context"]`(仅 npm 形态;git checkout 没有已发布入口)。包通过 `exports["./server"]` → `dist/agent/opencode-native.js` 暴露插件入口,opencode 用自己的 Npm.add 机制加载,插件自拉起的行为与 bili 安装的形态完全一致。另外要做两件 bili 安装器会替你做的事:在同一份配置里设 `"compaction": { "auto": false }`(否则 OpenCode 的原生自动压缩会双重压缩),并先手工备份该配置文件。
|
|
126
|
+
|
|
127
|
+
pi / omp / kimi / claude 没有客户端侧通道 —— 它们的配置条目由 `bili plugin install <client>` 代写(kimi 的声明式 `kimi.plugin.json` + 注册记录、claude 的受管 settings 块等)。
|
|
131
128
|
|
|
132
129
|
插件加载时**自拉起自己的代理**(已有健康实例则直接复用 —— 父进程 pid 看门狗在客户端退出时收掉它),把模型流量改写到 `<proxy>/bili/<上游URL>`,并把 `compress` / `decompress` / `acp_status` 注册为客户端原生工具(plugin 模式),`/acp` 面板绑定当前会话。插件还会把客户端**自己的模型配置**上报给代理(runtime-info 协议,#955),压缩预算用真实窗口而不是注册表猜测。退出开关:`BILI_NATIVE_PI=0`、`BILI_NATIVE_OMP=0`、`BILI_NATIVE_OPENCODE=0`、`BILI_NATIVE_DSH=0`、`BILI_NATIVE_KIMI=0`。
|
|
133
130
|
|
|
@@ -149,7 +146,7 @@ launcher 环境变量这档覆盖纯代理客户端(无进程内插件):`bili <c
|
|
|
149
146
|
注意:
|
|
150
147
|
|
|
151
148
|
- 原生模式与独立进程内扩展(`billion-context-pi`、`opencode-acp`)**互斥** —— 安装器负责换条目并把原配置快照(`.bili-bak`);迁移细节见上方客户端表(pi 需 `billion-context-pi` 0.1.72+ 才能干净退让)。
|
|
152
|
-
- OpenCode
|
|
149
|
+
- OpenCode:legacy `opencode-acp` 会话、V1/V2 插件形态与全部注意事项已并入 [OpenCode](#opencode) 一节。
|
|
153
150
|
- `kimi` 仅在自举时上报 runtime-info(静态 `custom_headers` 无法承载逐请求的窗口/模型头,否则会在模型切换后过期),子代理会话按每次调用的 `conversation_id` 绑定 —— 完整机制见下文「Kimi Code」小节。
|
|
154
151
|
- `claude` 有**原生姿态**(hybrid,#964):Claude Code 没有进程内扩展点,所以 `bili plugin install claude` 往 `~/.claude/settings.json` 写一个受管块(env `ANTHROPIC_BASE_URL=http://127.0.0.1:48787/bili/<upstream>`、`DISABLE_AUTO_COMPACT=1`、`SessionStart` hook),外加同样指向该稳定端口的用户级 MCP shell。hook 在首个模型请求前触发:附着到端口上健康的代理,或拉起一个 pid 看门狗追踪 claude 本身的代理 —— 代理随会话生灭。端口覆盖:`BILI_CLAUDE_NATIVE_PORT` > config `claude.nativePort` > 48787;上游覆盖:`BILI_CLAUDE_UPSTREAM`(或既有 `claude.anthropicBaseUrl`)。`BILI_NATIVE_CLAUDE=0` 退出 —— hook 改为拉起同端口的 **passthrough** 代理(原样转发、关闭压缩)。块是纯 JSON merge/strip:外部键从不触碰,`bili plugin remove claude` 精确还原。装有原生块的机器上 `bili claude` 仍可用 —— 它用自身临时代理覆盖静态 URL,hook 保持休眠。
|
|
155
152
|
- `codex` / `omp` 也有配套安装(MCP shell 与轻量扩展),但它们需要一个在跑的代理 —— 不属于原生模式。
|
|
@@ -167,7 +164,7 @@ bili pi # 拉起 pi,走代理 —— file-free(#53
|
|
|
167
164
|
bili codex # 拉起 codex
|
|
168
165
|
bili claude # 拉起 claude
|
|
169
166
|
bili omp # pi 同款,file-free(#535):环境变量 + 扩展 registerProvider + 压缩取消,真实 ~/.omp 不动
|
|
170
|
-
bili opencode #
|
|
167
|
+
bili opencode # OpenCode(1.x 与 2.x):完整指南见下文 [OpenCode](#opencode) 一节
|
|
171
168
|
bili hermes # file-free(#535):hermes 代理环境变量(HTTPS_PROXY + HERMES_CA_BUNDLE)—— https 走 CONNECT MITM,http 走绝对形式转发;真实 ~/.hermes 不动
|
|
172
169
|
bili dsh # deepseek-harness:经 --patch 注入完整原生插件(#941) —— compress/decompress/acp_status 注册为真实 dsh 工具,请求盖 dsh 会话 id(plugin 模式),/acp 会话绑定;非回环上游走代理 env(https MITM、http absolute-form),回环上游保留 overlay DSH_HOME(~/.dsh-bili)改写(#535),内置 deepseek 路由走 DEEPSEEK_BASE_URL;dsh 原生自动压缩被禁用(compaction-basic auto:false)
|
|
173
170
|
bili codebuddy # Tencent CodeBuddy Code CLI:CODEBUDDY_BASE_URL /bili/ 重写(OpenAI chat completions wire),预算对齐走 CODEBUDDY_AUTO_COMPACT_WINDOW;真实 ~/.codebuddy 不动
|
|
@@ -179,16 +176,6 @@ bili pi --mitm-domain api.foo.com # 向 MITM 白名单追加域名
|
|
|
179
176
|
```
|
|
180
177
|
|
|
181
178
|
|
|
182
|
-
### OpenCode 1.x —— 旧 opencode-acp 会话继续可用(#920)
|
|
183
|
-
|
|
184
|
-
在 1.x 主机上,`bili opencode` 会**通过 bili 代理运行新会话**,同时**让现有 `opencode-acp`("legacy")会话继续使用其自身机制正常工作**(#920)。启动器会从临时配置副本中移除 `opencode-acp` 条目(主机永远不会以激活状态加载它),而轻量的 bili 插件则改为以库的形式导入已安装的包:
|
|
185
|
-
|
|
186
|
-
- 每个 ACP 钩子都以"该会话存在 ACP 存储文件"为门控条件(`~/.local/share/opencode/storage/plugin/acp/<sessionID>.json`,或 `acp.jsonc` 中 `storagePath` 指定的目录)——旧版会话保留其 DCP compress / decompress / search_context / acp_status 工具和 `/dcp` 命令;新会话不会被接管,而是运行纯代理模式。
|
|
187
|
-
- 旧版 LLM 请求会被打上 `x-bili-plugin-bypass: 1` 标记,代理将其视为原始透传(无注入、无压缩、无会话状态)。
|
|
188
|
-
- 在代理模式下,压缩工具的名称由代理独占:请求体中同名的客户端工具会在注入前被丢弃,因此上游对每个名称只看到一个定义。
|
|
189
|
-
|
|
190
|
-
优雅降级:如果包无法找到/导入或不是 v1 版本,插件的行为与此更改之前完全一致——旧版会话的降级方式与 `opencode-acp` 在 `/bili/` baseURL 上自我禁用时的表现相同。
|
|
191
|
-
|
|
192
179
|
### 方式 3 —— 改url(`/bili/` 前缀)
|
|
193
180
|
|
|
194
181
|
启动代理:
|
|
@@ -206,7 +193,7 @@ bili
|
|
|
206
193
|
|
|
207
194
|
更多客户端配置参考网页引导: [http://localhost:8787](http://localhost:8787) .
|
|
208
195
|
|
|
209
|
-
|
|
196
|
+
### dsh(deepseek-harness)
|
|
210
197
|
|
|
211
198
|
两条通道,同一个插件(#941):
|
|
212
199
|
|
|
@@ -216,7 +203,7 @@ bili
|
|
|
216
203
|
|
|
217
204
|
`bili dsh` 启动下插件**附看**(attach)启动器的代理(不二次拉起)。裸上游 URL 与 spawn 模式一样重写为 `<proxy>/bili/<url>`(回环代理目标永不被代理 env 拦截,等于直接绕开 MITM);已经路由的 `/bili/` 前缀请求原样放行、只盖章。已知局限:手动 `/compact` 没有 dsh 侧事件钩子,其边界交给内核的自然 ingest diff(自动压缩已关,影响罕见)。
|
|
218
205
|
|
|
219
|
-
|
|
206
|
+
### Kimi Code(Moonshot)
|
|
220
207
|
|
|
221
208
|
三种对齐模式:`bili kimi`(启动器,证书 MITM —— 方式 2)、`/bili/` URL 前缀,以及原生插件模式(`bili plugin install kimi`,#963)。Kimi Code v2 的插件体系是纯声明式的(`kimi.plugin.json`:MCP server、hooks、skills —— 没有进程内 JS 执行),所以 bili 无法像 pi/opencode/dsh 那样补丁客户端的 fetch 栈。取而代之,插件带两个小型 node 脚本,在客户端外围完成工作:
|
|
222
209
|
|
|
@@ -243,44 +230,79 @@ curl -s http://localhost:8787/__bili/stats
|
|
|
243
230
|
同时也打到 stderr)。每个请求应该看到一行 `processTurn`,等对话变长后
|
|
244
231
|
会出现 `[acp-usage] round N input=X cached=Y (cache hit Z%)` + `compress` 事件。
|
|
245
232
|
|
|
246
|
-
###
|
|
233
|
+
### 客户端用 `http.proxy`(CONNECT)接入但从不压缩
|
|
234
|
+
|
|
235
|
+
部分客户端(VS Code 系 IDE:CodeBuddy、Cursor、Windsurf……)只提供一个 HTTP **代理**设置(`http.proxy`、`codingcopilot.httpProxyURL` 等),没有可改写的模型 base-URL。这类客户端不走普通的 `/bili/…` 请求,而是把 `CONNECT <模型域名>:443` 发给代理。只有当模型域名在 bili 的 **MITM 白名单**里时这条路径才会被解密;否则 bili 只做盲隧道(不透明转发),永远看不到——也就无法压缩——模型请求(#897)。
|
|
236
|
+
|
|
237
|
+
该失效模式现在不再静默:
|
|
238
|
+
|
|
239
|
+
- 日志里对每个目标域名打一次 `BLIND TUNNEL WARNING`,附修复步骤;
|
|
240
|
+
- `curl -s http://localhost:8787/__bili/health` 与 `/__bili/stats` 输出 `blindTunnels`(计数 + 精确目标域名,仅 loopback);
|
|
241
|
+
- 存在此类隧道时,`acp_status` 输出会多一节 `UNDECRYPTED TRAFFIC (instance-level)`。
|
|
242
|
+
|
|
243
|
+
要真正压缩这类客户端:把它的模型域名加进 `billion-context.json` 的 `"mitm".domains`(如 `"mitm": { "domains": ["copilot.tencent.com"] }`)或环境变量 `BILI_MITM_DOMAINS`,重启 bili,并让客户端信任 bili 的根 CA(Node 系客户端用 `NODE_EXTRA_CA_CERTS=~/.local/share/billion-context/ca/root-ca.pem`,有 CA 路径设置的用其设置)。`/bili/` 前缀方案在这里不适用——没有 URL 可改。详见 [CONFIGURATION.zh-CN.md → MITM](CONFIGURATION.zh-CN.md#mitm-透明代理登录客户端)。
|
|
244
|
+
|
|
245
|
+
## OpenCode
|
|
246
|
+
|
|
247
|
+
同一个内置插件同时服务两代 OpenCode:agent 文件同时保留 V1 `server()` 与 V2 `setup()` 导出 —— ≥ 1.18.29 的 1.x 宿主加载 V1 形状,2.x 宿主加载 V2 `setup()`。独立扩展 [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) 仅支持 V1,在 2.x 下**不加载** —— 对 OpenCode 2.x,**billion-context 是推荐的上下文管理方案**。以下均在 `@opencode/cli` 2.0.3 上端到端验证过(V1 泳道:1.14.46 与 1.18.31)。
|
|
247
248
|
|
|
248
|
-
|
|
249
|
+
| 路径 | 命令 | 适用 |
|
|
250
|
+
|---|---|---|
|
|
251
|
+
| 启动器(最省事) | `bili opencode` | 一条命令拉起代理 + 客户端;不碰真实配置 |
|
|
252
|
+
| 原生(免启动器) | `bili plugin install opencode` | 自拉起插件写进真实配置;照常启动 `opencode` |
|
|
253
|
+
| 纯代理(兜底) | baseURL 加 `/bili/` 前缀 | 无插件 —— wire 级工具注入 |
|
|
254
|
+
|
|
255
|
+
### 启动器 —— `bili opencode`
|
|
256
|
+
|
|
257
|
+
HTTPS 走证书 MITM,HTTP 走临时 `opencode.json` 副本(`/bili/` 改写;JSONC 注释照单接受,合并方式与 opencode 自身一致;相对本地插件路径在副本里重新锚定为绝对路径 —— opencode 按声明所在配置文件目录解析,#826)。宿主代次用 `--version` 探测(探测失败默认按 1.x):**2.x** 宿主注入内置 V2 插件(`dist/agent/opencode.js`),以临时包装目录形式给出(目录入口 `index.js` 再 re-export 插件文件 —— 2.x 拒绝配置 `plugin` 数组里的裸文件路径);**1.x** 宿主直接给裸文件路径。
|
|
258
|
+
|
|
259
|
+
插件在两代宿主上做的事相同:在宿主内原生注册 bili 工具 —— compress / decompress / search_context / acp_status(另加 absorb)—— 并在每个 provider 请求上盖章代理头,含从宿主自身模型目录(`ctx.catalog.model.list()`,每 60s 刷新)读取的 context-window / max-output,并以 runtime-info 上报给代理(#955)—— 压缩走插件模式,**不做** wire 级工具注入;原生 auto-compaction 自动关闭(`compaction.auto: false`)。所有注册都是防御式的(可选链):任一 2.x build 上接缝缺失或未触发时,插件保持惰性,会话透明回退纯代理模式而不是报错 —— 在相邻的 `dev` build 上观察到过 API 面互不相同(#754 评审探针)。
|
|
260
|
+
|
|
261
|
+
1.x 细节(1.14.46 + 1.18.31 验证):V1 `.server()` 钩子在进程内把每个 provider 的 `options.baseURL` 改写为 `<proxy>/bili/…` 并设 `compaction.auto: false`;`chat.headers` 每次请求盖章插件头;`tool` 用真实 zod 形状注册 bili 工具(zod 是运行时依赖 —— 解析不到时降级为只改写)。没有显式 `baseURL` 的 provider(SDK 默认值,如裸 `@ai-sdk/openai` → api.openai.com)由全局 `fetch` 补丁兜住(日志:`v1: fetch patch installed`)—— 幂等,`/bili/` 包装过的 URL 原样直通;含 OpenAI Responses 端点端到端验证。
|
|
262
|
+
|
|
263
|
+
### 原生(免启动器)—— `bili plugin install opencode`
|
|
249
264
|
|
|
250
|
-
|
|
251
|
-
- **原生(免启动器):** npm 装好包后跑 `bili plugin install opencode` —— 它在真实 opencode 配置里注册一个自拉起插件并设 `compaction.auto: false`,之后直接跑 `opencode` 即可。入口形态取决于**本 bili 自身的安装来源**:**npm 安装**写裸包名(`"plugin": ["billion-context"]`)—— 包通过 `exports["./server"]` → `dist/agent/opencode-native.js` 暴露插件入口,opencode 用自己的 Npm.add 机制加载、自行管理安装与升级;零绝对路径、可跨机同步。**git checkout / 开发构建**没有已发布入口,回退到本机 shim 目录(`<configDir>/plugins/billion-context/index.js` → 该 checkout 的 `dist/agent/opencode-native.js`)—— 按构造即机器本地、不可跨机;之后改用 npm 安装再跑一次 install 会把条目迁回裸包名。加载时插件自拉起自己的代理(健康的已有实例直接复用不重复起;父进程 pid 看门狗在 opencode 退出时收掉它),把模型流量路由到 `<proxy>/bili/<upstream-url>`,并暴露与启动器模式相同的原生 bili 工具 —— 无固定端口、无环境变量、免启动器。退出:`BILI_NATIVE_OPENCODE=0`。若没有任何代理能拉到健康状态,请求直连(不压缩)并给一次性告警,之后自动恢复。在 `bili opencode` 启动下该入口整体跳过(代理归启动器管)。
|
|
265
|
+
在真实 opencode 配置里注册一个自拉起插件并设 `compaction.auto: false`,之后直接跑 `opencode` 即可。默认不加 MCP 面(原生插件已提供会话绑定的 bili 工具);需要就传 `--with-mcp` —— 该条目不带 origin 钉扎,能扛过插件临时端口的代理重启(#926)。条目形态取决于**本 bili 自身的安装来源**:**npm 安装**写裸包名(`"plugin": ["billion-context"]`)—— 包经 `exports["./server"]` → `dist/agent/opencode-native.js` 暴露插件入口,opencode 用自己的 Npm.add 机制加载、自行管理安装与升级;零绝对路径、可跨机。(这个裸包名条目也可以不经 bili 直接手写进配置 —— 见方式 1。)**git checkout / 开发构建**回退到本机 shim 目录(`<configDir>/plugins/billion-context/index.js` → 该 checkout 的 `dist/agent/opencode-native.js`)—— 按构造即机器本地;之后改用 npm 安装再跑一次 install 会把条目迁回裸包名。
|
|
252
266
|
|
|
253
|
-
|
|
254
|
-
- **纯代理:** 与其它客户端一样,把 provider baseURL 指向代理:
|
|
267
|
+
加载时插件自拉起自己的代理(健康的已有实例直接复用不重复起;父进程 pid 看门狗在 opencode 退出时收掉它),把模型流量路由到 `<proxy>/bili/<upstream-url>`,暴露与启动器模式相同的原生 bili 工具 —— 无固定端口、无环境变量、免启动器。退出:`BILI_NATIVE_OPENCODE=0`。若没有任何代理能拉到健康状态,请求直连(不压缩)并给一次性告警,之后自动恢复。在 `bili opencode` 启动下该条目整体跳过(代理归启动器管)。
|
|
255
268
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
269
|
+
### 纯代理(无插件)
|
|
270
|
+
|
|
271
|
+
与其它客户端一样,把 provider baseURL 指向代理:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"provider": {
|
|
276
|
+
"myprovider": {
|
|
277
|
+
"npm": "@ai-sdk/openai-compatible",
|
|
278
|
+
"options": {
|
|
279
|
+
"baseURL": "http://localhost:8787/bili/http://upstream.example/v1",
|
|
280
|
+
"apiKey": "sk-any"
|
|
265
281
|
}
|
|
266
282
|
}
|
|
267
283
|
}
|
|
268
|
-
|
|
284
|
+
}
|
|
285
|
+
```
|
|
269
286
|
|
|
270
|
-
|
|
287
|
+
注意:2.0 AI-SDK provider 即使本地端点从不校验也要求 `apiKey` 字段 —— 随便填个非空值。
|
|
271
288
|
|
|
272
|
-
|
|
273
|
-
### 客户端用 `http.proxy`(CONNECT)接入但从不压缩
|
|
289
|
+
### 状态:`/acp` 与 `acp_status`
|
|
274
290
|
|
|
275
|
-
|
|
291
|
+
`/acp` 面板在所有模式下都绑定当前会话,`acp_status` 工具是其宿主内等价手段。在命令编辑器支持新增条目的宿主(2.0.x 稳定版,`editor.add`)上,V2 插件额外注册 `/acp` 斜杠命令 —— 以合成非模型消息渲染,面板优先(与 `acp_status` 工具一致);旧形状上该注册保持惰性。注意 `opencode run` 模式完全不派发斜杠命令(它们会透传给模型)—— 请用 TUI。
|
|
276
292
|
|
|
277
|
-
|
|
293
|
+
### 旧 opencode-acp 会话(#920)
|
|
278
294
|
|
|
279
|
-
-
|
|
280
|
-
- `curl -s http://localhost:8787/__bili/health` 与 `/__bili/stats` 输出 `blindTunnels`(计数 + 精确目标域名,仅 loopback);
|
|
281
|
-
- 存在此类隧道时,`acp_status` 输出会多一节 `UNDECRYPTED TRAFFIC (instance-level)`。
|
|
295
|
+
在 1.x 宿主上,迁移前的 [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) 旧会话在两条泳道下都继续可用:启动器从临时配置副本中移除 `opencode-acp` 条目(宿主永远不会以激活状态加载它),各泳道把已安装的包作为库吸收(直接从 `node_modules` 导入 —— `.opencode/node_modules`、项目 `node_modules`、全局 npm root、opencode 配置级 modules,先到先得)。会话属于 legacy ⟺ opencode-acp 的持久化状态文件存在(`<XDG_DATA_HOME>/opencode/storage/plugin/acp/<sessionID>.json`,或 `acp.jsonc` 中 `storagePath` 指定的目录):
|
|
282
296
|
|
|
283
|
-
|
|
297
|
+
- **旧会话** —— 压缩由被吸收的 opencode-acp 执行(它自己的引用号与块存储照常工作:`compress` / `decompress` / `search_context` / `acp_status` / `acp_context_recap` 全部在它里面执行)。其模型请求带 `x-bili-plugin-bypass: 1`,代理原样转发 —— 不注入 wire 工具、不注 nudge、不绑定会话。
|
|
298
|
+
- **新会话** —— bili 接管:工具调用转发到代理的 plugin 端点(plugin 模式)。执行器按会话分泳道:新会话的 `compress` 发到代理,旧会话的发给 opencode-acp。`acp_context_recap` 没有代理端对应 —— 新会话调用会收到代理的 unknown-tool 消息。
|
|
299
|
+
|
|
300
|
+
`/acp` 与 `/dcp` 同样路由。新会话被 opencode-acp 注册表收编的可能被其 transform 门控(system / messages / text.complete 都过 legacy 谓词)阻断。退化路径:包缺失、导入失败或不是 v1 时,bili 单独运行,旧会话退化为只读存档(旧标签照常渲染、`decompress` 返回 `[Block … not found]`、新引用号从 m00001 重新开始)。
|
|
301
|
+
|
|
302
|
+
### 注意事项
|
|
303
|
+
|
|
304
|
+
- 2.x 系列以 npm 包 `@opencode/cli` 发布,且插件 API 面在不同 build 间仍在变动(相邻 `dev` 通道构建暴露不同 `ctx` 形状)—— 上文钩子/工具细节是针对具体版本的观察,不是稳定契约。
|
|
305
|
+
- 设计说明:V2 插件是薄协议客户端(不含 acp-kernel)—— 代理始终是唯一的压缩权威,消除 agent 与代理间的内核版本漂移;它不依赖插件 API 无法改上下文这一事实(该能力随 2.x build 变化)。
|
|
284
306
|
|
|
285
307
|
## 运行代理
|
|
286
308
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "billion-context",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.123",
|
|
4
4
|
"description": "Context-compression proxy that lets AI coding agents run for days — billions of tokens through one context window. Sits between any agent (Claude Code, Codex, Cursor, Aider, …) and its model API, folding consumed conversation into reversible, prefix-cache-friendly summaries. Zero per-agent code: just point your base URL at the proxy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|