billion-context 0.1.53-pr.238.80 → 0.1.53-pr.239.86

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
@@ -148,6 +148,23 @@ bili --no-auto-update # disable self-update for this run
148
148
 
149
149
  Flags override env vars and the config file. `bili --help` lists them all.
150
150
 
151
+ ### Remote agents (`--host`)
152
+
153
+ By default the proxy binds `127.0.0.1` and only accepts loopback
154
+ connections. To serve agents on other machines, bind a non-loopback host:
155
+
156
+ ```bash
157
+ bili --host 0.0.0.0 # all interfaces (or use your LAN IP)
158
+ ```
159
+
160
+ - Remote agents point their model `baseURL` at `http://<this-host>:<port>/bili/…`.
161
+ - MITM-mode `CONNECT` then also accepts remote clients — for **whitelisted
162
+ model hosts only**. Blind tunnels to arbitrary hosts stay loopback-only, so
163
+ the proxy can never be used as an open relay.
164
+ - There is **no authentication**: only do this on a trusted LAN or behind a
165
+ firewall. The `/__bili/` management endpoints remain loopback-only.
166
+ - A startup `[security]` warning reminds you of the above.
167
+
151
168
  ### Debugging
152
169
 
153
170
  Three ways to enable verbose logging (priority: flag > env > config):
package/README.zh-CN.md CHANGED
@@ -133,6 +133,21 @@ bili --no-auto-update # 本次启动禁用自动更新
133
133
 
134
134
  参数优先级高于环境变量和配置文件。`bili --help` 列出全部。
135
135
 
136
+ ### 远程 agent(`--host`)
137
+
138
+ 默认绑定 `127.0.0.1`,只接受本机连接。要给其他机器上的 agent 用,绑定非 loopback 地址:
139
+
140
+ ```bash
141
+ bili --host 0.0.0.0 # 所有网卡(或直接用局域网 IP)
142
+ ```
143
+
144
+ - 远程 agent 把模型 `baseURL` 指向 `http://<本机IP>:<端口>/bili/…`。
145
+ - MITM 模式的 `CONNECT` 也会接受远程客户端 —— 但仅限**白名单内的模型域名**;
146
+ 到任意主机的盲隧道仍仅限本机,代理不会沦为开放中继。
147
+ - **没有任何鉴权**: 只应在可信局域网或防火墙内使用。`/__bili/` 管理
148
+ 端点仍仅限本机访问。
149
+ - 启动时的 `[security]` 警告会提醒上述事项。
150
+
136
151
  ### 调试
137
152
 
138
153
  三种方式打开详细日志(优先级:参数 > 环境变量 > 配置):
package/dist/index.js CHANGED
@@ -50295,6 +50295,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
50295
50295
  const calls = [];
50296
50296
  let usage = {};
50297
50297
  let finishReason;
50298
+ let sawDone = false;
50298
50299
  let suppressCompletion = false;
50299
50300
  for await (const ev of adapter.parseStream(currentUpstream, round)) {
50300
50301
  if (signal?.aborted) break;
@@ -50332,6 +50333,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
50332
50333
  cachedTokens: ev.cachedTokens
50333
50334
  };
50334
50335
  } else if (ev.kind === "done") {
50336
+ sawDone = true;
50335
50337
  finishReason = ev.finishReason;
50336
50338
  suppressCompletion = ev.suppressCompletion === true;
50337
50339
  } else if (ev.kind === "meta") {
@@ -50453,6 +50455,15 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
50453
50455
  }
50454
50456
  const reRequest = proxyResults.length > 0 && realCalls === 0;
50455
50457
  if (!reRequest) {
50458
+ if (!sawDone) {
50459
+ const partialText = assistantText.length;
50460
+ const partialReasoning = assistantReasoning.length;
50461
+ const msg = `upstream stream truncated (no completion event; round ${round}, ${partialText} text chars + ${partialReasoning} reasoning chars received)`;
50462
+ ctx.log(`[acp-loop] round ${round}: ${msg}`);
50463
+ log("error", `[acp-loop] ${msg}`);
50464
+ yield adapter.emitError(msg);
50465
+ return;
50466
+ }
50456
50467
  if (!suppressCompletion) {
50457
50468
  yield adapter.emitCompletion({ finishReason, usage });
50458
50469
  }
@@ -53217,17 +53228,23 @@ function isMitmHost(host, extraDomains = []) {
53217
53228
  return all.some((d) => h === d || h.endsWith("." + d));
53218
53229
  }
53219
53230
  function setupMitm(server, extraDomains = [], log2 = () => {
53220
- }, resolveProxyUrl) {
53231
+ }, resolveProxyUrl, allowRemoteClients = false) {
53221
53232
  ensureRootCA();
53222
53233
  server.on("connect", (req, clientSocket, head) => {
53223
- if (!isLoopbackAddress(clientSocket.remoteAddress)) {
53224
- log2(`CONNECT ${req.url} rejected: non-loopback client ${clientSocket.remoteAddress}`);
53234
+ const remote = !isLoopbackAddress(clientSocket.remoteAddress);
53235
+ if (remote && !allowRemoteClients) {
53236
+ log2(`CONNECT ${req.url} rejected: non-loopback client ${clientSocket.remoteAddress} (bind a non-loopback --host to allow remote clients)`);
53225
53237
  clientSocket.end("HTTP/1.1 403 Forbidden\r\n\r\n");
53226
53238
  return;
53227
53239
  }
53228
53240
  const { hostname, port } = parseHostPort(req.url ?? "");
53229
53241
  const targetPort = port || 443;
53230
53242
  if (!isMitmHost(hostname, extraDomains)) {
53243
+ if (remote) {
53244
+ log2(`CONNECT ${req.url} rejected: remote client ${clientSocket.remoteAddress} tunneling non-whitelisted host`);
53245
+ clientSocket.end("HTTP/1.1 403 Forbidden\r\n\r\n");
53246
+ return;
53247
+ }
53231
53248
  const proxyUrl = resolveProxyUrl?.(hostname);
53232
53249
  tunnelThrough(clientSocket, hostname, targetPort, head, log2, proxyUrl);
53233
53250
  return;
@@ -54147,10 +54164,12 @@ Content-Length: ${Buffer.byteLength(body)}\r
54147
54164
  );
54148
54165
  });
54149
54166
  if (opts.mitm.enabled) {
54150
- setupMitm(server, opts.mitm.domains, (msg) => log2("info", msg), (host) => resolveProxy(opts.routes, opts.proxy, `https://${host}`, opts.proxyFallback));
54167
+ const allowRemoteConnect = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
54168
+ setupMitm(server, opts.mitm.domains, (msg) => log2("info", msg), (host) => resolveProxy(opts.routes, opts.proxy, `https://${host}`, opts.proxyFallback), allowRemoteConnect);
54151
54169
  }
54152
54170
  server.listen(opts.port, opts.host, () => {
54153
- const displayHost = opts.host === "0.0.0.0" ? "localhost" : opts.host;
54171
+ const nonLoopbackBind = opts.host === "0.0.0.0" || opts.host === "::" || !isLoopbackAddress(opts.host);
54172
+ const displayHost = nonLoopbackBind ? opts.host : opts.host === "0.0.0.0" ? "localhost" : opts.host;
54154
54173
  try {
54155
54174
  fs6.mkdirSync(stateDir(), { recursive: true });
54156
54175
  const originHost = opts.host === "0.0.0.0" || opts.host === "::" || opts.host === "localhost" ? "127.0.0.1" : opts.host.includes(":") && !opts.host.startsWith("[") ? `[${opts.host}]` : opts.host;
@@ -54163,6 +54182,12 @@ Content-Length: ${Buffer.byteLength(body)}\r
54163
54182
  "info",
54164
54183
  `acp-proxy listening on http://${displayHost}:${opts.port} \u2014 web UI: http://${displayHost}:${opts.port}/__bili/ \u2014 zero-config: prefix any baseURL with http://${displayHost}:${opts.port}/bili/` + (nOverrides ? ` \u2014 context overrides for ${nOverrides} upstream URL(s)` : "") + (opts.mitm.enabled ? ` \u2014 MITM proxy on (whitelist)${opts.mitm.domains.length ? ` +${opts.mitm.domains.join(",")}` : ""}` : "")
54165
54184
  );
54185
+ if (nonLoopbackBind) {
54186
+ log2(
54187
+ "warn",
54188
+ `[security] bound to ${opts.host} \u2014 proxy endpoints (/bili/, CONNECT for whitelisted model hosts) are reachable from the network with NO authentication; /__bili/ management endpoints stay loopback-only. Restrict access with a firewall on untrusted networks. Remote agents: point baseURL at http://<this-host>:${opts.port}/bili/`
54189
+ );
54190
+ }
54166
54191
  if (opts.debug) {
54167
54192
  log2("info", `[debug] build features: raw-HTTP-capture(on) | remote_compaction_v2-strip(on) | cert-MITM-launcher(on) | strip-acp-summary(on) \u2014 seeing this line confirms the launcher build (not registry 0.1.34)`);
54168
54193
  }