billion-context 0.1.42 → 0.1.43
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 +52 -1
- package/dist/index.js +487 -133
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1141,14 +1141,14 @@ var require_util = __commonJS({
|
|
|
1141
1141
|
}
|
|
1142
1142
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
1143
1143
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
1144
|
-
let
|
|
1144
|
+
let path12 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
1145
1145
|
if (origin[origin.length - 1] === "/") {
|
|
1146
1146
|
origin = origin.slice(0, origin.length - 1);
|
|
1147
1147
|
}
|
|
1148
|
-
if (
|
|
1149
|
-
|
|
1148
|
+
if (path12 && path12[0] !== "/") {
|
|
1149
|
+
path12 = `/${path12}`;
|
|
1150
1150
|
}
|
|
1151
|
-
return new URL(`${origin}${
|
|
1151
|
+
return new URL(`${origin}${path12}`);
|
|
1152
1152
|
}
|
|
1153
1153
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
1154
1154
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -1969,9 +1969,9 @@ var require_diagnostics = __commonJS({
|
|
|
1969
1969
|
"undici:client:sendHeaders",
|
|
1970
1970
|
(evt) => {
|
|
1971
1971
|
const {
|
|
1972
|
-
request: { method, path:
|
|
1972
|
+
request: { method, path: path12, origin }
|
|
1973
1973
|
} = evt;
|
|
1974
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
1974
|
+
debugLog("sending request to %s %s%s", method, origin, path12);
|
|
1975
1975
|
}
|
|
1976
1976
|
);
|
|
1977
1977
|
}
|
|
@@ -1989,14 +1989,14 @@ var require_diagnostics = __commonJS({
|
|
|
1989
1989
|
"undici:request:headers",
|
|
1990
1990
|
(evt) => {
|
|
1991
1991
|
const {
|
|
1992
|
-
request: { method, path:
|
|
1992
|
+
request: { method, path: path12, origin },
|
|
1993
1993
|
response: { statusCode }
|
|
1994
1994
|
} = evt;
|
|
1995
1995
|
debugLog(
|
|
1996
1996
|
"received response to %s %s%s - HTTP %d",
|
|
1997
1997
|
method,
|
|
1998
1998
|
origin,
|
|
1999
|
-
|
|
1999
|
+
path12,
|
|
2000
2000
|
statusCode
|
|
2001
2001
|
);
|
|
2002
2002
|
}
|
|
@@ -2005,23 +2005,23 @@ var require_diagnostics = __commonJS({
|
|
|
2005
2005
|
"undici:request:trailers",
|
|
2006
2006
|
(evt) => {
|
|
2007
2007
|
const {
|
|
2008
|
-
request: { method, path:
|
|
2008
|
+
request: { method, path: path12, origin }
|
|
2009
2009
|
} = evt;
|
|
2010
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
2010
|
+
debugLog("trailers received from %s %s%s", method, origin, path12);
|
|
2011
2011
|
}
|
|
2012
2012
|
);
|
|
2013
2013
|
diagnosticsChannel.subscribe(
|
|
2014
2014
|
"undici:request:error",
|
|
2015
2015
|
(evt) => {
|
|
2016
2016
|
const {
|
|
2017
|
-
request: { method, path:
|
|
2017
|
+
request: { method, path: path12, origin },
|
|
2018
2018
|
error
|
|
2019
2019
|
} = evt;
|
|
2020
2020
|
debugLog(
|
|
2021
2021
|
"request to %s %s%s errored - %s",
|
|
2022
2022
|
method,
|
|
2023
2023
|
origin,
|
|
2024
|
-
|
|
2024
|
+
path12,
|
|
2025
2025
|
error.message
|
|
2026
2026
|
);
|
|
2027
2027
|
}
|
|
@@ -2136,7 +2136,7 @@ var require_request = __commonJS({
|
|
|
2136
2136
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
2137
2137
|
var Request = class {
|
|
2138
2138
|
constructor(origin, {
|
|
2139
|
-
path:
|
|
2139
|
+
path: path12,
|
|
2140
2140
|
method,
|
|
2141
2141
|
body,
|
|
2142
2142
|
headers,
|
|
@@ -2153,11 +2153,11 @@ var require_request = __commonJS({
|
|
|
2153
2153
|
maxRedirections,
|
|
2154
2154
|
typeOfService
|
|
2155
2155
|
}, handler) {
|
|
2156
|
-
if (typeof
|
|
2156
|
+
if (typeof path12 !== "string") {
|
|
2157
2157
|
throw new InvalidArgumentError("path must be a string");
|
|
2158
|
-
} else if (
|
|
2158
|
+
} else if (path12[0] !== "/" && !(path12.startsWith("http://") || path12.startsWith("https://")) && method !== "CONNECT") {
|
|
2159
2159
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
2160
|
-
} else if (invalidPathRegex.test(
|
|
2160
|
+
} else if (invalidPathRegex.test(path12)) {
|
|
2161
2161
|
throw new InvalidArgumentError("invalid request path");
|
|
2162
2162
|
}
|
|
2163
2163
|
if (typeof method !== "string") {
|
|
@@ -2232,7 +2232,7 @@ var require_request = __commonJS({
|
|
|
2232
2232
|
this.completed = false;
|
|
2233
2233
|
this.aborted = false;
|
|
2234
2234
|
this.upgrade = upgrade || null;
|
|
2235
|
-
this.path = query ? serializePathWithQuery(
|
|
2235
|
+
this.path = query ? serializePathWithQuery(path12, query) : path12;
|
|
2236
2236
|
this.origin = origin;
|
|
2237
2237
|
this.protocol = getProtocolFromUrlString(origin);
|
|
2238
2238
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -7415,7 +7415,7 @@ var require_client_h1 = __commonJS({
|
|
|
7415
7415
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
7416
7416
|
}
|
|
7417
7417
|
function writeH1(client, request) {
|
|
7418
|
-
const { method, path:
|
|
7418
|
+
const { method, path: path12, host, upgrade, blocking, reset } = request;
|
|
7419
7419
|
let { body, headers, contentLength } = request;
|
|
7420
7420
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
7421
7421
|
if (util.isFormDataLike(body)) {
|
|
@@ -7493,7 +7493,7 @@ var require_client_h1 = __commonJS({
|
|
|
7493
7493
|
if (socket.setTypeOfService) {
|
|
7494
7494
|
socket.setTypeOfService(request.typeOfService);
|
|
7495
7495
|
}
|
|
7496
|
-
let header = `${method} ${
|
|
7496
|
+
let header = `${method} ${path12} HTTP/1.1\r
|
|
7497
7497
|
`;
|
|
7498
7498
|
if (typeof host === "string") {
|
|
7499
7499
|
header += `host: ${host}\r
|
|
@@ -8146,7 +8146,7 @@ var require_client_h2 = __commonJS({
|
|
|
8146
8146
|
function writeH2(client, request) {
|
|
8147
8147
|
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
|
|
8148
8148
|
const session = client[kHTTP2Session];
|
|
8149
|
-
const { method, path:
|
|
8149
|
+
const { method, path: path12, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
|
|
8150
8150
|
let { body } = request;
|
|
8151
8151
|
if (upgrade != null && upgrade !== "websocket") {
|
|
8152
8152
|
util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -8214,7 +8214,7 @@ var require_client_h2 = __commonJS({
|
|
|
8214
8214
|
}
|
|
8215
8215
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
8216
8216
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
8217
|
-
headers[HTTP2_HEADER_PATH] =
|
|
8217
|
+
headers[HTTP2_HEADER_PATH] = path12;
|
|
8218
8218
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
8219
8219
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
8220
8220
|
} else {
|
|
@@ -8255,7 +8255,7 @@ var require_client_h2 = __commonJS({
|
|
|
8255
8255
|
stream2.setTimeout(requestTimeout);
|
|
8256
8256
|
return true;
|
|
8257
8257
|
}
|
|
8258
|
-
headers[HTTP2_HEADER_PATH] =
|
|
8258
|
+
headers[HTTP2_HEADER_PATH] = path12;
|
|
8259
8259
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
8260
8260
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
8261
8261
|
if (body && typeof body.read === "function") {
|
|
@@ -10598,10 +10598,10 @@ var require_proxy_agent = __commonJS({
|
|
|
10598
10598
|
};
|
|
10599
10599
|
const {
|
|
10600
10600
|
origin,
|
|
10601
|
-
path:
|
|
10601
|
+
path: path12 = "/",
|
|
10602
10602
|
headers = {}
|
|
10603
10603
|
} = opts;
|
|
10604
|
-
opts.path = origin +
|
|
10604
|
+
opts.path = origin + path12;
|
|
10605
10605
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
10606
10606
|
const { host } = new URL(origin);
|
|
10607
10607
|
headers.host = host;
|
|
@@ -12684,20 +12684,20 @@ var require_mock_utils = __commonJS({
|
|
|
12684
12684
|
}
|
|
12685
12685
|
return normalizedQp;
|
|
12686
12686
|
}
|
|
12687
|
-
function safeUrl(
|
|
12688
|
-
if (typeof
|
|
12689
|
-
return
|
|
12687
|
+
function safeUrl(path12) {
|
|
12688
|
+
if (typeof path12 !== "string") {
|
|
12689
|
+
return path12;
|
|
12690
12690
|
}
|
|
12691
|
-
const pathSegments =
|
|
12691
|
+
const pathSegments = path12.split("?", 3);
|
|
12692
12692
|
if (pathSegments.length !== 2) {
|
|
12693
|
-
return
|
|
12693
|
+
return path12;
|
|
12694
12694
|
}
|
|
12695
12695
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
12696
12696
|
qp.sort();
|
|
12697
12697
|
return [...pathSegments, qp.toString()].join("?");
|
|
12698
12698
|
}
|
|
12699
|
-
function matchKey(mockDispatch2, { path:
|
|
12700
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
12699
|
+
function matchKey(mockDispatch2, { path: path12, method, body, headers }) {
|
|
12700
|
+
const pathMatch = matchValue(mockDispatch2.path, path12);
|
|
12701
12701
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
12702
12702
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
12703
12703
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -12722,8 +12722,8 @@ var require_mock_utils = __commonJS({
|
|
|
12722
12722
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
12723
12723
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
12724
12724
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
12725
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
12726
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
12725
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path12, ignoreTrailingSlash }) => {
|
|
12726
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path12)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path12), resolvedPath);
|
|
12727
12727
|
});
|
|
12728
12728
|
if (matchedMockDispatches.length === 0) {
|
|
12729
12729
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -12762,19 +12762,19 @@ var require_mock_utils = __commonJS({
|
|
|
12762
12762
|
mockDispatches.splice(index, 1);
|
|
12763
12763
|
}
|
|
12764
12764
|
}
|
|
12765
|
-
function removeTrailingSlash(
|
|
12766
|
-
while (
|
|
12767
|
-
|
|
12765
|
+
function removeTrailingSlash(path12) {
|
|
12766
|
+
while (path12.endsWith("/")) {
|
|
12767
|
+
path12 = path12.slice(0, -1);
|
|
12768
12768
|
}
|
|
12769
|
-
if (
|
|
12770
|
-
|
|
12769
|
+
if (path12.length === 0) {
|
|
12770
|
+
path12 = "/";
|
|
12771
12771
|
}
|
|
12772
|
-
return
|
|
12772
|
+
return path12;
|
|
12773
12773
|
}
|
|
12774
12774
|
function buildKey(opts) {
|
|
12775
|
-
const { path:
|
|
12775
|
+
const { path: path12, method, body, headers, query } = opts;
|
|
12776
12776
|
return {
|
|
12777
|
-
path:
|
|
12777
|
+
path: path12,
|
|
12778
12778
|
method,
|
|
12779
12779
|
body,
|
|
12780
12780
|
headers,
|
|
@@ -13464,10 +13464,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
13464
13464
|
}
|
|
13465
13465
|
format(pendingInterceptors) {
|
|
13466
13466
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
13467
|
-
({ method, path:
|
|
13467
|
+
({ method, path: path12, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
13468
13468
|
Method: method,
|
|
13469
13469
|
Origin: origin,
|
|
13470
|
-
Path:
|
|
13470
|
+
Path: path12,
|
|
13471
13471
|
"Status code": statusCode,
|
|
13472
13472
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
13473
13473
|
Invocations: timesInvoked,
|
|
@@ -13549,9 +13549,9 @@ var require_mock_agent = __commonJS({
|
|
|
13549
13549
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
13550
13550
|
const dispatchOpts = { ...opts };
|
|
13551
13551
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
13552
|
-
const [
|
|
13552
|
+
const [path12, searchParams] = dispatchOpts.path.split("?");
|
|
13553
13553
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
13554
|
-
dispatchOpts.path = `${
|
|
13554
|
+
dispatchOpts.path = `${path12}?${normalizedSearchParams}`;
|
|
13555
13555
|
}
|
|
13556
13556
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
13557
13557
|
}
|
|
@@ -13680,7 +13680,7 @@ var require_snapshot_utils = __commonJS({
|
|
|
13680
13680
|
};
|
|
13681
13681
|
}
|
|
13682
13682
|
var crypto2 = runtimeFeatures.has("crypto") ? __require("crypto") : null;
|
|
13683
|
-
var
|
|
13683
|
+
var hashId3 = crypto2?.hash ? (value) => crypto2.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
|
|
13684
13684
|
function isUndiciHeaders(headers) {
|
|
13685
13685
|
return Array.isArray(headers) && (headers.length & 1) === 0;
|
|
13686
13686
|
}
|
|
@@ -13742,7 +13742,7 @@ var require_snapshot_utils = __commonJS({
|
|
|
13742
13742
|
}
|
|
13743
13743
|
module.exports = {
|
|
13744
13744
|
createHeaderFilters,
|
|
13745
|
-
hashId:
|
|
13745
|
+
hashId: hashId3,
|
|
13746
13746
|
isUndiciHeaders,
|
|
13747
13747
|
normalizeHeaders,
|
|
13748
13748
|
isUrlExcludedFactory,
|
|
@@ -13759,7 +13759,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13759
13759
|
var { dirname: dirname6, resolve } = __require("path");
|
|
13760
13760
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
|
|
13761
13761
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
13762
|
-
var { hashId:
|
|
13762
|
+
var { hashId: hashId3, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
13763
13763
|
function formatRequestKey(opts, headerFilters, matchOptions = {}) {
|
|
13764
13764
|
const url = new URL(opts.path, opts.origin);
|
|
13765
13765
|
const normalized = opts._normalizedHeaders || normalizeHeaders(opts.headers);
|
|
@@ -13822,7 +13822,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13822
13822
|
}
|
|
13823
13823
|
parts.push(formattedRequest.body);
|
|
13824
13824
|
const content = parts.join("|");
|
|
13825
|
-
return
|
|
13825
|
+
return hashId3(content);
|
|
13826
13826
|
}
|
|
13827
13827
|
var SnapshotRecorder = class {
|
|
13828
13828
|
/** @type {NodeJS.Timeout | null} */
|
|
@@ -13952,12 +13952,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13952
13952
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
13953
13953
|
*/
|
|
13954
13954
|
async loadSnapshots(filePath) {
|
|
13955
|
-
const
|
|
13956
|
-
if (!
|
|
13955
|
+
const path12 = filePath || this.#snapshotPath;
|
|
13956
|
+
if (!path12) {
|
|
13957
13957
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
13958
13958
|
}
|
|
13959
13959
|
try {
|
|
13960
|
-
const data = await readFile3(resolve(
|
|
13960
|
+
const data = await readFile3(resolve(path12), "utf8");
|
|
13961
13961
|
const parsed = JSON.parse(data);
|
|
13962
13962
|
if (Array.isArray(parsed)) {
|
|
13963
13963
|
this.#snapshots.clear();
|
|
@@ -13971,7 +13971,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13971
13971
|
if (error.code === "ENOENT") {
|
|
13972
13972
|
this.#snapshots.clear();
|
|
13973
13973
|
} else {
|
|
13974
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
13974
|
+
throw new UndiciError(`Failed to load snapshots from ${path12}`, { cause: error });
|
|
13975
13975
|
}
|
|
13976
13976
|
}
|
|
13977
13977
|
}
|
|
@@ -13982,11 +13982,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
13982
13982
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
13983
13983
|
*/
|
|
13984
13984
|
async saveSnapshots(filePath) {
|
|
13985
|
-
const
|
|
13986
|
-
if (!
|
|
13985
|
+
const path12 = filePath || this.#snapshotPath;
|
|
13986
|
+
if (!path12) {
|
|
13987
13987
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
13988
13988
|
}
|
|
13989
|
-
const resolvedPath = resolve(
|
|
13989
|
+
const resolvedPath = resolve(path12);
|
|
13990
13990
|
await mkdir3(dirname6(resolvedPath), { recursive: true });
|
|
13991
13991
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
13992
13992
|
hash,
|
|
@@ -14618,15 +14618,15 @@ var require_redirect_handler = __commonJS({
|
|
|
14618
14618
|
return;
|
|
14619
14619
|
}
|
|
14620
14620
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
14621
|
-
const
|
|
14622
|
-
const redirectUrlString = `${origin}${
|
|
14621
|
+
const path12 = search ? `${pathname}${search}` : pathname;
|
|
14622
|
+
const redirectUrlString = `${origin}${path12}`;
|
|
14623
14623
|
for (const historyUrl of this.history) {
|
|
14624
14624
|
if (historyUrl.toString() === redirectUrlString) {
|
|
14625
14625
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
14626
14626
|
}
|
|
14627
14627
|
}
|
|
14628
14628
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
14629
|
-
this.opts.path =
|
|
14629
|
+
this.opts.path = path12;
|
|
14630
14630
|
this.opts.origin = origin;
|
|
14631
14631
|
this.opts.query = null;
|
|
14632
14632
|
}
|
|
@@ -16395,10 +16395,10 @@ var require_cache_handler = __commonJS({
|
|
|
16395
16395
|
}
|
|
16396
16396
|
return locationUrl.pathname + locationUrl.search;
|
|
16397
16397
|
}
|
|
16398
|
-
function deleteCachedUri(store, cacheKey,
|
|
16398
|
+
function deleteCachedUri(store, cacheKey, path12) {
|
|
16399
16399
|
deleteCachedValue(store, {
|
|
16400
16400
|
...cacheKey,
|
|
16401
|
-
path:
|
|
16401
|
+
path: path12
|
|
16402
16402
|
});
|
|
16403
16403
|
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
16404
16404
|
const method = util.safeHTTPMethods[i];
|
|
@@ -16406,7 +16406,7 @@ var require_cache_handler = __commonJS({
|
|
|
16406
16406
|
deleteCachedValue(store, {
|
|
16407
16407
|
...cacheKey,
|
|
16408
16408
|
method,
|
|
16409
|
-
path:
|
|
16409
|
+
path: path12
|
|
16410
16410
|
});
|
|
16411
16411
|
}
|
|
16412
16412
|
}
|
|
@@ -16417,9 +16417,9 @@ var require_cache_handler = __commonJS({
|
|
|
16417
16417
|
}
|
|
16418
16418
|
const values = Array.isArray(headerValue2) ? headerValue2 : [headerValue2];
|
|
16419
16419
|
for (let i = 0; i < values.length; i++) {
|
|
16420
|
-
const
|
|
16421
|
-
if (
|
|
16422
|
-
deleteCachedUri(store, cacheKey,
|
|
16420
|
+
const path12 = getSameOriginPath(cacheKey, values[i]);
|
|
16421
|
+
if (path12 !== void 0) {
|
|
16422
|
+
deleteCachedUri(store, cacheKey, path12);
|
|
16423
16423
|
}
|
|
16424
16424
|
}
|
|
16425
16425
|
}
|
|
@@ -21297,11 +21297,11 @@ var require_fetch = __commonJS({
|
|
|
21297
21297
|
function dispatch({ body }) {
|
|
21298
21298
|
const url = requestCurrentURL(request);
|
|
21299
21299
|
const agent = fetchParams.controller.dispatcher;
|
|
21300
|
-
const
|
|
21300
|
+
const path12 = url.pathname + url.search;
|
|
21301
21301
|
const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
|
|
21302
21302
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
21303
21303
|
{
|
|
21304
|
-
path: hasTrailingQuestionMark ? `${
|
|
21304
|
+
path: hasTrailingQuestionMark ? `${path12}?` : path12,
|
|
21305
21305
|
origin: url.origin,
|
|
21306
21306
|
method: request.method,
|
|
21307
21307
|
body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
|
|
@@ -22248,9 +22248,9 @@ var require_util4 = __commonJS({
|
|
|
22248
22248
|
}
|
|
22249
22249
|
}
|
|
22250
22250
|
}
|
|
22251
|
-
function validateCookiePath(
|
|
22252
|
-
for (let i = 0; i <
|
|
22253
|
-
const code =
|
|
22251
|
+
function validateCookiePath(path12) {
|
|
22252
|
+
for (let i = 0; i < path12.length; ++i) {
|
|
22253
|
+
const code = path12.charCodeAt(i);
|
|
22254
22254
|
if (code < 32 || // exclude CTLs (0-31)
|
|
22255
22255
|
code > 126 || // exclude DEL and non-ascii
|
|
22256
22256
|
code === 59) {
|
|
@@ -25487,11 +25487,11 @@ var require_undici = __commonJS({
|
|
|
25487
25487
|
if (typeof opts.path !== "string") {
|
|
25488
25488
|
throw new InvalidArgumentError("invalid opts.path");
|
|
25489
25489
|
}
|
|
25490
|
-
let
|
|
25490
|
+
let path12 = opts.path;
|
|
25491
25491
|
if (!opts.path.startsWith("/")) {
|
|
25492
|
-
|
|
25492
|
+
path12 = `/${path12}`;
|
|
25493
25493
|
}
|
|
25494
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
25494
|
+
url = new URL(util.parseOrigin(url).origin + path12);
|
|
25495
25495
|
} else {
|
|
25496
25496
|
if (!opts) {
|
|
25497
25497
|
opts = typeof url === "object" ? url : {};
|
|
@@ -43539,6 +43539,7 @@ function createInitialState() {
|
|
|
43539
43539
|
return {
|
|
43540
43540
|
blocks: [],
|
|
43541
43541
|
messageRefs: { byRaw: {}, byRef: {} },
|
|
43542
|
+
tokenSnapshot: {},
|
|
43542
43543
|
nudge: {
|
|
43543
43544
|
lastPerMessageNudgeTokens: 0,
|
|
43544
43545
|
lastNudgeShownTokens: 0,
|
|
@@ -43708,11 +43709,23 @@ function syncBlocks(messages, state) {
|
|
|
43708
43709
|
byRaw: { ...state.messageRefs.byRaw },
|
|
43709
43710
|
byRef: { ...state.messageRefs.byRef }
|
|
43710
43711
|
},
|
|
43712
|
+
// Snapshot is keyed by ref with primitive values — shallow copy suffices.
|
|
43713
|
+
tokenSnapshot: { ...state.tokenSnapshot ?? {} },
|
|
43711
43714
|
nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
|
|
43712
43715
|
stats: { ...state.stats },
|
|
43713
43716
|
nextBlockId: state.nextBlockId,
|
|
43714
43717
|
nextRunId: state.nextRunId
|
|
43715
43718
|
};
|
|
43719
|
+
const liveRefs = new Set(
|
|
43720
|
+
messages.map((m2) => result.messageRefs.byRaw[m2.id]).filter((r) => typeof r === "string")
|
|
43721
|
+
);
|
|
43722
|
+
if (Object.keys(result.tokenSnapshot).length !== liveRefs.size) {
|
|
43723
|
+
const pruned = {};
|
|
43724
|
+
for (const [ref, n] of Object.entries(result.tokenSnapshot)) {
|
|
43725
|
+
if (liveRefs.has(ref)) pruned[ref] = n;
|
|
43726
|
+
}
|
|
43727
|
+
result.tokenSnapshot = pruned;
|
|
43728
|
+
}
|
|
43716
43729
|
const consumedBlockIds = /* @__PURE__ */ new Set();
|
|
43717
43730
|
for (const block of result.blocks) {
|
|
43718
43731
|
for (const consumedId of block.directBlockIds) {
|
|
@@ -44191,7 +44204,7 @@ var TAG_CLOSE = LT + "/acp" + GT;
|
|
|
44191
44204
|
function acpTag(ref, tokens, type) {
|
|
44192
44205
|
return TAG_OPEN + 'tokens="' + formatTokens(tokens) + '" type="' + type + '"' + GT + ref + TAG_CLOSE;
|
|
44193
44206
|
}
|
|
44194
|
-
function renderMessage(message, map, countTokens, strategy) {
|
|
44207
|
+
function renderMessage(message, map, countTokens, strategy, snapshot = null) {
|
|
44195
44208
|
const ref = refForRaw(map, message.id);
|
|
44196
44209
|
if (!ref || ref === BLOCKED_REF) return message;
|
|
44197
44210
|
if (strategy === "none") return message;
|
|
@@ -44202,26 +44215,33 @@ function renderMessage(message, map, countTokens, strategy) {
|
|
|
44202
44215
|
"^" + escapeRegex(TAG_OPEN) + "[^>]*" + GT + escapeRegex(ref) + escapeRegex(TAG_CLOSE) + "\\n?"
|
|
44203
44216
|
);
|
|
44204
44217
|
const cleanText = (message.text || "").replace(ownTagRe, "");
|
|
44205
|
-
const tokens = countTokens(cleanText);
|
|
44218
|
+
const tokens = snapshot ? snapshot[ref] ?? (snapshot[ref] = countTokens(cleanText)) : countTokens(cleanText);
|
|
44206
44219
|
const type = classifyType(message);
|
|
44207
44220
|
const prefix = acpTag(ref, tokens, type) + "\n";
|
|
44208
44221
|
if (!cleanText) return { ...message, text: prefix };
|
|
44209
44222
|
return { ...message, text: prefix + cleanText };
|
|
44210
44223
|
}
|
|
44211
|
-
function
|
|
44224
|
+
function renderWithSnapshot(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
|
|
44212
44225
|
const map = state.messageRefs;
|
|
44213
|
-
|
|
44214
|
-
|
|
44226
|
+
const snapshot = { ...state.tokenSnapshot ?? {} };
|
|
44227
|
+
const rendered = messages.map(
|
|
44228
|
+
(message) => renderMessage(message, map, countTokens, strategy, snapshot)
|
|
44215
44229
|
);
|
|
44230
|
+
return { messages: rendered, tokenSnapshot: snapshot };
|
|
44216
44231
|
}
|
|
44217
44232
|
function createRenderRefsNode(strategy) {
|
|
44218
44233
|
return {
|
|
44219
44234
|
name: "render-refs",
|
|
44220
44235
|
run(io2, ctx) {
|
|
44221
|
-
|
|
44222
|
-
|
|
44223
|
-
|
|
44224
|
-
|
|
44236
|
+
const { messages, tokenSnapshot } = renderWithSnapshot(
|
|
44237
|
+
io2.messages,
|
|
44238
|
+
io2.state,
|
|
44239
|
+
ctx.countTokens,
|
|
44240
|
+
strategy
|
|
44241
|
+
);
|
|
44242
|
+
const prev = io2.state.tokenSnapshot;
|
|
44243
|
+
const changed = !prev || Object.keys(tokenSnapshot).length !== Object.keys(prev).length;
|
|
44244
|
+
return changed ? { ...io2, messages, state: { ...io2.state, tokenSnapshot } } : { ...io2, messages };
|
|
44225
44245
|
}
|
|
44226
44246
|
};
|
|
44227
44247
|
}
|
|
@@ -44417,6 +44437,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
44417
44437
|
ref,
|
|
44418
44438
|
refNum: rn2,
|
|
44419
44439
|
tokens: countTokens(msg2.text ?? ""),
|
|
44440
|
+
chars: (msg2.text ?? "").length,
|
|
44420
44441
|
isTool: isToolMessage(msg2),
|
|
44421
44442
|
isUser: msg2.role === "user"
|
|
44422
44443
|
});
|
|
@@ -44437,6 +44458,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
44437
44458
|
endRef: info.ref,
|
|
44438
44459
|
count: 1,
|
|
44439
44460
|
tokens: info.tokens,
|
|
44461
|
+
chars: info.chars,
|
|
44440
44462
|
toolPct: info.isTool ? 100 : 0,
|
|
44441
44463
|
textPct: info.isTool ? 0 : 100
|
|
44442
44464
|
};
|
|
@@ -44444,6 +44466,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
44444
44466
|
cur.endRef = info.ref;
|
|
44445
44467
|
cur.count++;
|
|
44446
44468
|
cur.tokens += info.tokens;
|
|
44469
|
+
cur.chars = (cur.chars ?? 0) + info.chars;
|
|
44447
44470
|
if (info.isTool) {
|
|
44448
44471
|
cur.toolPct = Math.round((cur.toolPct * (cur.count - 1) + 100) / cur.count);
|
|
44449
44472
|
} else {
|
|
@@ -44491,6 +44514,7 @@ function mergeBatch(batch) {
|
|
|
44491
44514
|
const last = batch[batch.length - 1];
|
|
44492
44515
|
const count = batch.reduce((s3, r) => s3 + r.count, 0);
|
|
44493
44516
|
const tokens = batch.reduce((s3, r) => s3 + r.tokens, 0);
|
|
44517
|
+
const chars = batch.reduce((s3, r) => s3 + rangeChars(r), 0);
|
|
44494
44518
|
const toolPct = Math.round(
|
|
44495
44519
|
batch.reduce((s3, r) => s3 + r.toolPct * r.count, 0) / count
|
|
44496
44520
|
);
|
|
@@ -44499,6 +44523,7 @@ function mergeBatch(batch) {
|
|
|
44499
44523
|
endRef: last.endRef,
|
|
44500
44524
|
count,
|
|
44501
44525
|
tokens,
|
|
44526
|
+
chars,
|
|
44502
44527
|
toolPct,
|
|
44503
44528
|
textPct: 100 - toolPct
|
|
44504
44529
|
};
|
|
@@ -44507,16 +44532,21 @@ function mergeBatch(batch) {
|
|
|
44507
44532
|
}
|
|
44508
44533
|
return merged;
|
|
44509
44534
|
}
|
|
44535
|
+
function rangeChars(r) {
|
|
44536
|
+
return r.chars ?? r.tokens * 4;
|
|
44537
|
+
}
|
|
44510
44538
|
function mergeRangesToThreshold(ranges, minChars) {
|
|
44511
44539
|
if (minChars <= 0 || ranges.length === 0) return ranges;
|
|
44512
44540
|
const result = [];
|
|
44513
44541
|
let batch = [];
|
|
44542
|
+
let batchChars = 0;
|
|
44514
44543
|
for (const r of ranges) {
|
|
44515
44544
|
batch.push(r);
|
|
44516
|
-
|
|
44517
|
-
if (
|
|
44545
|
+
batchChars += rangeChars(r);
|
|
44546
|
+
if (batchChars >= minChars) {
|
|
44518
44547
|
result.push(mergeBatch(batch));
|
|
44519
44548
|
batch = [];
|
|
44549
|
+
batchChars = 0;
|
|
44520
44550
|
}
|
|
44521
44551
|
}
|
|
44522
44552
|
if (batch.length > 0) {
|
|
@@ -45104,7 +45134,7 @@ function resolveAdaptiveGrowth(modelContextLimit, nudge) {
|
|
|
45104
45134
|
function pendingByTier(state, recommendation, countTokens, minCompressRange) {
|
|
45105
45135
|
const out = {};
|
|
45106
45136
|
const merged = recommendation?.recommendedRanges ?? [];
|
|
45107
|
-
const effective = minCompressRange > 0 ? merged.filter((r) => r.tokens * 4 >= minCompressRange) : merged;
|
|
45137
|
+
const effective = minCompressRange > 0 ? merged.filter((r) => (r.chars ?? r.tokens * 4) >= minCompressRange) : merged;
|
|
45108
45138
|
out[1] = { pending: effective.reduce((s3, r) => s3 + r.tokens, 0), targetBlocks: [] };
|
|
45109
45139
|
const active = activeBlocks(state);
|
|
45110
45140
|
const t1 = active.filter((b2) => b2.tier === 1);
|
|
@@ -45266,6 +45296,7 @@ function cloneState(state) {
|
|
|
45266
45296
|
byRaw: { ...state.messageRefs.byRaw },
|
|
45267
45297
|
byRef: { ...state.messageRefs.byRef }
|
|
45268
45298
|
},
|
|
45299
|
+
tokenSnapshot: { ...state.tokenSnapshot ?? {} },
|
|
45269
45300
|
nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
|
|
45270
45301
|
stats: { ...state.stats },
|
|
45271
45302
|
nextBlockId: state.nextBlockId,
|
|
@@ -46507,13 +46538,13 @@ function getUpstreamConnectionStatus() {
|
|
|
46507
46538
|
}
|
|
46508
46539
|
|
|
46509
46540
|
// src/config.ts
|
|
46510
|
-
function safeReadJson(
|
|
46541
|
+
function safeReadJson(path12) {
|
|
46511
46542
|
try {
|
|
46512
|
-
const raw = readFileSync(
|
|
46543
|
+
const raw = readFileSync(path12, "utf8").replace(/^\uFEFF/, "");
|
|
46513
46544
|
return JSON.parse(raw);
|
|
46514
46545
|
} catch (e) {
|
|
46515
46546
|
if (e.code !== "ENOENT") {
|
|
46516
|
-
log("error", `[acp-config] failed to parse ${
|
|
46547
|
+
log("error", `[acp-config] failed to parse ${path12}: ${String(e)}`);
|
|
46517
46548
|
}
|
|
46518
46549
|
return void 0;
|
|
46519
46550
|
}
|
|
@@ -46724,6 +46755,65 @@ function parsePromptCacheRouting(value) {
|
|
|
46724
46755
|
function parseUpstreamProxyMode(value) {
|
|
46725
46756
|
return value === "manual" || value === "auto" ? value : "direct";
|
|
46726
46757
|
}
|
|
46758
|
+
function parseCompressSettings(v2) {
|
|
46759
|
+
if (!v2 || typeof v2 !== "object" || Array.isArray(v2)) return void 0;
|
|
46760
|
+
const obj = v2;
|
|
46761
|
+
const out = {};
|
|
46762
|
+
const numberOrPercent = (value) => typeof value === "number" && Number.isFinite(value) || typeof value === "string" && /^\d+(\.\d+)?%$/.test(value.trim());
|
|
46763
|
+
let ok = true;
|
|
46764
|
+
const takeNumber = (key) => {
|
|
46765
|
+
if (!(key in obj)) return;
|
|
46766
|
+
if (typeof obj[key] !== "number" || !Number.isFinite(obj[key])) ok = false;
|
|
46767
|
+
else out[key] = obj[key];
|
|
46768
|
+
};
|
|
46769
|
+
for (const key of ["modelContextLimit", "maxContextLimit", "emergencyThresholdPercent"]) {
|
|
46770
|
+
if (!(key in obj)) continue;
|
|
46771
|
+
if (!numberOrPercent(obj[key])) {
|
|
46772
|
+
ok = false;
|
|
46773
|
+
continue;
|
|
46774
|
+
}
|
|
46775
|
+
out[key] = typeof obj[key] === "string" ? obj[key].trim() : obj[key];
|
|
46776
|
+
}
|
|
46777
|
+
for (const key of ["nudgeGrowthTokens", "preserveRecentMessages", "preserveRecentTokens", "minCompressRange"]) {
|
|
46778
|
+
takeNumber(key);
|
|
46779
|
+
}
|
|
46780
|
+
if ("tiers" in obj) {
|
|
46781
|
+
if (typeof obj.tiers !== "boolean") ok = false;
|
|
46782
|
+
else out.tiers = obj.tiers;
|
|
46783
|
+
}
|
|
46784
|
+
for (const key of ["injectTool", "injectNudge"]) {
|
|
46785
|
+
if (key in obj) {
|
|
46786
|
+
if (typeof obj[key] !== "boolean") ok = false;
|
|
46787
|
+
else out[key] = obj[key];
|
|
46788
|
+
}
|
|
46789
|
+
}
|
|
46790
|
+
if ("acknowledgePromptsRisk" in obj) {
|
|
46791
|
+
if (typeof obj.acknowledgePromptsRisk !== "boolean") ok = false;
|
|
46792
|
+
else out.acknowledgePromptsRisk = obj.acknowledgePromptsRisk;
|
|
46793
|
+
}
|
|
46794
|
+
if ("prompts" in obj && obj.prompts !== void 0) {
|
|
46795
|
+
const prompts = obj.prompts;
|
|
46796
|
+
if (!prompts || typeof prompts !== "object" || Array.isArray(prompts)) {
|
|
46797
|
+
ok = false;
|
|
46798
|
+
} else {
|
|
46799
|
+
const cleaned = {};
|
|
46800
|
+
for (const [key, value] of Object.entries(prompts)) {
|
|
46801
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
46802
|
+
ok = false;
|
|
46803
|
+
continue;
|
|
46804
|
+
}
|
|
46805
|
+
if (key !== "compressPhilosophy" && key !== "howToCompressRules" && key !== "tier2DistillRules" && key !== "tier3CondenseRules") {
|
|
46806
|
+
ok = false;
|
|
46807
|
+
continue;
|
|
46808
|
+
}
|
|
46809
|
+
cleaned[key] = value;
|
|
46810
|
+
}
|
|
46811
|
+
if (ok) out.prompts = cleaned;
|
|
46812
|
+
}
|
|
46813
|
+
}
|
|
46814
|
+
if (!ok) return void 0;
|
|
46815
|
+
return out;
|
|
46816
|
+
}
|
|
46727
46817
|
function rejectLegacyRoute(key, value) {
|
|
46728
46818
|
if (typeof value !== "string") return;
|
|
46729
46819
|
throw new Error(
|
|
@@ -46978,23 +47068,11 @@ async function fetchWithTimeout(url, opts, timeoutMs = UPSTREAM_TIMEOUT_MS, exte
|
|
|
46978
47068
|
}
|
|
46979
47069
|
}
|
|
46980
47070
|
|
|
46981
|
-
//
|
|
47071
|
+
// node_modules/acp-kernel/dist/wire/index.js
|
|
46982
47072
|
import { createHash } from "crypto";
|
|
46983
47073
|
function hashId(s3) {
|
|
46984
47074
|
return createHash("sha256").update(s3, "utf8").digest("hex").slice(0, 16);
|
|
46985
47075
|
}
|
|
46986
|
-
function safeJsonParse(s3) {
|
|
46987
|
-
try {
|
|
46988
|
-
return s3 ? JSON.parse(s3) : {};
|
|
46989
|
-
} catch {
|
|
46990
|
-
return {};
|
|
46991
|
-
}
|
|
46992
|
-
}
|
|
46993
|
-
function isLoopbackAddress(addr) {
|
|
46994
|
-
return !!addr && (addr.startsWith("127.") || addr === "::1" || addr.startsWith("::ffff:127."));
|
|
46995
|
-
}
|
|
46996
|
-
|
|
46997
|
-
// src/message-id.ts
|
|
46998
47076
|
function deriveMessageId(role, contentType, text, options = {}) {
|
|
46999
47077
|
const seed = `${role}|${contentType}|${options.toolCallId ?? ""}|${options.toolName ?? ""}|${text}`;
|
|
47000
47078
|
return "h_" + hashId(seed);
|
|
@@ -47007,8 +47085,6 @@ var ClusterCounter = class {
|
|
|
47007
47085
|
return n === 0 ? baseId : `${baseId}_${n}`;
|
|
47008
47086
|
}
|
|
47009
47087
|
};
|
|
47010
|
-
|
|
47011
|
-
// src/anthropic.ts
|
|
47012
47088
|
function extractSystem(system) {
|
|
47013
47089
|
if (!system) return "";
|
|
47014
47090
|
if (typeof system === "string") return system;
|
|
@@ -47174,15 +47250,11 @@ function safeParse(s3) {
|
|
|
47174
47250
|
return {};
|
|
47175
47251
|
}
|
|
47176
47252
|
}
|
|
47177
|
-
|
|
47178
|
-
// src/bili-message.ts
|
|
47179
47253
|
function parseDataUrl(url) {
|
|
47180
47254
|
const m2 = /^data:([^;,]+)(?:;base64)?,(.+)$/i.exec(url);
|
|
47181
47255
|
if (!m2) return void 0;
|
|
47182
47256
|
return { mediaType: m2[1], base64: m2[2] };
|
|
47183
47257
|
}
|
|
47184
|
-
|
|
47185
|
-
// src/openai.ts
|
|
47186
47258
|
function openaiToCore(body) {
|
|
47187
47259
|
const msgs = [];
|
|
47188
47260
|
const clusters = new ClusterCounter();
|
|
@@ -47361,8 +47433,6 @@ function firstImagePart(content) {
|
|
|
47361
47433
|
}
|
|
47362
47434
|
return void 0;
|
|
47363
47435
|
}
|
|
47364
|
-
|
|
47365
|
-
// src/responses.ts
|
|
47366
47436
|
var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set([
|
|
47367
47437
|
"additional_tools",
|
|
47368
47438
|
"mcp_list_tools"
|
|
@@ -47638,13 +47708,32 @@ function conversationIdentityResponses(body, headerValue2) {
|
|
|
47638
47708
|
function conversationSignalResponses(body, headerValue2) {
|
|
47639
47709
|
return conversationIdentityResponses(body, headerValue2).value;
|
|
47640
47710
|
}
|
|
47711
|
+
function createSubagentNamespaces() {
|
|
47712
|
+
const anchors = /* @__PURE__ */ new Map();
|
|
47713
|
+
return {
|
|
47714
|
+
namespaceFor(identityValue, instructions) {
|
|
47715
|
+
if (typeof instructions !== "string" || instructions.trim().length === 0) return identityValue;
|
|
47716
|
+
const fp = hashId(instructions);
|
|
47717
|
+
const anchor = anchors.get(identityValue);
|
|
47718
|
+
if (anchor === void 0) {
|
|
47719
|
+
anchors.set(identityValue, fp);
|
|
47720
|
+
return identityValue;
|
|
47721
|
+
}
|
|
47722
|
+
return anchor === fp ? identityValue : `${identityValue}|sub:${fp}`;
|
|
47723
|
+
}
|
|
47724
|
+
};
|
|
47725
|
+
}
|
|
47726
|
+
var defaultNamespaces = createSubagentNamespaces();
|
|
47727
|
+
function subagentNamespace(identityValue, instructions) {
|
|
47728
|
+
return defaultNamespaces.namespaceFor(identityValue, instructions);
|
|
47729
|
+
}
|
|
47641
47730
|
|
|
47642
47731
|
// src/persist.ts
|
|
47643
47732
|
import { promises as fs } from "fs";
|
|
47644
47733
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
47645
47734
|
import { createHash as createHash2 } from "crypto";
|
|
47646
47735
|
import * as path4 from "path";
|
|
47647
|
-
var PERSIST_VERSION =
|
|
47736
|
+
var PERSIST_VERSION = 3;
|
|
47648
47737
|
function mergeState(parsed) {
|
|
47649
47738
|
const fresh = createInitialState();
|
|
47650
47739
|
return {
|
|
@@ -47653,7 +47742,8 @@ function mergeState(parsed) {
|
|
|
47653
47742
|
nudge: { ...fresh.nudge, ...parsed.nudge ?? {} },
|
|
47654
47743
|
stats: { ...fresh.stats, ...parsed.stats ?? {} },
|
|
47655
47744
|
nextBlockId: parsed.nextBlockId ?? fresh.nextBlockId,
|
|
47656
|
-
nextRunId: parsed.nextRunId ?? fresh.nextRunId
|
|
47745
|
+
nextRunId: parsed.nextRunId ?? fresh.nextRunId,
|
|
47746
|
+
tokenSnapshot: parsed.tokenSnapshot ?? fresh.tokenSnapshot
|
|
47657
47747
|
};
|
|
47658
47748
|
}
|
|
47659
47749
|
function hostLabel(upstreamOrigin) {
|
|
@@ -47913,6 +48003,7 @@ function buildRecord(session) {
|
|
|
47913
48003
|
id: session.id,
|
|
47914
48004
|
meta: { ...session.meta },
|
|
47915
48005
|
stats: { ...session.stats },
|
|
48006
|
+
messages: session.lastMessages,
|
|
47916
48007
|
metadata: { ...session.metadata },
|
|
47917
48008
|
state: session.state,
|
|
47918
48009
|
blockContents: Object.fromEntries(session.blockContents),
|
|
@@ -47949,6 +48040,7 @@ function buildSession(parsed) {
|
|
|
47949
48040
|
createdAt: parsed.createdAt ?? Date.now(),
|
|
47950
48041
|
lastSeen: Date.now(),
|
|
47951
48042
|
blockContents,
|
|
48043
|
+
lastMessages: Array.isArray(parsed.messages) ? parsed.messages : void 0,
|
|
47952
48044
|
inFlight: 0,
|
|
47953
48045
|
persisted: true
|
|
47954
48046
|
};
|
|
@@ -48084,6 +48176,9 @@ async function withSessionLock(session, fn) {
|
|
|
48084
48176
|
function listSessions() {
|
|
48085
48177
|
return [...sessions.values()].sort((a, b2) => b2.lastSeen - a.lastSeen);
|
|
48086
48178
|
}
|
|
48179
|
+
function snapshotMessages(session, messages) {
|
|
48180
|
+
if (messages.length > 0) session.lastMessages = messages;
|
|
48181
|
+
}
|
|
48087
48182
|
function markDirty(session) {
|
|
48088
48183
|
getStore().scheduleSave(session);
|
|
48089
48184
|
}
|
|
@@ -48608,16 +48703,17 @@ function busy(button,on,label){if(!button)return;if(on){button.dataset.label=but
|
|
|
48608
48703
|
async function json(url,options){const response=await fetch(url,options);const data=await response.json().catch(()=>({}));if(!response.ok)throw new Error(data.error||data.detail||("HTTP "+response.status));return data}
|
|
48609
48704
|
function showPage(name){document.querySelectorAll(".page").forEach((node)=>node.classList.toggle("active",node.id==="page-"+name));document.querySelectorAll(".nav button").forEach((node)=>node.classList.toggle("active",node.dataset.page===name));if(name==="sessions")loadSessions();if(name==="upstream"){loadUpstream();loadOverrides()}}
|
|
48610
48705
|
document.querySelectorAll(".nav button").forEach((button)=>button.addEventListener("click",()=>showPage(button.dataset.page)));
|
|
48611
|
-
async function loadConfig(){const data=await json("/__bili/config");byId("providers-json").value=JSON.stringify(data.providers||{},null,2);byId("proxy-url").value=data.upstreamProxy||"";document.querySelectorAll('input[name="proxy-mode"]').forEach((input)=>input.checked=input.value===(data.upstreamProxyMode||"direct"));return data}
|
|
48706
|
+
async function loadConfig(){const data=await json("/__bili/config");byId("providers-json").value=JSON.stringify(data.providers||{},null,2);byId("proxy-url").value=data.upstreamProxy||"";byId("compress-json").value=data.compress?JSON.stringify(data.compress,null,2):"";document.querySelectorAll('input[name="proxy-mode"]').forEach((input)=>input.checked=input.value===(data.upstreamProxyMode||"direct"));return data}
|
|
48612
48707
|
async function loadUpstream(){try{const data=await json("/__bili/upstream");const labels={"provider":"Provider \u5355\u72EC\u4EE3\u7406","provider-direct":"Provider \u76F4\u8FDE","bili-env":"BILI_UPSTREAM_PROXY","web-manual":"Web \u624B\u52A8\u4EE3\u7406","config":"\u914D\u7F6E\u6587\u4EF6\u4EE3\u7406","HTTPS_PROXY":"HTTPS_PROXY","HTTP_PROXY":"HTTP_PROXY","ALL_PROXY":"ALL_PROXY","windows-system":"Windows \u7CFB\u7EDF\u4EE3\u7406","windows-bypass":"Windows \u7ED5\u8FC7\u5217\u8868","no-proxy":"NO_PROXY","direct":"\u76F4\u8FDE"};byId("upstream-source").textContent=labels[data.source]||data.source||"\u76F4\u8FDE";byId("upstream-effective").textContent=data.proxy||"direct";byId("upstream-pac").textContent=data.autoConfigUrl||"\u2014";const state=byId("upstream-state");state.className="status "+(data.connected===true?"ok":data.connected===false?"err":"");state.textContent=data.connected===true?"CONNECT \u6B63\u5E38":data.connected===false?(data.error||"\u8FDE\u63A5\u5931\u8D25"):"\u5C1A\u672A\u89C2\u5BDF\u5230\u4E0A\u6E38\u8FDE\u63A5"}catch(error){byId("upstream-state").textContent=String(error)}}
|
|
48613
48708
|
async function saveUpstream(){const button=byId("save-upstream");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");const mode=document.querySelector('input[name="proxy-mode"]:checked').value;try{await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({upstreamProxyMode:mode,upstreamProxy:byId("proxy-url").value.trim()||null})});toast("\u4E0A\u6E38\u8BBE\u7F6E\u5DF2\u70ED\u66F4\u65B0");await loadUpstream()}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
48614
48709
|
async function testUpstream(){const button=byId("test-upstream");busy(button,true,"\u6D4B\u8BD5\u4E2D\u2026");try{const data=await json("/__bili/upstream/test",{method:"POST"});toast("\u8FDE\u63A5\u6210\u529F\uFF0CHTTP "+data.status);await loadUpstream()}catch(error){toast(String(error),true);await loadUpstream()}finally{busy(button,false)}}
|
|
48615
48710
|
async function saveProviders(){const button=byId("save-providers");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");try{const providers=JSON.parse(byId("providers-json").value);await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({providers})});await json("/__bili/config/reload",{method:"POST"});toast("Provider \u914D\u7F6E\u5DF2\u70ED\u66F4\u65B0")}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
48711
|
+
async function saveCompress(){const button=byId("save-compress");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");try{const text=byId("compress-json").value.trim();const compress=text?JSON.parse(text):null;await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({compress})});toast("\u538B\u7F29\u53C2\u6570\u5DF2\u70ED\u66F4\u65B0")}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
48616
48712
|
async function loadOverrides(){try{const data=await loadConfig();const providers=data.providers||{};const box=byId("upstream-overrides");const entries=Object.entries(providers);if(entries.length===0){box.innerHTML='<p class="status">\u6682\u65E0 Provider\u3002\u5728"\u9AD8\u7EA7\u8BBE\u7F6E"\u9875\u6DFB\u52A0 Provider \u540E\u53EF\u5728\u6B64\u6309 URL \u914D\u7F6E\u4EE3\u7406\u3002</p>';return}box.innerHTML='<table><thead><tr><th>Provider URL</th><th>\u4E0A\u6E38\u4EE3\u7406\uFF08\u7A7A=\u7EE7\u627F\u5168\u5C40\uFF09</th></tr></thead><tbody>'+entries.map(([url,route])=>'<tr><td class="mono">'+escapeHtml(url)+'</td><td><input class="mono override-proxy" data-url="'+escapeHtml(url)+'" value="'+escapeHtml((route&&route.proxy)||"")+'" placeholder="\u7EE7\u627F\u5168\u5C40"></td></tr>').join("")+'</tbody></table>'}catch(error){byId("upstream-overrides").textContent=String(error)}}
|
|
48617
48713
|
async function saveOverrides(){const button=byId("save-overrides");busy(button,true,"\u4FDD\u5B58\u4E2D\u2026");try{const data=await loadConfig();const providers=data.providers||{};document.querySelectorAll(".override-proxy").forEach((input)=>{const url=input.dataset.url;if(!url)return;if(!providers[url])providers[url]={};const val=input.value.trim();if(val)providers[url].proxy=val;else delete providers[url].proxy});await json("/__bili/config",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({providers})});await json("/__bili/config/reload",{method:"POST"});toast("\u6309 URL \u8986\u76D6\u5DF2\u70ED\u66F4\u65B0");await loadOverrides()}catch(error){toast(String(error),true)}finally{busy(button,false)}}
|
|
48618
48714
|
async function loadSessions(){try{const data=await json("/__bili/stats");const rows=(data.sessions||[]).map((item)=>"<tr><td>"+escapeHtml(item.title||"\u2014")+"</td><td>"+escapeHtml(item.protocol||"\u2014")+"</td><td class=mono>"+escapeHtml(item.label||"\u2014")+"</td><td>"+escapeHtml(item.requests)+"</td><td>"+escapeHtml(item.contextTokens)+"</td><td>"+escapeHtml(new Date(item.lastSeen).toLocaleString())+"</td></tr>").join("");byId("sessions-body").innerHTML=rows||'<tr><td colspan="6">\u6682\u65E0\u4F1A\u8BDD</td></tr>'}catch(error){toast(String(error),true);throw error}}
|
|
48619
48715
|
async function refreshSessions(){const button=byId("refresh-sessions");busy(button,true,"\u5237\u65B0\u4E2D\u2026");try{await loadSessions();toast("\u4F1A\u8BDD\u5217\u8868\u5DF2\u5237\u65B0")}catch{}finally{busy(button,false)}}
|
|
48620
|
-
document.querySelectorAll(".copy-btn").forEach((btn)=>btn.addEventListener("click",async()=>{busy(btn,true,"\u590D\u5236\u4E2D\u2026");try{await navigator.clipboard.writeText(btn.dataset.copy||"");toast("\u5DF2\u590D\u5236")}catch(e){toast(String(e),true)}finally{busy(btn,false)}}));byId("save-upstream").addEventListener("click",saveUpstream);byId("test-upstream").addEventListener("click",testUpstream);byId("save-providers").addEventListener("click",saveProviders);byId("save-overrides").addEventListener("click",saveOverrides);byId("refresh-sessions").addEventListener("click",refreshSessions);
|
|
48716
|
+
document.querySelectorAll(".copy-btn").forEach((btn)=>btn.addEventListener("click",async()=>{busy(btn,true,"\u590D\u5236\u4E2D\u2026");try{await navigator.clipboard.writeText(btn.dataset.copy||"");toast("\u5DF2\u590D\u5236")}catch(e){toast(String(e),true)}finally{busy(btn,false)}}));byId("save-upstream").addEventListener("click",saveUpstream);byId("test-upstream").addEventListener("click",testUpstream);byId("save-providers").addEventListener("click",saveProviders);byId("save-compress").addEventListener("click",saveCompress);byId("save-overrides").addEventListener("click",saveOverrides);byId("refresh-sessions").addEventListener("click",refreshSessions);
|
|
48621
48717
|
Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),true));setInterval(()=>{if(byId("page-sessions").classList.contains("active"))loadSessions().catch(()=>{})},5000);
|
|
48622
48718
|
`;
|
|
48623
48719
|
|
|
@@ -48648,7 +48744,7 @@ function renderPage(origin, version2) {
|
|
|
48648
48744
|
<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>
|
|
48649
48745
|
<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>
|
|
48650
48746
|
<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>
|
|
48651
|
-
<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></section></main></div><div id="toast" class="toast"></div><script>${WEB_CLIENT}</script></body></html>`;
|
|
48747
|
+
<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>`;
|
|
48652
48748
|
}
|
|
48653
48749
|
|
|
48654
48750
|
// src/web/api.ts
|
|
@@ -48693,12 +48789,14 @@ function atomicWriteConfig(config) {
|
|
|
48693
48789
|
}
|
|
48694
48790
|
async function handleConfigGet(res) {
|
|
48695
48791
|
const upstream = readUpstreamSettings();
|
|
48792
|
+
const config = readConfig();
|
|
48696
48793
|
res.writeHead(200, { "content-type": "application/json" });
|
|
48697
48794
|
res.end(JSON.stringify({
|
|
48698
48795
|
path: configFile(),
|
|
48699
48796
|
providers: readProviders(),
|
|
48700
48797
|
upstreamProxy: upstream.proxy ?? null,
|
|
48701
|
-
upstreamProxyMode: upstream.mode
|
|
48798
|
+
upstreamProxyMode: upstream.mode,
|
|
48799
|
+
compress: config.compress ?? null
|
|
48702
48800
|
}, null, 2));
|
|
48703
48801
|
}
|
|
48704
48802
|
async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
@@ -48708,7 +48806,8 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48708
48806
|
const hasProviders = Object.prototype.hasOwnProperty.call(body, "providers");
|
|
48709
48807
|
const hasProxy = Object.prototype.hasOwnProperty.call(body, "upstreamProxy");
|
|
48710
48808
|
const hasMode = Object.prototype.hasOwnProperty.call(body, "upstreamProxyMode");
|
|
48711
|
-
|
|
48809
|
+
const hasCompress = Object.prototype.hasOwnProperty.call(body, "compress");
|
|
48810
|
+
if (!hasProviders && !hasProxy && !hasMode && !hasCompress) return sendError(res, 400, "expected providers, upstream proxy, or compress settings");
|
|
48712
48811
|
const routes = {};
|
|
48713
48812
|
if (hasProviders) {
|
|
48714
48813
|
if (!body.providers || typeof body.providers !== "object" || Array.isArray(body.providers)) {
|
|
@@ -48747,6 +48846,11 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48747
48846
|
if (mode === "manual" && !proxy && !readUpstreamSettings().proxy) {
|
|
48748
48847
|
return sendError(res, 400, "manual mode requires an upstream proxy URL");
|
|
48749
48848
|
}
|
|
48849
|
+
let compress;
|
|
48850
|
+
if (hasCompress) {
|
|
48851
|
+
compress = body.compress === null ? {} : parseCompressSettings(body.compress);
|
|
48852
|
+
if (compress === void 0) return sendError(res, 400, "invalid compress settings");
|
|
48853
|
+
}
|
|
48750
48854
|
const config = readConfig();
|
|
48751
48855
|
if (hasProviders) config.providers = routes;
|
|
48752
48856
|
if (hasProxy) {
|
|
@@ -48754,13 +48858,21 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48754
48858
|
else delete config.upstreamProxy;
|
|
48755
48859
|
}
|
|
48756
48860
|
if (hasMode && mode) config.upstreamProxyMode = mode;
|
|
48861
|
+
if (hasCompress) {
|
|
48862
|
+
if (compress && Object.keys(compress).length > 0) config.compress = compress;
|
|
48863
|
+
else delete config.compress;
|
|
48864
|
+
}
|
|
48757
48865
|
try {
|
|
48758
48866
|
atomicWriteConfig(config);
|
|
48759
48867
|
onChanged?.();
|
|
48760
48868
|
} catch (error) {
|
|
48761
48869
|
return sendError(res, 500, `failed to apply config: ${String(error)}`);
|
|
48762
48870
|
}
|
|
48763
|
-
|
|
48871
|
+
const changed = [];
|
|
48872
|
+
if (hasProviders) changed.push(`${Object.keys(routes).length} routes`);
|
|
48873
|
+
if (hasProxy || hasMode) changed.push("network");
|
|
48874
|
+
if (hasCompress) changed.push("compress");
|
|
48875
|
+
log("info", `[acp-web] configuration updated (${changed.join(", ") || "none"})`);
|
|
48764
48876
|
res.writeHead(200, { "content-type": "application/json" });
|
|
48765
48877
|
res.end(JSON.stringify({ ok: true, providers: hasProviders ? Object.keys(routes).length : void 0 }));
|
|
48766
48878
|
}
|
|
@@ -50240,6 +50352,22 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
50240
50352
|
return current;
|
|
50241
50353
|
}
|
|
50242
50354
|
|
|
50355
|
+
// src/util.ts
|
|
50356
|
+
import { createHash as createHash3 } from "crypto";
|
|
50357
|
+
function hashId2(s3) {
|
|
50358
|
+
return createHash3("sha256").update(s3, "utf8").digest("hex").slice(0, 16);
|
|
50359
|
+
}
|
|
50360
|
+
function safeJsonParse(s3) {
|
|
50361
|
+
try {
|
|
50362
|
+
return s3 ? JSON.parse(s3) : {};
|
|
50363
|
+
} catch {
|
|
50364
|
+
return {};
|
|
50365
|
+
}
|
|
50366
|
+
}
|
|
50367
|
+
function isLoopbackAddress(addr) {
|
|
50368
|
+
return !!addr && (addr.startsWith("127.") || addr === "::1" || addr.startsWith("::ffff:127."));
|
|
50369
|
+
}
|
|
50370
|
+
|
|
50243
50371
|
// src/stream-openai.ts
|
|
50244
50372
|
function rewriteOpenaiJsonResponse(body, ctx) {
|
|
50245
50373
|
if (!body || typeof body !== "object") return body;
|
|
@@ -50408,7 +50536,7 @@ function clientConversationHeader(headers) {
|
|
|
50408
50536
|
function deriveSessionId(headers, protocol, upstream, conversation) {
|
|
50409
50537
|
if (!conversation) throw new Error("deriveSessionId: conversation dimension is required (pass the conversationSignal* output)");
|
|
50410
50538
|
const key = extractKey(headers);
|
|
50411
|
-
return
|
|
50539
|
+
return hashId2(`${protocol}|${upstream}|${key}|${conversation}`);
|
|
50412
50540
|
}
|
|
50413
50541
|
function affinityToken(identity) {
|
|
50414
50542
|
return identity.clientProvided ? identity.value : void 0;
|
|
@@ -50424,13 +50552,50 @@ import path5 from "path";
|
|
|
50424
50552
|
import tls2 from "tls";
|
|
50425
50553
|
var ROOT_CERT_FILE = "root-ca.pem";
|
|
50426
50554
|
var ROOT_KEY_FILE = "root-ca-key.pem";
|
|
50555
|
+
var COMBINED_CA_FILE = "combined-ca.pem";
|
|
50427
50556
|
var ROOT_CN = "billion-context MITM Root CA";
|
|
50557
|
+
var PLATFORM_CA_CANDIDATES = process.platform === "darwin" ? ["/etc/ssl/cert.pem", "/private/etc/ssl/cert.pem"] : [
|
|
50558
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
|
50559
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
50560
|
+
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
|
50561
|
+
"/etc/ssl/ca-bundle.pem",
|
|
50562
|
+
"/etc/ssl/cert.pem"
|
|
50563
|
+
];
|
|
50428
50564
|
var rootCertPem;
|
|
50429
50565
|
var rootKeyPem;
|
|
50430
50566
|
var rootCert;
|
|
50431
50567
|
var rootKey;
|
|
50432
50568
|
var secureContextCache = /* @__PURE__ */ new Map();
|
|
50433
50569
|
var SECURE_CONTEXT_CACHE_MAX = 64;
|
|
50570
|
+
function collectSystemCaPems(env = process.env) {
|
|
50571
|
+
const pems = [];
|
|
50572
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50573
|
+
const pushFile = (file) => {
|
|
50574
|
+
try {
|
|
50575
|
+
const text = fs2.readFileSync(file, "utf8");
|
|
50576
|
+
if (!text.includes("BEGIN CERTIFICATE") || seen.has(text)) return false;
|
|
50577
|
+
seen.add(text);
|
|
50578
|
+
pems.push(text);
|
|
50579
|
+
return true;
|
|
50580
|
+
} catch {
|
|
50581
|
+
}
|
|
50582
|
+
return false;
|
|
50583
|
+
};
|
|
50584
|
+
const userBundle = env.SSL_CERT_FILE?.trim();
|
|
50585
|
+
if (userBundle && pushFile(userBundle)) return pems;
|
|
50586
|
+
for (const candidate of PLATFORM_CA_CANDIDATES) {
|
|
50587
|
+
if (pushFile(candidate)) break;
|
|
50588
|
+
}
|
|
50589
|
+
return pems;
|
|
50590
|
+
}
|
|
50591
|
+
function writeCombinedBundle() {
|
|
50592
|
+
const certs = /* @__PURE__ */ new Set();
|
|
50593
|
+
for (const pem of collectSystemCaPems()) certs.add(pem.trim());
|
|
50594
|
+
for (const pem of tls2.rootCertificates) certs.add(pem.trim());
|
|
50595
|
+
certs.add(rootCertPem.trim());
|
|
50596
|
+
const body = [...certs].map((pem) => pem.endsWith("\n") ? pem : pem + "\n").join("");
|
|
50597
|
+
fs2.writeFileSync(path5.join(caDir(), COMBINED_CA_FILE), body, { mode: 420 });
|
|
50598
|
+
}
|
|
50434
50599
|
function generateRootCA() {
|
|
50435
50600
|
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
50436
50601
|
const cert = import_node_forge.default.pki.createCertificate();
|
|
@@ -50457,7 +50622,10 @@ function generateRootCA() {
|
|
|
50457
50622
|
};
|
|
50458
50623
|
}
|
|
50459
50624
|
function ensureRootCA() {
|
|
50460
|
-
if (rootCertPem && rootKeyPem)
|
|
50625
|
+
if (rootCertPem && rootKeyPem) {
|
|
50626
|
+
writeCombinedBundle();
|
|
50627
|
+
return;
|
|
50628
|
+
}
|
|
50461
50629
|
const dir = caDir();
|
|
50462
50630
|
fs2.mkdirSync(dir, { recursive: true });
|
|
50463
50631
|
const certPath = path5.join(dir, ROOT_CERT_FILE);
|
|
@@ -50467,6 +50635,7 @@ function ensureRootCA() {
|
|
|
50467
50635
|
rootKeyPem = fs2.readFileSync(keyPath, "utf8");
|
|
50468
50636
|
rootCert = import_node_forge.default.pki.certificateFromPem(rootCertPem);
|
|
50469
50637
|
rootKey = import_node_forge.default.pki.privateKeyFromPem(rootKeyPem);
|
|
50638
|
+
writeCombinedBundle();
|
|
50470
50639
|
return;
|
|
50471
50640
|
}
|
|
50472
50641
|
const { cert, key } = generateRootCA();
|
|
@@ -50476,6 +50645,7 @@ function ensureRootCA() {
|
|
|
50476
50645
|
rootKeyPem = key;
|
|
50477
50646
|
rootCert = import_node_forge.default.pki.certificateFromPem(cert);
|
|
50478
50647
|
rootKey = import_node_forge.default.pki.privateKeyFromPem(key);
|
|
50648
|
+
writeCombinedBundle();
|
|
50479
50649
|
}
|
|
50480
50650
|
function getSecureContext(host) {
|
|
50481
50651
|
if (!rootCertPem || !rootKeyPem || !rootCert || !rootKey) {
|
|
@@ -51794,6 +51964,7 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
51794
51964
|
opts.proxyMode = fresh.proxyMode;
|
|
51795
51965
|
opts.proxySource = fresh.proxySource;
|
|
51796
51966
|
opts.proxyFallback = fresh.proxyFallback;
|
|
51967
|
+
opts.compress = fresh.compress;
|
|
51797
51968
|
resetProxyCache();
|
|
51798
51969
|
for (const k2 of Object.keys(opts.routes)) delete opts.routes[k2];
|
|
51799
51970
|
Object.assign(opts.routes, loadRoutes());
|
|
@@ -51938,7 +52109,10 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
51938
52109
|
const clientConv = clientConversationHeader(req.headers);
|
|
51939
52110
|
const convHeader = clientConv ?? sessionHeader;
|
|
51940
52111
|
const responsesIdentity = protocol === "responses" ? conversationIdentityResponses(parsed, convHeader) : void 0;
|
|
51941
|
-
const conversation = protocol === "anthropic" ? conversationSignalAnthropic(parsed, convHeader) : protocol === "openai" ? conversationSignalOpenai(parsed, convHeader) :
|
|
52112
|
+
const conversation = protocol === "anthropic" ? conversationSignalAnthropic(parsed, convHeader) : protocol === "openai" ? conversationSignalOpenai(parsed, convHeader) : subagentNamespace(
|
|
52113
|
+
responsesIdentity?.value ?? conversationSignalResponses(parsed, convHeader),
|
|
52114
|
+
parsed.instructions
|
|
52115
|
+
);
|
|
51942
52116
|
const sessionId = deriveSessionId(req.headers, protocol, upstreamOrigin, conversation);
|
|
51943
52117
|
const affinity = affinityToken(responsesIdentity ?? {
|
|
51944
52118
|
value: clientConv ?? conversation,
|
|
@@ -51979,7 +52153,7 @@ function diagTagSummary(messages, sessionId, strategy) {
|
|
|
51979
52153
|
}
|
|
51980
52154
|
return `[${sessionId}] processTurn: ${messages.length} msgs, renderTags=${strategy}, ${textTagged} text tagged, ${toolTagged} tool tagged (should be 0 with text-only)`;
|
|
51981
52155
|
}
|
|
51982
|
-
function diagNudge(turn, sessionId, tokenCount, limit) {
|
|
52156
|
+
function diagNudge(turn, sessionId, tokenCount, limit, model) {
|
|
51983
52157
|
const n = turn.nudge;
|
|
51984
52158
|
if (!n) return `[${sessionId}] nudge: unavailable`;
|
|
51985
52159
|
const b2 = n.breakdown ?? {};
|
|
@@ -51990,7 +52164,8 @@ function diagNudge(turn, sessionId, tokenCount, limit) {
|
|
|
51990
52164
|
const pendingT1 = b2["pendingT1"] ?? 0;
|
|
51991
52165
|
const ref = b2["growthReference"] ?? 0;
|
|
51992
52166
|
const inject = n.shouldInject ? `INJECT T${n.tier ?? "?"}` : "idle";
|
|
51993
|
-
|
|
52167
|
+
const modelTag = model ? ` model=${model}` : "";
|
|
52168
|
+
return `[${sessionId}] nudge ${inject}: usage=${pct2} (${tokenCount}/${limit}), growth=${growth}/${floor} (ref=${ref}, interval=${interval}), pendingT1=${pendingT1}/${interval}${modelTag}, reason="${n.reason.slice(0, 120)}"`;
|
|
51994
52169
|
}
|
|
51995
52170
|
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session) {
|
|
51996
52171
|
const sessionId = session.id;
|
|
@@ -52016,7 +52191,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52016
52191
|
if (t) session.meta.title = t;
|
|
52017
52192
|
}
|
|
52018
52193
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52019
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52194
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52020
52195
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52021
52196
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52022
52197
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
@@ -52037,6 +52212,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52037
52212
|
log2("warn", `[${sessionId}] kernel transform failed, forwarding unchanged: ${String(err2)}`);
|
|
52038
52213
|
processedMessages = [];
|
|
52039
52214
|
}
|
|
52215
|
+
snapshotMessages(session, originalMessages);
|
|
52040
52216
|
markDirty(session);
|
|
52041
52217
|
const rebuilt = { ...parsed, messages: rebuiltMessages, system: systemOut, tools: toolsOut };
|
|
52042
52218
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: opts.compress.injectTool, nudge, prompts };
|
|
@@ -52066,7 +52242,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session)
|
|
|
52066
52242
|
if (t) session.meta.title = t;
|
|
52067
52243
|
}
|
|
52068
52244
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52069
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52245
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52070
52246
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52071
52247
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52072
52248
|
rebuiltMessages = coreToOpenai(processedMessages);
|
|
@@ -52093,6 +52269,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session)
|
|
|
52093
52269
|
if (stream2 && rebuilt.stream_options === void 0) {
|
|
52094
52270
|
rebuilt.stream_options = { include_usage: true };
|
|
52095
52271
|
}
|
|
52272
|
+
snapshotMessages(session, originalMessages);
|
|
52096
52273
|
markDirty(session);
|
|
52097
52274
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: shouldInject, nudge, prompts };
|
|
52098
52275
|
}
|
|
@@ -52129,7 +52306,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52129
52306
|
if (t) session.meta.title = t;
|
|
52130
52307
|
}
|
|
52131
52308
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52132
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52309
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52133
52310
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52134
52311
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52135
52312
|
rebuiltInput = patchResponsesInput(projection, processedMessages);
|
|
@@ -52176,6 +52353,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52176
52353
|
});
|
|
52177
52354
|
log2("info", `[${sessionId}] responses forward tools=[${fwdTools.join(",")}] injectTool=${shouldInject} NO_INJECT_TOOL=${!!process.env.ACP_NO_INJECT_TOOL} NO_COMPRESS_PROMPT=${!!process.env.ACP_NO_COMPRESS_PROMPT}`);
|
|
52178
52355
|
}
|
|
52356
|
+
snapshotMessages(session, originalMessages);
|
|
52179
52357
|
markDirty(session);
|
|
52180
52358
|
return {
|
|
52181
52359
|
body: JSON.stringify(rebuilt),
|
|
@@ -52572,10 +52750,10 @@ async function pipeThrough(stream2, res) {
|
|
|
52572
52750
|
}
|
|
52573
52751
|
}
|
|
52574
52752
|
async function dumpStreamToFile(stream2, dir, name) {
|
|
52575
|
-
const { mkdirSync:
|
|
52753
|
+
const { mkdirSync: mkdirSync7, createWriteStream: createWriteStream2 } = await import("fs");
|
|
52576
52754
|
const { join: join4 } = await import("path");
|
|
52577
52755
|
try {
|
|
52578
|
-
|
|
52756
|
+
mkdirSync7(dir, { recursive: true });
|
|
52579
52757
|
const ws2 = createWriteStream2(join4(dir, name));
|
|
52580
52758
|
ws2.on("error", (e) => {
|
|
52581
52759
|
log("debug", `[dump] write stream error: ${e.message ?? e}`);
|
|
@@ -52606,6 +52784,7 @@ function handleConfigReload(opts, res, log2) {
|
|
|
52606
52784
|
const fresh = loadRoutes();
|
|
52607
52785
|
for (const k2 of Object.keys(opts.routes)) delete opts.routes[k2];
|
|
52608
52786
|
Object.assign(opts.routes, fresh);
|
|
52787
|
+
opts.compress = loadOptions().compress;
|
|
52609
52788
|
resetProxyCache();
|
|
52610
52789
|
const names = Object.keys(fresh);
|
|
52611
52790
|
log2("info", `[acp-web] routes hot-reloaded (${names.length} providers): ${names.join(", ") || "(none)"}`);
|
|
@@ -56008,6 +56187,10 @@ function resolveCaCertPath(env) {
|
|
|
56008
56187
|
const base = env.XDG_DATA_HOME || path9.join(os4.homedir(), ".local/share");
|
|
56009
56188
|
return path9.join(base, "billion-context", "ca", "root-ca.pem");
|
|
56010
56189
|
}
|
|
56190
|
+
function resolveCombinedCaPath(env) {
|
|
56191
|
+
const base = env.XDG_DATA_HOME || path9.join(os4.homedir(), ".local/share");
|
|
56192
|
+
return path9.join(base, "billion-context", "ca", "combined-ca.pem");
|
|
56193
|
+
}
|
|
56011
56194
|
function discoverRoutes(client, config) {
|
|
56012
56195
|
const httpsDomains = [];
|
|
56013
56196
|
const httpRewrites = [];
|
|
@@ -56337,7 +56520,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
56337
56520
|
piTmpHome = preparePiHttpRewrite(resolvePiHome(process.env), handle2.origin, routes.httpRewrites, routes.httpsRewrites);
|
|
56338
56521
|
if (piTmpHome) env.PI_CODING_AGENT_DIR = piTmpHome;
|
|
56339
56522
|
} else if (base === "codex") {
|
|
56340
|
-
env = buildCodexEnv(handle2.origin,
|
|
56523
|
+
env = buildCodexEnv(handle2.origin, resolveCombinedCaPath(process.env), process.env);
|
|
56341
56524
|
clientArgs = buildCodexArgs(handle2.origin, routes.httpRewrites, routes.httpsRewrites, params.clientArgs);
|
|
56342
56525
|
} else {
|
|
56343
56526
|
env = buildClaudeEnv(handle2.origin, ca, routes.httpRewrites, routes.httpsRewrites, process.env);
|
|
@@ -56409,14 +56592,155 @@ async function runTestPi(params, deps = {}) {
|
|
|
56409
56592
|
process.exit(code ?? 0);
|
|
56410
56593
|
}
|
|
56411
56594
|
|
|
56595
|
+
// src/export.ts
|
|
56596
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
56597
|
+
import path10 from "path";
|
|
56598
|
+
function fmtDate(ms2) {
|
|
56599
|
+
return ms2 ? new Date(ms2).toISOString().replace("T", " ").slice(0, 19) + " UTC" : "\u2014";
|
|
56600
|
+
}
|
|
56601
|
+
async function listSessions2(opts = {}) {
|
|
56602
|
+
const store = new SessionStore({ dir: opts.dir, enabled: true });
|
|
56603
|
+
const sessions2 = [...(await store.loadAll()).values()];
|
|
56604
|
+
sessions2.sort((a, b2) => latestBlockTime(b2) - latestBlockTime(a));
|
|
56605
|
+
return sessions2.map((s3) => ({
|
|
56606
|
+
id: s3.id,
|
|
56607
|
+
title: s3.meta.title,
|
|
56608
|
+
label: s3.meta.label,
|
|
56609
|
+
protocol: s3.meta.protocol,
|
|
56610
|
+
upstreamOrigin: s3.meta.upstreamOrigin,
|
|
56611
|
+
savedAt: latestBlockTime(s3) || void 0,
|
|
56612
|
+
contextTokens: s3.stats.contextTokens,
|
|
56613
|
+
blocks: s3.state.blocks.length
|
|
56614
|
+
}));
|
|
56615
|
+
}
|
|
56616
|
+
function latestBlockTime(s3) {
|
|
56617
|
+
let latest = 0;
|
|
56618
|
+
for (const b2 of s3.state.blocks) if (b2.createdAt > latest) latest = b2.createdAt;
|
|
56619
|
+
return latest;
|
|
56620
|
+
}
|
|
56621
|
+
function renderHandoff(s3, full) {
|
|
56622
|
+
const lines = [];
|
|
56623
|
+
lines.push(`# billion-context session handoff`);
|
|
56624
|
+
lines.push("");
|
|
56625
|
+
lines.push(`- title: ${s3.meta.title ?? "(untitled)"}`);
|
|
56626
|
+
if (s3.meta.label) lines.push(`- label: ${s3.meta.label}`);
|
|
56627
|
+
lines.push(`- session id: ${s3.id}`);
|
|
56628
|
+
if (s3.meta.protocol) lines.push(`- protocol: ${s3.meta.protocol}`);
|
|
56629
|
+
if (s3.meta.upstreamOrigin) lines.push(`- upstream: ${s3.meta.upstreamOrigin}`);
|
|
56630
|
+
lines.push(`- requests: ${s3.stats.requests}`);
|
|
56631
|
+
if (s3.stats.contextTokens) lines.push(`- last context tokens: ~${s3.stats.contextTokens}`);
|
|
56632
|
+
lines.push(`- compression blocks: ${s3.state.blocks.length} (active ${s3.state.blocks.filter((b2) => b2.active).length})`);
|
|
56633
|
+
lines.push("");
|
|
56634
|
+
const messages = s3.lastMessages;
|
|
56635
|
+
if (messages && messages.length > 0) {
|
|
56636
|
+
lines.push(full ? `## Full conversation (${messages.length} messages)` : `## Conversation (folded view as the model saw it, ${messages.length} client messages)`);
|
|
56637
|
+
lines.push("");
|
|
56638
|
+
let lastRole = "";
|
|
56639
|
+
const view = full ? messages : prune(messages, s3.state);
|
|
56640
|
+
for (const m2 of view) {
|
|
56641
|
+
if (m2.role !== lastRole) {
|
|
56642
|
+
lines.push(`### ${m2.role}`);
|
|
56643
|
+
lines.push("");
|
|
56644
|
+
lastRole = m2.role;
|
|
56645
|
+
}
|
|
56646
|
+
lines.push(renderMessage2(m2));
|
|
56647
|
+
}
|
|
56648
|
+
lines.push("");
|
|
56649
|
+
return lines.join("\n");
|
|
56650
|
+
}
|
|
56651
|
+
const active = s3.state.blocks.filter((b2) => b2.active);
|
|
56652
|
+
if (active.length === 0) {
|
|
56653
|
+
lines.push("No active compression blocks and no persisted conversation snapshot (v2 session file). Original messages are only persisted when they are compressed into a block, so this session's conversation content is not available for export.");
|
|
56654
|
+
lines.push("");
|
|
56655
|
+
}
|
|
56656
|
+
for (const b2 of active) {
|
|
56657
|
+
lines.push(`## Block ${b2.blockId}${b2.topic ? ` \u2014 ${b2.topic}` : ""}`);
|
|
56658
|
+
lines.push("");
|
|
56659
|
+
lines.push(`tier ${b2.tier} \xB7 ~${b2.compressedTokens} tokens compressed \xB7 ${fmtDate(b2.createdAt)}`);
|
|
56660
|
+
lines.push("");
|
|
56661
|
+
lines.push(b2.summary.trim());
|
|
56662
|
+
lines.push("");
|
|
56663
|
+
const content = s3.blockContents.get(b2.blockId);
|
|
56664
|
+
if (full && content) {
|
|
56665
|
+
lines.push(`### Original messages (${content.full.count})`);
|
|
56666
|
+
lines.push("");
|
|
56667
|
+
lines.push(content.full.text.trim());
|
|
56668
|
+
lines.push("");
|
|
56669
|
+
}
|
|
56670
|
+
}
|
|
56671
|
+
if (active.length > 0) {
|
|
56672
|
+
lines.push("---");
|
|
56673
|
+
lines.push("");
|
|
56674
|
+
lines.push("Paste the block summaries above into a new session to continue without the proxy.");
|
|
56675
|
+
lines.push("");
|
|
56676
|
+
}
|
|
56677
|
+
return lines.join("\n");
|
|
56678
|
+
}
|
|
56679
|
+
function renderMessage2(m2) {
|
|
56680
|
+
const parts = [];
|
|
56681
|
+
switch (m2.contentType) {
|
|
56682
|
+
case "text":
|
|
56683
|
+
parts.push(m2.text ?? "");
|
|
56684
|
+
break;
|
|
56685
|
+
case "tool-call":
|
|
56686
|
+
parts.push(`\`${m2.toolName ?? "?"}(${m2.toolCallId ?? ""})\` args: ${m2.text ?? ""}`);
|
|
56687
|
+
break;
|
|
56688
|
+
case "tool-result":
|
|
56689
|
+
parts.push(`\`${m2.toolName ?? "?"}(${m2.toolCallId ?? ""})\` \u2192 ${m2.text ?? ""}`);
|
|
56690
|
+
break;
|
|
56691
|
+
case "reasoning":
|
|
56692
|
+
parts.push(`_reasoning_: ${m2.text ?? ""}`);
|
|
56693
|
+
break;
|
|
56694
|
+
}
|
|
56695
|
+
const body = parts.join("\n").trim();
|
|
56696
|
+
return body === "" ? "_(empty)_" : body + "\n";
|
|
56697
|
+
}
|
|
56698
|
+
function matchSession(sessions2, selector) {
|
|
56699
|
+
const exact = sessions2.filter((s3) => s3.id === selector);
|
|
56700
|
+
if (exact.length > 0) return exact;
|
|
56701
|
+
const byLabel = sessions2.filter((s3) => s3.meta.label === selector);
|
|
56702
|
+
if (byLabel.length > 0) return byLabel;
|
|
56703
|
+
const byPrefix = sessions2.filter((s3) => s3.id.startsWith(selector) || (s3.meta.label ?? "").startsWith(selector));
|
|
56704
|
+
return byPrefix;
|
|
56705
|
+
}
|
|
56706
|
+
async function exportSession(selector, opts = {}) {
|
|
56707
|
+
const store = new SessionStore({ dir: opts.dir, enabled: true });
|
|
56708
|
+
const all = [...(await store.loadAll()).values()];
|
|
56709
|
+
if (all.length === 0) {
|
|
56710
|
+
return "No persisted sessions found. Sessions are written under the sessions directory once the proxy has served a request (compression state and compressed originals only \u2014 uncompressed conversation text is not persisted).";
|
|
56711
|
+
}
|
|
56712
|
+
if (!selector) {
|
|
56713
|
+
const list = await listSessions2(opts);
|
|
56714
|
+
const rows = list.map(
|
|
56715
|
+
(s3) => `${s3.id}${s3.label ? ` label=${s3.label}` : ""}${s3.protocol ? ` [${s3.protocol}]` : ""} blocks=${s3.blocks}${s3.contextTokens ? ` ctx~${s3.contextTokens}` : ""} ${s3.title ?? ""}`
|
|
56716
|
+
);
|
|
56717
|
+
return ["Persisted sessions:", "", ...rows.map((r) => ` ${r}`), "", "Usage: bili export <session-id|label> [--output handoff.md] [--full]"].join("\n");
|
|
56718
|
+
}
|
|
56719
|
+
const matches = matchSession(all, selector);
|
|
56720
|
+
if (matches.length === 0) {
|
|
56721
|
+
throw new Error(`no session matches "${selector}" (run "bili export" to list sessions)`);
|
|
56722
|
+
}
|
|
56723
|
+
if (matches.length > 1) {
|
|
56724
|
+
const ids = matches.map((s3) => s3.id).join(", ");
|
|
56725
|
+
throw new Error(`selector "${selector}" matches ${matches.length} sessions (${ids}); use the full session id`);
|
|
56726
|
+
}
|
|
56727
|
+
const markdown = renderHandoff(matches[0], opts.full ?? false);
|
|
56728
|
+
if (opts.output) {
|
|
56729
|
+
mkdirSync6(path10.dirname(path10.resolve(opts.output)), { recursive: true });
|
|
56730
|
+
writeFileSync5(opts.output, markdown, "utf8");
|
|
56731
|
+
return `written to ${opts.output}`;
|
|
56732
|
+
}
|
|
56733
|
+
return markdown;
|
|
56734
|
+
}
|
|
56735
|
+
|
|
56412
56736
|
// src/cli.ts
|
|
56413
56737
|
import { readFileSync as readFileSync5 } from "fs";
|
|
56414
56738
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
56415
|
-
import
|
|
56739
|
+
import path11 from "path";
|
|
56416
56740
|
var VERSION = (() => {
|
|
56417
56741
|
try {
|
|
56418
56742
|
const here = fileURLToPath3(import.meta.url);
|
|
56419
|
-
const pkg =
|
|
56743
|
+
const pkg = path11.join(path11.dirname(here), "..", "package.json");
|
|
56420
56744
|
return JSON.parse(readFileSync5(pkg, "utf8")).version ?? "dev";
|
|
56421
56745
|
} catch {
|
|
56422
56746
|
return "dev";
|
|
@@ -56425,7 +56749,7 @@ var VERSION = (() => {
|
|
|
56425
56749
|
var PACKAGE_NAME = (() => {
|
|
56426
56750
|
try {
|
|
56427
56751
|
const here = fileURLToPath3(import.meta.url);
|
|
56428
|
-
const pkg =
|
|
56752
|
+
const pkg = path11.join(path11.dirname(here), "..", "package.json");
|
|
56429
56753
|
return JSON.parse(readFileSync5(pkg, "utf8")).name ?? "billion-context";
|
|
56430
56754
|
} catch {
|
|
56431
56755
|
return "billion-context";
|
|
@@ -56440,6 +56764,8 @@ Usage:
|
|
|
56440
56764
|
bili codex [opts --] [args] start a proxy + launch codex against it (cert-MITM)
|
|
56441
56765
|
bili claude [opts --] [args] start a proxy + launch claude against it (cert-MITM)
|
|
56442
56766
|
bili test pi non-polluting pi smoke test through the proxy
|
|
56767
|
+
bili export [session] [--full] list sessions / export one as a Markdown handoff
|
|
56768
|
+
(--full includes original messages; --output FILE)
|
|
56443
56769
|
bili update check for & install a newer version now
|
|
56444
56770
|
bili --version print version
|
|
56445
56771
|
bili --help show this help
|
|
@@ -56482,6 +56808,9 @@ function parseArgs(argv) {
|
|
|
56482
56808
|
let client;
|
|
56483
56809
|
let clientArgs = [];
|
|
56484
56810
|
const mitmDomains = [];
|
|
56811
|
+
let exportSelector;
|
|
56812
|
+
let exportOutput;
|
|
56813
|
+
let exportFull = false;
|
|
56485
56814
|
for (let i = 0; i < argv.length; i++) {
|
|
56486
56815
|
const a = argv[i];
|
|
56487
56816
|
if (!client && positional.length === 0 && isLaunchClient(a)) {
|
|
@@ -56519,6 +56848,18 @@ function parseArgs(argv) {
|
|
|
56519
56848
|
mitmDomains.push(val);
|
|
56520
56849
|
break;
|
|
56521
56850
|
}
|
|
56851
|
+
case "--full":
|
|
56852
|
+
exportFull = true;
|
|
56853
|
+
break;
|
|
56854
|
+
case "--output": {
|
|
56855
|
+
const val = argv[++i];
|
|
56856
|
+
if (val === void 0) {
|
|
56857
|
+
console.error(`bili: ${a} requires a value`);
|
|
56858
|
+
process.exit(2);
|
|
56859
|
+
}
|
|
56860
|
+
exportOutput = val;
|
|
56861
|
+
break;
|
|
56862
|
+
}
|
|
56522
56863
|
case "--port":
|
|
56523
56864
|
case "--host":
|
|
56524
56865
|
case "--config": {
|
|
@@ -56554,6 +56895,9 @@ function parseArgs(argv) {
|
|
|
56554
56895
|
command = command === "help" || command === "version" ? command : "start";
|
|
56555
56896
|
} else if (cmd === "update") {
|
|
56556
56897
|
command = "update";
|
|
56898
|
+
} else if (cmd === "export") {
|
|
56899
|
+
command = "export";
|
|
56900
|
+
exportSelector = positional[1];
|
|
56557
56901
|
} else if (cmd === "test") {
|
|
56558
56902
|
const target = positional[1];
|
|
56559
56903
|
if (target && isLaunchClient(target)) {
|
|
@@ -56568,10 +56912,10 @@ function parseArgs(argv) {
|
|
|
56568
56912
|
process.exit(2);
|
|
56569
56913
|
}
|
|
56570
56914
|
}
|
|
56571
|
-
return { command, client, clientArgs, mitmDomains, overrides };
|
|
56915
|
+
return { command, client, clientArgs, mitmDomains, overrides, exportSelector, exportOutput, exportFull };
|
|
56572
56916
|
}
|
|
56573
56917
|
async function main() {
|
|
56574
|
-
const { command, client, clientArgs, mitmDomains, overrides } = parseArgs(process.argv.slice(2));
|
|
56918
|
+
const { command, client, clientArgs, mitmDomains, overrides, exportSelector, exportOutput, exportFull } = parseArgs(process.argv.slice(2));
|
|
56575
56919
|
if (command === "help") {
|
|
56576
56920
|
process.stdout.write(HELP);
|
|
56577
56921
|
return;
|
|
@@ -56580,6 +56924,16 @@ async function main() {
|
|
|
56580
56924
|
process.stdout.write(VERSION + "\n");
|
|
56581
56925
|
return;
|
|
56582
56926
|
}
|
|
56927
|
+
if (command === "export") {
|
|
56928
|
+
try {
|
|
56929
|
+
const text = await exportSession(exportSelector, { output: exportOutput, full: exportFull });
|
|
56930
|
+
process.stdout.write(text + "\n");
|
|
56931
|
+
} catch (error) {
|
|
56932
|
+
console.error(`bili export: ${error instanceof Error ? error.message : String(error)}`);
|
|
56933
|
+
process.exit(1);
|
|
56934
|
+
}
|
|
56935
|
+
return;
|
|
56936
|
+
}
|
|
56583
56937
|
if (command === "update") {
|
|
56584
56938
|
await checkForUpdate({ packageName: PACKAGE_NAME, currentVersion: VERSION, autoUpdate: true }, true);
|
|
56585
56939
|
return;
|