billion-context 0.1.64-pr.360.210 → 0.1.64
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/dist/agent/omp.js +1 -9
- package/dist/agent/omp.js.map +1 -1
- package/dist/agent/pi.js +1 -9
- package/dist/agent/pi.js.map +1 -1
- package/dist/index.js +154 -237
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50626,153 +50626,6 @@ import { readFileSync as readFileSync3 } from "fs";
|
|
|
50626
50626
|
import { dirname as dirname4, join as join3 } from "path";
|
|
50627
50627
|
import { fileURLToPath } from "url";
|
|
50628
50628
|
|
|
50629
|
-
// src/web/page.ts
|
|
50630
|
-
import { existsSync as existsSync3 } from "fs";
|
|
50631
|
-
|
|
50632
|
-
// src/ca.ts
|
|
50633
|
-
var import_node_forge = __toESM(require_lib(), 1);
|
|
50634
|
-
import fs2 from "fs";
|
|
50635
|
-
import path6 from "path";
|
|
50636
|
-
import tls2 from "tls";
|
|
50637
|
-
var ROOT_CERT_FILE = "root-ca.pem";
|
|
50638
|
-
var ROOT_KEY_FILE = "root-ca-key.pem";
|
|
50639
|
-
var COMBINED_CA_FILE = "combined-ca.pem";
|
|
50640
|
-
var ROOT_CN = "billion-context MITM Root CA";
|
|
50641
|
-
var PLATFORM_CA_CANDIDATES = process.platform === "darwin" ? ["/etc/ssl/cert.pem", "/private/etc/ssl/cert.pem"] : [
|
|
50642
|
-
"/etc/ssl/certs/ca-certificates.crt",
|
|
50643
|
-
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
50644
|
-
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
|
50645
|
-
"/etc/ssl/ca-bundle.pem",
|
|
50646
|
-
"/etc/ssl/cert.pem"
|
|
50647
|
-
];
|
|
50648
|
-
var rootCertPem;
|
|
50649
|
-
var rootKeyPem;
|
|
50650
|
-
var rootCert;
|
|
50651
|
-
var rootKey;
|
|
50652
|
-
var secureContextCache = /* @__PURE__ */ new Map();
|
|
50653
|
-
var SECURE_CONTEXT_CACHE_MAX = 64;
|
|
50654
|
-
function rootCaPath() {
|
|
50655
|
-
return path6.join(caDir(), ROOT_CERT_FILE);
|
|
50656
|
-
}
|
|
50657
|
-
function collectSystemCaPems(env = process.env) {
|
|
50658
|
-
const pems = [];
|
|
50659
|
-
const seen = /* @__PURE__ */ new Set();
|
|
50660
|
-
const pushFile = (file) => {
|
|
50661
|
-
try {
|
|
50662
|
-
const text = fs2.readFileSync(file, "utf8");
|
|
50663
|
-
if (!text.includes("BEGIN CERTIFICATE") || seen.has(text)) return false;
|
|
50664
|
-
seen.add(text);
|
|
50665
|
-
pems.push(text);
|
|
50666
|
-
return true;
|
|
50667
|
-
} catch {
|
|
50668
|
-
}
|
|
50669
|
-
return false;
|
|
50670
|
-
};
|
|
50671
|
-
const userBundle = env.SSL_CERT_FILE?.trim();
|
|
50672
|
-
if (userBundle && pushFile(userBundle)) return pems;
|
|
50673
|
-
for (const candidate of PLATFORM_CA_CANDIDATES) {
|
|
50674
|
-
if (pushFile(candidate)) break;
|
|
50675
|
-
}
|
|
50676
|
-
return pems;
|
|
50677
|
-
}
|
|
50678
|
-
function writeCombinedBundle() {
|
|
50679
|
-
const certs = /* @__PURE__ */ new Set();
|
|
50680
|
-
for (const pem of collectSystemCaPems()) certs.add(pem.trim());
|
|
50681
|
-
for (const pem of tls2.rootCertificates) certs.add(pem.trim());
|
|
50682
|
-
certs.add(rootCertPem.trim());
|
|
50683
|
-
const body = [...certs].map((pem) => pem.endsWith("\n") ? pem : pem + "\n").join("");
|
|
50684
|
-
fs2.writeFileSync(path6.join(caDir(), COMBINED_CA_FILE), body, { mode: 420 });
|
|
50685
|
-
}
|
|
50686
|
-
function generateRootCA() {
|
|
50687
|
-
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
50688
|
-
const cert = import_node_forge.default.pki.createCertificate();
|
|
50689
|
-
cert.publicKey = keys.publicKey;
|
|
50690
|
-
cert.serialNumber = "01";
|
|
50691
|
-
cert.validity.notBefore = /* @__PURE__ */ new Date();
|
|
50692
|
-
cert.validity.notAfter = /* @__PURE__ */ new Date();
|
|
50693
|
-
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);
|
|
50694
|
-
const attrs = [
|
|
50695
|
-
{ name: "commonName", value: ROOT_CN },
|
|
50696
|
-
{ name: "organizationName", value: "billion-context" }
|
|
50697
|
-
];
|
|
50698
|
-
cert.setSubject(attrs);
|
|
50699
|
-
cert.setIssuer(attrs);
|
|
50700
|
-
cert.setExtensions([
|
|
50701
|
-
{ name: "basicConstraints", cA: true },
|
|
50702
|
-
{ name: "keyUsage", keyCertSign: true, cRLSign: true, digitalSignature: true },
|
|
50703
|
-
{ name: "subjectKeyIdentifier" }
|
|
50704
|
-
]);
|
|
50705
|
-
cert.sign(keys.privateKey, import_node_forge.default.md.sha256.create());
|
|
50706
|
-
return {
|
|
50707
|
-
cert: import_node_forge.default.pki.certificateToPem(cert),
|
|
50708
|
-
key: import_node_forge.default.pki.privateKeyToPem(keys.privateKey)
|
|
50709
|
-
};
|
|
50710
|
-
}
|
|
50711
|
-
function ensureRootCA() {
|
|
50712
|
-
if (rootCertPem && rootKeyPem) {
|
|
50713
|
-
writeCombinedBundle();
|
|
50714
|
-
return;
|
|
50715
|
-
}
|
|
50716
|
-
const dir = caDir();
|
|
50717
|
-
fs2.mkdirSync(dir, { recursive: true });
|
|
50718
|
-
const certPath = path6.join(dir, ROOT_CERT_FILE);
|
|
50719
|
-
const keyPath = path6.join(dir, ROOT_KEY_FILE);
|
|
50720
|
-
if (fs2.existsSync(certPath) && fs2.existsSync(keyPath)) {
|
|
50721
|
-
rootCertPem = fs2.readFileSync(certPath, "utf8");
|
|
50722
|
-
rootKeyPem = fs2.readFileSync(keyPath, "utf8");
|
|
50723
|
-
rootCert = import_node_forge.default.pki.certificateFromPem(rootCertPem);
|
|
50724
|
-
rootKey = import_node_forge.default.pki.privateKeyFromPem(rootKeyPem);
|
|
50725
|
-
writeCombinedBundle();
|
|
50726
|
-
return;
|
|
50727
|
-
}
|
|
50728
|
-
const { cert, key } = generateRootCA();
|
|
50729
|
-
fs2.writeFileSync(certPath, cert, { mode: 420 });
|
|
50730
|
-
fs2.writeFileSync(keyPath, key, { mode: 384 });
|
|
50731
|
-
rootCertPem = cert;
|
|
50732
|
-
rootKeyPem = key;
|
|
50733
|
-
rootCert = import_node_forge.default.pki.certificateFromPem(cert);
|
|
50734
|
-
rootKey = import_node_forge.default.pki.privateKeyFromPem(key);
|
|
50735
|
-
writeCombinedBundle();
|
|
50736
|
-
}
|
|
50737
|
-
function getSecureContext(host) {
|
|
50738
|
-
if (!rootCertPem || !rootKeyPem || !rootCert || !rootKey) {
|
|
50739
|
-
throw new Error("CA not initialized \u2014 call ensureRootCA() first");
|
|
50740
|
-
}
|
|
50741
|
-
const cached = secureContextCache.get(host);
|
|
50742
|
-
if (cached) {
|
|
50743
|
-
secureContextCache.delete(host);
|
|
50744
|
-
secureContextCache.set(host, cached);
|
|
50745
|
-
return cached;
|
|
50746
|
-
}
|
|
50747
|
-
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
50748
|
-
const cert = import_node_forge.default.pki.createCertificate();
|
|
50749
|
-
cert.publicKey = keys.publicKey;
|
|
50750
|
-
cert.serialNumber = Date.now().toString() + Math.floor(Math.random() * 1e6).toString();
|
|
50751
|
-
cert.validity.notBefore = /* @__PURE__ */ new Date();
|
|
50752
|
-
cert.validity.notAfter = /* @__PURE__ */ new Date();
|
|
50753
|
-
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 2);
|
|
50754
|
-
cert.setSubject([{ name: "commonName", value: host }]);
|
|
50755
|
-
cert.setIssuer(rootCert.subject.attributes);
|
|
50756
|
-
cert.setExtensions([
|
|
50757
|
-
{ name: "basicConstraints", cA: false },
|
|
50758
|
-
{ name: "keyUsage", digitalSignature: true, keyEncipherment: true },
|
|
50759
|
-
{ name: "extKeyUsage", serverAuth: true },
|
|
50760
|
-
{ name: "subjectAltName", altNames: [{ type: 2, value: host }] }
|
|
50761
|
-
]);
|
|
50762
|
-
cert.sign(rootKey, import_node_forge.default.md.sha256.create());
|
|
50763
|
-
const ctx = tls2.createSecureContext({
|
|
50764
|
-
cert: import_node_forge.default.pki.certificateToPem(cert),
|
|
50765
|
-
key: import_node_forge.default.pki.privateKeyToPem(keys.privateKey),
|
|
50766
|
-
ca: rootCertPem
|
|
50767
|
-
});
|
|
50768
|
-
secureContextCache.set(host, ctx);
|
|
50769
|
-
if (secureContextCache.size > SECURE_CONTEXT_CACHE_MAX) {
|
|
50770
|
-
const oldest = secureContextCache.keys().next().value;
|
|
50771
|
-
if (oldest !== void 0) secureContextCache.delete(oldest);
|
|
50772
|
-
}
|
|
50773
|
-
return ctx;
|
|
50774
|
-
}
|
|
50775
|
-
|
|
50776
50629
|
// src/web/client.ts
|
|
50777
50630
|
var WEB_CLIENT = `
|
|
50778
50631
|
const byId=(id)=>document.getElementById(id);
|
|
@@ -50805,13 +50658,7 @@ var WEB_STYLES = `
|
|
|
50805
50658
|
`;
|
|
50806
50659
|
|
|
50807
50660
|
// src/web/page.ts
|
|
50808
|
-
function escapeHtml(value) {
|
|
50809
|
-
return value.replace(/[&<>"']/g, (char) => char === "&" ? "&" : char === "<" ? "<" : char === ">" ? ">" : char === '"' ? """ : "'");
|
|
50810
|
-
}
|
|
50811
50661
|
function renderPage(origin, version2) {
|
|
50812
|
-
const caPath = rootCaPath();
|
|
50813
|
-
const caPathEsc = escapeHtml(caPath);
|
|
50814
|
-
const caReady = existsSync3(caPath);
|
|
50815
50662
|
return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>billion-context</title><style>${WEB_STYLES}</style></head><body>
|
|
50816
50663
|
<div class="app"><aside class="sidebar"><div class="brand"><div class="brand-title">billion<span>-context</span></div><div class="version">v${version2}</div></div><a class="fork-ribbon" href="https://github.com/ranxianglei/billion-context" target="_blank" rel="noopener">\u2605 Fork me on GitHub</a><nav class="nav"><button class="active" data-page="overview">\u6982\u89C8</button><button data-page="routing">\u63A5\u5165</button><button data-page="upstream">\u4E0A\u6E38</button><button data-page="sessions">\u4F1A\u8BDD</button><button data-page="settings">\u8BBE\u7F6E</button></nav></aside>
|
|
50817
50664
|
<main class="main"><section id="page-overview" class="page active"><h1>\u6982\u89C8</h1><p class="lead">\u672C\u5730\u8DEF\u7531\u4E0E\u4E0A\u6E38\u7F51\u7EDC\u76F8\u4E92\u72EC\u7ACB\uFF0CACP \u538B\u7F29\u8FD0\u884C\u5728\u4E24\u8005\u4E4B\u95F4\u3002</p><div class="grid"><div class="card"><h2>\u670D\u52A1\u5730\u5740</h2><p class="mono">${origin}</p></div><div class="card"><h2>\u5BA2\u6237\u7AEF\u63A5\u5165</h2><p class="status">\u5728"\u63A5\u5165"\u9875\u5C06\u5404\u5BA2\u6237\u7AEF\uFF08Codex / Claude Code / OpenCode / Pi \u7B49\uFF09\u7684\u6D41\u91CF\u8DEF\u7531\u5230 bili\u3002</p></div></div></section>
|
|
@@ -50826,14 +50673,14 @@ function renderPage(origin, version2) {
|
|
|
50826
50673
|
<div class="card"><div class="card-head"><h2>\u5176\u4ED6\uFF08Cursor / Aider / Continue\uFF09</h2><button class="btn small copy-btn" data-copy="${origin}/bili/">\u590D\u5236</button></div><dl class="kv"><dt>\u89C4\u5219</dt><dd>\u4EFB\u610F baseURL \u524D\u52A0 <span class="mono">${origin}/bili/</span></dd><dt>\u793A\u4F8B</dt><dd class="mono">${origin}/bili/https://api.openai.com/v1</dd></dl></div>
|
|
50827
50674
|
<h2 class="section-title">B. \u8BC1\u4E66\u63A5\u5165\u65B9\u5F0F\uFF08zcode \u7B49\u7C7B\u578B\uFF09</h2>
|
|
50828
50675
|
<p class="hint">\u4E0D\u652F\u6301\u6539 URL \u7684\u5BA2\u6237\u7AEF\uFF08endpoint \u786C\u7F16\u7801\uFF09\u9700 MITM \u900F\u660E\u4EE3\u7406\uFF0C\u8BBE HTTPS_PROXY + \u4FE1\u4EFB CA \u8BC1\u4E66\u3002</p>
|
|
50829
|
-
<div class="card"><div class="card-head"><h2>ZCode\uFF08\u7F16\u7A0B\u5957\u9910\uFF09</h2><span class="badge">MITM</span
|
|
50676
|
+
<div class="card"><div class="card-head"><h2>ZCode\uFF08\u7F16\u7A0B\u5957\u9910\uFF09</h2><span class="badge">MITM</span></div><dl class="kv"><dt>\u65B9\u5F0F</dt><dd>MITM \u900F\u660E\u4EE3\u7406</dd><dt>\u8BBE\u7F6E</dt><dd>Settings \u2192 Network \u2192 HTTP Proxy = <span class="mono">${origin}</span></dd><dt>CA \u8BC1\u4E66</dt><dd class="mono">~/.local/share/billion-context/ca/root-ca.pem</dd></dl></div></section>
|
|
50830
50677
|
<section id="page-upstream" class="page"><h1>\u4E0A\u6E38\u7F51\u7EDC</h1><p class="lead">\u63A7\u5236 bili \u5982\u4F55\u8BBF\u95EE\u771F\u5B9E Provider\uFF0C\u4E0D\u4F1A\u6539\u53D8\u5BA2\u6237\u7AEF\u7684\u672C\u5730\u8DEF\u7531\u5730\u5740\u3002</p><div class="card"><div class="card-head"><h2>\u5168\u5C40\u4EE3\u7406</h2></div><div class="modes"><label><input type="radio" name="proxy-mode" value="direct" checked>\u76F4\u8FDE\uFF08\u9ED8\u8BA4\uFF09</label><label><input type="radio" name="proxy-mode" value="manual">\u624B\u52A8\u4EE3\u7406</label><label><input type="radio" name="proxy-mode" value="auto">\u81EA\u52A8\uFF08\u8DDF\u968F\u7CFB\u7EDF\uFF09</label></div><div class="field"><label>HTTP / HTTPS Proxy</label><input id="proxy-url" class="mono" placeholder="http://127.0.0.1:7897"></div><dl class="kv"><dt>\u5F53\u524D\u6765\u6E90</dt><dd id="upstream-source">\u76F4\u8FDE</dd><dt>\u6709\u6548\u4EE3\u7406</dt><dd id="upstream-effective" class="mono">direct</dd><dt>\u7CFB\u7EDF PAC</dt><dd id="upstream-pac" class="mono">\u2014</dd><dt>\u72B6\u6001</dt><dd id="upstream-state" class="status">\u5C1A\u672A\u6D4B\u8BD5</dd></dl><div class="actions"><button id="save-upstream" class="btn primary">\u4FDD\u5B58\u5E76\u70ED\u66F4\u65B0</button><button id="test-upstream" class="btn">\u6D4B\u8BD5\u8FDE\u63A5</button></div></div><div class="card"><div class="card-head"><h2>\u6309 URL \u8986\u76D6</h2></div><p class="status">\u4E3A\u7279\u5B9A Provider \u5355\u72EC\u8BBE\u7F6E\u4E0A\u6E38\u4EE3\u7406\uFF0C\u8986\u76D6\u5168\u5C40\u8BBE\u7F6E\u3002\u7559\u7A7A = \u7EE7\u627F\u5168\u5C40\u3002</p><div id="upstream-overrides" class="status">\u52A0\u8F7D\u4E2D</div><div class="actions"><button id="save-overrides" class="btn primary">\u4FDD\u5B58\u8986\u76D6\u5E76\u70ED\u66F4\u65B0</button></div></div></section>
|
|
50831
50678
|
<section id="page-sessions" class="page"><div class="card-head"><div><h1>\u4F1A\u8BDD</h1><p class="lead">ACP \u538B\u7F29\u72B6\u6001\u4E0E\u4E0A\u6E38\u7528\u91CF\u3002</p></div><button id="refresh-sessions" class="btn">\u5237\u65B0</button></div><div class="card"><table><thead><tr><th>\u6807\u9898</th><th>\u534F\u8BAE</th><th>\u6807\u8BC6</th><th>\u8BF7\u6C42</th><th>\u4E0A\u4E0B\u6587</th><th>\u6700\u540E\u6D3B\u52A8</th></tr></thead><tbody id="sessions-body"></tbody></table></div></section>
|
|
50832
50679
|
<section id="page-settings" class="page"><h1>\u9AD8\u7EA7\u8BBE\u7F6E</h1><p class="lead">\u76F4\u63A5\u7F16\u8F91 providers JSON\uFF08\u6DFB\u52A0\u65B0 Provider\u3001\u914D\u7F6E\u6A21\u578B\u4E0A\u4E0B\u6587\u7A97\u53E3\u3001\u6309 URL \u4EE3\u7406\u7B49\uFF09\uFF1B\u4FDD\u5B58\u540E\u7ACB\u5373\u70ED\u66F4\u65B0\u3002</p><div class="card"><div class="field"><label>providers JSON</label><textarea id="providers-json">{}</textarea></div><div class="actions"><button id="save-providers" class="btn primary">\u4FDD\u5B58\u5E76\u5E94\u7528</button></div></div><div class="card"><div class="card-head"><h2>\u538B\u7F29\u53C2\u6570\uFF08\u5168\u5C40\uFF09</h2></div><p class="status">\u5168\u5C40 compress \u914D\u7F6E\uFF08modelContextLimit / maxContextLimit / emergencyThresholdPercent / nudgeGrowthTokens / preserveRecentMessages / preserveRecentTokens / minCompressRange / tiers / injectTool / injectNudge\uFF09\u3002\u4FDD\u5B58\u540E\u70ED\u66F4\u65B0\uFF0C\u65E0\u9700\u91CD\u542F\u3002\u7F6E\u7A7A = \u6062\u590D\u9ED8\u8BA4\u3002</p><div class="field"><label>compress JSON</label><textarea id="compress-json" placeholder='{"modelContextLimit": 200000}'></textarea></div><div class="actions"><button id="save-compress" class="btn primary">\u4FDD\u5B58\u5E76\u70ED\u66F4\u65B0</button></div></div></section></main></div><div id="toast" class="toast"></div><script>${WEB_CLIENT}</script></body></html>`;
|
|
50833
50680
|
}
|
|
50834
50681
|
|
|
50835
50682
|
// src/web/api.ts
|
|
50836
|
-
import { closeSync, existsSync as
|
|
50683
|
+
import { closeSync, existsSync as existsSync3, fsyncSync, mkdirSync as mkdirSync4, openSync, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
50837
50684
|
import { dirname as dirname3 } from "path";
|
|
50838
50685
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
50839
50686
|
function readConfig() {
|
|
@@ -50841,7 +50688,7 @@ function readConfig() {
|
|
|
50841
50688
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
50842
50689
|
}
|
|
50843
50690
|
function configParseError() {
|
|
50844
|
-
if (!
|
|
50691
|
+
if (!existsSync3(configFile())) return null;
|
|
50845
50692
|
const parsed = safeReadJson(configFile());
|
|
50846
50693
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return null;
|
|
50847
50694
|
return `config file is not valid JSON: ${configFile()}`;
|
|
@@ -52890,65 +52737,6 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
52890
52737
|
return current;
|
|
52891
52738
|
}
|
|
52892
52739
|
|
|
52893
|
-
// src/acp-panel.ts
|
|
52894
|
-
var PANEL_BOX_TOP = "\u256D";
|
|
52895
|
-
var PANEL_BOX_TITLE = "ACP Context Analysis";
|
|
52896
|
-
var PANEL_FALLBACK_HEADER = "\u{1F4CA} ACP status";
|
|
52897
|
-
function isAcpPanelText(text) {
|
|
52898
|
-
const t = text.trim();
|
|
52899
|
-
if (t.length === 0) return false;
|
|
52900
|
-
if (t.startsWith(PANEL_BOX_TOP) && t.includes(PANEL_BOX_TITLE)) return true;
|
|
52901
|
-
if (t.startsWith(PANEL_FALLBACK_HEADER)) return true;
|
|
52902
|
-
return false;
|
|
52903
|
-
}
|
|
52904
|
-
function messageText(content) {
|
|
52905
|
-
if (typeof content === "string") return content;
|
|
52906
|
-
if (Array.isArray(content)) {
|
|
52907
|
-
let joined = "";
|
|
52908
|
-
for (const part of content) {
|
|
52909
|
-
const p2 = part;
|
|
52910
|
-
if (p2 === null || typeof p2 !== "object") return void 0;
|
|
52911
|
-
const pt2 = p2.type;
|
|
52912
|
-
if (pt2 !== void 0 && pt2 !== "text" && pt2 !== "input_text" && pt2 !== "output_text") return void 0;
|
|
52913
|
-
if (typeof p2.text === "string") joined += p2.text;
|
|
52914
|
-
}
|
|
52915
|
-
return joined;
|
|
52916
|
-
}
|
|
52917
|
-
return void 0;
|
|
52918
|
-
}
|
|
52919
|
-
function stripAcpPanelMessages(messages) {
|
|
52920
|
-
if (!Array.isArray(messages)) return 0;
|
|
52921
|
-
let stripped = 0;
|
|
52922
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
52923
|
-
const rec = messages[i];
|
|
52924
|
-
if (rec === null || typeof rec !== "object") continue;
|
|
52925
|
-
if (rec.role !== "user") continue;
|
|
52926
|
-
const text = messageText(rec.content);
|
|
52927
|
-
if (text !== void 0 && isAcpPanelText(text)) {
|
|
52928
|
-
messages.splice(i, 1);
|
|
52929
|
-
stripped++;
|
|
52930
|
-
}
|
|
52931
|
-
}
|
|
52932
|
-
return stripped;
|
|
52933
|
-
}
|
|
52934
|
-
function stripAcpPanelResponsesInput(input) {
|
|
52935
|
-
if (!Array.isArray(input)) return 0;
|
|
52936
|
-
let stripped = 0;
|
|
52937
|
-
for (let i = input.length - 1; i >= 0; i--) {
|
|
52938
|
-
const rec = input[i];
|
|
52939
|
-
if (rec === null || typeof rec !== "object") continue;
|
|
52940
|
-
const type = rec.type;
|
|
52941
|
-
if (type !== "message" && type !== void 0) continue;
|
|
52942
|
-
if (rec.role !== "user") continue;
|
|
52943
|
-
const text = messageText(rec.content);
|
|
52944
|
-
if (text !== void 0 && isAcpPanelText(text)) {
|
|
52945
|
-
input.splice(i, 1);
|
|
52946
|
-
stripped++;
|
|
52947
|
-
}
|
|
52948
|
-
}
|
|
52949
|
-
return stripped;
|
|
52950
|
-
}
|
|
52951
|
-
|
|
52952
52740
|
// src/stream-openai.ts
|
|
52953
52741
|
function rewriteOpenaiJsonResponse(body, ctx) {
|
|
52954
52742
|
if (!body || typeof body !== "object") return body;
|
|
@@ -53557,13 +53345,13 @@ function buildStatusPanel(input) {
|
|
|
53557
53345
|
|
|
53558
53346
|
// src/plugin.ts
|
|
53559
53347
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
53560
|
-
import
|
|
53561
|
-
import
|
|
53348
|
+
import fs2 from "fs";
|
|
53349
|
+
import path6 from "path";
|
|
53562
53350
|
var PROXY_VERSION = (() => {
|
|
53563
53351
|
try {
|
|
53564
53352
|
const here = fileURLToPath2(import.meta.url);
|
|
53565
|
-
const pkg =
|
|
53566
|
-
return JSON.parse(
|
|
53353
|
+
const pkg = path6.join(path6.dirname(here), "..", "package.json");
|
|
53354
|
+
return JSON.parse(fs2.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53567
53355
|
} catch {
|
|
53568
53356
|
return "dev";
|
|
53569
53357
|
}
|
|
@@ -53575,8 +53363,8 @@ var PLUGIN_PROTOCOL_VERSION = 1;
|
|
|
53575
53363
|
var VERSION = (() => {
|
|
53576
53364
|
try {
|
|
53577
53365
|
const here = fileURLToPath2(import.meta.url);
|
|
53578
|
-
const pkg =
|
|
53579
|
-
return JSON.parse(
|
|
53366
|
+
const pkg = path6.join(path6.dirname(here), "..", "package.json");
|
|
53367
|
+
return JSON.parse(fs2.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
53580
53368
|
} catch {
|
|
53581
53369
|
return "dev";
|
|
53582
53370
|
}
|
|
@@ -53605,14 +53393,14 @@ function pluginReportedContextWindow(headers) {
|
|
|
53605
53393
|
var MAX_PLUGIN_CONVERSATIONS = 1024;
|
|
53606
53394
|
var conversations = /* @__PURE__ */ new Map();
|
|
53607
53395
|
var remembered = /* @__PURE__ */ new Map();
|
|
53608
|
-
var conversationsFile = () =>
|
|
53396
|
+
var conversationsFile = () => path6.join(stateDir(), "plugin-conversations.json");
|
|
53609
53397
|
var conversationsSaveTimer;
|
|
53610
53398
|
function writeConversationsFile() {
|
|
53611
53399
|
try {
|
|
53612
53400
|
const obj = {};
|
|
53613
53401
|
for (const [k2, v2] of conversations) obj[k2] = v2;
|
|
53614
|
-
|
|
53615
|
-
|
|
53402
|
+
fs2.mkdirSync(stateDir(), { recursive: true });
|
|
53403
|
+
fs2.writeFileSync(conversationsFile(), JSON.stringify(obj));
|
|
53616
53404
|
} catch {
|
|
53617
53405
|
}
|
|
53618
53406
|
}
|
|
@@ -53632,7 +53420,7 @@ function flushConversations() {
|
|
|
53632
53420
|
}
|
|
53633
53421
|
function loadConversations() {
|
|
53634
53422
|
try {
|
|
53635
|
-
const raw =
|
|
53423
|
+
const raw = fs2.readFileSync(conversationsFile(), "utf8");
|
|
53636
53424
|
const obj = JSON.parse(raw);
|
|
53637
53425
|
for (const [k2, v2] of Object.entries(obj)) {
|
|
53638
53426
|
if (v2 && typeof v2.sessionId === "string" && v2.sessionId.length > 0) {
|
|
@@ -54093,6 +53881,147 @@ async function pipePluginJson(stream2, res, session, protocol) {
|
|
|
54093
53881
|
// src/mitm.ts
|
|
54094
53882
|
import tls3 from "tls";
|
|
54095
53883
|
|
|
53884
|
+
// src/ca.ts
|
|
53885
|
+
var import_node_forge = __toESM(require_lib(), 1);
|
|
53886
|
+
import fs3 from "fs";
|
|
53887
|
+
import path7 from "path";
|
|
53888
|
+
import tls2 from "tls";
|
|
53889
|
+
var ROOT_CERT_FILE = "root-ca.pem";
|
|
53890
|
+
var ROOT_KEY_FILE = "root-ca-key.pem";
|
|
53891
|
+
var COMBINED_CA_FILE = "combined-ca.pem";
|
|
53892
|
+
var ROOT_CN = "billion-context MITM Root CA";
|
|
53893
|
+
var PLATFORM_CA_CANDIDATES = process.platform === "darwin" ? ["/etc/ssl/cert.pem", "/private/etc/ssl/cert.pem"] : [
|
|
53894
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
|
53895
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
53896
|
+
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
|
53897
|
+
"/etc/ssl/ca-bundle.pem",
|
|
53898
|
+
"/etc/ssl/cert.pem"
|
|
53899
|
+
];
|
|
53900
|
+
var rootCertPem;
|
|
53901
|
+
var rootKeyPem;
|
|
53902
|
+
var rootCert;
|
|
53903
|
+
var rootKey;
|
|
53904
|
+
var secureContextCache = /* @__PURE__ */ new Map();
|
|
53905
|
+
var SECURE_CONTEXT_CACHE_MAX = 64;
|
|
53906
|
+
function collectSystemCaPems(env = process.env) {
|
|
53907
|
+
const pems = [];
|
|
53908
|
+
const seen = /* @__PURE__ */ new Set();
|
|
53909
|
+
const pushFile = (file) => {
|
|
53910
|
+
try {
|
|
53911
|
+
const text = fs3.readFileSync(file, "utf8");
|
|
53912
|
+
if (!text.includes("BEGIN CERTIFICATE") || seen.has(text)) return false;
|
|
53913
|
+
seen.add(text);
|
|
53914
|
+
pems.push(text);
|
|
53915
|
+
return true;
|
|
53916
|
+
} catch {
|
|
53917
|
+
}
|
|
53918
|
+
return false;
|
|
53919
|
+
};
|
|
53920
|
+
const userBundle = env.SSL_CERT_FILE?.trim();
|
|
53921
|
+
if (userBundle && pushFile(userBundle)) return pems;
|
|
53922
|
+
for (const candidate of PLATFORM_CA_CANDIDATES) {
|
|
53923
|
+
if (pushFile(candidate)) break;
|
|
53924
|
+
}
|
|
53925
|
+
return pems;
|
|
53926
|
+
}
|
|
53927
|
+
function writeCombinedBundle() {
|
|
53928
|
+
const certs = /* @__PURE__ */ new Set();
|
|
53929
|
+
for (const pem of collectSystemCaPems()) certs.add(pem.trim());
|
|
53930
|
+
for (const pem of tls2.rootCertificates) certs.add(pem.trim());
|
|
53931
|
+
certs.add(rootCertPem.trim());
|
|
53932
|
+
const body = [...certs].map((pem) => pem.endsWith("\n") ? pem : pem + "\n").join("");
|
|
53933
|
+
fs3.writeFileSync(path7.join(caDir(), COMBINED_CA_FILE), body, { mode: 420 });
|
|
53934
|
+
}
|
|
53935
|
+
function generateRootCA() {
|
|
53936
|
+
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
53937
|
+
const cert = import_node_forge.default.pki.createCertificate();
|
|
53938
|
+
cert.publicKey = keys.publicKey;
|
|
53939
|
+
cert.serialNumber = "01";
|
|
53940
|
+
cert.validity.notBefore = /* @__PURE__ */ new Date();
|
|
53941
|
+
cert.validity.notAfter = /* @__PURE__ */ new Date();
|
|
53942
|
+
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);
|
|
53943
|
+
const attrs = [
|
|
53944
|
+
{ name: "commonName", value: ROOT_CN },
|
|
53945
|
+
{ name: "organizationName", value: "billion-context" }
|
|
53946
|
+
];
|
|
53947
|
+
cert.setSubject(attrs);
|
|
53948
|
+
cert.setIssuer(attrs);
|
|
53949
|
+
cert.setExtensions([
|
|
53950
|
+
{ name: "basicConstraints", cA: true },
|
|
53951
|
+
{ name: "keyUsage", keyCertSign: true, cRLSign: true, digitalSignature: true },
|
|
53952
|
+
{ name: "subjectKeyIdentifier" }
|
|
53953
|
+
]);
|
|
53954
|
+
cert.sign(keys.privateKey, import_node_forge.default.md.sha256.create());
|
|
53955
|
+
return {
|
|
53956
|
+
cert: import_node_forge.default.pki.certificateToPem(cert),
|
|
53957
|
+
key: import_node_forge.default.pki.privateKeyToPem(keys.privateKey)
|
|
53958
|
+
};
|
|
53959
|
+
}
|
|
53960
|
+
function ensureRootCA() {
|
|
53961
|
+
if (rootCertPem && rootKeyPem) {
|
|
53962
|
+
writeCombinedBundle();
|
|
53963
|
+
return;
|
|
53964
|
+
}
|
|
53965
|
+
const dir = caDir();
|
|
53966
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
53967
|
+
const certPath = path7.join(dir, ROOT_CERT_FILE);
|
|
53968
|
+
const keyPath = path7.join(dir, ROOT_KEY_FILE);
|
|
53969
|
+
if (fs3.existsSync(certPath) && fs3.existsSync(keyPath)) {
|
|
53970
|
+
rootCertPem = fs3.readFileSync(certPath, "utf8");
|
|
53971
|
+
rootKeyPem = fs3.readFileSync(keyPath, "utf8");
|
|
53972
|
+
rootCert = import_node_forge.default.pki.certificateFromPem(rootCertPem);
|
|
53973
|
+
rootKey = import_node_forge.default.pki.privateKeyFromPem(rootKeyPem);
|
|
53974
|
+
writeCombinedBundle();
|
|
53975
|
+
return;
|
|
53976
|
+
}
|
|
53977
|
+
const { cert, key } = generateRootCA();
|
|
53978
|
+
fs3.writeFileSync(certPath, cert, { mode: 420 });
|
|
53979
|
+
fs3.writeFileSync(keyPath, key, { mode: 384 });
|
|
53980
|
+
rootCertPem = cert;
|
|
53981
|
+
rootKeyPem = key;
|
|
53982
|
+
rootCert = import_node_forge.default.pki.certificateFromPem(cert);
|
|
53983
|
+
rootKey = import_node_forge.default.pki.privateKeyFromPem(key);
|
|
53984
|
+
writeCombinedBundle();
|
|
53985
|
+
}
|
|
53986
|
+
function getSecureContext(host) {
|
|
53987
|
+
if (!rootCertPem || !rootKeyPem || !rootCert || !rootKey) {
|
|
53988
|
+
throw new Error("CA not initialized \u2014 call ensureRootCA() first");
|
|
53989
|
+
}
|
|
53990
|
+
const cached = secureContextCache.get(host);
|
|
53991
|
+
if (cached) {
|
|
53992
|
+
secureContextCache.delete(host);
|
|
53993
|
+
secureContextCache.set(host, cached);
|
|
53994
|
+
return cached;
|
|
53995
|
+
}
|
|
53996
|
+
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
53997
|
+
const cert = import_node_forge.default.pki.createCertificate();
|
|
53998
|
+
cert.publicKey = keys.publicKey;
|
|
53999
|
+
cert.serialNumber = Date.now().toString() + Math.floor(Math.random() * 1e6).toString();
|
|
54000
|
+
cert.validity.notBefore = /* @__PURE__ */ new Date();
|
|
54001
|
+
cert.validity.notAfter = /* @__PURE__ */ new Date();
|
|
54002
|
+
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 2);
|
|
54003
|
+
cert.setSubject([{ name: "commonName", value: host }]);
|
|
54004
|
+
cert.setIssuer(rootCert.subject.attributes);
|
|
54005
|
+
cert.setExtensions([
|
|
54006
|
+
{ name: "basicConstraints", cA: false },
|
|
54007
|
+
{ name: "keyUsage", digitalSignature: true, keyEncipherment: true },
|
|
54008
|
+
{ name: "extKeyUsage", serverAuth: true },
|
|
54009
|
+
{ name: "subjectAltName", altNames: [{ type: 2, value: host }] }
|
|
54010
|
+
]);
|
|
54011
|
+
cert.sign(rootKey, import_node_forge.default.md.sha256.create());
|
|
54012
|
+
const ctx = tls2.createSecureContext({
|
|
54013
|
+
cert: import_node_forge.default.pki.certificateToPem(cert),
|
|
54014
|
+
key: import_node_forge.default.pki.privateKeyToPem(keys.privateKey),
|
|
54015
|
+
ca: rootCertPem
|
|
54016
|
+
});
|
|
54017
|
+
secureContextCache.set(host, ctx);
|
|
54018
|
+
if (secureContextCache.size > SECURE_CONTEXT_CACHE_MAX) {
|
|
54019
|
+
const oldest = secureContextCache.keys().next().value;
|
|
54020
|
+
if (oldest !== void 0) secureContextCache.delete(oldest);
|
|
54021
|
+
}
|
|
54022
|
+
return ctx;
|
|
54023
|
+
}
|
|
54024
|
+
|
|
54096
54025
|
// src/discover.ts
|
|
54097
54026
|
import fs5 from "fs";
|
|
54098
54027
|
import os2 from "os";
|
|
@@ -56142,10 +56071,6 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56142
56071
|
let rebuiltMessages = parsed.messages;
|
|
56143
56072
|
let systemOut = parsed.system;
|
|
56144
56073
|
let toolsOut = parsed.tools;
|
|
56145
|
-
const strippedPanels = stripAcpPanelMessages(parsed.messages);
|
|
56146
|
-
if (strippedPanels > 0) {
|
|
56147
|
-
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56148
|
-
}
|
|
56149
56074
|
try {
|
|
56150
56075
|
const { msgs, cacheControls } = anthropicToCore(parsed);
|
|
56151
56076
|
originalMessages = msgs;
|
|
@@ -56202,10 +56127,6 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
56202
56127
|
const isTitleGen = maxTokens <= 200;
|
|
56203
56128
|
const shouldInject = opts.compress.injectTool && !isTitleGen;
|
|
56204
56129
|
const injectTools = shouldInject && !pluginMode;
|
|
56205
|
-
const strippedPanels = stripAcpPanelMessages(parsed.messages);
|
|
56206
|
-
if (strippedPanels > 0) {
|
|
56207
|
-
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56208
|
-
}
|
|
56209
56130
|
try {
|
|
56210
56131
|
const { msgs, systemText } = openaiToCore(parsed);
|
|
56211
56132
|
openaiSystemText = systemText;
|
|
@@ -56287,10 +56208,6 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
56287
56208
|
if (droppedEmpty > 0) {
|
|
56288
56209
|
log2("info", `[${sessionId}] dropped ${droppedEmpty} whitespace-only message item(s) before projection (flattened-turn artifact)`);
|
|
56289
56210
|
}
|
|
56290
|
-
const strippedPanels = stripAcpPanelResponsesInput(parsed.input);
|
|
56291
|
-
if (strippedPanels > 0) {
|
|
56292
|
-
log2("info", `[${sessionId}] stripped ${strippedPanels} ACP panel message(s) before projection (UI-only, issue #359)`);
|
|
56293
|
-
}
|
|
56294
56211
|
const shouldInject = opts.compress.injectTool;
|
|
56295
56212
|
const injectTools = shouldInject && !pluginMode;
|
|
56296
56213
|
const isCompactionTrigger = hasCompactionTrigger(parsed.input);
|