billion-context 0.1.84-pr.537.356 → 0.1.84
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 +2 -14
- package/README.zh-CN.md +2 -2
- package/dist/index.js +82 -96
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,18 +112,6 @@ turn is a semantic mismatch the model tolerates (it is clearly marked
|
|
|
112
112
|
summaries (their tool call isn't in the agent's history and the agent's view
|
|
113
113
|
skips `acp_summary`) — but that needs the id match above, which doesn't occur.
|
|
114
114
|
|
|
115
|
-
### Injection priority — no files unless unavoidable
|
|
116
|
-
|
|
117
|
-
How the launcher points a client at the proxy follows a strict priority
|
|
118
|
-
(#535): **env vars** (`HTTPS_PROXY` cert-MITM for discovered upstream hosts,
|
|
119
|
-
`HTTP_PROXY` absolute-form requests for plaintext-http upstreams, plus the
|
|
120
|
-
per-client CA trust variable) > **client-native CLI flags / extension APIs**
|
|
121
|
-
> **generated config files** (last resort — today omp's overlay and dsh's
|
|
122
|
-
loopback exception). No real config file is ever edited, and bili never owns
|
|
123
|
-
user data: clients run against their real home directory, and pre-existing
|
|
124
|
-
overlay dirs from older versions (e.g. `~/.hermes-bili`) are left in place,
|
|
125
|
-
unmigrated.
|
|
126
|
-
|
|
127
115
|
## Which do I need?
|
|
128
116
|
|
|
129
117
|
Pick by your client:
|
|
@@ -169,8 +157,8 @@ bili codex # launch codex through the proxy
|
|
|
169
157
|
bili claude # launch claude through the proxy
|
|
170
158
|
bili omp # pi-style: MITM env + persistent overlay home (~/.omp/agent-bili, real config untouched)
|
|
171
159
|
bili opencode # MITM for HTTPS + temp opencode.json (/bili/ for HTTP) + thin /acp plugin
|
|
172
|
-
bili hermes #
|
|
173
|
-
bili dsh # deepseek-harness:
|
|
160
|
+
bili hermes # no MITM possible (certifi CA) — persistent overlay home (~/.hermes-bili), all traffic /bili/
|
|
161
|
+
bili dsh # deepseek-harness: built-in deepseek route via DEEPSEEK_BASE_URL + overlay DSH_HOME (~/.dsh-bili), all traffic /bili/, native /acp command injected via --patch
|
|
174
162
|
bili pi --mitm-domain api.foo.com # add a domain to the MITM whitelist
|
|
175
163
|
```
|
|
176
164
|
|
package/README.zh-CN.md
CHANGED
|
@@ -88,8 +88,8 @@ bili codex # 拉起 codex
|
|
|
88
88
|
bili claude # 拉起 claude
|
|
89
89
|
bili omp # pi 同款 MITM 环境变量 + 隔离临时 models.yml
|
|
90
90
|
bili opencode # HTTPS 走 MITM + 临时 opencode.json(HTTP 走 /bili/)+ 轻量 /acp 插件
|
|
91
|
-
bili hermes #
|
|
92
|
-
bili dsh # deepseek-harness
|
|
91
|
+
bili hermes # 无法 MITM(certifi CA)—— 隔离 HERMES_HOME,全部流量 /bili/
|
|
92
|
+
bili dsh # deepseek-harness:内置 deepseek 路由走 DEEPSEEK_BASE_URL + 隔离 DSH_HOME(~/.dsh-bili),全部流量 /bili/,经 --patch 注入原生 /acp 命令
|
|
93
93
|
bili pi --mitm-domain api.foo.com # 向 MITM 白名单追加域名
|
|
94
94
|
```
|
|
95
95
|
|
package/dist/index.js
CHANGED
|
@@ -56901,13 +56901,6 @@ function resolveUpstream(_opts, reqUrl, req) {
|
|
|
56901
56901
|
const mitmKey = mitmUpstream.replace(/^https:\/\//, "mitm://");
|
|
56902
56902
|
return { upstream: mitmUpstream, rewrittenUrl: mitmKey + (reqUrl ?? "") };
|
|
56903
56903
|
}
|
|
56904
|
-
if (/^https?:\/\//i.test(reqUrl)) {
|
|
56905
|
-
try {
|
|
56906
|
-
const u2 = new URL(reqUrl);
|
|
56907
|
-
return { upstream: `${u2.protocol}//${u2.host}`, rewrittenUrl: reqUrl, tunnel: true };
|
|
56908
|
-
} catch {
|
|
56909
|
-
}
|
|
56910
|
-
}
|
|
56911
56904
|
const KNOWN_PROTOCOLS = ["responses", "anthropic", "openai"];
|
|
56912
56905
|
if (reqUrl.startsWith("/bili/")) {
|
|
56913
56906
|
let rest = reqUrl.slice(6);
|
|
@@ -62796,12 +62789,6 @@ function unwrapUpstream2(url) {
|
|
|
62796
62789
|
const idx = url.indexOf("/bili/");
|
|
62797
62790
|
return idx >= 0 ? url.slice(idx + "/bili/".length) : url;
|
|
62798
62791
|
}
|
|
62799
|
-
function isLoopbackHost(host) {
|
|
62800
|
-
const h = host.toLowerCase();
|
|
62801
|
-
if (h === "localhost" || h === "::1" || h === "[::1]") return true;
|
|
62802
|
-
const m2 = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(h);
|
|
62803
|
-
return m2 !== null && m2[1] === "127";
|
|
62804
|
-
}
|
|
62805
62792
|
function resolveCaCertPath(env) {
|
|
62806
62793
|
const base = env.XDG_DATA_HOME || path15.join(os5.homedir(), ".local/share");
|
|
62807
62794
|
return path15.join(base, "billion-context", "ca", "root-ca.pem");
|
|
@@ -62814,8 +62801,6 @@ function discoverRoutes(client, config) {
|
|
|
62814
62801
|
const httpsDomains = [];
|
|
62815
62802
|
const httpRewrites = [];
|
|
62816
62803
|
const httpsRewrites = [];
|
|
62817
|
-
const httpEnvRoutes = [];
|
|
62818
|
-
const providerKeys = [];
|
|
62819
62804
|
const httpsSeen = /* @__PURE__ */ new Set();
|
|
62820
62805
|
const rewriteKeys = /* @__PURE__ */ new Set();
|
|
62821
62806
|
const httpsRewriteKeys = /* @__PURE__ */ new Set();
|
|
@@ -62872,25 +62857,14 @@ function discoverRoutes(client, config) {
|
|
|
62872
62857
|
for (const [name, prov] of Object.entries(config.hermes?.providers ?? {})) {
|
|
62873
62858
|
if (!nonEmpty2(prov.api)) continue;
|
|
62874
62859
|
const real = unwrapUpstream2(prov.api);
|
|
62875
|
-
let url;
|
|
62876
62860
|
try {
|
|
62877
|
-
url = new URL(real);
|
|
62861
|
+
const url = new URL(real);
|
|
62862
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") continue;
|
|
62863
|
+
if (hermesSeen.has(name)) continue;
|
|
62864
|
+
hermesSeen.add(name);
|
|
62865
|
+
rewriteKeys.add(name);
|
|
62866
|
+
httpRewrites.push({ key: name, realUpstream: real });
|
|
62878
62867
|
} catch {
|
|
62879
|
-
continue;
|
|
62880
|
-
}
|
|
62881
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") continue;
|
|
62882
|
-
if (hermesSeen.has(name)) continue;
|
|
62883
|
-
hermesSeen.add(name);
|
|
62884
|
-
rewriteKeys.add(name);
|
|
62885
|
-
providerKeys.push(name);
|
|
62886
|
-
if (url.protocol === "https:") {
|
|
62887
|
-
const host = url.hostname;
|
|
62888
|
-
if (host && !httpsSeen.has(host.toLowerCase())) {
|
|
62889
|
-
httpsSeen.add(host.toLowerCase());
|
|
62890
|
-
httpsDomains.push(host);
|
|
62891
|
-
}
|
|
62892
|
-
} else {
|
|
62893
|
-
httpEnvRoutes.push(real);
|
|
62894
62868
|
}
|
|
62895
62869
|
}
|
|
62896
62870
|
} else if (client === "dsh") {
|
|
@@ -62898,27 +62872,15 @@ function discoverRoutes(client, config) {
|
|
|
62898
62872
|
let anon = 0;
|
|
62899
62873
|
for (const raw of config.dsh?.baseUrls ?? []) {
|
|
62900
62874
|
const real = unwrapUpstream2(raw);
|
|
62901
|
-
let url;
|
|
62902
62875
|
try {
|
|
62903
|
-
url = new URL(real);
|
|
62904
|
-
|
|
62905
|
-
continue;
|
|
62906
|
-
|
|
62907
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") continue;
|
|
62908
|
-
if (dshSeen.has(real)) continue;
|
|
62909
|
-
dshSeen.add(real);
|
|
62910
|
-
if (isLoopbackHost(url.hostname)) {
|
|
62876
|
+
const url = new URL(real);
|
|
62877
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") continue;
|
|
62878
|
+
if (dshSeen.has(real)) continue;
|
|
62879
|
+
dshSeen.add(real);
|
|
62911
62880
|
anon += 1;
|
|
62912
62881
|
rewriteKeys.add(`dsh-${anon}`);
|
|
62913
62882
|
httpRewrites.push({ key: `dsh-${anon}`, realUpstream: real });
|
|
62914
|
-
}
|
|
62915
|
-
const host = url.hostname;
|
|
62916
|
-
if (!httpsSeen.has(host.toLowerCase())) {
|
|
62917
|
-
httpsSeen.add(host.toLowerCase());
|
|
62918
|
-
httpsDomains.push(host);
|
|
62919
|
-
}
|
|
62920
|
-
} else {
|
|
62921
|
-
httpEnvRoutes.push(real);
|
|
62883
|
+
} catch {
|
|
62922
62884
|
}
|
|
62923
62885
|
}
|
|
62924
62886
|
} else {
|
|
@@ -62927,7 +62889,7 @@ function discoverRoutes(client, config) {
|
|
|
62927
62889
|
}
|
|
62928
62890
|
classify(config.codex?.openaiBaseUrl, "openai_base_url");
|
|
62929
62891
|
}
|
|
62930
|
-
return { httpsDomains, httpRewrites, httpsRewrites
|
|
62892
|
+
return { httpsDomains, httpRewrites, httpsRewrites };
|
|
62931
62893
|
}
|
|
62932
62894
|
function discoverDomains(client, config) {
|
|
62933
62895
|
return discoverRoutes(client, config).httpsDomains;
|
|
@@ -63707,12 +63669,53 @@ function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
|
63707
63669
|
writeOmpCompactionDisabledConfig(ompHome, overlay);
|
|
63708
63670
|
return overlay;
|
|
63709
63671
|
}
|
|
63710
|
-
function
|
|
63711
|
-
|
|
63672
|
+
function prepareHermesHome(hermesHome, origin, rewrites) {
|
|
63673
|
+
if (rewrites.length === 0) return void 0;
|
|
63674
|
+
const cfgPath = path15.join(hermesHome, "config.yaml");
|
|
63675
|
+
let txt;
|
|
63712
63676
|
try {
|
|
63713
|
-
fs12.
|
|
63714
|
-
|
|
63715
|
-
|
|
63677
|
+
txt = fs12.readFileSync(cfgPath, "utf8");
|
|
63678
|
+
} catch {
|
|
63679
|
+
return void 0;
|
|
63680
|
+
}
|
|
63681
|
+
const wrapSet = new Set(rewrites.map((r) => r.realUpstream));
|
|
63682
|
+
const eol = txt.includes("\r\n") ? "\r\n" : "\n";
|
|
63683
|
+
const lines = txt.split(/\r?\n/);
|
|
63684
|
+
let changed = false;
|
|
63685
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63686
|
+
const rawLine = lines[i];
|
|
63687
|
+
const m2 = /^(\s*(?:api|base_url|url):\s*)(\S+)(\s+#.*)?$/.exec(rawLine);
|
|
63688
|
+
if (!m2) continue;
|
|
63689
|
+
const rawUrl = m2[2].replace(/^["']|["']$/g, "");
|
|
63690
|
+
if (!/^https?:\/\//i.test(rawUrl)) continue;
|
|
63691
|
+
const real = unwrapUpstream2(rawUrl);
|
|
63692
|
+
if (!wrapSet.has(real)) continue;
|
|
63693
|
+
lines[i] = `${m2[1]}${wrapUpstream(origin, real)}${m2[3] ?? ""}`;
|
|
63694
|
+
changed = true;
|
|
63695
|
+
}
|
|
63696
|
+
if (!changed) return void 0;
|
|
63697
|
+
const overlay = `${hermesHome}-bili`;
|
|
63698
|
+
if (!refreshOverlayHome(hermesHome, overlay, "config.yaml")) return void 0;
|
|
63699
|
+
writeOverlayFileAtomic(overlay, "config.yaml", lines.join(eol));
|
|
63700
|
+
return overlay;
|
|
63701
|
+
}
|
|
63702
|
+
function writeHermesIdentityPlugin(hermesHome, overlay, rewrites) {
|
|
63703
|
+
try {
|
|
63704
|
+
if (fs12.existsSync(path15.join(hermesHome, "plugins"))) return false;
|
|
63705
|
+
} catch {
|
|
63706
|
+
return false;
|
|
63707
|
+
}
|
|
63708
|
+
const dir = path15.join("plugins", "model-providers", "bili-session-identity");
|
|
63709
|
+
try {
|
|
63710
|
+
fs12.mkdirSync(path15.join(overlay, dir), { recursive: true });
|
|
63711
|
+
} catch {
|
|
63712
|
+
return false;
|
|
63713
|
+
}
|
|
63714
|
+
const keys = rewrites.map((r) => r.key);
|
|
63715
|
+
const pluginDir = path15.join(overlay, dir);
|
|
63716
|
+
try {
|
|
63717
|
+
fs12.writeFileSync(path15.join(pluginDir, "__init__.py"), hermesIdentityPluginSource(keys));
|
|
63718
|
+
fs12.writeFileSync(path15.join(pluginDir, "plugin.yaml"), [
|
|
63716
63719
|
"name: bili-session-identity",
|
|
63717
63720
|
"kind: model-provider",
|
|
63718
63721
|
"version: 1.0.0",
|
|
@@ -63724,7 +63727,7 @@ function writeHermesIdentityPlugin(hermesHome, providerKeys) {
|
|
|
63724
63727
|
return false;
|
|
63725
63728
|
}
|
|
63726
63729
|
try {
|
|
63727
|
-
return fs12.existsSync(path15.join(dir, "__init__.py"));
|
|
63730
|
+
return fs12.existsSync(path15.join(overlay, dir, "__init__.py"));
|
|
63728
63731
|
} catch {
|
|
63729
63732
|
return false;
|
|
63730
63733
|
}
|
|
@@ -63947,17 +63950,6 @@ function stripInheritedProxy(env) {
|
|
|
63947
63950
|
for (const key of INHERITED_PROXY_VARS) delete cleaned[key];
|
|
63948
63951
|
return cleaned;
|
|
63949
63952
|
}
|
|
63950
|
-
function stripLoopbackNoProxy(env) {
|
|
63951
|
-
const out = { ...env };
|
|
63952
|
-
for (const key of ["NO_PROXY", "no_proxy"]) {
|
|
63953
|
-
const value = out[key];
|
|
63954
|
-
if (typeof value !== "string" || value.length === 0) continue;
|
|
63955
|
-
const kept = value.split(",").map((s3) => s3.trim()).filter((s3) => s3.length > 0 && !isLoopbackHost(s3));
|
|
63956
|
-
if (kept.length > 0) out[key] = kept.join(",");
|
|
63957
|
-
else delete out[key];
|
|
63958
|
-
}
|
|
63959
|
-
return out;
|
|
63960
|
-
}
|
|
63961
63953
|
function proxyStartArgs(opts) {
|
|
63962
63954
|
const args = ["start", "--host", opts.host, "--port", String(opts.port)];
|
|
63963
63955
|
if (opts.passthrough) args.push("--passthrough");
|
|
@@ -64110,11 +64102,10 @@ async function runLaunch(params, deps = {}) {
|
|
|
64110
64102
|
const base = baseClientName(params.client);
|
|
64111
64103
|
const routes = discoverRoutes(base, config);
|
|
64112
64104
|
const biliRoutes = loadRoutes(process.env);
|
|
64113
|
-
const
|
|
64114
|
-
const domains = dedupeInOrder([...routes.httpsDomains, ...builtinDomains, ...params.mitmDomains ?? []]);
|
|
64105
|
+
const domains = dedupeInOrder([...routes.httpsDomains, ...params.mitmDomains ?? []]);
|
|
64115
64106
|
const handle2 = await ensureProxyRunning({ host, port, passthrough, debug, mitmDomains: domains, modelWindows: collectModelWindows(config, base) }, deps);
|
|
64116
64107
|
console.error(
|
|
64117
|
-
`bili: started proxy at ${handle2.origin} (MITM domains: ${domains.length ? domains.join(", ") : "defaults"})` + (routes.httpRewrites.length > 0 ? ` (HTTP /bili/ rewrites: ${routes.httpRewrites.length})` : "") + (routes.httpsRewrites.length > 0 ? ` (HTTPS cert rewrites: ${routes.httpsRewrites.length})` : "") + (
|
|
64108
|
+
`bili: started proxy at ${handle2.origin} (MITM domains: ${domains.length ? domains.join(", ") : "defaults"})` + (routes.httpRewrites.length > 0 ? ` (HTTP /bili/ rewrites: ${routes.httpRewrites.length})` : "") + (routes.httpsRewrites.length > 0 ? ` (HTTPS cert rewrites: ${routes.httpsRewrites.length})` : "") + (params.client === "pi-test" ? " (no extensions)" : "")
|
|
64118
64109
|
);
|
|
64119
64110
|
if (handle2.logPath) {
|
|
64120
64111
|
console.error(`bili: proxy log: ${handle2.logPath}`);
|
|
@@ -64125,6 +64116,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
64125
64116
|
let piOverlayHome;
|
|
64126
64117
|
let ompOverlayHome;
|
|
64127
64118
|
let opencodeTmpFile;
|
|
64119
|
+
let hermesOverlayHome;
|
|
64128
64120
|
let dshOverlayHome;
|
|
64129
64121
|
const tmpFiles = [];
|
|
64130
64122
|
const directUrl = launcherDirectUrl(process.env);
|
|
@@ -64174,42 +64166,36 @@ async function runLaunch(params, deps = {}) {
|
|
|
64174
64166
|
opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
|
|
64175
64167
|
if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
|
|
64176
64168
|
} else if (base === "hermes") {
|
|
64177
|
-
env =
|
|
64178
|
-
|
|
64179
|
-
|
|
64180
|
-
|
|
64181
|
-
|
|
64182
|
-
});
|
|
64183
|
-
if (routes.providerKeys.length > 0) {
|
|
64184
|
-
if (!writeHermesIdentityPlugin(resolveHermesHome(process.env), routes.providerKeys)) {
|
|
64169
|
+
env = { ...process.env };
|
|
64170
|
+
hermesOverlayHome = prepareHermesHome(resolveHermesHome(process.env), origin, routes.httpRewrites);
|
|
64171
|
+
if (hermesOverlayHome) {
|
|
64172
|
+
env.HERMES_HOME = hermesOverlayHome;
|
|
64173
|
+
if (!writeHermesIdentityPlugin(resolveHermesHome(process.env), hermesOverlayHome, routes.httpRewrites)) {
|
|
64185
64174
|
console.error(
|
|
64186
|
-
"bili:
|
|
64175
|
+
"bili: ~/.hermes has its own plugins/ \u2014 skipping the session-identity plugin; hermes requests will be rejected by the proxy without an identity (see #286)."
|
|
64187
64176
|
);
|
|
64188
64177
|
}
|
|
64189
64178
|
} else {
|
|
64190
64179
|
console.error(
|
|
64191
|
-
"bili: no hermes providers found in ~/.hermes/config.yaml \u2014
|
|
64180
|
+
routes.httpRewrites.length === 0 ? "bili: no hermes providers found in ~/.hermes/config.yaml \u2014 traffic will NOT go through the proxy (configure a provider first)." : "bili: hermes config.yaml could not be rewritten (unreadable or no matching provider endpoints) \u2014 traffic will NOT go through the proxy."
|
|
64192
64181
|
);
|
|
64193
64182
|
}
|
|
64194
64183
|
} else if (base === "dsh") {
|
|
64195
|
-
env =
|
|
64196
|
-
|
|
64197
|
-
BILLION_CONTEXT_PROXY: origin,
|
|
64198
|
-
HTTPS_PROXY: origin,
|
|
64199
|
-
NODE_EXTRA_CA_CERTS: ca,
|
|
64200
|
-
...routes.httpEnvRoutes.length > 0 ? { HTTP_PROXY: origin } : {}
|
|
64201
|
-
});
|
|
64184
|
+
env = { ...process.env, BILLION_CONTEXT_PROXY: origin };
|
|
64185
|
+
env.DEEPSEEK_BASE_URL = wrapUpstream(origin, "https://api.deepseek.com");
|
|
64202
64186
|
env.PI_CACHE_RETENTION = "long";
|
|
64203
64187
|
const dshHomeDir = resolveDshHome(process.env);
|
|
64204
|
-
|
|
64205
|
-
|
|
64206
|
-
|
|
64207
|
-
|
|
64208
|
-
|
|
64209
|
-
|
|
64210
|
-
|
|
64211
|
-
|
|
64212
|
-
|
|
64188
|
+
dshOverlayHome = prepareDshHome(dshHomeDir, origin, routes.httpRewrites);
|
|
64189
|
+
if (dshOverlayHome) {
|
|
64190
|
+
env.DSH_HOME = dshOverlayHome;
|
|
64191
|
+
} else if (routes.httpRewrites.length > 0) {
|
|
64192
|
+
console.error(
|
|
64193
|
+
"bili: dsh settings.yaml could not be rewritten (unreadable or no matching endpoints) \u2014 custom providers will NOT go through the proxy; the built-in deepseek route still does."
|
|
64194
|
+
);
|
|
64195
|
+
} else {
|
|
64196
|
+
console.error(
|
|
64197
|
+
"bili: no custom providers found in ~/.dsh/settings.yaml \u2014 proxying the built-in deepseek route via DEEPSEEK_BASE_URL only."
|
|
64198
|
+
);
|
|
64213
64199
|
}
|
|
64214
64200
|
const dshAcpPatch = writeDshAcpPatch(dshHomeDir);
|
|
64215
64201
|
if (dshAcpPatch) clientArgs = dshArgsWithPatch(clientArgs, dshAcpPatch);
|