billion-context 0.1.23 → 0.1.24

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 CHANGED
@@ -42,179 +42,103 @@ This installs the `bili` command (`bili-proxy` is kept as an alias).
42
42
 
43
43
  ## Quickstart
44
44
 
45
- Three steps: **start the proxy edit the config file → point your client at it**.
45
+ Two ways to use it pick one:
46
+
47
+ - **Zero-config (simplest):** prefix your client's baseURL with the proxy
48
+ origin + `/bili/`. No config file needed — context windows are auto-detected
49
+ from the [models.dev](https://models.dev) registry. The `/bili/` prefix also
50
+ doubles as a self-detection signal: billion-context client extensions
51
+ (billion-context-pi / opencode-acp) can recognize it in their own baseUrl
52
+ and self-disable, so you never get double compression.
53
+ - **Explicit context-window overrides:** declare per-URL context windows in a
54
+ config file (or the web UI) for endpoints the registry doesn't know about,
55
+ or when you want to pin an exact value. Routing is the same `/bili/` prefix
56
+ either way — the config only changes which context window the proxy uses.
57
+
46
58
  Compression is injected automatically — you only configure routing, never
47
59
  compression itself.
48
60
 
49
- ### Step 1Start the proxy
61
+ ### Option AZero-config (`/bili/` prefix)
62
+
63
+ Start the proxy:
50
64
 
51
65
  ```bash
52
66
  bili
53
67
  ```
54
68
 
55
- It listens on `http://127.0.0.1:8787`. Keep this terminal open (or run in the
56
- background; see [Running the proxy](#running-the-proxy)).
57
-
58
- Click [http://localhost:8787/__acp/](http://localhost:8787/__acp/) to add your models:
59
- <img width="2908" height="1787" alt="image" src="https://github.com/user-attachments/assets/cacf4b64-e5c6-41f2-b270-fd2be02eab0c" />
60
-
61
- On first run `bili` **auto-creates an empty config file** and tells you where,
62
- so you don't have to invent the schema from scratch. The startup banner prints
63
- the web UI URL too:
64
-
65
- ```
66
- acp-proxy listening on http://localhost:8787 — web UI: http://localhost:8787/__acp/
67
- ```
68
-
69
- ### How routing works
69
+ Then just prefix your client's existing baseURL with `http://localhost:8787/bili/`.
70
+ The full upstream URL is embedded in the path, so the proxy knows where to
71
+ forward without any config:
70
72
 
71
- The proxy routes by a **provider name in the URL path** — the first path
72
- segment after the host. It strips the name and forwards the rest to that
73
- provider. Everything after the name is passed through untouched:
74
-
75
- ```
76
- client baseURL: http://localhost:8787/zhipu/api/coding/paas/v4
77
- └──────────┬──────────┘└────────┬────────┘
78
- proxy host remaining path
79
- + provider name (forwarded as-is)
80
73
  ```
81
-
82
- This is why Step 2 has you declare named providers, and Step 3 has you put that
83
- same name at the start of the client's base URL — it's how the proxy knows where
84
- to send each request. In the config below, `zhipu` corresponds to:
85
- ```json
86
- "zhipu": {
87
- "url": "https://open.bigmodel.cn",
88
- "models": {
89
- "glm-5.2": { "context": 1000000, "output": 131072 }
90
- }
74
+ client baseURL before: https://api.openai.com/v1
75
+ client baseURL after: http://localhost:8787/bili/https://api.openai.com/v1
91
76
  ```
92
77
 
93
- ### Step 2 Configure your providers
94
-
95
- Copy the content below:
96
- <img width="2931" height="1519" alt="image" src="https://github.com/user-attachments/assets/c02278be-bc7a-4f14-8f58-0f2d83784d54" />
97
-
98
- > Prefer not to use the web UI? You can also edit the JSON file directly — see
99
- > [Manual config file](#manual-config-file) below.
100
-
101
- Then **restart `bili`** — the startup banner lists your routes:
102
-
103
- ```
104
- acp-proxy listening on http://localhost:8787 — routes: anthropic=https://api.anthropic.com, zhipu=https://open.bigmodel.cn
105
- ```
106
-
107
- That confirms the proxy picked up your config. (Prefer editing the JSON file by
108
- hand? See [Manual config file](#manual-config-file). Full schema — per-model
109
- context windows, optional fields — is in [Configuration](#configuration).)
110
-
111
- ### Step 3 — Point your client at the proxy
112
-
113
- Edit the client's own config file so it sends requests to
114
- `http://localhost:8787/<provider>/...` (the provider name from Step 2 as the
115
- first path segment). Put your **real** API key in the client's config too —
116
- the proxy passes it through untouched.
117
-
118
- #### Pi (billion-context-pi)
119
-
120
- Open `~/.pi/agent/models.json` and change your existing provider's **`baseUrl` line** to point at the proxy — leave every other field alone:
121
-
122
- ```jsonc
123
- // before:
124
- "baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4",
125
- // after (swap the host for the proxy + the provider name you picked):
126
- "baseUrl": "http://localhost:8787/zhipu/api/coding/paas/v4",
127
- ```
128
-
129
- `http://localhost:8787` is the proxy, `zhipu` is the name from Step 2, and the remaining path `/api/coding/paas/v4` is forwarded as-is to Zhipu. `apiKey`, `api`, and `models` stay unchanged.
130
-
131
- | `api` value | `baseUrl` should point at |
132
- |---|---|
133
- | `openai-completions` | an OpenAI-compatible endpoint (GLM/DeepSeek/OpenAI) → `…/zhipu/...` |
134
- | `anthropic-messages` | an Anthropic-compatible endpoint → `…/anthropic` |
78
+ That's itput your real API key in the client config as usual (the proxy
79
+ passes it through untouched). Context windows (gpt-5.1-codex=400K,
80
+ glm-5.2=1M, claude-opus-4=200K, …) are looked up from models.dev
81
+ automatically.
135
82
 
136
- > If you use the `billion-context-pi` extension, run Pi in an isolated agent
137
- dir (`PI_CODING_AGENT_DIR=…`) so the client-side extension doesn't double-
138
- compress alongside the proxy. The `bili-test-pi` helper does this for you.
139
-
140
- #### OpenCode
141
-
142
- Open `~/.config/opencode/opencode.json` and change your existing provider's **`baseURL` line** to point at the proxy:
83
+ #### Examples by client
143
84
 
85
+ **OpenCode** — edit `~/.config/opencode/opencode.json`, change the provider's `baseURL`:
144
86
  ```jsonc
145
87
  // before:
146
88
  "baseURL": "https://open.bigmodel.cn/api/coding/paas/v4"
147
- // after:
148
- "baseURL": "http://localhost:8787/zhipu/api/coding/paas/v4"
89
+ // after (just prepend the proxy origin + /bili/):
90
+ "baseURL": "http://localhost:8787/bili/https://open.bigmodel.cn/api/coding/paas/v4"
149
91
  ```
150
92
 
151
- Everything else (`apiKey`, `models`) stays unchanged. For an Anthropic provider, change `baseURL` to `http://localhost:8787/anthropic`.
152
-
153
- #### Codex
154
-
155
- Open `~/.codex/config.toml` and change your existing provider's **`base_url` line** to point at the proxy:
156
-
93
+ **Codex** edit `~/.codex/config.toml`, change the provider's `base_url`:
157
94
  ```toml
158
95
  # before:
159
- base_url = "https://open.bigmodel.cn/api/coding/paas/v4"
96
+ base_url = "https://api.openai.com/v1"
160
97
  # after:
161
- base_url = "http://localhost:8787/zhipu/api/coding/paas/v4"
98
+ base_url = "http://localhost:8787/bili/https://api.openai.com/v1"
162
99
  ```
163
100
 
164
- Everything else (`name`, `wire_api`, `env_key`) stays unchanged.
165
-
166
- > Codex's Responses API needs an upstream that speaks the Responses protocol.
167
- > Most regional OpenAI-compatible endpoints only speak `/chat/completions`; if
168
- > yours 404s on `/responses`, use a relay that speaks Responses, or the
169
- > official OpenAI API.
170
-
171
- #### Other clients (Cursor / Aider / Continue …)
172
-
173
- Not yet supported. The proxy currently speaks the Anthropic, OpenAI
174
- chat-completions, and OpenAI Responses protocols — if your client uses a
175
- different protocol or a non-standard auth header, it won't work yet.
176
-
177
- ### Web UI
178
-
179
- Open `http://localhost:8787/__acp/` in a browser while the proxy is running. You can:
180
-
181
- - **Edit providers** in a form (add/remove providers and per-model context windows) and save — this writes to `billion-context.json` directly.
182
- - **Generate client URLs** — pick a provider, get ready-to-copy config snippets for Pi / OpenCode / Codex (the `baseUrl`/`baseURL`/`base_url` line with the proxy origin + provider name filled in).
183
- - **View sessions** — live table of active sessions (requests, tokens saved, last seen), auto-refreshing.
184
-
185
- Changes to providers require a **restart** to take effect (the UI tells you this).
101
+ **Pi** edit `~/.pi/agent/models.json`, change the provider's `baseUrl`:
102
+ ```jsonc
103
+ // before:
104
+ "baseUrl": "https://api.anthropic.com"
105
+ // after:
106
+ "baseUrl": "http://localhost:8787/bili/https://api.anthropic.com"
107
+ ```
186
108
 
187
- ### Manual config file
109
+ **Other clients (Cursor / Aider / Continue …)** — wherever the upstream URL
110
+ is configured, prepend `http://localhost:8787/bili/` to it. Nothing else
111
+ changes.
188
112
 
189
- Prefer editing JSON by hand for git-managed configs, scripted deployments, or
190
- if you just don't want to use the browser? The web UI writes to the same file,
191
- so you can edit it directly with identical results.
113
+ ### Option BManual config file & context windows
192
114
 
193
115
  Open `~/.config/billion-context/billion-context.json` and edit the `providers`
194
- block. Each entry is a **name URL** mapping; the name is what you put in the
195
- client's base URL in Step 3.
116
+ block. **The key is the upstream URL** the string the client puts after
117
+ `/bili/`. The value declares per-model context windows for that URL:
196
118
 
197
119
  ```json
198
120
  {
199
121
  "providers": {
200
- "zhipu": {
201
- "url": "https://open.bigmodel.cn",
202
- "models": {
203
- "glm-5.2": { "context": 1000000, "output": 131072 }
204
- }
122
+ "https://open.bigmodel.cn/api/coding/paas/v4": {
123
+ "models": { "glm-5.2": { "context": 1000000 } }
205
124
  },
206
- "anthropic": "https://api.anthropic.com"
125
+ "https://api.anthropic.com": {}
207
126
  }
208
127
  }
209
128
  ```
210
129
 
211
- - Delete providers you don't use.
212
- - Add others (e.g. `"deepseek": "https://api.deepseek.com"`).
130
+ - A key matches when the client's embedded URL equals it or starts with it
131
+ (longest key wins). A bare host key covers every path on that host.
132
+ - An empty value `{}` means "this URL exists, no overrides" (context windows
133
+ come from models.dev / the prefix table).
134
+ - Delete entries you don't use; add others as needed.
213
135
  - The API key is **not** here — it lives in the client; the proxy passes it
214
136
  through untouched.
215
137
 
216
- After saving, **restart `bili`**. (Full schema per-model context windows,
217
- optional fields — is in [Configuration](#configuration).)
138
+ ### Option C Web UI & context windows
139
+
140
+ Open [http://localhost:8787/__bili/](http://localhost:8787/__bili/) to
141
+ configure.
218
142
 
219
143
  ### Verify
220
144
 
@@ -223,11 +147,11 @@ first real request shows compression activity in the log:
223
147
 
224
148
  ```bash
225
149
  # Health check (proxy up + where it forwards)
226
- curl -s http://localhost:8787/__acp/health
150
+ curl -s http://localhost:8787/__bili/health
227
151
  # → {"ok":true,"upstream":"https://api.anthropic.com"}
228
152
 
229
153
  # Live session stats (after a real request)
230
- curl -s http://localhost:8787/__acp/stats
154
+ curl -s http://localhost:8787/__bili/stats
231
155
  ```
232
156
 
233
157
  Then send one message from your client and watch the log
@@ -340,15 +264,13 @@ The config file is a single JSON object. Example:
340
264
  "port": 8787,
341
265
  "host": "127.0.0.1",
342
266
  "providers": {
343
- "zhipu": {
344
- "url": "https://open.bigmodel.cn",
267
+ "https://open.bigmodel.cn/api/coding/paas/v4": {
345
268
  "models": {
346
- "glm-5.2": { "context": 1000000, "output": 131072 },
347
- "glm-5.1": { "context": 200000, "output": 131072 }
269
+ "glm-5.2": { "context": 1000000 },
270
+ "glm-5.1": { "context": 200000 }
348
271
  }
349
272
  },
350
- "anthropic": "https://api.anthropic.com",
351
- "deepseek": "https://api.deepseek.com"
273
+ "https://api.deepseek.com": {}
352
274
  }
353
275
  }
354
276
  ```
@@ -359,12 +281,11 @@ The config file is a single JSON object. Example:
359
281
  |------|---------|-------------|
360
282
  | `port` | `8787` | Proxy listen port |
361
283
  | `host` | `127.0.0.1` | Proxy listen host |
362
- | `upstream` | `https://api.anthropic.com` | Default upstream when no route matches |
363
284
  | `sessionHeader` | `x-acp-session` | Header name clients may send to identify a conversation |
364
285
  | `log` | `true` | Enable request logging |
365
286
  | `debug` | `false` | Verbose logging (same as `ACP_DEBUG=1`) |
366
287
  | `passthrough` | `false` | Forward without compression (same as `ACP_PASSTHROUGH=1`) |
367
- | `providers` | *(none)* | Provider routes — see below |
288
+ | `providers` | *(none)* | Per-URL context overrides — see below |
368
289
  | `compress` | *(see defaults)* | `{ injectTool, injectNudge }` |
369
290
 
370
291
  > **Choosing a `host`** (IPv6 / containers): the default `127.0.0.1` is
@@ -376,53 +297,52 @@ The config file is a single JSON object. Example:
376
297
  > `--host 0.0.0.0` there. ⚠️ `0.0.0.0` / `::` expose the proxy on **all**
377
298
  > interfaces; ensure you're on a trusted network or behind a firewall.
378
299
 
379
- ### Providers (URL routing + per-model context)
300
+ ### Providers (per-URL context overrides)
380
301
 
381
- `providers` maps a route name to either a bare URL string (simple) or an
382
- object with `url` + optional per-model context window (recommended).
302
+ Routing is always the `/bili/` prefix (see [Option A](#option-a--zero-config-bili-prefix)).
303
+ The `providers` block only declares **context-window overrides** keyed by
304
+ upstream URL. The key is the same string the client puts after `/bili/`:
383
305
 
384
- **Simple form** — provider name → URL:
385
- ```json
386
- { "deepseek": "https://api.deepseek.com" }
387
- ```
388
-
389
- **Full form** — provider name → `{ url, models }`:
390
306
  ```json
391
307
  {
392
- "zhipu": {
393
- "url": "https://open.bigmodel.cn",
394
- "models": {
395
- "glm-5.2": { "context": 1000000, "output": 131072 },
396
- "glm-5.1": { "context": 200000 }
397
- }
308
+ "providers": {
309
+ "https://open.bigmodel.cn/api/coding/paas/v4": {
310
+ "models": {
311
+ "glm-5.2": { "context": 1000000 },
312
+ "glm-5.1": { "context": 200000 }
313
+ }
314
+ },
315
+ "https://api.deepseek.com": {}
398
316
  }
399
317
  }
400
318
  ```
401
319
 
402
- The same model can have a different context window behind different providers
403
- (e.g. relay wraps a model with a larger window). `context` is the **input
404
- context limit** (used by the compressor to decide when to nudge); `output` is
405
- the max output tokens. Both are optional; missing values fall back to the
406
- built-in model table, then to `modelContextLimit`.
320
+ The same model can have a different context window behind different upstreams
321
+ (e.g. a relay wraps a model with a larger window). `context` is the **input
322
+ context limit** (used by the compressor to decide when to nudge). It is
323
+ optional; missing values fall back to the [models.dev](https://models.dev)
324
+ registry, then the built-in prefix table.
407
325
 
408
326
  > **Why declare context at all?** The LLM `/models` API does **not** return
409
327
  > context windows (verified across OpenAI, Anthropic, 智谱, comfly). They are
410
328
  > document-level information. A wrong value (e.g. GLM-5.2 guessed as 128K
411
329
  > instead of 1M) causes spurious frequent compression. Declaring it per
412
- > provider + model makes the proxy match the registry the client itself uses.
330
+ > URL + model makes the proxy match the registry the client itself uses.
413
331
 
414
- **API keys are never stored in the proxy** — whatever key the agent sends is
415
- passed through untouched to the upstream.
332
+ ### URL key matching rules
416
333
 
417
- ### Provider name rules
334
+ - A request matches a key when the client's embedded URL **equals the key or
335
+ starts with it** (longest key wins).
336
+ - A shallow key like `https://open.bigmodel.cn` overrides every path on that
337
+ host; a deep key like `https://open.bigmodel.cn/api/anthropic` overrides
338
+ only that endpoint.
339
+ - Keys never cross hosts (the boundary check requires a `/` or end-of-string
340
+ after the key), so `https://x.com` does not match `https://x.com.evil`.
341
+ - Models not covered by any matching key fall back to models.dev, then the
342
+ prefix table, then `modelContextLimit`.
418
343
 
419
- - Must start with a letter, contain only letters/digits/`-`/`_`.
420
- - Reserved words (`v1`, `chat`, `completions`, `messages`, `models`, `api`)
421
- are rejected to avoid colliding with real API path segments.
422
- - The provider name can appear anywhere in the path; the longest match wins.
423
- - With **no providers** declared (e.g. you emptied the `providers` block),
424
- every request is forwarded to the default `upstream` with its full path —
425
- an edge case, not the normal flow.
344
+ **API keys are never stored in the proxy** — whatever key the agent sends is
345
+ passed through untouched to the upstream.
426
346
 
427
347
  ## How sessions work
428
348
 
@@ -460,7 +380,7 @@ pass an explicit `x-acp-session` header per conversation to avoid collisions.
460
380
 
461
381
  ## Status
462
382
 
463
- Early. Protocol handling and compression work against mock tests (141 passing). Real-model integration testing is the next milestone. Expect rough edges.
383
+ Early. Protocol handling and compression work against mock tests (146 passing). Real-model integration testing is the next milestone. Expect rough edges.
464
384
 
465
385
  See [billion-context-pi](https://github.com/ranxianglei/billion-context-pi) for the pi-extension mode (in-process, tighter integration, the reference implementation).
466
386