billion-context 0.1.42 → 0.1.44
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 +99 -1
- package/README.zh-CN.md +15 -0
- package/dist/index.js +1882 -554
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +159 -0
- package/dist/mcp.js.map +1 -0
- 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 path14 = 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 (path14 && path14[0] !== "/") {
|
|
1149
|
+
path14 = `/${path14}`;
|
|
1150
1150
|
}
|
|
1151
|
-
return new URL(`${origin}${
|
|
1151
|
+
return new URL(`${origin}${path14}`);
|
|
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: path14, origin }
|
|
1973
1973
|
} = evt;
|
|
1974
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
1974
|
+
debugLog("sending request to %s %s%s", method, origin, path14);
|
|
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: path14, 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
|
+
path14,
|
|
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: path14, origin }
|
|
2009
2009
|
} = evt;
|
|
2010
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
2010
|
+
debugLog("trailers received from %s %s%s", method, origin, path14);
|
|
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: path14, 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
|
+
path14,
|
|
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: path14,
|
|
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 path14 !== "string") {
|
|
2157
2157
|
throw new InvalidArgumentError("path must be a string");
|
|
2158
|
-
} else if (
|
|
2158
|
+
} else if (path14[0] !== "/" && !(path14.startsWith("http://") || path14.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(path14)) {
|
|
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(path14, query) : path14;
|
|
2236
2236
|
this.origin = origin;
|
|
2237
2237
|
this.protocol = getProtocolFromUrlString(origin);
|
|
2238
2238
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -6068,20 +6068,20 @@ var require_formdata_parser = __commonJS({
|
|
|
6068
6068
|
);
|
|
6069
6069
|
let value;
|
|
6070
6070
|
if (isExtended) {
|
|
6071
|
-
const
|
|
6071
|
+
const headerValue3 = collectASequenceOfBytes(
|
|
6072
6072
|
(char) => char !== 32 && char !== 13 && char !== 10 && char !== 59,
|
|
6073
6073
|
// not space, CRLF, or ;
|
|
6074
6074
|
input,
|
|
6075
6075
|
position
|
|
6076
6076
|
);
|
|
6077
|
-
if (
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6077
|
+
if (headerValue3[0] !== 117 && headerValue3[0] !== 85 || // u or U
|
|
6078
|
+
headerValue3[1] !== 116 && headerValue3[1] !== 84 || // t or T
|
|
6079
|
+
headerValue3[2] !== 102 && headerValue3[2] !== 70 || // f or F
|
|
6080
|
+
headerValue3[3] !== 45 || // -
|
|
6081
|
+
headerValue3[4] !== 56) {
|
|
6082
6082
|
throw parsingError("unknown encoding, expected utf-8''");
|
|
6083
6083
|
}
|
|
6084
|
-
value = decodeURIComponent(decoder.decode(
|
|
6084
|
+
value = decodeURIComponent(decoder.decode(headerValue3.subarray(7)));
|
|
6085
6085
|
} else if (input[position.position] === 34) {
|
|
6086
6086
|
position.position++;
|
|
6087
6087
|
const quotedValue = collectASequenceOfBytes(
|
|
@@ -6170,23 +6170,23 @@ var require_formdata_parser = __commonJS({
|
|
|
6170
6170
|
break;
|
|
6171
6171
|
}
|
|
6172
6172
|
case "content-type": {
|
|
6173
|
-
let
|
|
6173
|
+
let headerValue3 = collectASequenceOfBytes(
|
|
6174
6174
|
(char) => char !== 10 && char !== 13,
|
|
6175
6175
|
input,
|
|
6176
6176
|
position
|
|
6177
6177
|
);
|
|
6178
|
-
|
|
6179
|
-
contentType = isomorphicDecode(
|
|
6178
|
+
headerValue3 = removeChars(headerValue3, false, true, (char) => char === 9 || char === 32);
|
|
6179
|
+
contentType = isomorphicDecode(headerValue3);
|
|
6180
6180
|
break;
|
|
6181
6181
|
}
|
|
6182
6182
|
case "content-transfer-encoding": {
|
|
6183
|
-
let
|
|
6183
|
+
let headerValue3 = collectASequenceOfBytes(
|
|
6184
6184
|
(char) => char !== 10 && char !== 13,
|
|
6185
6185
|
input,
|
|
6186
6186
|
position
|
|
6187
6187
|
);
|
|
6188
|
-
|
|
6189
|
-
encoding = isomorphicDecode(
|
|
6188
|
+
headerValue3 = removeChars(headerValue3, false, true, (char) => char === 9 || char === 32);
|
|
6189
|
+
encoding = isomorphicDecode(headerValue3);
|
|
6190
6190
|
break;
|
|
6191
6191
|
}
|
|
6192
6192
|
default: {
|
|
@@ -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: path14, 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} ${path14} 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: path14, 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] = path14;
|
|
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] = path14;
|
|
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: path14 = "/",
|
|
10602
10602
|
headers = {}
|
|
10603
10603
|
} = opts;
|
|
10604
|
-
opts.path = origin +
|
|
10604
|
+
opts.path = origin + path14;
|
|
10605
10605
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
10606
10606
|
const { host } = new URL(origin);
|
|
10607
10607
|
headers.host = host;
|
|
@@ -12612,8 +12612,8 @@ var require_mock_utils = __commonJS({
|
|
|
12612
12612
|
}
|
|
12613
12613
|
function lowerCaseEntries(headers) {
|
|
12614
12614
|
return Object.fromEntries(
|
|
12615
|
-
Object.entries(headers).map(([headerName,
|
|
12616
|
-
return [headerName.toLocaleLowerCase(),
|
|
12615
|
+
Object.entries(headers).map(([headerName, headerValue3]) => {
|
|
12616
|
+
return [headerName.toLocaleLowerCase(), headerValue3];
|
|
12617
12617
|
})
|
|
12618
12618
|
);
|
|
12619
12619
|
}
|
|
@@ -12653,8 +12653,8 @@ var require_mock_utils = __commonJS({
|
|
|
12653
12653
|
return false;
|
|
12654
12654
|
}
|
|
12655
12655
|
for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch2.headers)) {
|
|
12656
|
-
const
|
|
12657
|
-
if (!matchValue(matchHeaderValue,
|
|
12656
|
+
const headerValue3 = getHeaderByName(headers, matchHeaderName);
|
|
12657
|
+
if (!matchValue(matchHeaderValue, headerValue3)) {
|
|
12658
12658
|
return false;
|
|
12659
12659
|
}
|
|
12660
12660
|
}
|
|
@@ -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(path14) {
|
|
12688
|
+
if (typeof path14 !== "string") {
|
|
12689
|
+
return path14;
|
|
12690
12690
|
}
|
|
12691
|
-
const pathSegments =
|
|
12691
|
+
const pathSegments = path14.split("?", 3);
|
|
12692
12692
|
if (pathSegments.length !== 2) {
|
|
12693
|
-
return
|
|
12693
|
+
return path14;
|
|
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: path14, method, body, headers }) {
|
|
12700
|
+
const pathMatch = matchValue(mockDispatch2.path, path14);
|
|
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: path14, ignoreTrailingSlash }) => {
|
|
12726
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path14)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path14), 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(path14) {
|
|
12766
|
+
while (path14.endsWith("/")) {
|
|
12767
|
+
path14 = path14.slice(0, -1);
|
|
12768
12768
|
}
|
|
12769
|
-
if (
|
|
12770
|
-
|
|
12769
|
+
if (path14.length === 0) {
|
|
12770
|
+
path14 = "/";
|
|
12771
12771
|
}
|
|
12772
|
-
return
|
|
12772
|
+
return path14;
|
|
12773
12773
|
}
|
|
12774
12774
|
function buildKey(opts) {
|
|
12775
|
-
const { path:
|
|
12775
|
+
const { path: path14, method, body, headers, query } = opts;
|
|
12776
12776
|
return {
|
|
12777
|
-
path:
|
|
12777
|
+
path: path14,
|
|
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: path14, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
13468
13468
|
Method: method,
|
|
13469
13469
|
Origin: origin,
|
|
13470
|
-
Path:
|
|
13470
|
+
Path: path14,
|
|
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 [path14, searchParams] = dispatchOpts.path.split("?");
|
|
13553
13553
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
13554
|
-
dispatchOpts.path = `${
|
|
13554
|
+
dispatchOpts.path = `${path14}?${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 path14 = filePath || this.#snapshotPath;
|
|
13956
|
+
if (!path14) {
|
|
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(path14), "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 ${path14}`, { 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 path14 = filePath || this.#snapshotPath;
|
|
13986
|
+
if (!path14) {
|
|
13987
13987
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
13988
13988
|
}
|
|
13989
|
-
const resolvedPath = resolve(
|
|
13989
|
+
const resolvedPath = resolve(path14);
|
|
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 path14 = search ? `${pathname}${search}` : pathname;
|
|
14622
|
+
const redirectUrlString = `${origin}${path14}`;
|
|
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 = path14;
|
|
14630
14630
|
this.opts.origin = origin;
|
|
14631
14631
|
this.opts.query = null;
|
|
14632
14632
|
}
|
|
@@ -15748,8 +15748,8 @@ var require_cache = __commonJS({
|
|
|
15748
15748
|
if (!isValidHTTPToken(trimmedHeader)) {
|
|
15749
15749
|
return void 0;
|
|
15750
15750
|
}
|
|
15751
|
-
const
|
|
15752
|
-
output[trimmedHeader] = Array.isArray(
|
|
15751
|
+
const headerValue3 = headers[trimmedHeader];
|
|
15752
|
+
output[trimmedHeader] = Array.isArray(headerValue3) ? headerValue3.slice() : headerValue3 ?? null;
|
|
15753
15753
|
}
|
|
15754
15754
|
return output;
|
|
15755
15755
|
}
|
|
@@ -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, path14) {
|
|
16399
16399
|
deleteCachedValue(store, {
|
|
16400
16400
|
...cacheKey,
|
|
16401
|
-
path:
|
|
16401
|
+
path: path14
|
|
16402
16402
|
});
|
|
16403
16403
|
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
16404
16404
|
const method = util.safeHTTPMethods[i];
|
|
@@ -16406,20 +16406,20 @@ var require_cache_handler = __commonJS({
|
|
|
16406
16406
|
deleteCachedValue(store, {
|
|
16407
16407
|
...cacheKey,
|
|
16408
16408
|
method,
|
|
16409
|
-
path:
|
|
16409
|
+
path: path14
|
|
16410
16410
|
});
|
|
16411
16411
|
}
|
|
16412
16412
|
}
|
|
16413
16413
|
}
|
|
16414
|
-
function deleteLocationTargets(store, cacheKey,
|
|
16415
|
-
if (
|
|
16414
|
+
function deleteLocationTargets(store, cacheKey, headerValue3) {
|
|
16415
|
+
if (headerValue3 === void 0) {
|
|
16416
16416
|
return;
|
|
16417
16417
|
}
|
|
16418
|
-
const values = Array.isArray(
|
|
16418
|
+
const values = Array.isArray(headerValue3) ? headerValue3 : [headerValue3];
|
|
16419
16419
|
for (let i = 0; i < values.length; i++) {
|
|
16420
|
-
const
|
|
16421
|
-
if (
|
|
16422
|
-
deleteCachedUri(store, cacheKey,
|
|
16420
|
+
const path14 = getSameOriginPath(cacheKey, values[i]);
|
|
16421
|
+
if (path14 !== void 0) {
|
|
16422
|
+
deleteCachedUri(store, cacheKey, path14);
|
|
16423
16423
|
}
|
|
16424
16424
|
}
|
|
16425
16425
|
}
|
|
@@ -18206,7 +18206,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18206
18206
|
var { Writable } = __require("stream");
|
|
18207
18207
|
var { assertCacheKey, assertCacheValue } = require_cache();
|
|
18208
18208
|
var DatabaseSync;
|
|
18209
|
-
var
|
|
18209
|
+
var VERSION4 = 3;
|
|
18210
18210
|
var MAX_ENTRY_SIZE = 2 * 1e3 * 1e3 * 1e3;
|
|
18211
18211
|
module.exports = class SqliteCacheStore {
|
|
18212
18212
|
#maxEntrySize = MAX_ENTRY_SIZE;
|
|
@@ -18277,7 +18277,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18277
18277
|
PRAGMA temp_store = memory;
|
|
18278
18278
|
PRAGMA optimize;
|
|
18279
18279
|
|
|
18280
|
-
CREATE TABLE IF NOT EXISTS cacheInterceptorV${
|
|
18280
|
+
CREATE TABLE IF NOT EXISTS cacheInterceptorV${VERSION4} (
|
|
18281
18281
|
-- Data specific to us
|
|
18282
18282
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18283
18283
|
url TEXT NOT NULL,
|
|
@@ -18296,8 +18296,8 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18296
18296
|
staleAt INTEGER NOT NULL
|
|
18297
18297
|
);
|
|
18298
18298
|
|
|
18299
|
-
CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${
|
|
18300
|
-
CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${
|
|
18299
|
+
CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${VERSION4}_getValuesQuery ON cacheInterceptorV${VERSION4}(url, method, deleteAt);
|
|
18300
|
+
CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${VERSION4}_deleteByUrlQuery ON cacheInterceptorV${VERSION4}(deleteAt);
|
|
18301
18301
|
`);
|
|
18302
18302
|
this.#getValuesQuery = this.#db.prepare(`
|
|
18303
18303
|
SELECT
|
|
@@ -18312,7 +18312,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18312
18312
|
vary,
|
|
18313
18313
|
cachedAt,
|
|
18314
18314
|
staleAt
|
|
18315
|
-
FROM cacheInterceptorV${
|
|
18315
|
+
FROM cacheInterceptorV${VERSION4}
|
|
18316
18316
|
WHERE
|
|
18317
18317
|
url = ?
|
|
18318
18318
|
AND method = ?
|
|
@@ -18320,7 +18320,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18320
18320
|
deleteAt ASC
|
|
18321
18321
|
`);
|
|
18322
18322
|
this.#updateValueQuery = this.#db.prepare(`
|
|
18323
|
-
UPDATE cacheInterceptorV${
|
|
18323
|
+
UPDATE cacheInterceptorV${VERSION4} SET
|
|
18324
18324
|
body = ?,
|
|
18325
18325
|
deleteAt = ?,
|
|
18326
18326
|
statusCode = ?,
|
|
@@ -18334,7 +18334,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18334
18334
|
id = ?
|
|
18335
18335
|
`);
|
|
18336
18336
|
this.#insertValueQuery = this.#db.prepare(`
|
|
18337
|
-
INSERT INTO cacheInterceptorV${
|
|
18337
|
+
INSERT INTO cacheInterceptorV${VERSION4} (
|
|
18338
18338
|
url,
|
|
18339
18339
|
method,
|
|
18340
18340
|
body,
|
|
@@ -18350,20 +18350,20 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
18350
18350
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
18351
18351
|
`);
|
|
18352
18352
|
this.#deleteByUrlQuery = this.#db.prepare(
|
|
18353
|
-
`DELETE FROM cacheInterceptorV${
|
|
18353
|
+
`DELETE FROM cacheInterceptorV${VERSION4} WHERE url = ?`
|
|
18354
18354
|
);
|
|
18355
18355
|
this.#countEntriesQuery = this.#db.prepare(
|
|
18356
|
-
`SELECT COUNT(*) AS total FROM cacheInterceptorV${
|
|
18356
|
+
`SELECT COUNT(*) AS total FROM cacheInterceptorV${VERSION4}`
|
|
18357
18357
|
);
|
|
18358
18358
|
this.#deleteExpiredValuesQuery = this.#db.prepare(
|
|
18359
|
-
`DELETE FROM cacheInterceptorV${
|
|
18359
|
+
`DELETE FROM cacheInterceptorV${VERSION4} WHERE deleteAt <= ?`
|
|
18360
18360
|
);
|
|
18361
18361
|
this.#deleteOldValuesQuery = this.#maxCount === Infinity ? null : this.#db.prepare(`
|
|
18362
|
-
DELETE FROM cacheInterceptorV${
|
|
18362
|
+
DELETE FROM cacheInterceptorV${VERSION4}
|
|
18363
18363
|
WHERE id IN (
|
|
18364
18364
|
SELECT
|
|
18365
18365
|
id
|
|
18366
|
-
FROM cacheInterceptorV${
|
|
18366
|
+
FROM cacheInterceptorV${VERSION4}
|
|
18367
18367
|
ORDER BY cachedAt ASC
|
|
18368
18368
|
LIMIT ?
|
|
18369
18369
|
)
|
|
@@ -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 path14 = 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 ? `${path14}?` : path14,
|
|
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(path14) {
|
|
22252
|
+
for (let i = 0; i < path14.length; ++i) {
|
|
22253
|
+
const code = path14.charCodeAt(i);
|
|
22254
22254
|
if (code < 32 || // exclude CTLs (0-31)
|
|
22255
22255
|
code > 126 || // exclude DEL and non-ascii
|
|
22256
22256
|
code === 59) {
|
|
@@ -23096,8 +23096,8 @@ var require_util5 = __commonJS({
|
|
|
23096
23096
|
return false;
|
|
23097
23097
|
}
|
|
23098
23098
|
}
|
|
23099
|
-
const
|
|
23100
|
-
return
|
|
23099
|
+
const num2 = Number.parseInt(value, 10);
|
|
23100
|
+
return num2 >= 8 && num2 <= 15;
|
|
23101
23101
|
}
|
|
23102
23102
|
function getURLRecord(url, baseURL) {
|
|
23103
23103
|
let urlRecord;
|
|
@@ -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 path14 = opts.path;
|
|
25491
25491
|
if (!opts.path.startsWith("/")) {
|
|
25492
|
-
|
|
25492
|
+
path14 = `/${path14}`;
|
|
25493
25493
|
}
|
|
25494
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
25494
|
+
url = new URL(util.parseOrigin(url).origin + path14);
|
|
25495
25495
|
} else {
|
|
25496
25496
|
if (!opts) {
|
|
25497
25497
|
opts = typeof url === "object" ? url : {};
|
|
@@ -25523,14 +25523,14 @@ var require_undici = __commonJS({
|
|
|
25523
25523
|
if (stack && (stack.includes(filename) || stack.includes(normalizedFilename))) {
|
|
25524
25524
|
return;
|
|
25525
25525
|
}
|
|
25526
|
-
const
|
|
25527
|
-
Error.captureStackTrace(
|
|
25528
|
-
if (!
|
|
25526
|
+
const capture2 = {};
|
|
25527
|
+
Error.captureStackTrace(capture2, appendFetchStackTrace);
|
|
25528
|
+
if (!capture2.stack) {
|
|
25529
25529
|
return;
|
|
25530
25530
|
}
|
|
25531
|
-
const captureLines =
|
|
25531
|
+
const captureLines = capture2.stack.split("\n").slice(1).join("\n");
|
|
25532
25532
|
err2.stack = stack ? `${stack}
|
|
25533
|
-
${captureLines}` :
|
|
25533
|
+
${captureLines}` : capture2.stack;
|
|
25534
25534
|
}
|
|
25535
25535
|
module.exports.fetch = function fetch2(init, options = void 0) {
|
|
25536
25536
|
return fetchImpl(init, options).catch((err2) => {
|
|
@@ -26930,11 +26930,11 @@ var require_util7 = __commonJS({
|
|
|
26930
26930
|
}
|
|
26931
26931
|
var b2 = util.createBuffer();
|
|
26932
26932
|
for (var i = 0; i < ip.length; ++i) {
|
|
26933
|
-
var
|
|
26934
|
-
if (isNaN(
|
|
26933
|
+
var num2 = parseInt(ip[i], 10);
|
|
26934
|
+
if (isNaN(num2)) {
|
|
26935
26935
|
return null;
|
|
26936
26936
|
}
|
|
26937
|
-
b2.putByte(
|
|
26937
|
+
b2.putByte(num2);
|
|
26938
26938
|
}
|
|
26939
26939
|
return b2.getBytes();
|
|
26940
26940
|
};
|
|
@@ -27873,8 +27873,8 @@ var require_cipherModes = __commonJS({
|
|
|
27873
27873
|
function inc32(block) {
|
|
27874
27874
|
block[block.length - 1] = block[block.length - 1] + 1 & 4294967295;
|
|
27875
27875
|
}
|
|
27876
|
-
function from64To32(
|
|
27877
|
-
return [
|
|
27876
|
+
function from64To32(num2) {
|
|
27877
|
+
return [num2 / 4294967296 | 0, num2 & 4294967295];
|
|
27878
27878
|
}
|
|
27879
27879
|
}
|
|
27880
27880
|
});
|
|
@@ -28859,7 +28859,7 @@ var require_asn1 = __commonJS({
|
|
|
28859
28859
|
}
|
|
28860
28860
|
return bytes.getSignedInt(n);
|
|
28861
28861
|
};
|
|
28862
|
-
asn1.validate = function(obj, v2,
|
|
28862
|
+
asn1.validate = function(obj, v2, capture2, errors) {
|
|
28863
28863
|
var rval = false;
|
|
28864
28864
|
if ((obj.tagClass === v2.tagClass || typeof v2.tagClass === "undefined") && (obj.type === v2.type || typeof v2.type === "undefined")) {
|
|
28865
28865
|
if (obj.constructed === v2.constructed || typeof v2.constructed === "undefined") {
|
|
@@ -28892,7 +28892,7 @@ var require_asn1 = __commonJS({
|
|
|
28892
28892
|
break;
|
|
28893
28893
|
}
|
|
28894
28894
|
}
|
|
28895
|
-
var childRval = asn1.validate(objChild, schemaItem,
|
|
28895
|
+
var childRval = asn1.validate(objChild, schemaItem, capture2, errors);
|
|
28896
28896
|
if (childRval) {
|
|
28897
28897
|
++j2;
|
|
28898
28898
|
rval = true;
|
|
@@ -28904,20 +28904,20 @@ var require_asn1 = __commonJS({
|
|
|
28904
28904
|
}
|
|
28905
28905
|
}
|
|
28906
28906
|
}
|
|
28907
|
-
if (rval &&
|
|
28907
|
+
if (rval && capture2) {
|
|
28908
28908
|
if (v2.capture) {
|
|
28909
|
-
|
|
28909
|
+
capture2[v2.capture] = obj.value;
|
|
28910
28910
|
}
|
|
28911
28911
|
if (v2.captureAsn1) {
|
|
28912
|
-
|
|
28912
|
+
capture2[v2.captureAsn1] = obj;
|
|
28913
28913
|
}
|
|
28914
28914
|
if (v2.captureBitStringContents && "bitStringContents" in obj) {
|
|
28915
|
-
|
|
28915
|
+
capture2[v2.captureBitStringContents] = obj.bitStringContents;
|
|
28916
28916
|
}
|
|
28917
28917
|
if (v2.captureBitStringValue && "bitStringContents" in obj) {
|
|
28918
28918
|
var value;
|
|
28919
28919
|
if (obj.bitStringContents.length < 2) {
|
|
28920
|
-
|
|
28920
|
+
capture2[v2.captureBitStringValue] = "";
|
|
28921
28921
|
} else {
|
|
28922
28922
|
var unused = obj.bitStringContents.charCodeAt(0);
|
|
28923
28923
|
if (unused !== 0) {
|
|
@@ -28925,7 +28925,7 @@ var require_asn1 = __commonJS({
|
|
|
28925
28925
|
"captureBitStringValue only supported for zero unused bits"
|
|
28926
28926
|
);
|
|
28927
28927
|
}
|
|
28928
|
-
|
|
28928
|
+
capture2[v2.captureBitStringValue] = obj.bitStringContents.slice(1);
|
|
28929
28929
|
}
|
|
28930
28930
|
}
|
|
28931
28931
|
}
|
|
@@ -32653,9 +32653,9 @@ var require_prime = __commonJS({
|
|
|
32653
32653
|
return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
|
|
32654
32654
|
}
|
|
32655
32655
|
function primeincFindPrimeWithoutWorkers(bits, rng, options, callback) {
|
|
32656
|
-
var
|
|
32656
|
+
var num2 = generateRandom(bits, rng);
|
|
32657
32657
|
var deltaIdx = 0;
|
|
32658
|
-
var mrTests = getMillerRabinTests(
|
|
32658
|
+
var mrTests = getMillerRabinTests(num2.bitLength());
|
|
32659
32659
|
if ("millerRabinTests" in options) {
|
|
32660
32660
|
mrTests = options.millerRabinTests;
|
|
32661
32661
|
}
|
|
@@ -32663,28 +32663,28 @@ var require_prime = __commonJS({
|
|
|
32663
32663
|
if ("maxBlockTime" in options) {
|
|
32664
32664
|
maxBlockTime = options.maxBlockTime;
|
|
32665
32665
|
}
|
|
32666
|
-
_primeinc(
|
|
32666
|
+
_primeinc(num2, bits, rng, deltaIdx, mrTests, maxBlockTime, callback);
|
|
32667
32667
|
}
|
|
32668
|
-
function _primeinc(
|
|
32668
|
+
function _primeinc(num2, bits, rng, deltaIdx, mrTests, maxBlockTime, callback) {
|
|
32669
32669
|
var start = +/* @__PURE__ */ new Date();
|
|
32670
32670
|
do {
|
|
32671
|
-
if (
|
|
32672
|
-
|
|
32671
|
+
if (num2.bitLength() > bits) {
|
|
32672
|
+
num2 = generateRandom(bits, rng);
|
|
32673
32673
|
}
|
|
32674
|
-
if (
|
|
32675
|
-
return callback(null,
|
|
32674
|
+
if (num2.isProbablePrime(mrTests)) {
|
|
32675
|
+
return callback(null, num2);
|
|
32676
32676
|
}
|
|
32677
|
-
|
|
32677
|
+
num2.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0);
|
|
32678
32678
|
} while (maxBlockTime < 0 || +/* @__PURE__ */ new Date() - start < maxBlockTime);
|
|
32679
32679
|
forge2.util.setImmediate(function() {
|
|
32680
|
-
_primeinc(
|
|
32680
|
+
_primeinc(num2, bits, rng, deltaIdx, mrTests, maxBlockTime, callback);
|
|
32681
32681
|
});
|
|
32682
32682
|
}
|
|
32683
32683
|
function primeincFindPrimeWithWorkers(bits, rng, options, callback) {
|
|
32684
32684
|
if (typeof Worker === "undefined") {
|
|
32685
32685
|
return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
|
|
32686
32686
|
}
|
|
32687
|
-
var
|
|
32687
|
+
var num2 = generateRandom(bits, rng);
|
|
32688
32688
|
var numWorkers = options.workers;
|
|
32689
32689
|
var workLoad = options.workLoad || 100;
|
|
32690
32690
|
var range = workLoad * 30 / 8;
|
|
@@ -32723,26 +32723,26 @@ var require_prime = __commonJS({
|
|
|
32723
32723
|
found = true;
|
|
32724
32724
|
return callback(null, new BigInteger(data.prime, 16));
|
|
32725
32725
|
}
|
|
32726
|
-
if (
|
|
32727
|
-
|
|
32726
|
+
if (num2.bitLength() > bits) {
|
|
32727
|
+
num2 = generateRandom(bits, rng);
|
|
32728
32728
|
}
|
|
32729
|
-
var hex =
|
|
32729
|
+
var hex = num2.toString(16);
|
|
32730
32730
|
e.target.postMessage({
|
|
32731
32731
|
hex,
|
|
32732
32732
|
workLoad
|
|
32733
32733
|
});
|
|
32734
|
-
|
|
32734
|
+
num2.dAddOffset(range, 0);
|
|
32735
32735
|
}
|
|
32736
32736
|
}
|
|
32737
32737
|
}
|
|
32738
32738
|
function generateRandom(bits, rng) {
|
|
32739
|
-
var
|
|
32739
|
+
var num2 = new BigInteger(bits, rng);
|
|
32740
32740
|
var bits1 = bits - 1;
|
|
32741
|
-
if (!
|
|
32742
|
-
|
|
32741
|
+
if (!num2.testBit(bits1)) {
|
|
32742
|
+
num2.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num2);
|
|
32743
32743
|
}
|
|
32744
|
-
|
|
32745
|
-
return
|
|
32744
|
+
num2.dAddOffset(31 - num2.mod(THIRTY).byteValue(), 0);
|
|
32745
|
+
return num2;
|
|
32746
32746
|
}
|
|
32747
32747
|
function getMillerRabinTests(bits) {
|
|
32748
32748
|
if (bits <= 100) return 27;
|
|
@@ -33462,16 +33462,16 @@ var require_rsa = __commonJS({
|
|
|
33462
33462
|
var obj = asn1.fromDer(d2, {
|
|
33463
33463
|
parseAllBytes: options._parseAllDigestBytes
|
|
33464
33464
|
});
|
|
33465
|
-
var
|
|
33465
|
+
var capture2 = {};
|
|
33466
33466
|
var errors = [];
|
|
33467
|
-
if (!asn1.validate(obj, digestInfoValidator,
|
|
33467
|
+
if (!asn1.validate(obj, digestInfoValidator, capture2, errors) || obj.value.length !== 2) {
|
|
33468
33468
|
var error = new Error(
|
|
33469
33469
|
"ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 DigestInfo value."
|
|
33470
33470
|
);
|
|
33471
33471
|
error.errors = errors;
|
|
33472
33472
|
throw error;
|
|
33473
33473
|
}
|
|
33474
|
-
var oid = asn1.derToOid(
|
|
33474
|
+
var oid = asn1.derToOid(capture2.algorithmIdentifier);
|
|
33475
33475
|
if (!(oid === forge2.oids.md2 || oid === forge2.oids.md5 || oid === forge2.oids.sha1 || oid === forge2.oids.sha224 || oid === forge2.oids.sha256 || oid === forge2.oids.sha384 || oid === forge2.oids.sha512 || oid === forge2.oids["sha512-224"] || oid === forge2.oids["sha512-256"])) {
|
|
33476
33476
|
var error = new Error(
|
|
33477
33477
|
"Unknown RSASSA-PKCS1-v1_5 DigestAlgorithm identifier."
|
|
@@ -33480,13 +33480,13 @@ var require_rsa = __commonJS({
|
|
|
33480
33480
|
throw error;
|
|
33481
33481
|
}
|
|
33482
33482
|
if (oid === forge2.oids.md2 || oid === forge2.oids.md5) {
|
|
33483
|
-
if (!("parameters" in
|
|
33483
|
+
if (!("parameters" in capture2)) {
|
|
33484
33484
|
throw new Error(
|
|
33485
33485
|
"ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 DigestInfo value. Missing algorithm identifier NULL parameters."
|
|
33486
33486
|
);
|
|
33487
33487
|
}
|
|
33488
33488
|
}
|
|
33489
|
-
return digest2 ===
|
|
33489
|
+
return digest2 === capture2.digest;
|
|
33490
33490
|
}
|
|
33491
33491
|
};
|
|
33492
33492
|
} else if (scheme === "NONE" || scheme === "NULL" || scheme === null) {
|
|
@@ -33585,27 +33585,27 @@ var require_rsa = __commonJS({
|
|
|
33585
33585
|
]);
|
|
33586
33586
|
};
|
|
33587
33587
|
pki.privateKeyFromAsn1 = function(obj) {
|
|
33588
|
-
var
|
|
33588
|
+
var capture2 = {};
|
|
33589
33589
|
var errors = [];
|
|
33590
|
-
if (asn1.validate(obj, privateKeyValidator,
|
|
33591
|
-
obj = asn1.fromDer(forge2.util.createBuffer(
|
|
33590
|
+
if (asn1.validate(obj, privateKeyValidator, capture2, errors)) {
|
|
33591
|
+
obj = asn1.fromDer(forge2.util.createBuffer(capture2.privateKey));
|
|
33592
33592
|
}
|
|
33593
|
-
|
|
33593
|
+
capture2 = {};
|
|
33594
33594
|
errors = [];
|
|
33595
|
-
if (!asn1.validate(obj, rsaPrivateKeyValidator,
|
|
33595
|
+
if (!asn1.validate(obj, rsaPrivateKeyValidator, capture2, errors)) {
|
|
33596
33596
|
var error = new Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.");
|
|
33597
33597
|
error.errors = errors;
|
|
33598
33598
|
throw error;
|
|
33599
33599
|
}
|
|
33600
33600
|
var n, e, d, p2, q2, dP, dQ, qInv;
|
|
33601
|
-
n = forge2.util.createBuffer(
|
|
33602
|
-
e = forge2.util.createBuffer(
|
|
33603
|
-
d = forge2.util.createBuffer(
|
|
33604
|
-
p2 = forge2.util.createBuffer(
|
|
33605
|
-
q2 = forge2.util.createBuffer(
|
|
33606
|
-
dP = forge2.util.createBuffer(
|
|
33607
|
-
dQ = forge2.util.createBuffer(
|
|
33608
|
-
qInv = forge2.util.createBuffer(
|
|
33601
|
+
n = forge2.util.createBuffer(capture2.privateKeyModulus).toHex();
|
|
33602
|
+
e = forge2.util.createBuffer(capture2.privateKeyPublicExponent).toHex();
|
|
33603
|
+
d = forge2.util.createBuffer(capture2.privateKeyPrivateExponent).toHex();
|
|
33604
|
+
p2 = forge2.util.createBuffer(capture2.privateKeyPrime1).toHex();
|
|
33605
|
+
q2 = forge2.util.createBuffer(capture2.privateKeyPrime2).toHex();
|
|
33606
|
+
dP = forge2.util.createBuffer(capture2.privateKeyExponent1).toHex();
|
|
33607
|
+
dQ = forge2.util.createBuffer(capture2.privateKeyExponent2).toHex();
|
|
33608
|
+
qInv = forge2.util.createBuffer(capture2.privateKeyCoefficient).toHex();
|
|
33609
33609
|
return pki.setRsaPrivateKey(
|
|
33610
33610
|
new BigInteger(n, 16),
|
|
33611
33611
|
new BigInteger(e, 16),
|
|
@@ -33685,25 +33685,25 @@ var require_rsa = __commonJS({
|
|
|
33685
33685
|
]);
|
|
33686
33686
|
};
|
|
33687
33687
|
pki.publicKeyFromAsn1 = function(obj) {
|
|
33688
|
-
var
|
|
33688
|
+
var capture2 = {};
|
|
33689
33689
|
var errors = [];
|
|
33690
|
-
if (asn1.validate(obj, publicKeyValidator,
|
|
33691
|
-
var oid = asn1.derToOid(
|
|
33690
|
+
if (asn1.validate(obj, publicKeyValidator, capture2, errors)) {
|
|
33691
|
+
var oid = asn1.derToOid(capture2.publicKeyOid);
|
|
33692
33692
|
if (oid !== pki.oids.rsaEncryption) {
|
|
33693
33693
|
var error = new Error("Cannot read public key. Unknown OID.");
|
|
33694
33694
|
error.oid = oid;
|
|
33695
33695
|
throw error;
|
|
33696
33696
|
}
|
|
33697
|
-
obj =
|
|
33697
|
+
obj = capture2.rsaPublicKey;
|
|
33698
33698
|
}
|
|
33699
33699
|
errors = [];
|
|
33700
|
-
if (!asn1.validate(obj, rsaPublicKeyValidator,
|
|
33700
|
+
if (!asn1.validate(obj, rsaPublicKeyValidator, capture2, errors)) {
|
|
33701
33701
|
var error = new Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey.");
|
|
33702
33702
|
error.errors = errors;
|
|
33703
33703
|
throw error;
|
|
33704
33704
|
}
|
|
33705
|
-
var n = forge2.util.createBuffer(
|
|
33706
|
-
var e = forge2.util.createBuffer(
|
|
33705
|
+
var n = forge2.util.createBuffer(capture2.publicKeyModulus).toHex();
|
|
33706
|
+
var e = forge2.util.createBuffer(capture2.publicKeyExponent).toHex();
|
|
33707
33707
|
return pki.setRsaPublicKey(
|
|
33708
33708
|
new BigInteger(n, 16),
|
|
33709
33709
|
new BigInteger(e, 16)
|
|
@@ -33852,11 +33852,11 @@ var require_rsa = __commonJS({
|
|
|
33852
33852
|
}
|
|
33853
33853
|
generate();
|
|
33854
33854
|
function generate() {
|
|
33855
|
-
getPrime(state.pBits, function(err2,
|
|
33855
|
+
getPrime(state.pBits, function(err2, num2) {
|
|
33856
33856
|
if (err2) {
|
|
33857
33857
|
return callback(err2);
|
|
33858
33858
|
}
|
|
33859
|
-
state.p =
|
|
33859
|
+
state.p = num2;
|
|
33860
33860
|
if (state.q !== null) {
|
|
33861
33861
|
return finish(err2, state.q);
|
|
33862
33862
|
}
|
|
@@ -33866,11 +33866,11 @@ var require_rsa = __commonJS({
|
|
|
33866
33866
|
function getPrime(bits, callback2) {
|
|
33867
33867
|
forge2.prime.generateProbablePrime(bits, opts, callback2);
|
|
33868
33868
|
}
|
|
33869
|
-
function finish(err2,
|
|
33869
|
+
function finish(err2, num2) {
|
|
33870
33870
|
if (err2) {
|
|
33871
33871
|
return callback(err2);
|
|
33872
33872
|
}
|
|
33873
|
-
state.q =
|
|
33873
|
+
state.q = num2;
|
|
33874
33874
|
if (state.p.compareTo(state.q) < 0) {
|
|
33875
33875
|
var tmp = state.p;
|
|
33876
33876
|
state.p = state.q;
|
|
@@ -34266,16 +34266,16 @@ var require_pbe = __commonJS({
|
|
|
34266
34266
|
};
|
|
34267
34267
|
pki.decryptPrivateKeyInfo = function(obj, password) {
|
|
34268
34268
|
var rval = null;
|
|
34269
|
-
var
|
|
34269
|
+
var capture2 = {};
|
|
34270
34270
|
var errors = [];
|
|
34271
|
-
if (!asn1.validate(obj, encryptedPrivateKeyValidator,
|
|
34271
|
+
if (!asn1.validate(obj, encryptedPrivateKeyValidator, capture2, errors)) {
|
|
34272
34272
|
var error = new Error("Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
34273
34273
|
error.errors = errors;
|
|
34274
34274
|
throw error;
|
|
34275
34275
|
}
|
|
34276
|
-
var oid = asn1.derToOid(
|
|
34277
|
-
var cipher = pki.pbe.getCipher(oid,
|
|
34278
|
-
var encrypted = forge2.util.createBuffer(
|
|
34276
|
+
var oid = asn1.derToOid(capture2.encryptionOid);
|
|
34277
|
+
var cipher = pki.pbe.getCipher(oid, capture2.encryptionParams, password);
|
|
34278
|
+
var encrypted = forge2.util.createBuffer(capture2.encryptedData);
|
|
34279
34279
|
cipher.update(encrypted);
|
|
34280
34280
|
if (cipher.finish()) {
|
|
34281
34281
|
rval = asn1.fromDer(cipher.output);
|
|
@@ -34530,21 +34530,21 @@ var require_pbe = __commonJS({
|
|
|
34530
34530
|
}
|
|
34531
34531
|
};
|
|
34532
34532
|
pki.pbe.getCipherForPBES2 = function(oid, params, password) {
|
|
34533
|
-
var
|
|
34533
|
+
var capture2 = {};
|
|
34534
34534
|
var errors = [];
|
|
34535
|
-
if (!asn1.validate(params, PBES2AlgorithmsValidator,
|
|
34535
|
+
if (!asn1.validate(params, PBES2AlgorithmsValidator, capture2, errors)) {
|
|
34536
34536
|
var error = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
34537
34537
|
error.errors = errors;
|
|
34538
34538
|
throw error;
|
|
34539
34539
|
}
|
|
34540
|
-
oid = asn1.derToOid(
|
|
34540
|
+
oid = asn1.derToOid(capture2.kdfOid);
|
|
34541
34541
|
if (oid !== pki.oids["pkcs5PBKDF2"]) {
|
|
34542
34542
|
var error = new Error("Cannot read encrypted private key. Unsupported key derivation function OID.");
|
|
34543
34543
|
error.oid = oid;
|
|
34544
34544
|
error.supportedOids = ["pkcs5PBKDF2"];
|
|
34545
34545
|
throw error;
|
|
34546
34546
|
}
|
|
34547
|
-
oid = asn1.derToOid(
|
|
34547
|
+
oid = asn1.derToOid(capture2.encOid);
|
|
34548
34548
|
if (oid !== pki.oids["aes128-CBC"] && oid !== pki.oids["aes192-CBC"] && oid !== pki.oids["aes256-CBC"] && oid !== pki.oids["des-EDE3-CBC"] && oid !== pki.oids["desCBC"]) {
|
|
34549
34549
|
var error = new Error("Cannot read encrypted private key. Unsupported encryption scheme OID.");
|
|
34550
34550
|
error.oid = oid;
|
|
@@ -34557,8 +34557,8 @@ var require_pbe = __commonJS({
|
|
|
34557
34557
|
];
|
|
34558
34558
|
throw error;
|
|
34559
34559
|
}
|
|
34560
|
-
var salt =
|
|
34561
|
-
var count = forge2.util.createBuffer(
|
|
34560
|
+
var salt = capture2.kdfSalt;
|
|
34561
|
+
var count = forge2.util.createBuffer(capture2.kdfIterationCount);
|
|
34562
34562
|
count = count.getInt(count.length() << 3);
|
|
34563
34563
|
var dkLen;
|
|
34564
34564
|
var cipherFn;
|
|
@@ -34584,23 +34584,23 @@ var require_pbe = __commonJS({
|
|
|
34584
34584
|
cipherFn = forge2.des.createDecryptionCipher;
|
|
34585
34585
|
break;
|
|
34586
34586
|
}
|
|
34587
|
-
var md = prfOidToMessageDigest(
|
|
34587
|
+
var md = prfOidToMessageDigest(capture2.prfOid);
|
|
34588
34588
|
var dk = forge2.pkcs5.pbkdf2(password, salt, count, dkLen, md);
|
|
34589
|
-
var iv =
|
|
34589
|
+
var iv = capture2.encIv;
|
|
34590
34590
|
var cipher = cipherFn(dk);
|
|
34591
34591
|
cipher.start(iv);
|
|
34592
34592
|
return cipher;
|
|
34593
34593
|
};
|
|
34594
34594
|
pki.pbe.getCipherForPKCS12PBE = function(oid, params, password) {
|
|
34595
|
-
var
|
|
34595
|
+
var capture2 = {};
|
|
34596
34596
|
var errors = [];
|
|
34597
|
-
if (!asn1.validate(params, pkcs12PbeParamsValidator,
|
|
34597
|
+
if (!asn1.validate(params, pkcs12PbeParamsValidator, capture2, errors)) {
|
|
34598
34598
|
var error = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
34599
34599
|
error.errors = errors;
|
|
34600
34600
|
throw error;
|
|
34601
34601
|
}
|
|
34602
|
-
var salt = forge2.util.createBuffer(
|
|
34603
|
-
var count = forge2.util.createBuffer(
|
|
34602
|
+
var salt = forge2.util.createBuffer(capture2.salt);
|
|
34603
|
+
var count = forge2.util.createBuffer(capture2.iterations);
|
|
34604
34604
|
count = count.getInt(count.length() << 3);
|
|
34605
34605
|
var dkLen, dIvLen, cipherFn;
|
|
34606
34606
|
switch (oid) {
|
|
@@ -34623,7 +34623,7 @@ var require_pbe = __commonJS({
|
|
|
34623
34623
|
error.oid = oid;
|
|
34624
34624
|
throw error;
|
|
34625
34625
|
}
|
|
34626
|
-
var md = prfOidToMessageDigest(
|
|
34626
|
+
var md = prfOidToMessageDigest(capture2.prfOid);
|
|
34627
34627
|
var key = pki.pbe.generatePkcs12Key(password, salt, 1, count, dkLen, md);
|
|
34628
34628
|
md.start();
|
|
34629
34629
|
var iv = pki.pbe.generatePkcs12Key(password, salt, 2, count, dIvLen, md);
|
|
@@ -35689,25 +35689,25 @@ var require_x509 = __commonJS({
|
|
|
35689
35689
|
saltLength: 20
|
|
35690
35690
|
};
|
|
35691
35691
|
}
|
|
35692
|
-
var
|
|
35692
|
+
var capture2 = {};
|
|
35693
35693
|
var errors = [];
|
|
35694
|
-
if (!asn1.validate(obj, rsassaPssParameterValidator,
|
|
35694
|
+
if (!asn1.validate(obj, rsassaPssParameterValidator, capture2, errors)) {
|
|
35695
35695
|
var error = new Error("Cannot read RSASSA-PSS parameter block.");
|
|
35696
35696
|
error.errors = errors;
|
|
35697
35697
|
throw error;
|
|
35698
35698
|
}
|
|
35699
|
-
if (
|
|
35699
|
+
if (capture2.hashOid !== void 0) {
|
|
35700
35700
|
params.hash = params.hash || {};
|
|
35701
|
-
params.hash.algorithmOid = asn1.derToOid(
|
|
35701
|
+
params.hash.algorithmOid = asn1.derToOid(capture2.hashOid);
|
|
35702
35702
|
}
|
|
35703
|
-
if (
|
|
35703
|
+
if (capture2.maskGenOid !== void 0) {
|
|
35704
35704
|
params.mgf = params.mgf || {};
|
|
35705
|
-
params.mgf.algorithmOid = asn1.derToOid(
|
|
35705
|
+
params.mgf.algorithmOid = asn1.derToOid(capture2.maskGenOid);
|
|
35706
35706
|
params.mgf.hash = params.mgf.hash || {};
|
|
35707
|
-
params.mgf.hash.algorithmOid = asn1.derToOid(
|
|
35707
|
+
params.mgf.hash.algorithmOid = asn1.derToOid(capture2.maskGenHashOid);
|
|
35708
35708
|
}
|
|
35709
|
-
if (
|
|
35710
|
-
params.saltLength =
|
|
35709
|
+
if (capture2.saltLength !== void 0) {
|
|
35710
|
+
params.saltLength = capture2.saltLength.charCodeAt(0);
|
|
35711
35711
|
}
|
|
35712
35712
|
return params;
|
|
35713
35713
|
};
|
|
@@ -36040,49 +36040,49 @@ var require_x509 = __commonJS({
|
|
|
36040
36040
|
return cert;
|
|
36041
36041
|
};
|
|
36042
36042
|
pki.certificateFromAsn1 = function(obj, computeHash) {
|
|
36043
|
-
var
|
|
36043
|
+
var capture2 = {};
|
|
36044
36044
|
var errors = [];
|
|
36045
|
-
if (!asn1.validate(obj, x509CertificateValidator,
|
|
36045
|
+
if (!asn1.validate(obj, x509CertificateValidator, capture2, errors)) {
|
|
36046
36046
|
var error = new Error("Cannot read X.509 certificate. ASN.1 object is not an X509v3 Certificate.");
|
|
36047
36047
|
error.errors = errors;
|
|
36048
36048
|
throw error;
|
|
36049
36049
|
}
|
|
36050
|
-
var oid = asn1.derToOid(
|
|
36050
|
+
var oid = asn1.derToOid(capture2.publicKeyOid);
|
|
36051
36051
|
if (oid !== pki.oids.rsaEncryption) {
|
|
36052
36052
|
throw new Error("Cannot read public key. OID is not RSA.");
|
|
36053
36053
|
}
|
|
36054
36054
|
var cert = pki.createCertificate();
|
|
36055
|
-
cert.version =
|
|
36056
|
-
var serial = forge2.util.createBuffer(
|
|
36055
|
+
cert.version = capture2.certVersion ? capture2.certVersion.charCodeAt(0) : 0;
|
|
36056
|
+
var serial = forge2.util.createBuffer(capture2.certSerialNumber);
|
|
36057
36057
|
cert.serialNumber = serial.toHex();
|
|
36058
|
-
cert.signatureOid = forge2.asn1.derToOid(
|
|
36058
|
+
cert.signatureOid = forge2.asn1.derToOid(capture2.certSignatureOid);
|
|
36059
36059
|
cert.signatureParameters = _readSignatureParameters(
|
|
36060
36060
|
cert.signatureOid,
|
|
36061
|
-
|
|
36061
|
+
capture2.certSignatureParams,
|
|
36062
36062
|
true
|
|
36063
36063
|
);
|
|
36064
|
-
cert.siginfo.algorithmOid = forge2.asn1.derToOid(
|
|
36064
|
+
cert.siginfo.algorithmOid = forge2.asn1.derToOid(capture2.certinfoSignatureOid);
|
|
36065
36065
|
cert.siginfo.parameters = _readSignatureParameters(
|
|
36066
36066
|
cert.siginfo.algorithmOid,
|
|
36067
|
-
|
|
36067
|
+
capture2.certinfoSignatureParams,
|
|
36068
36068
|
false
|
|
36069
36069
|
);
|
|
36070
|
-
cert.signature =
|
|
36070
|
+
cert.signature = capture2.certSignature;
|
|
36071
36071
|
var validity = [];
|
|
36072
|
-
if (
|
|
36073
|
-
validity.push(asn1.utcTimeToDate(
|
|
36072
|
+
if (capture2.certValidity1UTCTime !== void 0) {
|
|
36073
|
+
validity.push(asn1.utcTimeToDate(capture2.certValidity1UTCTime));
|
|
36074
36074
|
}
|
|
36075
|
-
if (
|
|
36075
|
+
if (capture2.certValidity2GeneralizedTime !== void 0) {
|
|
36076
36076
|
validity.push(asn1.generalizedTimeToDate(
|
|
36077
|
-
|
|
36077
|
+
capture2.certValidity2GeneralizedTime
|
|
36078
36078
|
));
|
|
36079
36079
|
}
|
|
36080
|
-
if (
|
|
36081
|
-
validity.push(asn1.utcTimeToDate(
|
|
36080
|
+
if (capture2.certValidity3UTCTime !== void 0) {
|
|
36081
|
+
validity.push(asn1.utcTimeToDate(capture2.certValidity3UTCTime));
|
|
36082
36082
|
}
|
|
36083
|
-
if (
|
|
36083
|
+
if (capture2.certValidity4GeneralizedTime !== void 0) {
|
|
36084
36084
|
validity.push(asn1.generalizedTimeToDate(
|
|
36085
|
-
|
|
36085
|
+
capture2.certValidity4GeneralizedTime
|
|
36086
36086
|
));
|
|
36087
36087
|
}
|
|
36088
36088
|
if (validity.length > 2) {
|
|
@@ -36093,7 +36093,7 @@ var require_x509 = __commonJS({
|
|
|
36093
36093
|
}
|
|
36094
36094
|
cert.validity.notBefore = validity[0];
|
|
36095
36095
|
cert.validity.notAfter = validity[1];
|
|
36096
|
-
cert.tbsCertificate =
|
|
36096
|
+
cert.tbsCertificate = capture2.tbsCertificate;
|
|
36097
36097
|
if (computeHash) {
|
|
36098
36098
|
cert.md = _createSignatureDigest({
|
|
36099
36099
|
signatureOid: cert.signatureOid,
|
|
@@ -36103,7 +36103,7 @@ var require_x509 = __commonJS({
|
|
|
36103
36103
|
cert.md.update(bytes.getBytes());
|
|
36104
36104
|
}
|
|
36105
36105
|
var imd = forge2.md.sha1.create();
|
|
36106
|
-
var ibytes = asn1.toDer(
|
|
36106
|
+
var ibytes = asn1.toDer(capture2.certIssuer);
|
|
36107
36107
|
imd.update(ibytes.getBytes());
|
|
36108
36108
|
cert.issuer.getField = function(sn2) {
|
|
36109
36109
|
return _getAttribute(cert.issuer, sn2);
|
|
@@ -36112,13 +36112,13 @@ var require_x509 = __commonJS({
|
|
|
36112
36112
|
_fillMissingFields([attr]);
|
|
36113
36113
|
cert.issuer.attributes.push(attr);
|
|
36114
36114
|
};
|
|
36115
|
-
cert.issuer.attributes = pki.RDNAttributesAsArray(
|
|
36116
|
-
if (
|
|
36117
|
-
cert.issuer.uniqueId =
|
|
36115
|
+
cert.issuer.attributes = pki.RDNAttributesAsArray(capture2.certIssuer);
|
|
36116
|
+
if (capture2.certIssuerUniqueId) {
|
|
36117
|
+
cert.issuer.uniqueId = capture2.certIssuerUniqueId;
|
|
36118
36118
|
}
|
|
36119
36119
|
cert.issuer.hash = imd.digest().toHex();
|
|
36120
36120
|
var smd = forge2.md.sha1.create();
|
|
36121
|
-
var sbytes = asn1.toDer(
|
|
36121
|
+
var sbytes = asn1.toDer(capture2.certSubject);
|
|
36122
36122
|
smd.update(sbytes.getBytes());
|
|
36123
36123
|
cert.subject.getField = function(sn2) {
|
|
36124
36124
|
return _getAttribute(cert.subject, sn2);
|
|
@@ -36127,17 +36127,17 @@ var require_x509 = __commonJS({
|
|
|
36127
36127
|
_fillMissingFields([attr]);
|
|
36128
36128
|
cert.subject.attributes.push(attr);
|
|
36129
36129
|
};
|
|
36130
|
-
cert.subject.attributes = pki.RDNAttributesAsArray(
|
|
36131
|
-
if (
|
|
36132
|
-
cert.subject.uniqueId =
|
|
36130
|
+
cert.subject.attributes = pki.RDNAttributesAsArray(capture2.certSubject);
|
|
36131
|
+
if (capture2.certSubjectUniqueId) {
|
|
36132
|
+
cert.subject.uniqueId = capture2.certSubjectUniqueId;
|
|
36133
36133
|
}
|
|
36134
36134
|
cert.subject.hash = smd.digest().toHex();
|
|
36135
|
-
if (
|
|
36136
|
-
cert.extensions = pki.certificateExtensionsFromAsn1(
|
|
36135
|
+
if (capture2.certExtensions) {
|
|
36136
|
+
cert.extensions = pki.certificateExtensionsFromAsn1(capture2.certExtensions);
|
|
36137
36137
|
} else {
|
|
36138
36138
|
cert.extensions = [];
|
|
36139
36139
|
}
|
|
36140
|
-
cert.publicKey = pki.publicKeyFromAsn1(
|
|
36140
|
+
cert.publicKey = pki.publicKeyFromAsn1(capture2.subjectPublicKeyInfo);
|
|
36141
36141
|
return cert;
|
|
36142
36142
|
};
|
|
36143
36143
|
pki.certificateExtensionsFromAsn1 = function(exts) {
|
|
@@ -36257,33 +36257,33 @@ var require_x509 = __commonJS({
|
|
|
36257
36257
|
return e;
|
|
36258
36258
|
};
|
|
36259
36259
|
pki.certificationRequestFromAsn1 = function(obj, computeHash) {
|
|
36260
|
-
var
|
|
36260
|
+
var capture2 = {};
|
|
36261
36261
|
var errors = [];
|
|
36262
|
-
if (!asn1.validate(obj, certificationRequestValidator,
|
|
36262
|
+
if (!asn1.validate(obj, certificationRequestValidator, capture2, errors)) {
|
|
36263
36263
|
var error = new Error("Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.");
|
|
36264
36264
|
error.errors = errors;
|
|
36265
36265
|
throw error;
|
|
36266
36266
|
}
|
|
36267
|
-
var oid = asn1.derToOid(
|
|
36267
|
+
var oid = asn1.derToOid(capture2.publicKeyOid);
|
|
36268
36268
|
if (oid !== pki.oids.rsaEncryption) {
|
|
36269
36269
|
throw new Error("Cannot read public key. OID is not RSA.");
|
|
36270
36270
|
}
|
|
36271
36271
|
var csr = pki.createCertificationRequest();
|
|
36272
|
-
csr.version =
|
|
36273
|
-
csr.signatureOid = forge2.asn1.derToOid(
|
|
36272
|
+
csr.version = capture2.csrVersion ? capture2.csrVersion.charCodeAt(0) : 0;
|
|
36273
|
+
csr.signatureOid = forge2.asn1.derToOid(capture2.csrSignatureOid);
|
|
36274
36274
|
csr.signatureParameters = _readSignatureParameters(
|
|
36275
36275
|
csr.signatureOid,
|
|
36276
|
-
|
|
36276
|
+
capture2.csrSignatureParams,
|
|
36277
36277
|
true
|
|
36278
36278
|
);
|
|
36279
|
-
csr.siginfo.algorithmOid = forge2.asn1.derToOid(
|
|
36279
|
+
csr.siginfo.algorithmOid = forge2.asn1.derToOid(capture2.csrSignatureOid);
|
|
36280
36280
|
csr.siginfo.parameters = _readSignatureParameters(
|
|
36281
36281
|
csr.siginfo.algorithmOid,
|
|
36282
|
-
|
|
36282
|
+
capture2.csrSignatureParams,
|
|
36283
36283
|
false
|
|
36284
36284
|
);
|
|
36285
|
-
csr.signature =
|
|
36286
|
-
csr.certificationRequestInfo =
|
|
36285
|
+
csr.signature = capture2.csrSignature;
|
|
36286
|
+
csr.certificationRequestInfo = capture2.certificationRequestInfo;
|
|
36287
36287
|
if (computeHash) {
|
|
36288
36288
|
csr.md = _createSignatureDigest({
|
|
36289
36289
|
signatureOid: csr.signatureOid,
|
|
@@ -36301,11 +36301,11 @@ var require_x509 = __commonJS({
|
|
|
36301
36301
|
csr.subject.attributes.push(attr);
|
|
36302
36302
|
};
|
|
36303
36303
|
csr.subject.attributes = pki.RDNAttributesAsArray(
|
|
36304
|
-
|
|
36304
|
+
capture2.certificationRequestInfoSubject,
|
|
36305
36305
|
smd
|
|
36306
36306
|
);
|
|
36307
36307
|
csr.subject.hash = smd.digest().toHex();
|
|
36308
|
-
csr.publicKey = pki.publicKeyFromAsn1(
|
|
36308
|
+
csr.publicKey = pki.publicKeyFromAsn1(capture2.subjectPublicKeyInfo);
|
|
36309
36309
|
csr.getAttribute = function(sn2) {
|
|
36310
36310
|
return _getAttribute(csr, sn2);
|
|
36311
36311
|
};
|
|
@@ -36314,7 +36314,7 @@ var require_x509 = __commonJS({
|
|
|
36314
36314
|
csr.attributes.push(attr);
|
|
36315
36315
|
};
|
|
36316
36316
|
csr.attributes = pki.CRIAttributesAsArray(
|
|
36317
|
-
|
|
36317
|
+
capture2.certificationRequestInfoAttributes || []
|
|
36318
36318
|
);
|
|
36319
36319
|
return csr;
|
|
36320
36320
|
};
|
|
@@ -37544,15 +37544,15 @@ var require_pkcs12 = __commonJS({
|
|
|
37544
37544
|
} else if (strict === void 0) {
|
|
37545
37545
|
strict = true;
|
|
37546
37546
|
}
|
|
37547
|
-
var
|
|
37547
|
+
var capture2 = {};
|
|
37548
37548
|
var errors = [];
|
|
37549
|
-
if (!asn1.validate(obj, pfxValidator,
|
|
37549
|
+
if (!asn1.validate(obj, pfxValidator, capture2, errors)) {
|
|
37550
37550
|
var error = new Error("Cannot read PKCS#12 PFX. ASN.1 object is not an PKCS#12 PFX.");
|
|
37551
37551
|
error.errors = error;
|
|
37552
37552
|
throw error;
|
|
37553
37553
|
}
|
|
37554
37554
|
var pfx = {
|
|
37555
|
-
version:
|
|
37555
|
+
version: capture2.version.charCodeAt(0),
|
|
37556
37556
|
safeContents: [],
|
|
37557
37557
|
/**
|
|
37558
37558
|
* Gets bags with matching attributes.
|
|
@@ -37638,25 +37638,25 @@ var require_pkcs12 = __commonJS({
|
|
|
37638
37638
|
);
|
|
37639
37639
|
}
|
|
37640
37640
|
};
|
|
37641
|
-
if (
|
|
37641
|
+
if (capture2.version.charCodeAt(0) !== 3) {
|
|
37642
37642
|
var error = new Error("PKCS#12 PFX of version other than 3 not supported.");
|
|
37643
|
-
error.version =
|
|
37643
|
+
error.version = capture2.version.charCodeAt(0);
|
|
37644
37644
|
throw error;
|
|
37645
37645
|
}
|
|
37646
|
-
if (asn1.derToOid(
|
|
37646
|
+
if (asn1.derToOid(capture2.contentType) !== pki.oids.data) {
|
|
37647
37647
|
var error = new Error("Only PKCS#12 PFX in password integrity mode supported.");
|
|
37648
|
-
error.oid = asn1.derToOid(
|
|
37648
|
+
error.oid = asn1.derToOid(capture2.contentType);
|
|
37649
37649
|
throw error;
|
|
37650
37650
|
}
|
|
37651
|
-
var data =
|
|
37651
|
+
var data = capture2.content.value[0];
|
|
37652
37652
|
if (data.tagClass !== asn1.Class.UNIVERSAL || data.type !== asn1.Type.OCTETSTRING) {
|
|
37653
37653
|
throw new Error("PKCS#12 authSafe content data is not an OCTET STRING.");
|
|
37654
37654
|
}
|
|
37655
37655
|
data = _decodePkcs7Data(data);
|
|
37656
|
-
if (
|
|
37656
|
+
if (capture2.mac) {
|
|
37657
37657
|
var md = null;
|
|
37658
37658
|
var macKeyBytes = 0;
|
|
37659
|
-
var macAlgorithm = asn1.derToOid(
|
|
37659
|
+
var macAlgorithm = asn1.derToOid(capture2.macAlgorithm);
|
|
37660
37660
|
switch (macAlgorithm) {
|
|
37661
37661
|
case pki.oids.sha1:
|
|
37662
37662
|
md = forge2.md.sha1.create();
|
|
@@ -37682,8 +37682,8 @@ var require_pkcs12 = __commonJS({
|
|
|
37682
37682
|
if (md === null) {
|
|
37683
37683
|
throw new Error("PKCS#12 uses unsupported MAC algorithm: " + macAlgorithm);
|
|
37684
37684
|
}
|
|
37685
|
-
var macSalt = new forge2.util.ByteBuffer(
|
|
37686
|
-
var macIterations = "macIterations" in
|
|
37685
|
+
var macSalt = new forge2.util.ByteBuffer(capture2.macSalt);
|
|
37686
|
+
var macIterations = "macIterations" in capture2 ? parseInt(forge2.util.bytesToHex(capture2.macIterations), 16) : 1;
|
|
37687
37687
|
var macKey = p12.generateKey(
|
|
37688
37688
|
password,
|
|
37689
37689
|
macSalt,
|
|
@@ -37696,7 +37696,7 @@ var require_pkcs12 = __commonJS({
|
|
|
37696
37696
|
mac.start(md, macKey);
|
|
37697
37697
|
mac.update(data.value);
|
|
37698
37698
|
var macValue = mac.getMac();
|
|
37699
|
-
if (macValue.getBytes() !==
|
|
37699
|
+
if (macValue.getBytes() !== capture2.macDigest) {
|
|
37700
37700
|
throw new Error("PKCS#12 MAC could not be verified. Invalid password?");
|
|
37701
37701
|
}
|
|
37702
37702
|
} else if (Array.isArray(obj.value) && obj.value.length > 2) {
|
|
@@ -37723,9 +37723,9 @@ var require_pkcs12 = __commonJS({
|
|
|
37723
37723
|
}
|
|
37724
37724
|
for (var i = 0; i < authSafe.value.length; i++) {
|
|
37725
37725
|
var contentInfo = authSafe.value[i];
|
|
37726
|
-
var
|
|
37726
|
+
var capture2 = {};
|
|
37727
37727
|
var errors = [];
|
|
37728
|
-
if (!asn1.validate(contentInfo, contentInfoValidator,
|
|
37728
|
+
if (!asn1.validate(contentInfo, contentInfoValidator, capture2, errors)) {
|
|
37729
37729
|
var error = new Error("Cannot read ContentInfo.");
|
|
37730
37730
|
error.errors = errors;
|
|
37731
37731
|
throw error;
|
|
@@ -37734,8 +37734,8 @@ var require_pkcs12 = __commonJS({
|
|
|
37734
37734
|
encrypted: false
|
|
37735
37735
|
};
|
|
37736
37736
|
var safeContents = null;
|
|
37737
|
-
var data =
|
|
37738
|
-
switch (asn1.derToOid(
|
|
37737
|
+
var data = capture2.content.value[0];
|
|
37738
|
+
switch (asn1.derToOid(capture2.contentType)) {
|
|
37739
37739
|
case pki.oids.data:
|
|
37740
37740
|
if (data.tagClass !== asn1.Class.UNIVERSAL || data.type !== asn1.Type.OCTETSTRING) {
|
|
37741
37741
|
throw new Error("PKCS#12 SafeContents Data is not an OCTET STRING.");
|
|
@@ -37748,7 +37748,7 @@ var require_pkcs12 = __commonJS({
|
|
|
37748
37748
|
break;
|
|
37749
37749
|
default:
|
|
37750
37750
|
var error = new Error("Unsupported PKCS#12 contentType.");
|
|
37751
|
-
error.contentType = asn1.derToOid(
|
|
37751
|
+
error.contentType = asn1.derToOid(capture2.contentType);
|
|
37752
37752
|
throw error;
|
|
37753
37753
|
}
|
|
37754
37754
|
obj.safeBags = _decodeSafeContents(safeContents, strict, password);
|
|
@@ -37756,19 +37756,19 @@ var require_pkcs12 = __commonJS({
|
|
|
37756
37756
|
}
|
|
37757
37757
|
}
|
|
37758
37758
|
function _decryptSafeContents(data, password) {
|
|
37759
|
-
var
|
|
37759
|
+
var capture2 = {};
|
|
37760
37760
|
var errors = [];
|
|
37761
37761
|
if (!asn1.validate(
|
|
37762
37762
|
data,
|
|
37763
37763
|
forge2.pkcs7.asn1.encryptedDataValidator,
|
|
37764
|
-
|
|
37764
|
+
capture2,
|
|
37765
37765
|
errors
|
|
37766
37766
|
)) {
|
|
37767
37767
|
var error = new Error("Cannot read EncryptedContentInfo.");
|
|
37768
37768
|
error.errors = errors;
|
|
37769
37769
|
throw error;
|
|
37770
37770
|
}
|
|
37771
|
-
var oid = asn1.derToOid(
|
|
37771
|
+
var oid = asn1.derToOid(capture2.contentType);
|
|
37772
37772
|
if (oid !== pki.oids.data) {
|
|
37773
37773
|
var error = new Error(
|
|
37774
37774
|
"PKCS#12 EncryptedContentInfo ContentType is not Data."
|
|
@@ -37776,9 +37776,9 @@ var require_pkcs12 = __commonJS({
|
|
|
37776
37776
|
error.oid = oid;
|
|
37777
37777
|
throw error;
|
|
37778
37778
|
}
|
|
37779
|
-
oid = asn1.derToOid(
|
|
37780
|
-
var cipher = pki.pbe.getCipher(oid,
|
|
37781
|
-
var encryptedContentAsn1 = _decodePkcs7Data(
|
|
37779
|
+
oid = asn1.derToOid(capture2.encAlgorithm);
|
|
37780
|
+
var cipher = pki.pbe.getCipher(oid, capture2.encParameter, password);
|
|
37781
|
+
var encryptedContentAsn1 = _decodePkcs7Data(capture2.encryptedContentAsn1);
|
|
37782
37782
|
var encrypted = forge2.util.createBuffer(encryptedContentAsn1.value);
|
|
37783
37783
|
cipher.update(encrypted);
|
|
37784
37784
|
if (!cipher.finish()) {
|
|
@@ -37799,20 +37799,20 @@ var require_pkcs12 = __commonJS({
|
|
|
37799
37799
|
var res = [];
|
|
37800
37800
|
for (var i = 0; i < safeContents.value.length; i++) {
|
|
37801
37801
|
var safeBag = safeContents.value[i];
|
|
37802
|
-
var
|
|
37802
|
+
var capture2 = {};
|
|
37803
37803
|
var errors = [];
|
|
37804
|
-
if (!asn1.validate(safeBag, safeBagValidator,
|
|
37804
|
+
if (!asn1.validate(safeBag, safeBagValidator, capture2, errors)) {
|
|
37805
37805
|
var error = new Error("Cannot read SafeBag.");
|
|
37806
37806
|
error.errors = errors;
|
|
37807
37807
|
throw error;
|
|
37808
37808
|
}
|
|
37809
37809
|
var bag = {
|
|
37810
|
-
type: asn1.derToOid(
|
|
37811
|
-
attributes: _decodeBagAttributes(
|
|
37810
|
+
type: asn1.derToOid(capture2.bagId),
|
|
37811
|
+
attributes: _decodeBagAttributes(capture2.bagAttributes)
|
|
37812
37812
|
};
|
|
37813
37813
|
res.push(bag);
|
|
37814
37814
|
var validator, decoder;
|
|
37815
|
-
var bagAsn1 =
|
|
37815
|
+
var bagAsn1 = capture2.bagValue.value[0];
|
|
37816
37816
|
switch (bag.type) {
|
|
37817
37817
|
case pki.oids.pkcs8ShroudedKeyBag:
|
|
37818
37818
|
bagAsn1 = pki.decryptPrivateKeyInfo(bagAsn1, password);
|
|
@@ -37834,14 +37834,14 @@ var require_pkcs12 = __commonJS({
|
|
|
37834
37834
|
case pki.oids.certBag:
|
|
37835
37835
|
validator = certBagValidator;
|
|
37836
37836
|
decoder = function() {
|
|
37837
|
-
if (asn1.derToOid(
|
|
37837
|
+
if (asn1.derToOid(capture2.certId) !== pki.oids.x509Certificate) {
|
|
37838
37838
|
var error2 = new Error(
|
|
37839
37839
|
"Unsupported certificate type, only X.509 supported."
|
|
37840
37840
|
);
|
|
37841
|
-
error2.oid = asn1.derToOid(
|
|
37841
|
+
error2.oid = asn1.derToOid(capture2.certId);
|
|
37842
37842
|
throw error2;
|
|
37843
37843
|
}
|
|
37844
|
-
var certAsn1 = asn1.fromDer(
|
|
37844
|
+
var certAsn1 = asn1.fromDer(capture2.cert, strict);
|
|
37845
37845
|
try {
|
|
37846
37846
|
bag.cert = pki.certificateFromAsn1(certAsn1, true);
|
|
37847
37847
|
} catch (e) {
|
|
@@ -37855,7 +37855,7 @@ var require_pkcs12 = __commonJS({
|
|
|
37855
37855
|
error.oid = bag.type;
|
|
37856
37856
|
throw error;
|
|
37857
37857
|
}
|
|
37858
|
-
if (validator !== void 0 && !asn1.validate(bagAsn1, validator,
|
|
37858
|
+
if (validator !== void 0 && !asn1.validate(bagAsn1, validator, capture2, errors)) {
|
|
37859
37859
|
var error = new Error("Cannot read PKCS#12 " + validator.name);
|
|
37860
37860
|
error.errors = errors;
|
|
37861
37861
|
throw error;
|
|
@@ -37868,20 +37868,20 @@ var require_pkcs12 = __commonJS({
|
|
|
37868
37868
|
var decodedAttrs = {};
|
|
37869
37869
|
if (attributes !== void 0) {
|
|
37870
37870
|
for (var i = 0; i < attributes.length; ++i) {
|
|
37871
|
-
var
|
|
37871
|
+
var capture2 = {};
|
|
37872
37872
|
var errors = [];
|
|
37873
|
-
if (!asn1.validate(attributes[i], attributeValidator,
|
|
37873
|
+
if (!asn1.validate(attributes[i], attributeValidator, capture2, errors)) {
|
|
37874
37874
|
var error = new Error("Cannot read PKCS#12 BagAttribute.");
|
|
37875
37875
|
error.errors = errors;
|
|
37876
37876
|
throw error;
|
|
37877
37877
|
}
|
|
37878
|
-
var oid = asn1.derToOid(
|
|
37878
|
+
var oid = asn1.derToOid(capture2.oid);
|
|
37879
37879
|
if (pki.oids[oid] === void 0) {
|
|
37880
37880
|
continue;
|
|
37881
37881
|
}
|
|
37882
37882
|
decodedAttrs[pki.oids[oid]] = [];
|
|
37883
|
-
for (var j2 = 0; j2 <
|
|
37884
|
-
decodedAttrs[pki.oids[oid]].push(
|
|
37883
|
+
for (var j2 = 0; j2 < capture2.values.length; ++j2) {
|
|
37884
|
+
decodedAttrs[pki.oids[oid]].push(capture2.values[j2].value);
|
|
37885
37885
|
}
|
|
37886
37886
|
}
|
|
37887
37887
|
}
|
|
@@ -40994,20 +40994,20 @@ var require_ed25519 = __commonJS({
|
|
|
40994
40994
|
return { publicKey: pk, privateKey: sk };
|
|
40995
40995
|
};
|
|
40996
40996
|
ed25519.privateKeyFromAsn1 = function(obj) {
|
|
40997
|
-
var
|
|
40997
|
+
var capture2 = {};
|
|
40998
40998
|
var errors = [];
|
|
40999
|
-
var valid = forge2.asn1.validate(obj, privateKeyValidator,
|
|
40999
|
+
var valid = forge2.asn1.validate(obj, privateKeyValidator, capture2, errors);
|
|
41000
41000
|
if (!valid) {
|
|
41001
41001
|
var error = new Error("Invalid Key.");
|
|
41002
41002
|
error.errors = errors;
|
|
41003
41003
|
throw error;
|
|
41004
41004
|
}
|
|
41005
|
-
var oid = forge2.asn1.derToOid(
|
|
41005
|
+
var oid = forge2.asn1.derToOid(capture2.privateKeyOid);
|
|
41006
41006
|
var ed25519Oid = forge2.oids.EdDSA25519;
|
|
41007
41007
|
if (oid !== ed25519Oid) {
|
|
41008
41008
|
throw new Error('Invalid OID "' + oid + '"; OID must be "' + ed25519Oid + '".');
|
|
41009
41009
|
}
|
|
41010
|
-
var privateKey =
|
|
41010
|
+
var privateKey = capture2.privateKey;
|
|
41011
41011
|
var privateKeyBytes = messageToNativeBuffer({
|
|
41012
41012
|
message: forge2.asn1.fromDer(privateKey).value,
|
|
41013
41013
|
encoding: "binary"
|
|
@@ -41015,20 +41015,20 @@ var require_ed25519 = __commonJS({
|
|
|
41015
41015
|
return { privateKeyBytes };
|
|
41016
41016
|
};
|
|
41017
41017
|
ed25519.publicKeyFromAsn1 = function(obj) {
|
|
41018
|
-
var
|
|
41018
|
+
var capture2 = {};
|
|
41019
41019
|
var errors = [];
|
|
41020
|
-
var valid = forge2.asn1.validate(obj, publicKeyValidator,
|
|
41020
|
+
var valid = forge2.asn1.validate(obj, publicKeyValidator, capture2, errors);
|
|
41021
41021
|
if (!valid) {
|
|
41022
41022
|
var error = new Error("Invalid Key.");
|
|
41023
41023
|
error.errors = errors;
|
|
41024
41024
|
throw error;
|
|
41025
41025
|
}
|
|
41026
|
-
var oid = forge2.asn1.derToOid(
|
|
41026
|
+
var oid = forge2.asn1.derToOid(capture2.publicKeyOid);
|
|
41027
41027
|
var ed25519Oid = forge2.oids.EdDSA25519;
|
|
41028
41028
|
if (oid !== ed25519Oid) {
|
|
41029
41029
|
throw new Error('Invalid OID "' + oid + '"; OID must be "' + ed25519Oid + '".');
|
|
41030
41030
|
}
|
|
41031
|
-
var publicKeyBytes =
|
|
41031
|
+
var publicKeyBytes = capture2.ed25519PublicKey;
|
|
41032
41032
|
if (publicKeyBytes.length !== ed25519.constants.PUBLIC_KEY_BYTE_LENGTH) {
|
|
41033
41033
|
throw new Error("Key length is invalid.");
|
|
41034
41034
|
}
|
|
@@ -41485,31 +41485,31 @@ var require_ed25519 = __commonJS({
|
|
|
41485
41485
|
}
|
|
41486
41486
|
}
|
|
41487
41487
|
function unpackneg(r, p2) {
|
|
41488
|
-
var t = gf(), chk = gf(),
|
|
41488
|
+
var t = gf(), chk = gf(), num2 = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf();
|
|
41489
41489
|
set25519(r[2], gf1);
|
|
41490
41490
|
unpack25519(r[1], p2);
|
|
41491
|
-
S2(
|
|
41492
|
-
M2(den,
|
|
41493
|
-
Z2(
|
|
41491
|
+
S2(num2, r[1]);
|
|
41492
|
+
M2(den, num2, D);
|
|
41493
|
+
Z2(num2, num2, r[2]);
|
|
41494
41494
|
A2(den, r[2], den);
|
|
41495
41495
|
S2(den2, den);
|
|
41496
41496
|
S2(den4, den2);
|
|
41497
41497
|
M2(den6, den4, den2);
|
|
41498
|
-
M2(t, den6,
|
|
41498
|
+
M2(t, den6, num2);
|
|
41499
41499
|
M2(t, t, den);
|
|
41500
41500
|
pow2523(t, t);
|
|
41501
|
-
M2(t, t,
|
|
41501
|
+
M2(t, t, num2);
|
|
41502
41502
|
M2(t, t, den);
|
|
41503
41503
|
M2(t, t, den);
|
|
41504
41504
|
M2(r[0], t, den);
|
|
41505
41505
|
S2(chk, r[0]);
|
|
41506
41506
|
M2(chk, chk, den);
|
|
41507
|
-
if (neq25519(chk,
|
|
41507
|
+
if (neq25519(chk, num2)) {
|
|
41508
41508
|
M2(r[0], r[0], I2);
|
|
41509
41509
|
}
|
|
41510
41510
|
S2(chk, r[0]);
|
|
41511
41511
|
M2(chk, chk, den);
|
|
41512
|
-
if (neq25519(chk,
|
|
41512
|
+
if (neq25519(chk, num2)) {
|
|
41513
41513
|
return -1;
|
|
41514
41514
|
}
|
|
41515
41515
|
if (par25519(r[0]) === p2[31] >> 7) {
|
|
@@ -42344,14 +42344,14 @@ var require_pkcs7 = __commonJS({
|
|
|
42344
42344
|
return forge2.pem.encode(pemObj, { maxline });
|
|
42345
42345
|
};
|
|
42346
42346
|
p7.messageFromAsn1 = function(obj) {
|
|
42347
|
-
var
|
|
42347
|
+
var capture2 = {};
|
|
42348
42348
|
var errors = [];
|
|
42349
|
-
if (!asn1.validate(obj, p7.asn1.contentInfoValidator,
|
|
42349
|
+
if (!asn1.validate(obj, p7.asn1.contentInfoValidator, capture2, errors)) {
|
|
42350
42350
|
var error = new Error("Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 ContentInfo.");
|
|
42351
42351
|
error.errors = errors;
|
|
42352
42352
|
throw error;
|
|
42353
42353
|
}
|
|
42354
|
-
var contentType = asn1.derToOid(
|
|
42354
|
+
var contentType = asn1.derToOid(capture2.contentType);
|
|
42355
42355
|
var msg2;
|
|
42356
42356
|
switch (contentType) {
|
|
42357
42357
|
case forge2.pki.oids.envelopedData:
|
|
@@ -42366,7 +42366,7 @@ var require_pkcs7 = __commonJS({
|
|
|
42366
42366
|
default:
|
|
42367
42367
|
throw new Error("Cannot read PKCS#7 message. ContentType with OID " + contentType + " is not (yet) supported.");
|
|
42368
42368
|
}
|
|
42369
|
-
msg2.fromAsn1(
|
|
42369
|
+
msg2.fromAsn1(capture2.content.value[0]);
|
|
42370
42370
|
return msg2;
|
|
42371
42371
|
};
|
|
42372
42372
|
p7.createSignedData = function() {
|
|
@@ -42787,8 +42787,8 @@ var require_pkcs7 = __commonJS({
|
|
|
42787
42787
|
* @param obj the ASN.1 representation of the EnvelopedData content block.
|
|
42788
42788
|
*/
|
|
42789
42789
|
fromAsn1: function(obj) {
|
|
42790
|
-
var
|
|
42791
|
-
msg2.recipients = _recipientsFromAsn1(
|
|
42790
|
+
var capture2 = _fromAsn1(msg2, obj, p7.asn1.envelopedDataValidator);
|
|
42791
|
+
msg2.recipients = _recipientsFromAsn1(capture2.recipientInfos.value);
|
|
42792
42792
|
},
|
|
42793
42793
|
toAsn1: function() {
|
|
42794
42794
|
return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
|
|
@@ -42977,21 +42977,21 @@ var require_pkcs7 = __commonJS({
|
|
|
42977
42977
|
return msg2;
|
|
42978
42978
|
};
|
|
42979
42979
|
function _recipientFromAsn1(obj) {
|
|
42980
|
-
var
|
|
42980
|
+
var capture2 = {};
|
|
42981
42981
|
var errors = [];
|
|
42982
|
-
if (!asn1.validate(obj, p7.asn1.recipientInfoValidator,
|
|
42982
|
+
if (!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture2, errors)) {
|
|
42983
42983
|
var error = new Error("Cannot read PKCS#7 RecipientInfo. ASN.1 object is not an PKCS#7 RecipientInfo.");
|
|
42984
42984
|
error.errors = errors;
|
|
42985
42985
|
throw error;
|
|
42986
42986
|
}
|
|
42987
42987
|
return {
|
|
42988
|
-
version:
|
|
42989
|
-
issuer: forge2.pki.RDNAttributesAsArray(
|
|
42990
|
-
serialNumber: forge2.util.createBuffer(
|
|
42988
|
+
version: capture2.version.charCodeAt(0),
|
|
42989
|
+
issuer: forge2.pki.RDNAttributesAsArray(capture2.issuer),
|
|
42990
|
+
serialNumber: forge2.util.createBuffer(capture2.serial).toHex(),
|
|
42991
42991
|
encryptedContent: {
|
|
42992
|
-
algorithm: asn1.derToOid(
|
|
42993
|
-
parameter:
|
|
42994
|
-
content:
|
|
42992
|
+
algorithm: asn1.derToOid(capture2.encAlgorithm),
|
|
42993
|
+
parameter: capture2.encParameter ? capture2.encParameter.value : void 0,
|
|
42994
|
+
content: capture2.encKey
|
|
42995
42995
|
}
|
|
42996
42996
|
};
|
|
42997
42997
|
}
|
|
@@ -43220,52 +43220,52 @@ var require_pkcs7 = __commonJS({
|
|
|
43220
43220
|
];
|
|
43221
43221
|
}
|
|
43222
43222
|
function _fromAsn1(msg2, obj, validator) {
|
|
43223
|
-
var
|
|
43223
|
+
var capture2 = {};
|
|
43224
43224
|
var errors = [];
|
|
43225
|
-
if (!asn1.validate(obj, validator,
|
|
43225
|
+
if (!asn1.validate(obj, validator, capture2, errors)) {
|
|
43226
43226
|
var error = new Error("Cannot read PKCS#7 message. ASN.1 object is not a supported PKCS#7 message.");
|
|
43227
43227
|
error.errors = error;
|
|
43228
43228
|
throw error;
|
|
43229
43229
|
}
|
|
43230
|
-
var contentType = asn1.derToOid(
|
|
43230
|
+
var contentType = asn1.derToOid(capture2.contentType);
|
|
43231
43231
|
if (contentType !== forge2.pki.oids.data) {
|
|
43232
43232
|
throw new Error("Unsupported PKCS#7 message. Only wrapped ContentType Data supported.");
|
|
43233
43233
|
}
|
|
43234
|
-
if (
|
|
43234
|
+
if (capture2.encryptedContent) {
|
|
43235
43235
|
var content = "";
|
|
43236
|
-
if (forge2.util.isArray(
|
|
43237
|
-
for (var i = 0; i <
|
|
43238
|
-
if (
|
|
43236
|
+
if (forge2.util.isArray(capture2.encryptedContent)) {
|
|
43237
|
+
for (var i = 0; i < capture2.encryptedContent.length; ++i) {
|
|
43238
|
+
if (capture2.encryptedContent[i].type !== asn1.Type.OCTETSTRING) {
|
|
43239
43239
|
throw new Error("Malformed PKCS#7 message, expecting encrypted content constructed of only OCTET STRING objects.");
|
|
43240
43240
|
}
|
|
43241
|
-
content +=
|
|
43241
|
+
content += capture2.encryptedContent[i].value;
|
|
43242
43242
|
}
|
|
43243
43243
|
} else {
|
|
43244
|
-
content =
|
|
43244
|
+
content = capture2.encryptedContent;
|
|
43245
43245
|
}
|
|
43246
43246
|
msg2.encryptedContent = {
|
|
43247
|
-
algorithm: asn1.derToOid(
|
|
43248
|
-
parameter: forge2.util.createBuffer(
|
|
43247
|
+
algorithm: asn1.derToOid(capture2.encAlgorithm),
|
|
43248
|
+
parameter: forge2.util.createBuffer(capture2.encParameter.value),
|
|
43249
43249
|
content: forge2.util.createBuffer(content)
|
|
43250
43250
|
};
|
|
43251
43251
|
}
|
|
43252
|
-
if (
|
|
43252
|
+
if (capture2.content) {
|
|
43253
43253
|
var content = "";
|
|
43254
|
-
if (forge2.util.isArray(
|
|
43255
|
-
for (var i = 0; i <
|
|
43256
|
-
if (
|
|
43254
|
+
if (forge2.util.isArray(capture2.content)) {
|
|
43255
|
+
for (var i = 0; i < capture2.content.length; ++i) {
|
|
43256
|
+
if (capture2.content[i].type !== asn1.Type.OCTETSTRING) {
|
|
43257
43257
|
throw new Error("Malformed PKCS#7 message, expecting content constructed of only OCTET STRING objects.");
|
|
43258
43258
|
}
|
|
43259
|
-
content +=
|
|
43259
|
+
content += capture2.content[i].value;
|
|
43260
43260
|
}
|
|
43261
43261
|
} else {
|
|
43262
|
-
content =
|
|
43262
|
+
content = capture2.content;
|
|
43263
43263
|
}
|
|
43264
43264
|
msg2.content = forge2.util.createBuffer(content);
|
|
43265
43265
|
}
|
|
43266
|
-
msg2.version =
|
|
43267
|
-
msg2.rawCapture =
|
|
43268
|
-
return
|
|
43266
|
+
msg2.version = capture2.version.charCodeAt(0);
|
|
43267
|
+
msg2.rawCapture = capture2;
|
|
43268
|
+
return capture2;
|
|
43269
43269
|
}
|
|
43270
43270
|
function _decryptContent(msg2) {
|
|
43271
43271
|
if (msg2.encryptedContent.key === void 0) {
|
|
@@ -43425,8 +43425,8 @@ var require_ssh = __commonJS({
|
|
|
43425
43425
|
}
|
|
43426
43426
|
function _sha1() {
|
|
43427
43427
|
var sha = forge2.md.sha1.create();
|
|
43428
|
-
var
|
|
43429
|
-
for (var i = 0; i <
|
|
43428
|
+
var num2 = arguments.length;
|
|
43429
|
+
for (var i = 0; i < num2; ++i) {
|
|
43430
43430
|
sha.update(arguments[i]);
|
|
43431
43431
|
}
|
|
43432
43432
|
return sha.digest();
|
|
@@ -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,
|
|
@@ -45814,14 +45845,14 @@ function renderUncompressedRanges(visible) {
|
|
|
45814
45845
|
};
|
|
45815
45846
|
const merged = [];
|
|
45816
45847
|
for (const m2 of visible) {
|
|
45817
|
-
const
|
|
45848
|
+
const num2 = refNum2(m2.ref);
|
|
45818
45849
|
const last = merged[merged.length - 1];
|
|
45819
|
-
if (last &&
|
|
45850
|
+
if (last && num2 === last.startNum + last.count) {
|
|
45820
45851
|
last.endRef = m2.ref;
|
|
45821
45852
|
last.count += 1;
|
|
45822
45853
|
last.tokens += m2.tokens;
|
|
45823
45854
|
} else {
|
|
45824
|
-
merged.push({ startRef: m2.ref, endRef: m2.ref, startNum:
|
|
45855
|
+
merged.push({ startRef: m2.ref, endRef: m2.ref, startNum: num2, count: 1, tokens: m2.tokens, tool: m2.tool });
|
|
45825
45856
|
}
|
|
45826
45857
|
}
|
|
45827
45858
|
for (const r of merged.slice(0, 30)) {
|
|
@@ -46133,7 +46164,14 @@ function configureLogger(file) {
|
|
|
46133
46164
|
stream = openStream(file);
|
|
46134
46165
|
return file;
|
|
46135
46166
|
}
|
|
46167
|
+
var capture = null;
|
|
46136
46168
|
var log = (level, msg2) => {
|
|
46169
|
+
if (capture) {
|
|
46170
|
+
try {
|
|
46171
|
+
capture(level, msg2);
|
|
46172
|
+
} catch {
|
|
46173
|
+
}
|
|
46174
|
+
}
|
|
46137
46175
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
46138
46176
|
const line = `${ts2} [${level}] ${msg2}
|
|
46139
46177
|
`;
|
|
@@ -46399,13 +46437,32 @@ function openProxySocket(proxy) {
|
|
|
46399
46437
|
}
|
|
46400
46438
|
return net.connect(proxy.port, proxy.host);
|
|
46401
46439
|
}
|
|
46440
|
+
var CONNECT_TIMEOUT_MS = 1e4;
|
|
46441
|
+
var connectFactory = (port, host) => net.connect(port, host);
|
|
46442
|
+
function connectDirect(host, port, timeoutMs = CONNECT_TIMEOUT_MS) {
|
|
46443
|
+
return new Promise((resolve, reject) => {
|
|
46444
|
+
const socket = connectFactory(port, host);
|
|
46445
|
+
let settled = false;
|
|
46446
|
+
const finishError = (error) => {
|
|
46447
|
+
if (settled) return;
|
|
46448
|
+
settled = true;
|
|
46449
|
+
clearTimeout(timer2);
|
|
46450
|
+
socket.destroy();
|
|
46451
|
+
reject(error);
|
|
46452
|
+
};
|
|
46453
|
+
const timer2 = setTimeout(() => finishError(new Error(`upstream connect ${host}:${port} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
46454
|
+
socket.once("error", finishError);
|
|
46455
|
+
socket.once("connect", () => {
|
|
46456
|
+
if (settled) return;
|
|
46457
|
+
settled = true;
|
|
46458
|
+
clearTimeout(timer2);
|
|
46459
|
+
resolve(socket);
|
|
46460
|
+
});
|
|
46461
|
+
});
|
|
46462
|
+
}
|
|
46402
46463
|
function connectThroughProxy(host, port, proxyUrl) {
|
|
46403
46464
|
if (!proxyUrl) {
|
|
46404
|
-
return
|
|
46405
|
-
const socket = net.connect(port, host);
|
|
46406
|
-
socket.once("connect", () => resolve(socket));
|
|
46407
|
-
socket.once("error", reject);
|
|
46408
|
-
});
|
|
46465
|
+
return connectDirect(host, port);
|
|
46409
46466
|
}
|
|
46410
46467
|
const proxy = parseHttpProxy(proxyUrl);
|
|
46411
46468
|
if (!proxy) return Promise.reject(new Error(`invalid upstream proxy: ${redactProxyUrl(proxyUrl)}`));
|
|
@@ -46419,7 +46476,7 @@ function connectThroughProxy(host, port, proxyUrl) {
|
|
|
46419
46476
|
socket.destroy();
|
|
46420
46477
|
reject(error);
|
|
46421
46478
|
};
|
|
46422
|
-
const timer2 = setTimeout(() => finishError(new Error(`upstream proxy CONNECT ${host}:${port} handshake timeout`)),
|
|
46479
|
+
const timer2 = setTimeout(() => finishError(new Error(`upstream proxy CONNECT ${host}:${port} handshake timeout`)), CONNECT_TIMEOUT_MS);
|
|
46423
46480
|
socket.once("error", finishError);
|
|
46424
46481
|
const connectedEvent = proxy.protocol === "https:" ? "secureConnect" : "connect";
|
|
46425
46482
|
socket.once(connectedEvent, () => {
|
|
@@ -46507,13 +46564,13 @@ function getUpstreamConnectionStatus() {
|
|
|
46507
46564
|
}
|
|
46508
46565
|
|
|
46509
46566
|
// src/config.ts
|
|
46510
|
-
function safeReadJson(
|
|
46567
|
+
function safeReadJson(path14) {
|
|
46511
46568
|
try {
|
|
46512
|
-
const raw = readFileSync(
|
|
46569
|
+
const raw = readFileSync(path14, "utf8").replace(/^\uFEFF/, "");
|
|
46513
46570
|
return JSON.parse(raw);
|
|
46514
46571
|
} catch (e) {
|
|
46515
46572
|
if (e.code !== "ENOENT") {
|
|
46516
|
-
log("error", `[acp-config] failed to parse ${
|
|
46573
|
+
log("error", `[acp-config] failed to parse ${path14}: ${String(e)}`);
|
|
46517
46574
|
}
|
|
46518
46575
|
return void 0;
|
|
46519
46576
|
}
|
|
@@ -46593,7 +46650,8 @@ function loadOptions(env = process.env) {
|
|
|
46593
46650
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
46594
46651
|
throw new Error(`Invalid port ${Number.isNaN(port) ? "(not a number)" : port}; must be 1-65535`);
|
|
46595
46652
|
}
|
|
46596
|
-
const
|
|
46653
|
+
const rawHost = env.ACP_HOST ?? fileConfig.host ?? "127.0.0.1";
|
|
46654
|
+
const host = rawHost === "localhost" ? "127.0.0.1" : rawHost;
|
|
46597
46655
|
const upstream = (env.ACP_UPSTREAM ?? fileConfig.upstream ?? "https://api.anthropic.com").replace(/\/$/, "");
|
|
46598
46656
|
const routes = loadRoutes(env);
|
|
46599
46657
|
const modelContextLimit = parseInt(env.ACP_MODEL_CONTEXT_LIMIT ?? `${fileConfig.modelContextLimit ?? 2e5}`, 10);
|
|
@@ -46724,6 +46782,65 @@ function parsePromptCacheRouting(value) {
|
|
|
46724
46782
|
function parseUpstreamProxyMode(value) {
|
|
46725
46783
|
return value === "manual" || value === "auto" ? value : "direct";
|
|
46726
46784
|
}
|
|
46785
|
+
function parseCompressSettings(v2) {
|
|
46786
|
+
if (!v2 || typeof v2 !== "object" || Array.isArray(v2)) return void 0;
|
|
46787
|
+
const obj = v2;
|
|
46788
|
+
const out = {};
|
|
46789
|
+
const numberOrPercent = (value) => typeof value === "number" && Number.isFinite(value) || typeof value === "string" && /^\d+(\.\d+)?%$/.test(value.trim());
|
|
46790
|
+
let ok = true;
|
|
46791
|
+
const takeNumber = (key) => {
|
|
46792
|
+
if (!(key in obj)) return;
|
|
46793
|
+
if (typeof obj[key] !== "number" || !Number.isFinite(obj[key])) ok = false;
|
|
46794
|
+
else out[key] = obj[key];
|
|
46795
|
+
};
|
|
46796
|
+
for (const key of ["modelContextLimit", "maxContextLimit", "emergencyThresholdPercent"]) {
|
|
46797
|
+
if (!(key in obj)) continue;
|
|
46798
|
+
if (!numberOrPercent(obj[key])) {
|
|
46799
|
+
ok = false;
|
|
46800
|
+
continue;
|
|
46801
|
+
}
|
|
46802
|
+
out[key] = typeof obj[key] === "string" ? obj[key].trim() : obj[key];
|
|
46803
|
+
}
|
|
46804
|
+
for (const key of ["nudgeGrowthTokens", "preserveRecentMessages", "preserveRecentTokens", "minCompressRange"]) {
|
|
46805
|
+
takeNumber(key);
|
|
46806
|
+
}
|
|
46807
|
+
if ("tiers" in obj) {
|
|
46808
|
+
if (typeof obj.tiers !== "boolean") ok = false;
|
|
46809
|
+
else out.tiers = obj.tiers;
|
|
46810
|
+
}
|
|
46811
|
+
for (const key of ["injectTool", "injectNudge"]) {
|
|
46812
|
+
if (key in obj) {
|
|
46813
|
+
if (typeof obj[key] !== "boolean") ok = false;
|
|
46814
|
+
else out[key] = obj[key];
|
|
46815
|
+
}
|
|
46816
|
+
}
|
|
46817
|
+
if ("acknowledgePromptsRisk" in obj) {
|
|
46818
|
+
if (typeof obj.acknowledgePromptsRisk !== "boolean") ok = false;
|
|
46819
|
+
else out.acknowledgePromptsRisk = obj.acknowledgePromptsRisk;
|
|
46820
|
+
}
|
|
46821
|
+
if ("prompts" in obj && obj.prompts !== void 0) {
|
|
46822
|
+
const prompts = obj.prompts;
|
|
46823
|
+
if (!prompts || typeof prompts !== "object" || Array.isArray(prompts)) {
|
|
46824
|
+
ok = false;
|
|
46825
|
+
} else {
|
|
46826
|
+
const cleaned = {};
|
|
46827
|
+
for (const [key, value] of Object.entries(prompts)) {
|
|
46828
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
46829
|
+
ok = false;
|
|
46830
|
+
continue;
|
|
46831
|
+
}
|
|
46832
|
+
if (key !== "compressPhilosophy" && key !== "howToCompressRules" && key !== "tier2DistillRules" && key !== "tier3CondenseRules") {
|
|
46833
|
+
ok = false;
|
|
46834
|
+
continue;
|
|
46835
|
+
}
|
|
46836
|
+
cleaned[key] = value;
|
|
46837
|
+
}
|
|
46838
|
+
if (ok) out.prompts = cleaned;
|
|
46839
|
+
}
|
|
46840
|
+
}
|
|
46841
|
+
if (!ok) return void 0;
|
|
46842
|
+
return out;
|
|
46843
|
+
}
|
|
46727
46844
|
function rejectLegacyRoute(key, value) {
|
|
46728
46845
|
if (typeof value !== "string") return;
|
|
46729
46846
|
throw new Error(
|
|
@@ -46733,7 +46850,7 @@ function rejectLegacyRoute(key, value) {
|
|
|
46733
46850
|
|
|
46734
46851
|
// src/server.ts
|
|
46735
46852
|
import http from "http";
|
|
46736
|
-
import
|
|
46853
|
+
import fs6 from "fs";
|
|
46737
46854
|
|
|
46738
46855
|
// src/compress-settings.ts
|
|
46739
46856
|
function resolveContextLimitValue(raw, nativeLimit) {
|
|
@@ -46978,23 +47095,11 @@ async function fetchWithTimeout(url, opts, timeoutMs = UPSTREAM_TIMEOUT_MS, exte
|
|
|
46978
47095
|
}
|
|
46979
47096
|
}
|
|
46980
47097
|
|
|
46981
|
-
//
|
|
47098
|
+
// node_modules/acp-kernel/dist/wire/index.js
|
|
46982
47099
|
import { createHash } from "crypto";
|
|
46983
47100
|
function hashId(s3) {
|
|
46984
47101
|
return createHash("sha256").update(s3, "utf8").digest("hex").slice(0, 16);
|
|
46985
47102
|
}
|
|
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
47103
|
function deriveMessageId(role, contentType, text, options = {}) {
|
|
46999
47104
|
const seed = `${role}|${contentType}|${options.toolCallId ?? ""}|${options.toolName ?? ""}|${text}`;
|
|
47000
47105
|
return "h_" + hashId(seed);
|
|
@@ -47007,8 +47112,6 @@ var ClusterCounter = class {
|
|
|
47007
47112
|
return n === 0 ? baseId : `${baseId}_${n}`;
|
|
47008
47113
|
}
|
|
47009
47114
|
};
|
|
47010
|
-
|
|
47011
|
-
// src/anthropic.ts
|
|
47012
47115
|
function extractSystem(system) {
|
|
47013
47116
|
if (!system) return "";
|
|
47014
47117
|
if (typeof system === "string") return system;
|
|
@@ -47153,8 +47256,8 @@ function coreToAnthropic(messages, cacheControls) {
|
|
|
47153
47256
|
flush();
|
|
47154
47257
|
return out;
|
|
47155
47258
|
}
|
|
47156
|
-
function conversationSignalAnthropic(body,
|
|
47157
|
-
if (
|
|
47259
|
+
function conversationSignalAnthropic(body, headerValue3) {
|
|
47260
|
+
if (headerValue3 && headerValue3.trim()) return headerValue3.trim();
|
|
47158
47261
|
const firstUser = body.messages.find((m2) => m2.role === "user");
|
|
47159
47262
|
const seed = firstUser ? JSON.stringify(firstUser.content) : "default";
|
|
47160
47263
|
return hashId(seed);
|
|
@@ -47174,15 +47277,11 @@ function safeParse(s3) {
|
|
|
47174
47277
|
return {};
|
|
47175
47278
|
}
|
|
47176
47279
|
}
|
|
47177
|
-
|
|
47178
|
-
// src/bili-message.ts
|
|
47179
47280
|
function parseDataUrl(url) {
|
|
47180
47281
|
const m2 = /^data:([^;,]+)(?:;base64)?,(.+)$/i.exec(url);
|
|
47181
47282
|
if (!m2) return void 0;
|
|
47182
47283
|
return { mediaType: m2[1], base64: m2[2] };
|
|
47183
47284
|
}
|
|
47184
|
-
|
|
47185
|
-
// src/openai.ts
|
|
47186
47285
|
function openaiToCore(body) {
|
|
47187
47286
|
const msgs = [];
|
|
47188
47287
|
const clusters = new ClusterCounter();
|
|
@@ -47333,8 +47432,8 @@ ${extra}` : extra;
|
|
|
47333
47432
|
}
|
|
47334
47433
|
return [{ role: "system", content: extra }, ...messages];
|
|
47335
47434
|
}
|
|
47336
|
-
function conversationSignalOpenai(body,
|
|
47337
|
-
if (
|
|
47435
|
+
function conversationSignalOpenai(body, headerValue3) {
|
|
47436
|
+
if (headerValue3 && headerValue3.trim()) return headerValue3.trim();
|
|
47338
47437
|
const firstUser = body.messages.find((m2) => m2.role === "user");
|
|
47339
47438
|
const seed = firstUser ? stringContent(firstUser.content) : "default";
|
|
47340
47439
|
return hashId(seed);
|
|
@@ -47361,8 +47460,6 @@ function firstImagePart(content) {
|
|
|
47361
47460
|
}
|
|
47362
47461
|
return void 0;
|
|
47363
47462
|
}
|
|
47364
|
-
|
|
47365
|
-
// src/responses.ts
|
|
47366
47463
|
var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set([
|
|
47367
47464
|
"additional_tools",
|
|
47368
47465
|
"mcp_list_tools"
|
|
@@ -47621,8 +47718,8 @@ function injectResponsesDeveloperMessage(input, content) {
|
|
|
47621
47718
|
items.splice(index, 0, { type: "message", role: "developer", content });
|
|
47622
47719
|
return items;
|
|
47623
47720
|
}
|
|
47624
|
-
function conversationIdentityResponses(body,
|
|
47625
|
-
if (
|
|
47721
|
+
function conversationIdentityResponses(body, headerValue3) {
|
|
47722
|
+
if (headerValue3?.trim()) return { value: headerValue3.trim(), source: "header", clientProvided: true };
|
|
47626
47723
|
if (typeof body.session_id === "string" && body.session_id.trim()) {
|
|
47627
47724
|
return { value: body.session_id.trim(), source: "body-session", clientProvided: true };
|
|
47628
47725
|
}
|
|
@@ -47635,8 +47732,27 @@ function conversationIdentityResponses(body, headerValue2) {
|
|
|
47635
47732
|
}
|
|
47636
47733
|
return { value: hashId(JSON.stringify(body.input ?? [])), source: "content-fingerprint", clientProvided: false };
|
|
47637
47734
|
}
|
|
47638
|
-
function conversationSignalResponses(body,
|
|
47639
|
-
return conversationIdentityResponses(body,
|
|
47735
|
+
function conversationSignalResponses(body, headerValue3) {
|
|
47736
|
+
return conversationIdentityResponses(body, headerValue3).value;
|
|
47737
|
+
}
|
|
47738
|
+
function createSubagentNamespaces() {
|
|
47739
|
+
const anchors = /* @__PURE__ */ new Map();
|
|
47740
|
+
return {
|
|
47741
|
+
namespaceFor(identityValue, instructions) {
|
|
47742
|
+
if (typeof instructions !== "string" || instructions.trim().length === 0) return identityValue;
|
|
47743
|
+
const fp = hashId(instructions);
|
|
47744
|
+
const anchor = anchors.get(identityValue);
|
|
47745
|
+
if (anchor === void 0) {
|
|
47746
|
+
anchors.set(identityValue, fp);
|
|
47747
|
+
return identityValue;
|
|
47748
|
+
}
|
|
47749
|
+
return anchor === fp ? identityValue : `${identityValue}|sub:${fp}`;
|
|
47750
|
+
}
|
|
47751
|
+
};
|
|
47752
|
+
}
|
|
47753
|
+
var defaultNamespaces = createSubagentNamespaces();
|
|
47754
|
+
function subagentNamespace(identityValue, instructions) {
|
|
47755
|
+
return defaultNamespaces.namespaceFor(identityValue, instructions);
|
|
47640
47756
|
}
|
|
47641
47757
|
|
|
47642
47758
|
// src/persist.ts
|
|
@@ -47644,7 +47760,7 @@ import { promises as fs } from "fs";
|
|
|
47644
47760
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
47645
47761
|
import { createHash as createHash2 } from "crypto";
|
|
47646
47762
|
import * as path4 from "path";
|
|
47647
|
-
var PERSIST_VERSION =
|
|
47763
|
+
var PERSIST_VERSION = 3;
|
|
47648
47764
|
function mergeState(parsed) {
|
|
47649
47765
|
const fresh = createInitialState();
|
|
47650
47766
|
return {
|
|
@@ -47653,7 +47769,8 @@ function mergeState(parsed) {
|
|
|
47653
47769
|
nudge: { ...fresh.nudge, ...parsed.nudge ?? {} },
|
|
47654
47770
|
stats: { ...fresh.stats, ...parsed.stats ?? {} },
|
|
47655
47771
|
nextBlockId: parsed.nextBlockId ?? fresh.nextBlockId,
|
|
47656
|
-
nextRunId: parsed.nextRunId ?? fresh.nextRunId
|
|
47772
|
+
nextRunId: parsed.nextRunId ?? fresh.nextRunId,
|
|
47773
|
+
tokenSnapshot: parsed.tokenSnapshot ?? fresh.tokenSnapshot
|
|
47657
47774
|
};
|
|
47658
47775
|
}
|
|
47659
47776
|
function hostLabel(upstreamOrigin) {
|
|
@@ -47913,6 +48030,7 @@ function buildRecord(session) {
|
|
|
47913
48030
|
id: session.id,
|
|
47914
48031
|
meta: { ...session.meta },
|
|
47915
48032
|
stats: { ...session.stats },
|
|
48033
|
+
messages: session.lastMessages,
|
|
47916
48034
|
metadata: { ...session.metadata },
|
|
47917
48035
|
state: session.state,
|
|
47918
48036
|
blockContents: Object.fromEntries(session.blockContents),
|
|
@@ -47949,6 +48067,7 @@ function buildSession(parsed) {
|
|
|
47949
48067
|
createdAt: parsed.createdAt ?? Date.now(),
|
|
47950
48068
|
lastSeen: Date.now(),
|
|
47951
48069
|
blockContents,
|
|
48070
|
+
lastMessages: Array.isArray(parsed.messages) ? parsed.messages : void 0,
|
|
47952
48071
|
inFlight: 0,
|
|
47953
48072
|
persisted: true
|
|
47954
48073
|
};
|
|
@@ -48084,6 +48203,12 @@ async function withSessionLock(session, fn) {
|
|
|
48084
48203
|
function listSessions() {
|
|
48085
48204
|
return [...sessions.values()].sort((a, b2) => b2.lastSeen - a.lastSeen);
|
|
48086
48205
|
}
|
|
48206
|
+
function peekSession(id) {
|
|
48207
|
+
return sessions.get(id);
|
|
48208
|
+
}
|
|
48209
|
+
function snapshotMessages(session, messages) {
|
|
48210
|
+
if (messages.length > 0) session.lastMessages = messages;
|
|
48211
|
+
}
|
|
48087
48212
|
function markDirty(session) {
|
|
48088
48213
|
getStore().scheduleSave(session);
|
|
48089
48214
|
}
|
|
@@ -48183,8 +48308,17 @@ function parseCompressInput(input, callId) {
|
|
|
48183
48308
|
return [];
|
|
48184
48309
|
}
|
|
48185
48310
|
const obj = input;
|
|
48311
|
+
let content = obj.content;
|
|
48312
|
+
if (typeof content === "string") {
|
|
48313
|
+
try {
|
|
48314
|
+
content = JSON.parse(content);
|
|
48315
|
+
} catch {
|
|
48316
|
+
log("warn", `[acp-compress-input] content is a string but not valid JSON; parsed 0 valid ranges`);
|
|
48317
|
+
return [];
|
|
48318
|
+
}
|
|
48319
|
+
}
|
|
48186
48320
|
const single = toRange(obj);
|
|
48187
|
-
const ranges = Array.isArray(
|
|
48321
|
+
const ranges = Array.isArray(content) ? content.map((r) => toRange(r)).filter((r) => r !== null) : single ? [single] : [];
|
|
48188
48322
|
if (ranges.length === 0) {
|
|
48189
48323
|
log("warn", `[acp-compress-input] parsed 0 valid ranges. top keys: ${Object.keys(obj).join(",")}`);
|
|
48190
48324
|
}
|
|
@@ -48489,6 +48623,12 @@ ${body.slice(0, 4e3)}...`;
|
|
|
48489
48623
|
${body}`;
|
|
48490
48624
|
}
|
|
48491
48625
|
|
|
48626
|
+
// src/sse-util.ts
|
|
48627
|
+
function normalizeSseLineEndings(buf) {
|
|
48628
|
+
if (buf.indexOf("\r") === -1) return buf;
|
|
48629
|
+
return buf.replace(/\r\n|\r/g, "\n");
|
|
48630
|
+
}
|
|
48631
|
+
|
|
48492
48632
|
// src/stream.ts
|
|
48493
48633
|
function executeAnthropicProxyTool(toolName, args, ctx) {
|
|
48494
48634
|
if (toolName === COMPRESS_TOOL_NAME) {
|
|
@@ -48608,16 +48748,17 @@ function busy(button,on,label){if(!button)return;if(on){button.dataset.label=but
|
|
|
48608
48748
|
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
48749
|
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
48750
|
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}
|
|
48751
|
+
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
48752
|
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
48753
|
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
48754
|
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
48755
|
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)}}
|
|
48756
|
+
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
48757
|
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
48758
|
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
48759
|
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
48760
|
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);
|
|
48761
|
+
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
48762
|
Promise.all([loadConfig(),loadUpstream()]).catch((error)=>toast(String(error),true));setInterval(()=>{if(byId("page-sessions").classList.contains("active"))loadSessions().catch(()=>{})},5000);
|
|
48622
48763
|
`;
|
|
48623
48764
|
|
|
@@ -48639,7 +48780,7 @@ function renderPage(origin, version2) {
|
|
|
48639
48780
|
<p class="hint">\u5728\u5BA2\u6237\u7AEF\u914D\u7F6E\u91CC\u628A\u539F baseURL \u524D\u52A0\u4E0A <span class="mono">${origin}/bili/</span> \u5373\u53EF\uFF0C\u5176\u4F59\u4E0D\u53D8\u3002</p>
|
|
48640
48781
|
<div class="card"><div class="card-head"><h2>OpenCode</h2><button class="btn small copy-btn" data-copy="${origin}/bili/https://open.bigmodel.cn/api/coding/paas/v4">\u590D\u5236</button></div><dl class="kv"><dt>\u914D\u7F6E\u6587\u4EF6</dt><dd class="mono">~/.config/opencode/opencode.json</dd><dt>baseURL</dt><dd class="mono">${origin}/bili/https://open.bigmodel.cn/api/coding/paas/v4</dd></dl></div>
|
|
48641
48782
|
<div class="card"><div class="card-head"><h2>Codex\uFF08API key\uFF09</h2><button class="btn small copy-btn" data-copy="${origin}/bili/https://api.openai.com/v1">\u590D\u5236</button></div><dl class="kv"><dt>\u914D\u7F6E\u6587\u4EF6</dt><dd class="mono">~/.codex/config.toml</dd><dt>base_url</dt><dd class="mono">${origin}/bili/https://api.openai.com/v1</dd></dl></div>
|
|
48642
|
-
<div class="card"><div class="card-head"><h2>Codex\uFF08ChatGPT \u767B\u5F55\uFF09</h2><button class="btn small copy-btn" data-copy="
|
|
48783
|
+
<div class="card"><div class="card-head"><h2>Codex\uFF08ChatGPT \u767B\u5F55\uFF09</h2><button class="btn small copy-btn" data-copy="openai_base_url = "${origin}/bili/https://chatgpt.com/backend-api/codex"">\u590D\u5236\u914D\u7F6E</button></div><dl class="kv"><dt>\u914D\u7F6E\u6587\u4EF6</dt><dd class="mono">~/.codex/config.toml</dd><dt>\u914D\u7F6E</dt><dd class="mono">openai_base_url = "${origin}/bili/https://chatgpt.com/backend-api/codex"</dd><dt>\u8BA4\u8BC1</dt><dd><span class="mono">codex login</span>\uFF08OAuth token \u900F\u4F20\uFF0C\u65E0\u9700\u8BC1\u4E66\uFF09</dd><dt>\u8BF4\u660E</dt><dd>\u9ED8\u8BA4 provider \u5C31\u662F openai\uFF0C\u65E0\u9700 model_provider\uFF1B\u82E5 config.toml \u91CC\u6539\u8FC7 <span class="mono">model_provider</span>\uFF0C\u9700\u518D\u52A0\u4E00\u884C <span class="mono">model_provider = "openai"</span>\u3002\u8FDE\u4E0D\u4E0A\u65F6\u68C0\u67E5\u4EE3\u7406\u73AF\u5883\u53D8\u91CF\uFF1A\u8BBE\u4E86 HTTP(S)_PROXY \u9700\u52A0 <span class="mono">NO_PROXY=localhost,127.0.0.1</span>\uFF1Bbili \u8DD1\u5728 WSL2/Docker \u91CC\u65F6 Windows \u4FA7\u8BF7\u7528 <span class="mono">localhost</span>\uFF08\u81EA\u52A8\u8F6C\u53D1\uFF09\uFF0C127.0.0.1 \u4E0D\u901A\u3002</dd></dl></div>
|
|
48643
48784
|
<div class="card"><div class="card-head"><h2>Claude Code\uFF08API key\uFF09</h2><button class="btn small copy-btn" data-copy="${origin}/bili/https://api.anthropic.com">\u590D\u5236</button></div><dl class="kv"><dt>\u73AF\u5883\u53D8\u91CF</dt><dd class="mono">ANTHROPIC_BASE_URL=${origin}/bili/https://api.anthropic.com</dd></dl></div>
|
|
48644
48785
|
<div class="card"><div class="card-head"><h2>Pi</h2><span class="badge">\u4E0D\u63A8\u8350</span><button class="btn small copy-btn" data-copy="${origin}/bili/https://api.anthropic.com">\u590D\u5236</button></div><dl class="kv"><dt>\u914D\u7F6E\u6587\u4EF6</dt><dd class="mono">~/.pi/agent/models.json</dd><dt>baseUrl</dt><dd class="mono">${origin}/bili/https://api.anthropic.com</dd></dl><p class="hint">\u26A0\uFE0F \u4E0D\u63A8\u8350\uFF1APi \u7684 session \u7BA1\u7406\u4E0E bili \u538B\u7F29\u72B6\u6001\u5B58\u5728\u51B2\u7A81\uFF0C\u8BE6\u89C1 README\u3002</p></div>
|
|
48645
48786
|
<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>
|
|
@@ -48648,7 +48789,7 @@ function renderPage(origin, version2) {
|
|
|
48648
48789
|
<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
48790
|
<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
48791
|
<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>`;
|
|
48792
|
+
<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
48793
|
}
|
|
48653
48794
|
|
|
48654
48795
|
// src/web/api.ts
|
|
@@ -48693,12 +48834,14 @@ function atomicWriteConfig(config) {
|
|
|
48693
48834
|
}
|
|
48694
48835
|
async function handleConfigGet(res) {
|
|
48695
48836
|
const upstream = readUpstreamSettings();
|
|
48837
|
+
const config = readConfig();
|
|
48696
48838
|
res.writeHead(200, { "content-type": "application/json" });
|
|
48697
48839
|
res.end(JSON.stringify({
|
|
48698
48840
|
path: configFile(),
|
|
48699
48841
|
providers: readProviders(),
|
|
48700
48842
|
upstreamProxy: upstream.proxy ?? null,
|
|
48701
|
-
upstreamProxyMode: upstream.mode
|
|
48843
|
+
upstreamProxyMode: upstream.mode,
|
|
48844
|
+
compress: config.compress ?? null
|
|
48702
48845
|
}, null, 2));
|
|
48703
48846
|
}
|
|
48704
48847
|
async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
@@ -48708,7 +48851,8 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48708
48851
|
const hasProviders = Object.prototype.hasOwnProperty.call(body, "providers");
|
|
48709
48852
|
const hasProxy = Object.prototype.hasOwnProperty.call(body, "upstreamProxy");
|
|
48710
48853
|
const hasMode = Object.prototype.hasOwnProperty.call(body, "upstreamProxyMode");
|
|
48711
|
-
|
|
48854
|
+
const hasCompress = Object.prototype.hasOwnProperty.call(body, "compress");
|
|
48855
|
+
if (!hasProviders && !hasProxy && !hasMode && !hasCompress) return sendError(res, 400, "expected providers, upstream proxy, or compress settings");
|
|
48712
48856
|
const routes = {};
|
|
48713
48857
|
if (hasProviders) {
|
|
48714
48858
|
if (!body.providers || typeof body.providers !== "object" || Array.isArray(body.providers)) {
|
|
@@ -48747,6 +48891,11 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48747
48891
|
if (mode === "manual" && !proxy && !readUpstreamSettings().proxy) {
|
|
48748
48892
|
return sendError(res, 400, "manual mode requires an upstream proxy URL");
|
|
48749
48893
|
}
|
|
48894
|
+
let compress;
|
|
48895
|
+
if (hasCompress) {
|
|
48896
|
+
compress = body.compress === null ? {} : parseCompressSettings(body.compress);
|
|
48897
|
+
if (compress === void 0) return sendError(res, 400, "invalid compress settings");
|
|
48898
|
+
}
|
|
48750
48899
|
const config = readConfig();
|
|
48751
48900
|
if (hasProviders) config.providers = routes;
|
|
48752
48901
|
if (hasProxy) {
|
|
@@ -48754,13 +48903,21 @@ async function handleConfigPut(req, res, onChanged, biliPort = 8787) {
|
|
|
48754
48903
|
else delete config.upstreamProxy;
|
|
48755
48904
|
}
|
|
48756
48905
|
if (hasMode && mode) config.upstreamProxyMode = mode;
|
|
48906
|
+
if (hasCompress) {
|
|
48907
|
+
if (compress && Object.keys(compress).length > 0) config.compress = compress;
|
|
48908
|
+
else delete config.compress;
|
|
48909
|
+
}
|
|
48757
48910
|
try {
|
|
48758
48911
|
atomicWriteConfig(config);
|
|
48759
48912
|
onChanged?.();
|
|
48760
48913
|
} catch (error) {
|
|
48761
48914
|
return sendError(res, 500, `failed to apply config: ${String(error)}`);
|
|
48762
48915
|
}
|
|
48763
|
-
|
|
48916
|
+
const changed = [];
|
|
48917
|
+
if (hasProviders) changed.push(`${Object.keys(routes).length} routes`);
|
|
48918
|
+
if (hasProxy || hasMode) changed.push("network");
|
|
48919
|
+
if (hasCompress) changed.push("compress");
|
|
48920
|
+
log("info", `[acp-web] configuration updated (${changed.join(", ") || "none"})`);
|
|
48764
48921
|
res.writeHead(200, { "content-type": "application/json" });
|
|
48765
48922
|
res.end(JSON.stringify({ ok: true, providers: hasProviders ? Object.keys(routes).length : void 0 }));
|
|
48766
48923
|
}
|
|
@@ -48914,16 +49071,18 @@ function recordUsage(ctx, usage, round) {
|
|
|
48914
49071
|
const prompt = usage.inputTokens;
|
|
48915
49072
|
const cached = usage.cachedTokens;
|
|
48916
49073
|
const out = usage.outputTokens;
|
|
48917
|
-
|
|
48918
|
-
|
|
49074
|
+
const includesCached = ctx.protocol === "openai" || ctx.protocol === "responses";
|
|
49075
|
+
const total = (typeof prompt === "number" ? prompt : 0) + (!includesCached && typeof cached === "number" ? cached : 0);
|
|
49076
|
+
if (total > 0) ctx.session.stats.inputTokens += total;
|
|
49077
|
+
ctx.session.stats.lastInputTokens = total;
|
|
48919
49078
|
if (typeof cached === "number") {
|
|
48920
49079
|
ctx.session.stats.cachedTokens += cached;
|
|
48921
49080
|
ctx.session.stats.cacheSamples += 1;
|
|
48922
49081
|
}
|
|
48923
49082
|
if (typeof out === "number") ctx.session.stats.outputTokens += out;
|
|
48924
|
-
const hitPct = typeof
|
|
49083
|
+
const hitPct = typeof cached === "number" && total > 0 ? Math.round(cached / total * 100) : 0;
|
|
48925
49084
|
ctx.log(
|
|
48926
|
-
`[acp-usage] round ${round} input=${
|
|
49085
|
+
`[acp-usage] round ${round} input=${total} cached=${cached ?? 0} (cache hit ${hitPct}%)`
|
|
48927
49086
|
);
|
|
48928
49087
|
}
|
|
48929
49088
|
async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adapter, systemPrompt, signal) {
|
|
@@ -49110,11 +49269,11 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
49110
49269
|
const newBody = adapter.buildRequest(coreMessages, systemPrompt, requestBody);
|
|
49111
49270
|
if (process.env.ACP_DUMP_REQ !== "0" && ctx.debug) {
|
|
49112
49271
|
try {
|
|
49113
|
-
const
|
|
49272
|
+
const fs10 = await import("fs");
|
|
49114
49273
|
const dumpDir = process.env.ACP_DUMP_DIR || `${process.env.HOME}/.local/state/billion-context/dumps`;
|
|
49115
|
-
|
|
49274
|
+
fs10.mkdirSync(dumpDir, { recursive: true });
|
|
49116
49275
|
const sid = ctx.session.id ?? "unknown";
|
|
49117
|
-
|
|
49276
|
+
fs10.writeFileSync(`${dumpDir}/req-${Date.now()}-${sid}-REREQUEST.json`, JSON.stringify(newBody, null, 2));
|
|
49118
49277
|
} catch {
|
|
49119
49278
|
}
|
|
49120
49279
|
}
|
|
@@ -49753,6 +49912,7 @@ function createOpenaiAdapter(requestBody) {
|
|
|
49753
49912
|
const usage = opts?.usage ? {
|
|
49754
49913
|
prompt_tokens: opts.usage.inputTokens,
|
|
49755
49914
|
completion_tokens: opts.usage.outputTokens,
|
|
49915
|
+
total_tokens: (opts.usage.inputTokens ?? 0) + (opts.usage.outputTokens ?? 0),
|
|
49756
49916
|
...typeof opts.usage.cachedTokens === "number" ? { prompt_tokens_details: { cached_tokens: opts.usage.cachedTokens } } : {}
|
|
49757
49917
|
} : null;
|
|
49758
49918
|
return Buffer.concat([buildFinish(finishReason, usage), Buffer.from("data: [DONE]\n\n", "utf8")]);
|
|
@@ -49989,8 +50149,8 @@ ${systemPrompt}` : systemPrompt;
|
|
|
49989
50149
|
} else if (type === "message_delta") {
|
|
49990
50150
|
const u2 = data.usage ?? {};
|
|
49991
50151
|
if (typeof u2.output_tokens === "number") roundOutput = u2.output_tokens;
|
|
49992
|
-
if (typeof u2.input_tokens === "number") roundInput = u2.input_tokens;
|
|
49993
|
-
if (typeof u2.cache_read_input_tokens === "number") roundCached = u2.cache_read_input_tokens;
|
|
50152
|
+
if (typeof u2.input_tokens === "number" && u2.input_tokens > 0) roundInput = u2.input_tokens;
|
|
50153
|
+
if (typeof u2.cache_read_input_tokens === "number" && u2.cache_read_input_tokens > 0) roundCached = u2.cache_read_input_tokens;
|
|
49994
50154
|
const d = data.delta ?? {};
|
|
49995
50155
|
if (typeof d.stop_reason === "string") stopReason = d.stop_reason;
|
|
49996
50156
|
if (!usageYielded) {
|
|
@@ -50240,6 +50400,87 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
50240
50400
|
return current;
|
|
50241
50401
|
}
|
|
50242
50402
|
|
|
50403
|
+
// src/util.ts
|
|
50404
|
+
import { createHash as createHash3 } from "crypto";
|
|
50405
|
+
function hashId2(s3) {
|
|
50406
|
+
return createHash3("sha256").update(s3, "utf8").digest("hex").slice(0, 16);
|
|
50407
|
+
}
|
|
50408
|
+
function safeJsonParse(s3) {
|
|
50409
|
+
try {
|
|
50410
|
+
return s3 ? JSON.parse(s3) : {};
|
|
50411
|
+
} catch {
|
|
50412
|
+
return {};
|
|
50413
|
+
}
|
|
50414
|
+
}
|
|
50415
|
+
function isLoopbackAddress(addr) {
|
|
50416
|
+
return !!addr && (addr.startsWith("127.") || addr === "::1" || addr.startsWith("::ffff:127."));
|
|
50417
|
+
}
|
|
50418
|
+
function usageTotals(protocol, usage) {
|
|
50419
|
+
const num2 = (v2) => typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
50420
|
+
if (protocol === "anthropic") {
|
|
50421
|
+
const fresh = num2(usage["input_tokens"]);
|
|
50422
|
+
const read = num2(usage["cache_read_input_tokens"]);
|
|
50423
|
+
const creation = num2(usage["cache_creation_input_tokens"]);
|
|
50424
|
+
const any = fresh !== void 0 || read !== void 0 || creation !== void 0;
|
|
50425
|
+
return {
|
|
50426
|
+
total: any ? (fresh ?? 0) + (read ?? 0) + (creation ?? 0) : void 0,
|
|
50427
|
+
cached: read
|
|
50428
|
+
};
|
|
50429
|
+
}
|
|
50430
|
+
if (protocol === "openai") {
|
|
50431
|
+
return {
|
|
50432
|
+
total: num2(usage["prompt_tokens"]),
|
|
50433
|
+
cached: num2(usage["prompt_tokens_details"]?.["cached_tokens"])
|
|
50434
|
+
};
|
|
50435
|
+
}
|
|
50436
|
+
return {
|
|
50437
|
+
total: num2(usage["input_tokens"]),
|
|
50438
|
+
cached: num2(usage["input_tokens_details"]?.["cached_tokens"])
|
|
50439
|
+
};
|
|
50440
|
+
}
|
|
50441
|
+
var CONTEXT_OVERFLOW_PATTERNS = [
|
|
50442
|
+
/context_length_exceeded/i,
|
|
50443
|
+
/context length exceeded/i,
|
|
50444
|
+
/maximum context length/i,
|
|
50445
|
+
/max context length/i,
|
|
50446
|
+
/maximum context size/i,
|
|
50447
|
+
/exceeds the context window/i,
|
|
50448
|
+
/exceeded model token limit/i,
|
|
50449
|
+
/prompt is too long/i,
|
|
50450
|
+
/prompt_too_long/i,
|
|
50451
|
+
/prompt_is_too_long/i,
|
|
50452
|
+
/request_too_large/i,
|
|
50453
|
+
/token limit exceeded/i
|
|
50454
|
+
];
|
|
50455
|
+
function toTokenNumber(s3) {
|
|
50456
|
+
const n = parseInt(s3.replace(/,/g, ""), 10);
|
|
50457
|
+
return Number.isFinite(n) && n >= 1e3 ? n : void 0;
|
|
50458
|
+
}
|
|
50459
|
+
function parseOverflowWindow(text) {
|
|
50460
|
+
let m2 = text.match(/>\s*(\d[\d,]*)\s*maximum/i);
|
|
50461
|
+
if (m2) return toTokenNumber(m2[1]);
|
|
50462
|
+
m2 = text.match(/maximum context length is (\d[\d,]*)/i) ?? text.match(/maximum context length of (\d[\d,]*)/i) ?? text.match(/maximum context size (?:is|of) (\d[\d,]*)/i) ?? text.match(/(?:maximum|max)\s+(?:context\s+)?length\s+(?:is\s+)?(\d[\d,]*)/i) ?? text.match(/limit of (\d[\d,]*)\s*token/i) ?? text.match(/(\d[\d,]*)\s*maximum\b/i);
|
|
50463
|
+
if (m2) return toTokenNumber(m2[1]);
|
|
50464
|
+
return void 0;
|
|
50465
|
+
}
|
|
50466
|
+
function inspectContextOverflow(status, bodyText) {
|
|
50467
|
+
const message = (bodyText ?? "").slice(0, 300);
|
|
50468
|
+
if (status !== 400 && status !== 413) return { isOverflow: false, message };
|
|
50469
|
+
if (!bodyText) return { isOverflow: false, message };
|
|
50470
|
+
const isOverflow = CONTEXT_OVERFLOW_PATTERNS.some((p2) => p2.test(bodyText));
|
|
50471
|
+
if (!isOverflow) return { isOverflow: false, message };
|
|
50472
|
+
return { isOverflow: true, window: parseOverflowWindow(bodyText), message };
|
|
50473
|
+
}
|
|
50474
|
+
function reserveOutputHeadroom(window2, maxOutput) {
|
|
50475
|
+
if (Number.isFinite(window2) && window2 > 0 && Number.isFinite(maxOutput) && maxOutput > 0 && maxOutput < window2) {
|
|
50476
|
+
return window2 - maxOutput;
|
|
50477
|
+
}
|
|
50478
|
+
return window2;
|
|
50479
|
+
}
|
|
50480
|
+
function shouldReserveOutputHeadroom(protocol) {
|
|
50481
|
+
return protocol !== "anthropic";
|
|
50482
|
+
}
|
|
50483
|
+
|
|
50243
50484
|
// src/stream-openai.ts
|
|
50244
50485
|
function rewriteOpenaiJsonResponse(body, ctx) {
|
|
50245
50486
|
if (!body || typeof body !== "object") return body;
|
|
@@ -50398,8 +50639,10 @@ function extractKey(headers) {
|
|
|
50398
50639
|
return "(no-key)";
|
|
50399
50640
|
}
|
|
50400
50641
|
function clientConversationHeader(headers) {
|
|
50401
|
-
const
|
|
50642
|
+
const pluginMarker = typeof headers["x-bili-plugin"] === "string";
|
|
50643
|
+
const names = ["x-bili-plugin-conversation", "x-claude-code-session-id", "x-session-affinity", "x-acp-session", "x-session-id", "x-opencode-session", "session-id", "session_id"];
|
|
50402
50644
|
for (const name of names) {
|
|
50645
|
+
if (name === "x-bili-plugin-conversation" && !pluginMarker) continue;
|
|
50403
50646
|
const v2 = headers[name];
|
|
50404
50647
|
if (typeof v2 === "string" && v2.trim().length > 0) return v2.trim();
|
|
50405
50648
|
}
|
|
@@ -50408,29 +50651,404 @@ function clientConversationHeader(headers) {
|
|
|
50408
50651
|
function deriveSessionId(headers, protocol, upstream, conversation) {
|
|
50409
50652
|
if (!conversation) throw new Error("deriveSessionId: conversation dimension is required (pass the conversationSignal* output)");
|
|
50410
50653
|
const key = extractKey(headers);
|
|
50411
|
-
return
|
|
50654
|
+
return hashId2(`${protocol}|${upstream}|${key}|${conversation}`);
|
|
50412
50655
|
}
|
|
50413
50656
|
function affinityToken(identity) {
|
|
50414
50657
|
return identity.clientProvided ? identity.value : void 0;
|
|
50415
50658
|
}
|
|
50416
50659
|
|
|
50660
|
+
// src/plugin.ts
|
|
50661
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
50662
|
+
import fs2 from "fs";
|
|
50663
|
+
import path5 from "path";
|
|
50664
|
+
var PLUGIN_AGENT_HEADER = "x-bili-plugin";
|
|
50665
|
+
var PLUGIN_CONVERSATION_HEADER = "x-bili-plugin-conversation";
|
|
50666
|
+
var PLUGIN_CONTEXT_WINDOW_HEADER = "x-bili-plugin-context-window";
|
|
50667
|
+
var PLUGIN_PROTOCOL_VERSION = 1;
|
|
50668
|
+
var VERSION = (() => {
|
|
50669
|
+
try {
|
|
50670
|
+
const here = fileURLToPath2(import.meta.url);
|
|
50671
|
+
const pkg = path5.join(path5.dirname(here), "..", "package.json");
|
|
50672
|
+
return JSON.parse(fs2.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
50673
|
+
} catch {
|
|
50674
|
+
return "dev";
|
|
50675
|
+
}
|
|
50676
|
+
})();
|
|
50677
|
+
function headerValue(headers, name) {
|
|
50678
|
+
const v2 = headers[name];
|
|
50679
|
+
const s3 = typeof v2 === "string" ? v2 : Array.isArray(v2) ? v2[0] : void 0;
|
|
50680
|
+
const t = s3?.trim();
|
|
50681
|
+
return t && t.length > 0 ? t : void 0;
|
|
50682
|
+
}
|
|
50683
|
+
function pluginAgentHeader(headers) {
|
|
50684
|
+
return headerValue(headers, PLUGIN_AGENT_HEADER);
|
|
50685
|
+
}
|
|
50686
|
+
function pluginConversationHeader(headers) {
|
|
50687
|
+
return headerValue(headers, PLUGIN_CONVERSATION_HEADER);
|
|
50688
|
+
}
|
|
50689
|
+
function pluginContextWindowHeader(headers) {
|
|
50690
|
+
const raw = headerValue(headers, PLUGIN_CONTEXT_WINDOW_HEADER);
|
|
50691
|
+
if (raw === void 0) return void 0;
|
|
50692
|
+
const n = Number.parseInt(raw, 10);
|
|
50693
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
50694
|
+
}
|
|
50695
|
+
function pluginReportedContextWindow(headers) {
|
|
50696
|
+
return pluginAgentHeader(headers) !== void 0 ? pluginContextWindowHeader(headers) : void 0;
|
|
50697
|
+
}
|
|
50698
|
+
var MAX_PLUGIN_CONVERSATIONS = 1024;
|
|
50699
|
+
var conversations = /* @__PURE__ */ new Map();
|
|
50700
|
+
var remembered = /* @__PURE__ */ new Map();
|
|
50701
|
+
function recordPluginSession(conversationId2, sessionId) {
|
|
50702
|
+
conversations.delete(conversationId2);
|
|
50703
|
+
conversations.set(conversationId2, { sessionId, lastSeen: Date.now() });
|
|
50704
|
+
if (conversations.size > MAX_PLUGIN_CONVERSATIONS) {
|
|
50705
|
+
const oldest = conversations.keys().next().value;
|
|
50706
|
+
if (oldest !== void 0) conversations.delete(oldest);
|
|
50707
|
+
}
|
|
50708
|
+
}
|
|
50709
|
+
function rememberPluginMessages(sessionId, processed, original, nudge) {
|
|
50710
|
+
const staleSessionIds = new Set(
|
|
50711
|
+
[...remembered.keys()].filter((id) => id === sessionId || !peekSession(id))
|
|
50712
|
+
);
|
|
50713
|
+
for (const id of staleSessionIds) remembered.delete(id);
|
|
50714
|
+
remembered.set(sessionId, { processed, original, nudge });
|
|
50715
|
+
}
|
|
50716
|
+
var MAX_PENDING_REGISTERS = 64;
|
|
50717
|
+
var pendingRegisters = [];
|
|
50718
|
+
function queuePluginRegister(conversationId2, agent, identity) {
|
|
50719
|
+
if (!identity) {
|
|
50720
|
+
for (let i = 0; i < pendingRegisters.length; i++) {
|
|
50721
|
+
if (pendingRegisters[i].conversationId === conversationId2) {
|
|
50722
|
+
pendingRegisters.splice(i, 1);
|
|
50723
|
+
break;
|
|
50724
|
+
}
|
|
50725
|
+
}
|
|
50726
|
+
pendingRegisters.push({ conversationId: conversationId2, agent, ts: Date.now() });
|
|
50727
|
+
while (pendingRegisters.length > MAX_PENDING_REGISTERS) pendingRegisters.shift();
|
|
50728
|
+
} else {
|
|
50729
|
+
registeredIds.set(conversationId2, agent);
|
|
50730
|
+
while (registeredIds.size > MAX_PENDING_REGISTERS) {
|
|
50731
|
+
const oldest = registeredIds.keys().next().value;
|
|
50732
|
+
if (oldest !== void 0) registeredIds.delete(oldest);
|
|
50733
|
+
}
|
|
50734
|
+
}
|
|
50735
|
+
}
|
|
50736
|
+
var PENDING_REGISTER_TTL_MS = 10 * 60 * 1e3;
|
|
50737
|
+
function takePendingPluginRegister() {
|
|
50738
|
+
const now = Date.now();
|
|
50739
|
+
while (pendingRegisters.length > 0 && now - pendingRegisters[0].ts > PENDING_REGISTER_TTL_MS) {
|
|
50740
|
+
pendingRegisters.shift();
|
|
50741
|
+
}
|
|
50742
|
+
return pendingRegisters.shift();
|
|
50743
|
+
}
|
|
50744
|
+
var registeredIds = /* @__PURE__ */ new Map();
|
|
50745
|
+
function consumePluginRegisterFor(conversationId2) {
|
|
50746
|
+
const agent = registeredIds.get(conversationId2);
|
|
50747
|
+
if (agent !== void 0) registeredIds.delete(conversationId2);
|
|
50748
|
+
return agent;
|
|
50749
|
+
}
|
|
50750
|
+
function handlePluginRegister(payload, res) {
|
|
50751
|
+
let parsed;
|
|
50752
|
+
try {
|
|
50753
|
+
parsed = JSON.parse(payload);
|
|
50754
|
+
} catch {
|
|
50755
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
50756
|
+
res.end(JSON.stringify({ ok: false, error: "invalid JSON body" }));
|
|
50757
|
+
return;
|
|
50758
|
+
}
|
|
50759
|
+
const conversationId2 = typeof parsed.conversationId === "string" ? parsed.conversationId.trim() : "";
|
|
50760
|
+
if (!conversationId2) {
|
|
50761
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
50762
|
+
res.end(JSON.stringify({ ok: false, error: "conversationId is required" }));
|
|
50763
|
+
return;
|
|
50764
|
+
}
|
|
50765
|
+
const agent = typeof parsed.agent === "string" && parsed.agent.trim() ? parsed.agent.trim() : "launcher";
|
|
50766
|
+
queuePluginRegister(conversationId2, agent, parsed.identity === true);
|
|
50767
|
+
res.end(JSON.stringify({ ok: true, conversationId: conversationId2, agent }));
|
|
50768
|
+
}
|
|
50769
|
+
function handlePluginManifest(res) {
|
|
50770
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
50771
|
+
res.end(JSON.stringify({
|
|
50772
|
+
ok: true,
|
|
50773
|
+
protocolVersion: PLUGIN_PROTOCOL_VERSION,
|
|
50774
|
+
proxy: "billion-context",
|
|
50775
|
+
version: VERSION,
|
|
50776
|
+
toolNames: [...PROXY_TOOL_NAMES],
|
|
50777
|
+
tools: {
|
|
50778
|
+
anthropic: ACP_TOOLS_ANTHROPIC,
|
|
50779
|
+
openai: ACP_TOOLS_OPENAI,
|
|
50780
|
+
responses: ACP_TOOLS_RESPONSES
|
|
50781
|
+
},
|
|
50782
|
+
headers: { agent: PLUGIN_AGENT_HEADER, conversation: PLUGIN_CONVERSATION_HEADER, contextWindow: PLUGIN_CONTEXT_WINDOW_HEADER },
|
|
50783
|
+
toolEndpoint: "/__bili/plugin/tool",
|
|
50784
|
+
statusEndpoint: "/__bili/plugin/status"
|
|
50785
|
+
}));
|
|
50786
|
+
}
|
|
50787
|
+
function handlePluginStatus(conversationId2, res) {
|
|
50788
|
+
const entry = conversations.get(conversationId2);
|
|
50789
|
+
const session = entry ? peekSession(entry.sessionId) : void 0;
|
|
50790
|
+
if (!entry || !session) {
|
|
50791
|
+
res.writeHead(404, { "content-type": "application/json" });
|
|
50792
|
+
res.end(JSON.stringify({ ok: false, error: "unknown plugin conversation" }));
|
|
50793
|
+
return;
|
|
50794
|
+
}
|
|
50795
|
+
entry.lastSeen = Date.now();
|
|
50796
|
+
const limit = session.metadata.effectiveContextLimit;
|
|
50797
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
50798
|
+
res.end(JSON.stringify({
|
|
50799
|
+
ok: true,
|
|
50800
|
+
conversationId: conversationId2,
|
|
50801
|
+
sessionId: session.id,
|
|
50802
|
+
label: session.meta.label ?? null,
|
|
50803
|
+
pluginAgent: session.metadata.pluginAgent ?? null,
|
|
50804
|
+
contextLimit: typeof limit === "number" ? limit : null,
|
|
50805
|
+
contextTokens: session.stats.lastInputTokens,
|
|
50806
|
+
inputTokens: session.stats.inputTokens,
|
|
50807
|
+
outputTokens: session.stats.outputTokens,
|
|
50808
|
+
cachedTokens: session.stats.cachedTokens,
|
|
50809
|
+
requests: session.stats.requests,
|
|
50810
|
+
blocks: session.state.blocks.map((b2) => ({ id: b2.blockId, tier: b2.tier, active: b2.active })),
|
|
50811
|
+
lastSeen: session.lastSeen
|
|
50812
|
+
}));
|
|
50813
|
+
}
|
|
50814
|
+
async function handlePluginTool(payload, res, deps) {
|
|
50815
|
+
let parsed;
|
|
50816
|
+
try {
|
|
50817
|
+
parsed = JSON.parse(payload);
|
|
50818
|
+
} catch {
|
|
50819
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
50820
|
+
res.end(JSON.stringify({ ok: false, error: "invalid JSON body" }));
|
|
50821
|
+
return;
|
|
50822
|
+
}
|
|
50823
|
+
const conversationId2 = typeof parsed.conversationId === "string" ? parsed.conversationId.trim() : "";
|
|
50824
|
+
const tool = typeof parsed.tool === "string" ? parsed.tool : "";
|
|
50825
|
+
if (!conversationId2) {
|
|
50826
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
50827
|
+
res.end(JSON.stringify({ ok: false, error: `conversationId is required (send the same value as the ${PLUGIN_CONVERSATION_HEADER} header)` }));
|
|
50828
|
+
return;
|
|
50829
|
+
}
|
|
50830
|
+
if (!PROXY_TOOL_NAMES.has(tool)) {
|
|
50831
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
50832
|
+
res.end(JSON.stringify({ ok: false, error: `unknown tool "${tool}" (expected one of: ${[...PROXY_TOOL_NAMES].join(", ")})` }));
|
|
50833
|
+
return;
|
|
50834
|
+
}
|
|
50835
|
+
const entry = conversations.get(conversationId2);
|
|
50836
|
+
const session = entry ? peekSession(entry.sessionId) : void 0;
|
|
50837
|
+
if (!entry || !session) {
|
|
50838
|
+
res.writeHead(404, { "content-type": "application/json" });
|
|
50839
|
+
res.end(JSON.stringify({ ok: false, error: "unknown plugin conversation (no model request has arrived with this conversation id yet)" }));
|
|
50840
|
+
return;
|
|
50841
|
+
}
|
|
50842
|
+
entry.lastSeen = Date.now();
|
|
50843
|
+
const args = parsed.args && typeof parsed.args === "object" ? parsed.args : {};
|
|
50844
|
+
const callId = `plugin_${Date.now().toString(36)}`;
|
|
50845
|
+
acquireInFlight(session);
|
|
50846
|
+
let result;
|
|
50847
|
+
try {
|
|
50848
|
+
result = await withSessionLock(session, async () => {
|
|
50849
|
+
const mem = remembered.get(session.id);
|
|
50850
|
+
const messages = mem ? mem.processed.length > 0 ? mem.processed : mem.original : [];
|
|
50851
|
+
return executeProxyTool(tool, args, {
|
|
50852
|
+
core: deps.core,
|
|
50853
|
+
config: deps.config,
|
|
50854
|
+
messages,
|
|
50855
|
+
session,
|
|
50856
|
+
log: (m2) => deps.log("info", `[${session.id}] [plugin] ${m2}`),
|
|
50857
|
+
nudge: mem?.nudge
|
|
50858
|
+
}, callId);
|
|
50859
|
+
});
|
|
50860
|
+
} catch (err2) {
|
|
50861
|
+
releaseInFlight(session);
|
|
50862
|
+
deps.log("warn", `[${session.id}] [plugin] tool ${tool} threw: ${String(err2)}`);
|
|
50863
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
50864
|
+
res.end(JSON.stringify({ ok: false, error: String(err2) }));
|
|
50865
|
+
return;
|
|
50866
|
+
}
|
|
50867
|
+
releaseInFlight(session);
|
|
50868
|
+
markDirty(session);
|
|
50869
|
+
deps.log("info", `[${session.id}] [plugin] tool ${tool} executed via plugin (${result.length} chars)`);
|
|
50870
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
50871
|
+
res.end(JSON.stringify({ ok: true, tool, conversationId: conversationId2, result }));
|
|
50872
|
+
}
|
|
50873
|
+
function num(v2) {
|
|
50874
|
+
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
50875
|
+
}
|
|
50876
|
+
function usageFromSseEvent(obj) {
|
|
50877
|
+
const type = obj["type"];
|
|
50878
|
+
if (type === "message_start") {
|
|
50879
|
+
const usage2 = obj["message"]?.["usage"];
|
|
50880
|
+
if (!usage2) return void 0;
|
|
50881
|
+
const input = num(usage2["input_tokens"]);
|
|
50882
|
+
if (input === void 0) return void 0;
|
|
50883
|
+
return { inputTokens: input, cachedTokens: num(usage2["cache_read_input_tokens"]) };
|
|
50884
|
+
}
|
|
50885
|
+
if (type === "message_delta") {
|
|
50886
|
+
const usage2 = obj["usage"];
|
|
50887
|
+
if (!usage2) return void 0;
|
|
50888
|
+
const input = num(usage2["input_tokens"]);
|
|
50889
|
+
return { inputTokens: input && input > 0 ? input : void 0, outputTokens: num(usage2["output_tokens"]) };
|
|
50890
|
+
}
|
|
50891
|
+
if (type === "response.completed") {
|
|
50892
|
+
const usage2 = obj["response"]?.["usage"];
|
|
50893
|
+
if (!usage2) return void 0;
|
|
50894
|
+
return {
|
|
50895
|
+
inputTokens: num(usage2["input_tokens"]),
|
|
50896
|
+
outputTokens: num(usage2["output_tokens"]),
|
|
50897
|
+
cachedTokens: num(usage2["input_tokens_details"]?.["cached_tokens"])
|
|
50898
|
+
};
|
|
50899
|
+
}
|
|
50900
|
+
const usage = obj["usage"];
|
|
50901
|
+
if (usage && (num(usage["prompt_tokens"]) !== void 0 || num(usage["completion_tokens"]) !== void 0)) {
|
|
50902
|
+
return {
|
|
50903
|
+
inputTokens: num(usage["prompt_tokens"]),
|
|
50904
|
+
outputTokens: num(usage["completion_tokens"]),
|
|
50905
|
+
cachedTokens: num(usage["prompt_tokens_details"]?.["cached_tokens"])
|
|
50906
|
+
};
|
|
50907
|
+
}
|
|
50908
|
+
return void 0;
|
|
50909
|
+
}
|
|
50910
|
+
function applyUsageSample(session, sample, protocol) {
|
|
50911
|
+
const includesCached = protocol === "openai" || protocol === "responses";
|
|
50912
|
+
if (sample.cachedTokens !== void 0) {
|
|
50913
|
+
session.stats.cachedTokens += sample.cachedTokens;
|
|
50914
|
+
session.stats.cacheSamples += 1;
|
|
50915
|
+
}
|
|
50916
|
+
if (sample.inputTokens !== void 0) {
|
|
50917
|
+
const total = sample.inputTokens + (!includesCached && sample.cachedTokens !== void 0 ? sample.cachedTokens : 0);
|
|
50918
|
+
session.stats.inputTokens += total;
|
|
50919
|
+
session.stats.lastInputTokens = total;
|
|
50920
|
+
}
|
|
50921
|
+
if (sample.outputTokens !== void 0) session.stats.outputTokens += sample.outputTokens;
|
|
50922
|
+
}
|
|
50923
|
+
function mergeUsageSample(acc, sample) {
|
|
50924
|
+
if (sample.inputTokens !== void 0) acc.inputTokens = sample.inputTokens;
|
|
50925
|
+
if (sample.cachedTokens !== void 0) acc.cachedTokens = sample.cachedTokens;
|
|
50926
|
+
if (sample.outputTokens !== void 0) acc.outputTokens = sample.outputTokens;
|
|
50927
|
+
}
|
|
50928
|
+
async function pipeThroughWithUsage(stream2, res, session, protocol) {
|
|
50929
|
+
const reader = stream2.getReader();
|
|
50930
|
+
const decoder = new TextDecoder("utf-8");
|
|
50931
|
+
let buf = "";
|
|
50932
|
+
const acc = {};
|
|
50933
|
+
try {
|
|
50934
|
+
for (; ; ) {
|
|
50935
|
+
const { done, value } = await reader.read();
|
|
50936
|
+
if (done) break;
|
|
50937
|
+
if (value && value.length > 0) {
|
|
50938
|
+
if (!res.write(Buffer.from(value))) {
|
|
50939
|
+
await new Promise((r) => res.once("drain", () => r()));
|
|
50940
|
+
}
|
|
50941
|
+
buf = normalizeSseLineEndings(buf + decoder.decode(value, { stream: true }));
|
|
50942
|
+
let idx;
|
|
50943
|
+
while ((idx = buf.indexOf("\n\n")) !== -1) {
|
|
50944
|
+
const rawEvent = buf.slice(0, idx);
|
|
50945
|
+
buf = buf.slice(idx + 2);
|
|
50946
|
+
const dataLines = rawEvent.split("\n").filter((l) => l.startsWith("data:"));
|
|
50947
|
+
if (dataLines.length === 0) continue;
|
|
50948
|
+
const jsonStr = dataLines.map((l) => l.slice(5).replace(/^ /, "")).join("\n").trim();
|
|
50949
|
+
if (!jsonStr || jsonStr === "[DONE]") continue;
|
|
50950
|
+
try {
|
|
50951
|
+
const ev = JSON.parse(jsonStr);
|
|
50952
|
+
const sample = usageFromSseEvent(ev);
|
|
50953
|
+
if (sample) mergeUsageSample(acc, sample);
|
|
50954
|
+
} catch {
|
|
50955
|
+
}
|
|
50956
|
+
}
|
|
50957
|
+
}
|
|
50958
|
+
if (res.destroyed || res.writableEnded) break;
|
|
50959
|
+
}
|
|
50960
|
+
if (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0) {
|
|
50961
|
+
applyUsageSample(session, acc, protocol);
|
|
50962
|
+
markDirty(session);
|
|
50963
|
+
}
|
|
50964
|
+
} finally {
|
|
50965
|
+
reader.releaseLock();
|
|
50966
|
+
res.end();
|
|
50967
|
+
}
|
|
50968
|
+
}
|
|
50969
|
+
async function pipePluginJson(stream2, res, session, protocol) {
|
|
50970
|
+
const reader = stream2.getReader();
|
|
50971
|
+
const chunks = [];
|
|
50972
|
+
for (; ; ) {
|
|
50973
|
+
const { done, value } = await reader.read();
|
|
50974
|
+
if (done) break;
|
|
50975
|
+
if (value && value.length > 0) chunks.push(Buffer.from(value));
|
|
50976
|
+
}
|
|
50977
|
+
reader.releaseLock();
|
|
50978
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
50979
|
+
try {
|
|
50980
|
+
const json = JSON.parse(text);
|
|
50981
|
+
const usage = json["usage"];
|
|
50982
|
+
if (usage) {
|
|
50983
|
+
const input = num(usage["prompt_tokens"]) ?? num(usage["input_tokens"]);
|
|
50984
|
+
if (input !== void 0) {
|
|
50985
|
+
applyUsageSample(session, {
|
|
50986
|
+
inputTokens: input,
|
|
50987
|
+
outputTokens: num(usage["completion_tokens"]) ?? num(usage["output_tokens"]),
|
|
50988
|
+
cachedTokens: num(usage["prompt_tokens_details"]?.["cached_tokens"]) ?? num(usage["input_tokens_details"]?.["cached_tokens"]) ?? num(usage["cache_read_input_tokens"])
|
|
50989
|
+
}, protocol);
|
|
50990
|
+
markDirty(session);
|
|
50991
|
+
}
|
|
50992
|
+
}
|
|
50993
|
+
} catch {
|
|
50994
|
+
}
|
|
50995
|
+
res.end(text);
|
|
50996
|
+
}
|
|
50997
|
+
|
|
50417
50998
|
// src/mitm.ts
|
|
50418
50999
|
import tls3 from "tls";
|
|
50419
51000
|
|
|
50420
51001
|
// src/ca.ts
|
|
50421
51002
|
var import_node_forge = __toESM(require_lib(), 1);
|
|
50422
|
-
import
|
|
50423
|
-
import
|
|
51003
|
+
import fs3 from "fs";
|
|
51004
|
+
import path6 from "path";
|
|
50424
51005
|
import tls2 from "tls";
|
|
50425
51006
|
var ROOT_CERT_FILE = "root-ca.pem";
|
|
50426
51007
|
var ROOT_KEY_FILE = "root-ca-key.pem";
|
|
51008
|
+
var COMBINED_CA_FILE = "combined-ca.pem";
|
|
50427
51009
|
var ROOT_CN = "billion-context MITM Root CA";
|
|
51010
|
+
var PLATFORM_CA_CANDIDATES = process.platform === "darwin" ? ["/etc/ssl/cert.pem", "/private/etc/ssl/cert.pem"] : [
|
|
51011
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
|
51012
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
51013
|
+
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
|
51014
|
+
"/etc/ssl/ca-bundle.pem",
|
|
51015
|
+
"/etc/ssl/cert.pem"
|
|
51016
|
+
];
|
|
50428
51017
|
var rootCertPem;
|
|
50429
51018
|
var rootKeyPem;
|
|
50430
51019
|
var rootCert;
|
|
50431
51020
|
var rootKey;
|
|
50432
51021
|
var secureContextCache = /* @__PURE__ */ new Map();
|
|
50433
51022
|
var SECURE_CONTEXT_CACHE_MAX = 64;
|
|
51023
|
+
function collectSystemCaPems(env = process.env) {
|
|
51024
|
+
const pems = [];
|
|
51025
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51026
|
+
const pushFile = (file) => {
|
|
51027
|
+
try {
|
|
51028
|
+
const text = fs3.readFileSync(file, "utf8");
|
|
51029
|
+
if (!text.includes("BEGIN CERTIFICATE") || seen.has(text)) return false;
|
|
51030
|
+
seen.add(text);
|
|
51031
|
+
pems.push(text);
|
|
51032
|
+
return true;
|
|
51033
|
+
} catch {
|
|
51034
|
+
}
|
|
51035
|
+
return false;
|
|
51036
|
+
};
|
|
51037
|
+
const userBundle = env.SSL_CERT_FILE?.trim();
|
|
51038
|
+
if (userBundle && pushFile(userBundle)) return pems;
|
|
51039
|
+
for (const candidate of PLATFORM_CA_CANDIDATES) {
|
|
51040
|
+
if (pushFile(candidate)) break;
|
|
51041
|
+
}
|
|
51042
|
+
return pems;
|
|
51043
|
+
}
|
|
51044
|
+
function writeCombinedBundle() {
|
|
51045
|
+
const certs = /* @__PURE__ */ new Set();
|
|
51046
|
+
for (const pem of collectSystemCaPems()) certs.add(pem.trim());
|
|
51047
|
+
for (const pem of tls2.rootCertificates) certs.add(pem.trim());
|
|
51048
|
+
certs.add(rootCertPem.trim());
|
|
51049
|
+
const body = [...certs].map((pem) => pem.endsWith("\n") ? pem : pem + "\n").join("");
|
|
51050
|
+
fs3.writeFileSync(path6.join(caDir(), COMBINED_CA_FILE), body, { mode: 420 });
|
|
51051
|
+
}
|
|
50434
51052
|
function generateRootCA() {
|
|
50435
51053
|
const keys = import_node_forge.default.pki.rsa.generateKeyPair({ bits: 2048 });
|
|
50436
51054
|
const cert = import_node_forge.default.pki.createCertificate();
|
|
@@ -50457,25 +51075,30 @@ function generateRootCA() {
|
|
|
50457
51075
|
};
|
|
50458
51076
|
}
|
|
50459
51077
|
function ensureRootCA() {
|
|
50460
|
-
if (rootCertPem && rootKeyPem)
|
|
51078
|
+
if (rootCertPem && rootKeyPem) {
|
|
51079
|
+
writeCombinedBundle();
|
|
51080
|
+
return;
|
|
51081
|
+
}
|
|
50461
51082
|
const dir = caDir();
|
|
50462
|
-
|
|
50463
|
-
const certPath =
|
|
50464
|
-
const keyPath =
|
|
50465
|
-
if (
|
|
50466
|
-
rootCertPem =
|
|
50467
|
-
rootKeyPem =
|
|
51083
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
51084
|
+
const certPath = path6.join(dir, ROOT_CERT_FILE);
|
|
51085
|
+
const keyPath = path6.join(dir, ROOT_KEY_FILE);
|
|
51086
|
+
if (fs3.existsSync(certPath) && fs3.existsSync(keyPath)) {
|
|
51087
|
+
rootCertPem = fs3.readFileSync(certPath, "utf8");
|
|
51088
|
+
rootKeyPem = fs3.readFileSync(keyPath, "utf8");
|
|
50468
51089
|
rootCert = import_node_forge.default.pki.certificateFromPem(rootCertPem);
|
|
50469
51090
|
rootKey = import_node_forge.default.pki.privateKeyFromPem(rootKeyPem);
|
|
51091
|
+
writeCombinedBundle();
|
|
50470
51092
|
return;
|
|
50471
51093
|
}
|
|
50472
51094
|
const { cert, key } = generateRootCA();
|
|
50473
|
-
|
|
50474
|
-
|
|
51095
|
+
fs3.writeFileSync(certPath, cert, { mode: 420 });
|
|
51096
|
+
fs3.writeFileSync(keyPath, key, { mode: 384 });
|
|
50475
51097
|
rootCertPem = cert;
|
|
50476
51098
|
rootKeyPem = key;
|
|
50477
51099
|
rootCert = import_node_forge.default.pki.certificateFromPem(cert);
|
|
50478
51100
|
rootKey = import_node_forge.default.pki.privateKeyFromPem(key);
|
|
51101
|
+
writeCombinedBundle();
|
|
50479
51102
|
}
|
|
50480
51103
|
function getSecureContext(host) {
|
|
50481
51104
|
if (!rootCertPem || !rootKeyPem || !rootCert || !rootKey) {
|
|
@@ -50517,20 +51140,20 @@ function getSecureContext(host) {
|
|
|
50517
51140
|
}
|
|
50518
51141
|
|
|
50519
51142
|
// src/discover.ts
|
|
50520
|
-
import
|
|
51143
|
+
import fs5 from "fs";
|
|
50521
51144
|
import os2 from "os";
|
|
50522
|
-
import
|
|
51145
|
+
import path8 from "path";
|
|
50523
51146
|
|
|
50524
51147
|
// src/client-config.ts
|
|
50525
|
-
import
|
|
51148
|
+
import fs4 from "fs";
|
|
50526
51149
|
import os from "os";
|
|
50527
|
-
import
|
|
51150
|
+
import path7 from "path";
|
|
50528
51151
|
function nonEmpty2(s3) {
|
|
50529
51152
|
return typeof s3 === "string" && s3.trim().length > 0;
|
|
50530
51153
|
}
|
|
50531
51154
|
function readJsonObject(filePath) {
|
|
50532
51155
|
try {
|
|
50533
|
-
const txt =
|
|
51156
|
+
const txt = fs4.readFileSync(filePath, "utf8");
|
|
50534
51157
|
const parsed = JSON.parse(txt);
|
|
50535
51158
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
50536
51159
|
} catch {
|
|
@@ -50539,12 +51162,12 @@ function readJsonObject(filePath) {
|
|
|
50539
51162
|
}
|
|
50540
51163
|
function resolvePiHome(env) {
|
|
50541
51164
|
const h = os.homedir();
|
|
50542
|
-
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : nonEmpty2(env.PI_HOME) ? env.PI_HOME :
|
|
51165
|
+
return nonEmpty2(env.PI_CODING_AGENT_DIR) ? env.PI_CODING_AGENT_DIR : nonEmpty2(env.PI_HOME) ? env.PI_HOME : path7.join(h, ".pi", "agent");
|
|
50543
51166
|
}
|
|
50544
51167
|
function readClaudeSettings(homeDir, cwd) {
|
|
50545
51168
|
const files = [
|
|
50546
|
-
|
|
50547
|
-
|
|
51169
|
+
path7.join(homeDir, ".claude", "settings.json"),
|
|
51170
|
+
path7.join(cwd, ".claude", "settings.json")
|
|
50548
51171
|
];
|
|
50549
51172
|
let anthropicBaseUrl;
|
|
50550
51173
|
for (const f2 of files) {
|
|
@@ -50587,17 +51210,17 @@ function parseCodexToml(text) {
|
|
|
50587
51210
|
return result;
|
|
50588
51211
|
}
|
|
50589
51212
|
function readCodexConfig(codexHome) {
|
|
50590
|
-
const cfgPath =
|
|
51213
|
+
const cfgPath = path7.join(codexHome, "config.toml");
|
|
50591
51214
|
let text;
|
|
50592
51215
|
try {
|
|
50593
|
-
text =
|
|
51216
|
+
text = fs4.readFileSync(cfgPath, "utf8");
|
|
50594
51217
|
} catch {
|
|
50595
51218
|
return { providers: {} };
|
|
50596
51219
|
}
|
|
50597
51220
|
return parseCodexToml(text);
|
|
50598
51221
|
}
|
|
50599
51222
|
function readPiConfig(piHome) {
|
|
50600
|
-
const cfgPath =
|
|
51223
|
+
const cfgPath = path7.join(piHome, "models.json");
|
|
50601
51224
|
const obj = readJsonObject(cfgPath);
|
|
50602
51225
|
const providers = {};
|
|
50603
51226
|
const rawProviders = obj?.providers;
|
|
@@ -50628,10 +51251,10 @@ function parseZcodeConfig(obj) {
|
|
|
50628
51251
|
return result;
|
|
50629
51252
|
}
|
|
50630
51253
|
function readZcodeConfig(zcodeHome) {
|
|
50631
|
-
const cfgPath =
|
|
51254
|
+
const cfgPath = path7.join(zcodeHome, "v2", "config.json");
|
|
50632
51255
|
let txt;
|
|
50633
51256
|
try {
|
|
50634
|
-
txt =
|
|
51257
|
+
txt = fs4.readFileSync(cfgPath, "utf8");
|
|
50635
51258
|
} catch {
|
|
50636
51259
|
return { providers: {} };
|
|
50637
51260
|
}
|
|
@@ -50647,10 +51270,10 @@ function loadClientConfig(env, cwd) {
|
|
|
50647
51270
|
const home = os.homedir();
|
|
50648
51271
|
const config = {};
|
|
50649
51272
|
config.claude = readClaudeSettings(home, cwd);
|
|
50650
|
-
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME :
|
|
51273
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path7.join(home, ".codex");
|
|
50651
51274
|
config.codex = readCodexConfig(codexHome);
|
|
50652
51275
|
config.pi = readPiConfig(resolvePiHome(env));
|
|
50653
|
-
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR :
|
|
51276
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path7.join(home, ".zcode");
|
|
50654
51277
|
config.zcode = readZcodeConfig(zcodeHome);
|
|
50655
51278
|
return config;
|
|
50656
51279
|
}
|
|
@@ -50693,21 +51316,21 @@ function extractHttpsHosts(config) {
|
|
|
50693
51316
|
}
|
|
50694
51317
|
function configFilePaths(env) {
|
|
50695
51318
|
const home = os2.homedir();
|
|
50696
|
-
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME :
|
|
50697
|
-
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR :
|
|
51319
|
+
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path8.join(home, ".codex");
|
|
51320
|
+
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path8.join(home, ".zcode");
|
|
50698
51321
|
return [
|
|
50699
|
-
|
|
50700
|
-
|
|
50701
|
-
|
|
50702
|
-
|
|
50703
|
-
|
|
51322
|
+
path8.join(home, ".claude", "settings.json"),
|
|
51323
|
+
path8.join(process.cwd(), ".claude", "settings.json"),
|
|
51324
|
+
path8.join(codexHome, "config.toml"),
|
|
51325
|
+
path8.join(resolvePiHome(env), "models.json"),
|
|
51326
|
+
path8.join(zcodeHome, "v2", "config.json")
|
|
50704
51327
|
];
|
|
50705
51328
|
}
|
|
50706
51329
|
function readMtimes(paths) {
|
|
50707
51330
|
const mtimes = /* @__PURE__ */ new Map();
|
|
50708
51331
|
for (const p2 of paths) {
|
|
50709
51332
|
try {
|
|
50710
|
-
const st2 =
|
|
51333
|
+
const st2 = fs5.statSync(p2);
|
|
50711
51334
|
mtimes.set(p2, st2.mtimeMs);
|
|
50712
51335
|
} catch {
|
|
50713
51336
|
}
|
|
@@ -51671,6 +52294,20 @@ async function startServer(opts) {
|
|
|
51671
52294
|
}
|
|
51672
52295
|
}
|
|
51673
52296
|
});
|
|
52297
|
+
server.on("upgrade", (req, socket) => {
|
|
52298
|
+
log2("info", `[ws] rejected ${req.method} ${req.url ?? ""} host=${req.headers.host ?? "?"} with 426`);
|
|
52299
|
+
socket.on("error", () => {
|
|
52300
|
+
});
|
|
52301
|
+
const body = JSON.stringify({ error: "WebSocket upgrades are not supported; use HTTP POST" });
|
|
52302
|
+
socket.end(
|
|
52303
|
+
`HTTP/1.1 426 Upgrade Required\r
|
|
52304
|
+
Connection: close\r
|
|
52305
|
+
Content-Type: application/json\r
|
|
52306
|
+
Content-Length: ${Buffer.byteLength(body)}\r
|
|
52307
|
+
\r
|
|
52308
|
+
` + body
|
|
52309
|
+
);
|
|
52310
|
+
});
|
|
51674
52311
|
if (opts.mitm.enabled) {
|
|
51675
52312
|
setupMitm(server, opts.mitm.domains, (msg2) => log2("info", msg2), (host) => resolveProxy(opts.routes, opts.proxy, `https://${host}`, opts.proxyFallback));
|
|
51676
52313
|
}
|
|
@@ -51794,6 +52431,7 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
51794
52431
|
opts.proxyMode = fresh.proxyMode;
|
|
51795
52432
|
opts.proxySource = fresh.proxySource;
|
|
51796
52433
|
opts.proxyFallback = fresh.proxyFallback;
|
|
52434
|
+
opts.compress = fresh.compress;
|
|
51797
52435
|
resetProxyCache();
|
|
51798
52436
|
for (const k2 of Object.keys(opts.routes)) delete opts.routes[k2];
|
|
51799
52437
|
Object.assign(opts.routes, loadRoutes());
|
|
@@ -51847,10 +52485,37 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
51847
52485
|
}
|
|
51848
52486
|
return;
|
|
51849
52487
|
}
|
|
51850
|
-
if (req.
|
|
51851
|
-
|
|
51852
|
-
|
|
51853
|
-
|
|
52488
|
+
if (req.method === "GET" && req.url === "/__bili/plugin/manifest") return handlePluginManifest(res);
|
|
52489
|
+
if (req.method === "GET" && req.url?.startsWith("/__bili/plugin/status")) {
|
|
52490
|
+
const query = req.url.slice(req.url.indexOf("?") + 1);
|
|
52491
|
+
const conversationId2 = new URLSearchParams(query).get("conversationId")?.trim() ?? "";
|
|
52492
|
+
if (!conversationId2) {
|
|
52493
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
52494
|
+
res.end(JSON.stringify({ ok: false, error: "conversationId query parameter is required" }));
|
|
52495
|
+
return;
|
|
52496
|
+
}
|
|
52497
|
+
return handlePluginStatus(conversationId2, res);
|
|
52498
|
+
}
|
|
52499
|
+
if (req.method === "POST" && req.url === "/__bili/plugin/tool") {
|
|
52500
|
+
try {
|
|
52501
|
+
const body = await readBody(req);
|
|
52502
|
+
return await handlePluginTool(body.toString("utf8"), res, { core, config, log: log2 });
|
|
52503
|
+
} catch (err2) {
|
|
52504
|
+
res.writeHead(err2 instanceof BodyTooLargeError ? 413 : 400, { "content-type": "application/json" });
|
|
52505
|
+
res.end(JSON.stringify({ ok: false, error: String(err2) }));
|
|
52506
|
+
return;
|
|
52507
|
+
}
|
|
52508
|
+
}
|
|
52509
|
+
if (req.method === "POST" && req.url === "/__bili/plugin/register") {
|
|
52510
|
+
try {
|
|
52511
|
+
const body = await readBody(req);
|
|
52512
|
+
handlePluginRegister(body.toString("utf8"), res);
|
|
52513
|
+
return;
|
|
52514
|
+
} catch (err2) {
|
|
52515
|
+
res.writeHead(err2 instanceof BodyTooLargeError ? 413 : 400, { "content-type": "application/json" });
|
|
52516
|
+
res.end(JSON.stringify({ ok: false, error: String(err2) }));
|
|
52517
|
+
return;
|
|
52518
|
+
}
|
|
51854
52519
|
}
|
|
51855
52520
|
let bodyBuffer;
|
|
51856
52521
|
let urlPath;
|
|
@@ -51867,7 +52532,7 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
51867
52532
|
upstreamOrigin = route ? route.upstream : /^https?:\/\//i.test(url) ? new URL(url).origin : opts.upstream;
|
|
51868
52533
|
protocol = route?.explicitProtocol ?? (req.method === "POST" && bodyBuffer.length > 0 ? urlPath.endsWith("/chat/completions") ? "openai" : urlPath.endsWith("/v1/messages") || urlPath.endsWith("/messages") ? "anthropic" : urlPath.endsWith("/responses") || responsesCompact ? "responses" : null : null);
|
|
51869
52534
|
if (protocol !== null && bodyBuffer.length > 0) {
|
|
51870
|
-
const decoded = await decodeRequestBody(
|
|
52535
|
+
const decoded = await decodeRequestBody(headerValue2(req, "content-encoding"), bodyBuffer, MAX_REQUEST_BYTES);
|
|
51871
52536
|
bodyBuffer = decoded.body;
|
|
51872
52537
|
if (decoded.decoded) delete req.headers["content-encoding"];
|
|
51873
52538
|
}
|
|
@@ -51900,11 +52565,11 @@ async function handle(req, res, opts, core, config, log2) {
|
|
|
51900
52565
|
log2("info", `[debug] INCOMING previous_response_id=${hasPrev ? String(p2.previous_response_id).slice(0, 16) : "absent"} input_items=${inLen} instructions=${p2.instructions !== void 0 ? "present" : "absent"}`);
|
|
51901
52566
|
const rawDir = `${stateDir()}/raw`;
|
|
51902
52567
|
try {
|
|
51903
|
-
|
|
52568
|
+
fs6.mkdirSync(rawDir, { recursive: true });
|
|
51904
52569
|
} catch {
|
|
51905
52570
|
}
|
|
51906
52571
|
const hdrs = Object.entries(req.headers).filter(([k2]) => !/authorization|x-api-key|cookie/i.test(k2)).map(([k2, v2]) => `${k2}: ${Array.isArray(v2) ? v2.join(",") : v2}`).join("\n");
|
|
51907
|
-
|
|
52572
|
+
fs6.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${req.url}
|
|
51908
52573
|
${hdrs}
|
|
51909
52574
|
|
|
51910
52575
|
${bodyBuffer.toString("utf8")}`);
|
|
@@ -51917,7 +52582,7 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
51917
52582
|
const model = parsed.model;
|
|
51918
52583
|
if (model) {
|
|
51919
52584
|
const embeddedUrl = route?.rewrittenUrl;
|
|
51920
|
-
let native = resolveContextLimit(opts.routes, embeddedUrl, model);
|
|
52585
|
+
let native = pluginReportedContextWindow(req.headers) ?? resolveContextLimit(opts.routes, embeddedUrl, model);
|
|
51921
52586
|
if (!native && embeddedUrl) {
|
|
51922
52587
|
const host = (() => {
|
|
51923
52588
|
try {
|
|
@@ -51934,11 +52599,16 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
51934
52599
|
}
|
|
51935
52600
|
let prepared = null;
|
|
51936
52601
|
if (!opts.passthrough && protocol && parsed && typeof parsed === "object") {
|
|
51937
|
-
const sessionHeader =
|
|
52602
|
+
const sessionHeader = headerValue2(req, opts.sessionHeader);
|
|
52603
|
+
let pluginAgent = pluginAgentHeader(req.headers);
|
|
52604
|
+
let pluginConversation = pluginConversationHeader(req.headers);
|
|
51938
52605
|
const clientConv = clientConversationHeader(req.headers);
|
|
51939
52606
|
const convHeader = clientConv ?? sessionHeader;
|
|
51940
52607
|
const responsesIdentity = protocol === "responses" ? conversationIdentityResponses(parsed, convHeader) : void 0;
|
|
51941
|
-
const conversation = protocol === "anthropic" ? conversationSignalAnthropic(parsed, convHeader) : protocol === "openai" ? conversationSignalOpenai(parsed, convHeader) :
|
|
52608
|
+
const conversation = protocol === "anthropic" ? conversationSignalAnthropic(parsed, convHeader) : protocol === "openai" ? conversationSignalOpenai(parsed, convHeader) : subagentNamespace(
|
|
52609
|
+
responsesIdentity?.value ?? conversationSignalResponses(parsed, convHeader),
|
|
52610
|
+
parsed.instructions
|
|
52611
|
+
);
|
|
51942
52612
|
const sessionId = deriveSessionId(req.headers, protocol, upstreamOrigin, conversation);
|
|
51943
52613
|
const affinity = affinityToken(responsesIdentity ?? {
|
|
51944
52614
|
value: clientConv ?? conversation,
|
|
@@ -51947,11 +52617,51 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
51947
52617
|
});
|
|
51948
52618
|
const clientLabel = responsesIdentity?.clientProvided ? responsesIdentity.value : clientConversationHeader(req.headers);
|
|
51949
52619
|
const session = getSession(sessionId, { protocol, upstreamOrigin, label: clientLabel ?? void 0 });
|
|
52620
|
+
if (!pluginAgent) {
|
|
52621
|
+
const identityAgent = consumePluginRegisterFor(clientConv ?? conversation);
|
|
52622
|
+
if (identityAgent) {
|
|
52623
|
+
pluginAgent = identityAgent;
|
|
52624
|
+
pluginConversation = clientConv ?? conversation;
|
|
52625
|
+
}
|
|
52626
|
+
}
|
|
52627
|
+
if (!pluginAgent && session.stats.requests === 0) {
|
|
52628
|
+
const pending = takePendingPluginRegister();
|
|
52629
|
+
if (pending) {
|
|
52630
|
+
pluginAgent = pending.agent;
|
|
52631
|
+
pluginConversation = pending.conversationId;
|
|
52632
|
+
}
|
|
52633
|
+
}
|
|
52634
|
+
if (!pluginAgent && typeof session.metadata.pluginAgent === "string") pluginAgent = session.metadata.pluginAgent;
|
|
52635
|
+
if (pluginAgent && !pluginConversation) pluginConversation = conversation;
|
|
52636
|
+
if (pluginAgent) {
|
|
52637
|
+
if (session.metadata.pluginAgent !== pluginAgent) session.metadata.pluginAgent = pluginAgent;
|
|
52638
|
+
session.metadata.effectiveContextLimit = reqConfig.modelContextLimit;
|
|
52639
|
+
recordPluginSession(pluginConversation ?? conversation, session.id);
|
|
52640
|
+
}
|
|
52641
|
+
const pluginMode = pluginAgent !== void 0;
|
|
52642
|
+
const reqModel = parsed.model;
|
|
52643
|
+
const learnedMap = session.metadata.learnedContextLimits;
|
|
52644
|
+
const learnedLimit = (reqModel && learnedMap ? learnedMap[reqModel] : void 0) ?? session.metadata.learnedContextLimit;
|
|
52645
|
+
if (learnedLimit && learnedLimit > 0 && learnedLimit < reqConfig.modelContextLimit) {
|
|
52646
|
+
const resolved = reqConfig.modelContextLimit;
|
|
52647
|
+
reqConfig = { ...reqConfig, modelContextLimit: learnedLimit };
|
|
52648
|
+
log2("info", `[${session.id}] self-healed context window: ${resolved} \u2192 ${learnedLimit} (learned from an upstream overflow)`);
|
|
52649
|
+
}
|
|
52650
|
+
if (shouldReserveOutputHeadroom(protocol)) {
|
|
52651
|
+
const p2 = parsed;
|
|
52652
|
+
const rawMax = p2.max_tokens ?? p2.max_completion_tokens ?? p2.max_output_tokens;
|
|
52653
|
+
const maxOutput = typeof rawMax === "number" ? rawMax : 0;
|
|
52654
|
+
const reserved = reserveOutputHeadroom(reqConfig.modelContextLimit, maxOutput);
|
|
52655
|
+
if (reserved !== reqConfig.modelContextLimit) reqConfig = { ...reqConfig, modelContextLimit: reserved };
|
|
52656
|
+
}
|
|
51950
52657
|
acquireInFlight(session);
|
|
51951
52658
|
try {
|
|
51952
52659
|
await withSessionLock(session, async () => {
|
|
51953
|
-
prepared = countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, reqPrompts, log2, session) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, reqPrompts, log2, session) : responsesCompact ? prepareResponsesCompact(bodyBuffer, parsed, session) : prepareResponses(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity);
|
|
52660
|
+
prepared = countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : responsesCompact ? prepareResponsesCompact(bodyBuffer, parsed, session) : prepareResponses(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode);
|
|
51954
52661
|
await forward(req, res, opts, prepared.body, prepared, core, reqConfig, log2, route, affinity);
|
|
52662
|
+
if (pluginMode && prepared) {
|
|
52663
|
+
rememberPluginMessages(sessionId, prepared.processedMessages, prepared.originalMessages, prepared.nudge);
|
|
52664
|
+
}
|
|
51955
52665
|
});
|
|
51956
52666
|
} finally {
|
|
51957
52667
|
releaseInFlight(session);
|
|
@@ -51979,7 +52689,7 @@ function diagTagSummary(messages, sessionId, strategy) {
|
|
|
51979
52689
|
}
|
|
51980
52690
|
return `[${sessionId}] processTurn: ${messages.length} msgs, renderTags=${strategy}, ${textTagged} text tagged, ${toolTagged} tool tagged (should be 0 with text-only)`;
|
|
51981
52691
|
}
|
|
51982
|
-
function diagNudge(turn, sessionId, tokenCount, limit) {
|
|
52692
|
+
function diagNudge(turn, sessionId, tokenCount, limit, model) {
|
|
51983
52693
|
const n = turn.nudge;
|
|
51984
52694
|
if (!n) return `[${sessionId}] nudge: unavailable`;
|
|
51985
52695
|
const b2 = n.breakdown ?? {};
|
|
@@ -51990,12 +52700,14 @@ function diagNudge(turn, sessionId, tokenCount, limit) {
|
|
|
51990
52700
|
const pendingT1 = b2["pendingT1"] ?? 0;
|
|
51991
52701
|
const ref = b2["growthReference"] ?? 0;
|
|
51992
52702
|
const inject = n.shouldInject ? `INJECT T${n.tier ?? "?"}` : "idle";
|
|
51993
|
-
|
|
52703
|
+
const modelTag = model ? ` model=${model}` : "";
|
|
52704
|
+
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
52705
|
}
|
|
51995
|
-
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session) {
|
|
52706
|
+
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
|
|
51996
52707
|
const sessionId = session.id;
|
|
51997
52708
|
const stream2 = parsed.stream === true;
|
|
51998
52709
|
++session.stats.requests;
|
|
52710
|
+
const injectTools = opts.compress.injectTool && !pluginMode;
|
|
51999
52711
|
let processedMessages = [];
|
|
52000
52712
|
let originalMessages = [];
|
|
52001
52713
|
let nudge;
|
|
@@ -52016,12 +52728,12 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52016
52728
|
if (t) session.meta.title = t;
|
|
52017
52729
|
}
|
|
52018
52730
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52019
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52731
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52020
52732
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52021
52733
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52022
52734
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
52023
52735
|
systemOut = injectSystem(parsed, opts, prompts);
|
|
52024
|
-
if (
|
|
52736
|
+
if (injectTools) {
|
|
52025
52737
|
toolsOut = injectTool(parsed.tools);
|
|
52026
52738
|
}
|
|
52027
52739
|
if (opts.compress.injectNudge && turn.nudge?.shouldInject) {
|
|
@@ -52037,11 +52749,12 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52037
52749
|
log2("warn", `[${sessionId}] kernel transform failed, forwarding unchanged: ${String(err2)}`);
|
|
52038
52750
|
processedMessages = [];
|
|
52039
52751
|
}
|
|
52752
|
+
snapshotMessages(session, originalMessages);
|
|
52040
52753
|
markDirty(session);
|
|
52041
52754
|
const rebuilt = { ...parsed, messages: rebuiltMessages, system: systemOut, tools: toolsOut };
|
|
52042
|
-
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected:
|
|
52755
|
+
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts };
|
|
52043
52756
|
}
|
|
52044
|
-
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session) {
|
|
52757
|
+
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
|
|
52045
52758
|
const sessionId = session.id;
|
|
52046
52759
|
const stream2 = parsed.stream === true;
|
|
52047
52760
|
++session.stats.requests;
|
|
@@ -52053,6 +52766,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session)
|
|
|
52053
52766
|
const maxTokens = typeof parsed.max_tokens === "number" ? parsed.max_tokens : 8192;
|
|
52054
52767
|
const isTitleGen = maxTokens <= 200;
|
|
52055
52768
|
const shouldInject = opts.compress.injectTool && !isTitleGen;
|
|
52769
|
+
const injectTools = shouldInject && !pluginMode;
|
|
52056
52770
|
try {
|
|
52057
52771
|
const { msgs } = openaiToCore(parsed);
|
|
52058
52772
|
originalMessages = msgs;
|
|
@@ -52066,14 +52780,14 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session)
|
|
|
52066
52780
|
if (t) session.meta.title = t;
|
|
52067
52781
|
}
|
|
52068
52782
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52069
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52783
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52070
52784
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52071
52785
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52072
52786
|
rebuiltMessages = coreToOpenai(processedMessages);
|
|
52073
52787
|
const sysParts = [];
|
|
52074
52788
|
if (shouldInject) sysParts.push(buildCompressSystemPrompt(prompts));
|
|
52075
52789
|
rebuiltMessages = injectOpenaiSystem(rebuiltMessages, sysParts);
|
|
52076
|
-
if (
|
|
52790
|
+
if (injectTools) {
|
|
52077
52791
|
toolsOut = injectOpenaiTool(parsed.tools);
|
|
52078
52792
|
}
|
|
52079
52793
|
if (opts.compress.injectNudge && turn.nudge?.shouldInject && shouldInject) {
|
|
@@ -52093,10 +52807,11 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session)
|
|
|
52093
52807
|
if (stream2 && rebuilt.stream_options === void 0) {
|
|
52094
52808
|
rebuilt.stream_options = { include_usage: true };
|
|
52095
52809
|
}
|
|
52810
|
+
snapshotMessages(session, originalMessages);
|
|
52096
52811
|
markDirty(session);
|
|
52097
|
-
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected:
|
|
52812
|
+
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts };
|
|
52098
52813
|
}
|
|
52099
|
-
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity) {
|
|
52814
|
+
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode) {
|
|
52100
52815
|
const sessionId = session.id;
|
|
52101
52816
|
const stream2 = parsed.stream === true;
|
|
52102
52817
|
++session.stats.requests;
|
|
@@ -52110,6 +52825,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52110
52825
|
let rebuiltInput = parsed.input;
|
|
52111
52826
|
let toolsOut = parsed.tools;
|
|
52112
52827
|
const shouldInject = opts.compress.injectTool;
|
|
52828
|
+
const injectTools = shouldInject && !pluginMode;
|
|
52113
52829
|
const responsesTextProtocol = FORCE_TEXT_PROTOCOL || resolveCompressProtocol(opts.routes, session.meta.upstreamOrigin) === "marker";
|
|
52114
52830
|
try {
|
|
52115
52831
|
const projection = responsesToCore(parsed);
|
|
@@ -52129,7 +52845,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52129
52845
|
if (t) session.meta.title = t;
|
|
52130
52846
|
}
|
|
52131
52847
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
52132
|
-
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit));
|
|
52848
|
+
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
52133
52849
|
processedMessages = stripKernelSummaries(turn.messages);
|
|
52134
52850
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
52135
52851
|
rebuiltInput = patchResponsesInput(projection, processedMessages);
|
|
@@ -52137,7 +52853,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52137
52853
|
const prompt = responsesTextProtocol ? buildCompressHybridSystemPrompt(prompts) : buildCompressSystemPrompt(prompts);
|
|
52138
52854
|
const devContent = [...projection.systemParts, prompt].join("\n\n---\n\n");
|
|
52139
52855
|
rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
|
|
52140
|
-
if (!process.env.ACP_NO_INJECT_TOOL) {
|
|
52856
|
+
if (!process.env.ACP_NO_INJECT_TOOL && injectTools) {
|
|
52141
52857
|
toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools);
|
|
52142
52858
|
}
|
|
52143
52859
|
} else if (projection.systemParts.length > 0) {
|
|
@@ -52176,6 +52892,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52176
52892
|
});
|
|
52177
52893
|
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
52894
|
}
|
|
52895
|
+
snapshotMessages(session, originalMessages);
|
|
52179
52896
|
markDirty(session);
|
|
52180
52897
|
return {
|
|
52181
52898
|
body: JSON.stringify(rebuilt),
|
|
@@ -52185,7 +52902,8 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
52185
52902
|
responsesProjection,
|
|
52186
52903
|
protocol: "responses",
|
|
52187
52904
|
stream: stream2,
|
|
52188
|
-
compressInjected:
|
|
52905
|
+
compressInjected: injectTools,
|
|
52906
|
+
pluginMode,
|
|
52189
52907
|
responsesTextProtocol,
|
|
52190
52908
|
nudge,
|
|
52191
52909
|
prompts
|
|
@@ -52316,16 +53034,16 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
52316
53034
|
if (process.env.ACP_DUMP_REQ !== "0") {
|
|
52317
53035
|
const dumpDir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
|
|
52318
53036
|
try {
|
|
52319
|
-
|
|
53037
|
+
fs6.mkdirSync(dumpDir, { recursive: true });
|
|
52320
53038
|
} catch {
|
|
52321
53039
|
}
|
|
52322
53040
|
const sid = prepared?.session.id ?? "unknown";
|
|
52323
53041
|
const out = `${dumpDir}/req-${Date.now()}-${sid}.json`;
|
|
52324
53042
|
try {
|
|
52325
53043
|
const pretty = JSON.stringify(JSON.parse(body), null, 2);
|
|
52326
|
-
|
|
53044
|
+
fs6.writeFileSync(out, pretty);
|
|
52327
53045
|
} catch {
|
|
52328
|
-
|
|
53046
|
+
fs6.writeFileSync(out, body);
|
|
52329
53047
|
}
|
|
52330
53048
|
log2("info", `[debug] forwarded body written to ${out}`);
|
|
52331
53049
|
}
|
|
@@ -52360,7 +53078,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
52360
53078
|
const rawBase = opts.debug ? (() => {
|
|
52361
53079
|
try {
|
|
52362
53080
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
52363
|
-
|
|
53081
|
+
fs6.mkdirSync(rawDir, { recursive: true });
|
|
52364
53082
|
return `${rawDir}/${Date.now()}-${prepared?.session.id ?? "unknown"}`;
|
|
52365
53083
|
} catch {
|
|
52366
53084
|
return "";
|
|
@@ -52372,7 +53090,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
52372
53090
|
const hdrText = Object.entries(headers).map(([k2, v2]) => `${k2}: ${maskHdr(k2, String(v2))}`).join("\n");
|
|
52373
53091
|
const bodyText = req.method === "GET" || req.method === "HEAD" ? "" : typeof body === "string" ? body : Buffer.from(body).toString("utf8");
|
|
52374
53092
|
const reqPath = `${rawBase}-REQ.txt`;
|
|
52375
|
-
|
|
53093
|
+
fs6.writeFileSync(reqPath, `${req.method ?? "POST"} ${upstreamUrl}
|
|
52376
53094
|
${hdrText}
|
|
52377
53095
|
|
|
52378
53096
|
${bodyText}`);
|
|
@@ -52387,9 +53105,13 @@ ${bodyText}`);
|
|
|
52387
53105
|
body: req.method === "GET" || req.method === "HEAD" ? void 0 : body
|
|
52388
53106
|
};
|
|
52389
53107
|
if (dispatcher) init.dispatcher = dispatcher;
|
|
53108
|
+
const clientAbort = new AbortController();
|
|
53109
|
+
res.on("close", () => {
|
|
53110
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
53111
|
+
});
|
|
52390
53112
|
let upstreamResult;
|
|
52391
53113
|
try {
|
|
52392
|
-
upstreamResult = await fetchWithTimeout(upstreamUrl, init);
|
|
53114
|
+
upstreamResult = await fetchWithTimeout(upstreamUrl, init, void 0, clientAbort.signal);
|
|
52393
53115
|
recordUpstreamConnection(upstreamUrl, proxyUrl);
|
|
52394
53116
|
} catch (error) {
|
|
52395
53117
|
recordUpstreamConnection(upstreamUrl, proxyUrl, error);
|
|
@@ -52417,7 +53139,7 @@ ${bodyText}`);
|
|
|
52417
53139
|
const maskHdr = (k2, v2) => /key|auth|token/i.test(k2) ? `<masked ${v2.length} chars>` : v2;
|
|
52418
53140
|
const hdrText = Object.entries(respHeaders).map(([k2, v2]) => `${k2}: ${maskHdr(k2, v2)}`).join("\n");
|
|
52419
53141
|
const resPath = `${rawBase}-RES.txt`;
|
|
52420
|
-
|
|
53142
|
+
fs6.writeFileSync(resPath, `${upstream.status}
|
|
52421
53143
|
${hdrText}
|
|
52422
53144
|
`);
|
|
52423
53145
|
log2("info", `[debug] RAW response dump: ${resPath}`);
|
|
@@ -52425,8 +53147,53 @@ ${hdrText}
|
|
|
52425
53147
|
}
|
|
52426
53148
|
}
|
|
52427
53149
|
if (!upstream.ok) {
|
|
52428
|
-
|
|
52429
|
-
if (upstream.body)
|
|
53150
|
+
let errBody = null;
|
|
53151
|
+
if (upstream.body) {
|
|
53152
|
+
try {
|
|
53153
|
+
errBody = await readStreamToBuffer(upstream.body);
|
|
53154
|
+
} catch {
|
|
53155
|
+
errBody = null;
|
|
53156
|
+
}
|
|
53157
|
+
}
|
|
53158
|
+
if (prepared?.session && errBody) {
|
|
53159
|
+
const s3 = prepared.session;
|
|
53160
|
+
const info = inspectContextOverflow(upstream.status, errBody.toString("utf8"));
|
|
53161
|
+
if (info.isOverflow) {
|
|
53162
|
+
let reqModel;
|
|
53163
|
+
try {
|
|
53164
|
+
const rawBody = typeof prepared.body === "string" ? prepared.body : prepared.body.toString("utf8");
|
|
53165
|
+
reqModel = JSON.parse(rawBody).model;
|
|
53166
|
+
} catch {
|
|
53167
|
+
reqModel = void 0;
|
|
53168
|
+
}
|
|
53169
|
+
const learnedMap = s3.metadata.learnedContextLimits ?? {};
|
|
53170
|
+
if (info.window) {
|
|
53171
|
+
const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit;
|
|
53172
|
+
if (reqModel) learnedMap[reqModel] = info.window;
|
|
53173
|
+
else s3.metadata.learnedContextLimit = info.window;
|
|
53174
|
+
s3.metadata.learnedContextLimits = learnedMap;
|
|
53175
|
+
log2("warn", `[${s3.id}] upstream context overflow \u2014 learned real window ${info.window} for ${reqModel ?? "(unknown model)"} (was ${prev ?? "unset"}); arming emergency shrink`);
|
|
53176
|
+
} else {
|
|
53177
|
+
log2("warn", `[${s3.id}] upstream context overflow (window not parseable): ${info.message}`);
|
|
53178
|
+
}
|
|
53179
|
+
const floor = info.window ?? (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit ?? s3.metadata.effectiveContextLimit ?? 0;
|
|
53180
|
+
if (floor > 0) s3.stats.lastInputTokens = Math.max(s3.stats.lastInputTokens, floor);
|
|
53181
|
+
markDirty(s3);
|
|
53182
|
+
}
|
|
53183
|
+
}
|
|
53184
|
+
const errSid = prepared?.session.id ?? "unknown";
|
|
53185
|
+
const reqId = upstream.headers.get("x-request-id") ?? upstream.headers.get("request-id");
|
|
53186
|
+
const reqIdText = reqId ? ` request-id=${reqId}` : "";
|
|
53187
|
+
const bodyText = errBody ? new TextDecoder().decode(errBody) : "";
|
|
53188
|
+
let snippet = bodyText.slice(0, 600).replace(/\s+/g, " ").trim();
|
|
53189
|
+
if (bodyText.length > 600) snippet += " \u2026";
|
|
53190
|
+
if (!snippet) snippet = "(no body)";
|
|
53191
|
+
log("warn", `[${errSid}] \u2190 upstream ${upstream.status}${reqIdText}: ${snippet}`);
|
|
53192
|
+
const errHeaders = { ...respHeaders };
|
|
53193
|
+
delete errHeaders["content-length"];
|
|
53194
|
+
delete errHeaders["transfer-encoding"];
|
|
53195
|
+
res.writeHead(upstream.status, errHeaders);
|
|
53196
|
+
res.end(errBody ?? void 0);
|
|
52430
53197
|
clearUpstreamTimer();
|
|
52431
53198
|
return;
|
|
52432
53199
|
}
|
|
@@ -52440,6 +53207,15 @@ ${hdrText}
|
|
|
52440
53207
|
}
|
|
52441
53208
|
return;
|
|
52442
53209
|
}
|
|
53210
|
+
if (prepared?.pluginMode) {
|
|
53211
|
+
if (prepared.stream) {
|
|
53212
|
+
await pipeThroughWithUsage(upstream.body, res, prepared.session, prepared.protocol);
|
|
53213
|
+
} else {
|
|
53214
|
+
await pipePluginJson(upstream.body, res, prepared.session, prepared.protocol);
|
|
53215
|
+
}
|
|
53216
|
+
clearUpstreamTimer();
|
|
53217
|
+
return;
|
|
53218
|
+
}
|
|
52443
53219
|
const useRewriter = prepared !== null && prepared.compressInjected && prepared.processedMessages.length > 0;
|
|
52444
53220
|
if (!useRewriter || prepared === null) {
|
|
52445
53221
|
await pipeThrough(upstream.body, res);
|
|
@@ -52472,20 +53248,17 @@ ${hdrText}
|
|
|
52472
53248
|
const textProtocol = prepared.protocol === "responses" && !!prepared.responsesTextProtocol;
|
|
52473
53249
|
const systemPrompt = textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts);
|
|
52474
53250
|
const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem);
|
|
52475
|
-
const abortCtrl = new AbortController();
|
|
52476
|
-
req.on("close", () => {
|
|
52477
|
-
if (!res.writableEnded) abortCtrl.abort();
|
|
52478
|
-
});
|
|
52479
53251
|
const loop = runCompressLoop(
|
|
52480
53252
|
streamToRead,
|
|
52481
|
-
{ core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, textProtocol, debug: opts.debug, nudge: prepared.nudge },
|
|
53253
|
+
{ core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, protocol: prepared.protocol, textProtocol, debug: opts.debug, nudge: prepared.nudge },
|
|
52482
53254
|
parsedReq,
|
|
52483
53255
|
{ url: upstreamUrl, headers: reqHeaders },
|
|
52484
53256
|
adapter,
|
|
52485
53257
|
systemPrompt,
|
|
52486
|
-
|
|
53258
|
+
clientAbort.signal
|
|
52487
53259
|
);
|
|
52488
53260
|
for await (const chunk of loop) {
|
|
53261
|
+
if (res.destroyed || res.writableEnded) break;
|
|
52489
53262
|
{
|
|
52490
53263
|
const s3 = chunk.toString("utf8");
|
|
52491
53264
|
if (s3.includes("<acp ") || s3.includes("</acp")) {
|
|
@@ -52525,13 +53298,10 @@ ${hdrText}
|
|
|
52525
53298
|
);
|
|
52526
53299
|
}
|
|
52527
53300
|
const u2 = json.usage ?? {};
|
|
52528
|
-
const
|
|
52529
|
-
if (typeof
|
|
52530
|
-
prepared.session.stats.inputTokens +=
|
|
52531
|
-
|
|
52532
|
-
const inputDetails = u2.input_tokens_details;
|
|
52533
|
-
const cached = promptDetails?.cached_tokens ?? inputDetails?.cached_tokens ?? u2.cache_read_input_tokens;
|
|
52534
|
-
prepared.session.stats.lastInputTokens = prompt + (typeof cached === "number" ? cached : 0);
|
|
53301
|
+
const { total, cached } = usageTotals(prepared.protocol, u2);
|
|
53302
|
+
if (typeof total === "number") {
|
|
53303
|
+
prepared.session.stats.inputTokens += total;
|
|
53304
|
+
prepared.session.stats.lastInputTokens = total;
|
|
52535
53305
|
if (typeof cached === "number") {
|
|
52536
53306
|
prepared.session.stats.cachedTokens += cached;
|
|
52537
53307
|
prepared.session.stats.cacheSamples += 1;
|
|
@@ -52556,6 +53326,25 @@ ${hdrText}
|
|
|
52556
53326
|
}
|
|
52557
53327
|
markDirty(prepared.session);
|
|
52558
53328
|
}
|
|
53329
|
+
async function readStreamToBuffer(stream2, maxBytes = 1 << 20) {
|
|
53330
|
+
const reader = stream2.getReader();
|
|
53331
|
+
const chunks = [];
|
|
53332
|
+
let kept = 0;
|
|
53333
|
+
try {
|
|
53334
|
+
for (; ; ) {
|
|
53335
|
+
const { done, value } = await reader.read();
|
|
53336
|
+
if (done) break;
|
|
53337
|
+
if (value && kept < maxBytes) {
|
|
53338
|
+
const take = Math.min(value.length, maxBytes - kept);
|
|
53339
|
+
chunks.push(Buffer.from(value.subarray(0, take)));
|
|
53340
|
+
kept += take;
|
|
53341
|
+
}
|
|
53342
|
+
}
|
|
53343
|
+
} finally {
|
|
53344
|
+
reader.releaseLock();
|
|
53345
|
+
}
|
|
53346
|
+
return Buffer.concat(chunks);
|
|
53347
|
+
}
|
|
52559
53348
|
async function pipeThrough(stream2, res) {
|
|
52560
53349
|
const reader = stream2.getReader();
|
|
52561
53350
|
try {
|
|
@@ -52572,10 +53361,10 @@ async function pipeThrough(stream2, res) {
|
|
|
52572
53361
|
}
|
|
52573
53362
|
}
|
|
52574
53363
|
async function dumpStreamToFile(stream2, dir, name) {
|
|
52575
|
-
const { mkdirSync:
|
|
53364
|
+
const { mkdirSync: mkdirSync7, createWriteStream: createWriteStream2 } = await import("fs");
|
|
52576
53365
|
const { join: join4 } = await import("path");
|
|
52577
53366
|
try {
|
|
52578
|
-
|
|
53367
|
+
mkdirSync7(dir, { recursive: true });
|
|
52579
53368
|
const ws2 = createWriteStream2(join4(dir, name));
|
|
52580
53369
|
ws2.on("error", (e) => {
|
|
52581
53370
|
log("debug", `[dump] write stream error: ${e.message ?? e}`);
|
|
@@ -52606,6 +53395,7 @@ function handleConfigReload(opts, res, log2) {
|
|
|
52606
53395
|
const fresh = loadRoutes();
|
|
52607
53396
|
for (const k2 of Object.keys(opts.routes)) delete opts.routes[k2];
|
|
52608
53397
|
Object.assign(opts.routes, fresh);
|
|
53398
|
+
opts.compress = loadOptions().compress;
|
|
52609
53399
|
resetProxyCache();
|
|
52610
53400
|
const names = Object.keys(fresh);
|
|
52611
53401
|
log2("info", `[acp-web] routes hot-reloaded (${names.length} providers): ${names.join(", ") || "(none)"}`);
|
|
@@ -52631,7 +53421,7 @@ function sendStats(res) {
|
|
|
52631
53421
|
res.writeHead(200, { "content-type": "application/json" });
|
|
52632
53422
|
res.end(JSON.stringify({ sessions: sessions2 }, null, 2));
|
|
52633
53423
|
}
|
|
52634
|
-
function
|
|
53424
|
+
function headerValue2(req, name) {
|
|
52635
53425
|
const lower = name.toLowerCase();
|
|
52636
53426
|
for (const [k2, v2] of Object.entries(req.headers)) {
|
|
52637
53427
|
if (k2.toLowerCase() === lower) return Array.isArray(v2) ? v2[0] : v2;
|
|
@@ -52677,6 +53467,7 @@ function logMsg(opts, level, msg2) {
|
|
|
52677
53467
|
|
|
52678
53468
|
// src/update.ts
|
|
52679
53469
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, access, constants, rm, cp, unlink } from "fs/promises";
|
|
53470
|
+
import { execFile } from "child_process";
|
|
52680
53471
|
import crypto from "crypto";
|
|
52681
53472
|
|
|
52682
53473
|
// node_modules/tar/dist/esm/index.min.js
|
|
@@ -54616,7 +55407,7 @@ var hr = /* @__PURE__ */ Symbol("entry");
|
|
|
54616
55407
|
var cs = /* @__PURE__ */ Symbol("entryOpt");
|
|
54617
55408
|
var ui = /* @__PURE__ */ Symbol("writeEntryClass");
|
|
54618
55409
|
var lr = /* @__PURE__ */ Symbol("write");
|
|
54619
|
-
var
|
|
55410
|
+
var fs7 = /* @__PURE__ */ Symbol("ondrain");
|
|
54620
55411
|
var wt = class extends A {
|
|
54621
55412
|
sync = false;
|
|
54622
55413
|
opt;
|
|
@@ -54650,8 +55441,8 @@ var wt = class extends A {
|
|
|
54650
55441
|
if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
|
|
54651
55442
|
if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = true), this.zip = new ze(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new We(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ye(t.zstd)), !this.zip) throw new Error("impossible");
|
|
54652
55443
|
let e = this.zip;
|
|
54653
|
-
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[
|
|
54654
|
-
} else this.on("drain", this[
|
|
55444
|
+
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs7]()), this.on("resume", () => e.resume());
|
|
55445
|
+
} else this.on("drain", this[fs7]);
|
|
54655
55446
|
this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => true, this[W] = new hi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[Ee] = false, this[me] = false;
|
|
54656
55447
|
}
|
|
54657
55448
|
[lr](t) {
|
|
@@ -54764,7 +55555,7 @@ var wt = class extends A {
|
|
|
54764
55555
|
this.emit("error", e);
|
|
54765
55556
|
}
|
|
54766
55557
|
}
|
|
54767
|
-
[
|
|
55558
|
+
[fs7]() {
|
|
54768
55559
|
this[Et] && this[Et].entry && this[Et].entry.resume();
|
|
54769
55560
|
}
|
|
54770
55561
|
[di](t) {
|
|
@@ -55649,12 +56440,12 @@ var To = (s3) => {
|
|
|
55649
56440
|
};
|
|
55650
56441
|
|
|
55651
56442
|
// src/update.ts
|
|
55652
|
-
import
|
|
55653
|
-
import { fileURLToPath as
|
|
56443
|
+
import path9 from "path";
|
|
56444
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
55654
56445
|
var REGISTRY_BASE = "https://registry.npmjs.org";
|
|
55655
56446
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
55656
|
-
var THROTTLE_FILE =
|
|
55657
|
-
var LOCK_FILE =
|
|
56447
|
+
var THROTTLE_FILE = path9.join(cacheDir(), ".update-check");
|
|
56448
|
+
var LOCK_FILE = path9.join(cacheDir(), ".update-lock");
|
|
55658
56449
|
var LOCK_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
55659
56450
|
function shouldStealLock(holderAlive, ageMs) {
|
|
55660
56451
|
return !holderAlive || ageMs >= LOCK_MAX_AGE_MS;
|
|
@@ -55686,32 +56477,101 @@ async function readLastCheck() {
|
|
|
55686
56477
|
}
|
|
55687
56478
|
async function writeLastCheck(ts2) {
|
|
55688
56479
|
try {
|
|
55689
|
-
await mkdir2(
|
|
56480
|
+
await mkdir2(path9.dirname(THROTTLE_FILE), { recursive: true });
|
|
55690
56481
|
await writeFile2(THROTTLE_FILE, String(ts2), "utf-8");
|
|
55691
56482
|
} catch {
|
|
55692
56483
|
}
|
|
55693
56484
|
}
|
|
55694
56485
|
async function findInstallDir(packageName) {
|
|
55695
|
-
let dir =
|
|
56486
|
+
let dir = path9.dirname(fileURLToPath3(import.meta.url));
|
|
55696
56487
|
for (; ; ) {
|
|
55697
56488
|
try {
|
|
55698
|
-
const pkg = JSON.parse(await readFile2(
|
|
56489
|
+
const pkg = JSON.parse(await readFile2(path9.join(dir, "package.json"), "utf-8"));
|
|
55699
56490
|
if (pkg.name === packageName) return dir;
|
|
55700
56491
|
} catch {
|
|
55701
56492
|
}
|
|
55702
|
-
const parent =
|
|
56493
|
+
const parent = path9.dirname(dir);
|
|
55703
56494
|
if (parent === dir) return void 0;
|
|
55704
56495
|
dir = parent;
|
|
55705
56496
|
}
|
|
55706
56497
|
}
|
|
55707
56498
|
async function readDiskVersion(installDir) {
|
|
55708
56499
|
try {
|
|
55709
|
-
const pkg = JSON.parse(await readFile2(
|
|
56500
|
+
const pkg = JSON.parse(await readFile2(path9.join(installDir, "package.json"), "utf-8"));
|
|
55710
56501
|
return pkg.version;
|
|
55711
56502
|
} catch {
|
|
55712
56503
|
return void 0;
|
|
55713
56504
|
}
|
|
55714
56505
|
}
|
|
56506
|
+
function declaredEntryRelPaths(pkg) {
|
|
56507
|
+
const entries = /* @__PURE__ */ new Set();
|
|
56508
|
+
if (typeof pkg.main === "string") entries.add(pkg.main);
|
|
56509
|
+
const bin = pkg.bin;
|
|
56510
|
+
if (typeof bin === "string") entries.add(bin);
|
|
56511
|
+
else if (bin && typeof bin === "object") {
|
|
56512
|
+
for (const v2 of Object.values(bin)) {
|
|
56513
|
+
if (typeof v2 === "string") entries.add(v2);
|
|
56514
|
+
}
|
|
56515
|
+
}
|
|
56516
|
+
return [...entries];
|
|
56517
|
+
}
|
|
56518
|
+
function runNodeCheck(file) {
|
|
56519
|
+
return new Promise((resolve) => {
|
|
56520
|
+
execFile(
|
|
56521
|
+
process.execPath,
|
|
56522
|
+
["--check", file],
|
|
56523
|
+
{ timeout: 15e3, maxBuffer: 4 * 1024 * 1024 },
|
|
56524
|
+
(err2, _stdout, stderr) => {
|
|
56525
|
+
resolve({ code: err2 ? 1 : 0, stderr: String(stderr) });
|
|
56526
|
+
}
|
|
56527
|
+
);
|
|
56528
|
+
});
|
|
56529
|
+
}
|
|
56530
|
+
async function syntaxCheckEntry(entryAbs) {
|
|
56531
|
+
let source;
|
|
56532
|
+
try {
|
|
56533
|
+
source = await readFile2(entryAbs, "utf-8");
|
|
56534
|
+
} catch (e) {
|
|
56535
|
+
return `entry unreadable: ${String(e)}`;
|
|
56536
|
+
}
|
|
56537
|
+
const tmpCheck = path9.join(cacheDir(), ".update-syntax-check.mjs");
|
|
56538
|
+
try {
|
|
56539
|
+
await mkdir2(cacheDir(), { recursive: true });
|
|
56540
|
+
await writeFile2(tmpCheck, source);
|
|
56541
|
+
const r = await runNodeCheck(tmpCheck);
|
|
56542
|
+
if (r.code !== 0) {
|
|
56543
|
+
return `entry does not parse (${path9.basename(entryAbs)}): ${r.stderr.split("\n").filter(Boolean).slice(0, 3).join(" | ").slice(0, 300)}`;
|
|
56544
|
+
}
|
|
56545
|
+
return null;
|
|
56546
|
+
} finally {
|
|
56547
|
+
try {
|
|
56548
|
+
await rm(tmpCheck, { force: true });
|
|
56549
|
+
} catch {
|
|
56550
|
+
}
|
|
56551
|
+
}
|
|
56552
|
+
}
|
|
56553
|
+
async function verifyEntries(dir, label) {
|
|
56554
|
+
let pkg;
|
|
56555
|
+
try {
|
|
56556
|
+
pkg = JSON.parse(await readFile2(path9.join(dir, "package.json"), "utf-8"));
|
|
56557
|
+
} catch (e) {
|
|
56558
|
+
return `${label}: package.json unreadable: ${String(e)}`;
|
|
56559
|
+
}
|
|
56560
|
+
const entries = declaredEntryRelPaths(pkg);
|
|
56561
|
+
if (entries.length === 0) {
|
|
56562
|
+
return `${label}: no declared entry (main/bin)`;
|
|
56563
|
+
}
|
|
56564
|
+
for (const rel of entries) {
|
|
56565
|
+
try {
|
|
56566
|
+
await access(path9.join(dir, rel));
|
|
56567
|
+
} catch {
|
|
56568
|
+
return `${label}: entry missing: ${rel}`;
|
|
56569
|
+
}
|
|
56570
|
+
const reason = await syntaxCheckEntry(path9.join(dir, rel));
|
|
56571
|
+
if (reason) return `${label}: ${reason}`;
|
|
56572
|
+
}
|
|
56573
|
+
return null;
|
|
56574
|
+
}
|
|
55715
56575
|
async function tryAcquireLock() {
|
|
55716
56576
|
const pid = process.pid;
|
|
55717
56577
|
const now = Date.now();
|
|
@@ -55908,14 +56768,14 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
55908
56768
|
if (!v2.ok) {
|
|
55909
56769
|
return { ok: false, error: `tarball integrity verification failed: ${v2.error}` };
|
|
55910
56770
|
}
|
|
55911
|
-
const tmpFile =
|
|
56771
|
+
const tmpFile = path9.join(cacheDir(), `.update-${version2}.tgz`);
|
|
55912
56772
|
try {
|
|
55913
56773
|
await mkdir2(cacheDir(), { recursive: true });
|
|
55914
56774
|
await writeFile2(tmpFile, tgzBuffer);
|
|
55915
56775
|
} catch (e) {
|
|
55916
56776
|
return { ok: false, error: `failed to write temp file ${tmpFile}: ${String(e)}` };
|
|
55917
56777
|
}
|
|
55918
|
-
const stagingDir =
|
|
56778
|
+
const stagingDir = path9.join(cacheDir(), `.update-staging-${version2}`);
|
|
55919
56779
|
try {
|
|
55920
56780
|
await rm(stagingDir, { recursive: true, force: true });
|
|
55921
56781
|
await mkdir2(stagingDir, { recursive: true });
|
|
@@ -55928,22 +56788,57 @@ async function installViaTarball(version2, tarballUrl, installDir, integrity, sh
|
|
|
55928
56788
|
if (stagingVersion !== version2) {
|
|
55929
56789
|
return { ok: false, error: `staging verification failed: version is ${stagingVersion ?? "missing"}, expected ${version2}` };
|
|
55930
56790
|
}
|
|
56791
|
+
const stagingEntryErr = await verifyEntries(stagingDir, "staging verification failed");
|
|
56792
|
+
if (stagingEntryErr) {
|
|
56793
|
+
return { ok: false, error: stagingEntryErr };
|
|
56794
|
+
}
|
|
55931
56795
|
} catch (e) {
|
|
55932
56796
|
return { ok: false, error: `extraction failed: ${String(e)}` };
|
|
55933
56797
|
} finally {
|
|
55934
56798
|
await rm(tmpFile, { force: true });
|
|
55935
56799
|
}
|
|
56800
|
+
const backupDir = path9.join(cacheDir(), `.update-backup-${version2}`);
|
|
56801
|
+
try {
|
|
56802
|
+
await rm(backupDir, { recursive: true, force: true });
|
|
56803
|
+
await cp(installDir, backupDir, { recursive: true, force: true });
|
|
56804
|
+
} catch (e) {
|
|
56805
|
+
return { ok: false, error: `backup of current install failed (install left untouched): ${String(e)}` };
|
|
56806
|
+
}
|
|
56807
|
+
const restoreFromBackup = async () => {
|
|
56808
|
+
try {
|
|
56809
|
+
await rm(installDir, { recursive: true, force: true });
|
|
56810
|
+
await cp(backupDir, installDir, { recursive: true, force: true });
|
|
56811
|
+
return null;
|
|
56812
|
+
} catch (e) {
|
|
56813
|
+
return `ROLLBACK FAILED \u2014 restore ${backupDir} to ${installDir} manually: ${String(e)}`;
|
|
56814
|
+
}
|
|
56815
|
+
};
|
|
56816
|
+
let copyError = null;
|
|
55936
56817
|
try {
|
|
55937
56818
|
await cp(stagingDir, installDir, { recursive: true, force: true });
|
|
55938
56819
|
} catch (e) {
|
|
55939
|
-
|
|
56820
|
+
copyError = `failed to copy to install dir: ${String(e)}`;
|
|
55940
56821
|
} finally {
|
|
55941
56822
|
await rm(stagingDir, { recursive: true, force: true });
|
|
55942
56823
|
}
|
|
56824
|
+
if (copyError !== null) {
|
|
56825
|
+
const rb2 = await restoreFromBackup();
|
|
56826
|
+
return { ok: false, error: rb2 ?? copyError };
|
|
56827
|
+
}
|
|
55943
56828
|
const newVersion = await readDiskVersion(installDir);
|
|
55944
56829
|
if (newVersion !== version2) {
|
|
55945
|
-
|
|
56830
|
+
const rb2 = await restoreFromBackup();
|
|
56831
|
+
return {
|
|
56832
|
+
ok: false,
|
|
56833
|
+
error: rb2 ?? `post-install verification failed: package.json version is ${newVersion ?? "missing"}, expected ${version2}`
|
|
56834
|
+
};
|
|
55946
56835
|
}
|
|
56836
|
+
const postEntryErr = await verifyEntries(installDir, "post-install verification failed");
|
|
56837
|
+
if (postEntryErr) {
|
|
56838
|
+
const rb2 = await restoreFromBackup();
|
|
56839
|
+
return { ok: false, error: rb2 ?? postEntryErr };
|
|
56840
|
+
}
|
|
56841
|
+
await rm(backupDir, { recursive: true, force: true });
|
|
55947
56842
|
return { ok: true };
|
|
55948
56843
|
}
|
|
55949
56844
|
function startAutoUpdate(opts) {
|
|
@@ -55957,11 +56852,165 @@ function startAutoUpdate(opts) {
|
|
|
55957
56852
|
timer.unref?.();
|
|
55958
56853
|
}
|
|
55959
56854
|
|
|
56855
|
+
// src/mcp.ts
|
|
56856
|
+
import fs8 from "fs";
|
|
56857
|
+
import path10 from "path";
|
|
56858
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
56859
|
+
var VERSION2 = (() => {
|
|
56860
|
+
try {
|
|
56861
|
+
const here = fileURLToPath4(import.meta.url);
|
|
56862
|
+
const pkg = path10.join(path10.dirname(here), "..", "package.json");
|
|
56863
|
+
return JSON.parse(fs8.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
56864
|
+
} catch {
|
|
56865
|
+
return "dev";
|
|
56866
|
+
}
|
|
56867
|
+
})();
|
|
56868
|
+
var PROXY_ORIGIN = process.env.BILI_MCP_PROXY ?? "http://127.0.0.1:8787";
|
|
56869
|
+
var CONVERSATION_FROM_ENV = process.env.CLAUDE_CODE_SESSION_ID?.trim() || process.env.BILI_CONVERSATION_ID?.trim() || void 0;
|
|
56870
|
+
var IDENTITY_BINDING = Boolean(process.env.CLAUDE_CODE_SESSION_ID?.trim());
|
|
56871
|
+
var manifestTools = [];
|
|
56872
|
+
var conversationId = CONVERSATION_FROM_ENV;
|
|
56873
|
+
var registered = false;
|
|
56874
|
+
var initialized2 = false;
|
|
56875
|
+
function send(msg2) {
|
|
56876
|
+
process.stdout.write(JSON.stringify(msg2) + "\n");
|
|
56877
|
+
}
|
|
56878
|
+
function sendResult(id, result) {
|
|
56879
|
+
if (id === null) return;
|
|
56880
|
+
send({ jsonrpc: "2.0", id, result });
|
|
56881
|
+
}
|
|
56882
|
+
function sendError2(id, code, message) {
|
|
56883
|
+
if (id === null) return;
|
|
56884
|
+
send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
56885
|
+
}
|
|
56886
|
+
async function fetchManifest() {
|
|
56887
|
+
const res = await fetch(`${PROXY_ORIGIN}/__bili/plugin/manifest`);
|
|
56888
|
+
if (!res.ok) throw new Error(`manifest fetch failed: ${res.status}`);
|
|
56889
|
+
const data = await res.json();
|
|
56890
|
+
const anthropic = data.tools?.anthropic ?? [];
|
|
56891
|
+
manifestTools = anthropic.map((t) => ({ name: t.name, description: t.description, inputSchema: t.input_schema }));
|
|
56892
|
+
if (manifestTools.length === 0) throw new Error("manifest served no anthropic tools");
|
|
56893
|
+
}
|
|
56894
|
+
async function forwardTool(tool, args) {
|
|
56895
|
+
const res = await fetch(`${PROXY_ORIGIN}/__bili/plugin/tool`, {
|
|
56896
|
+
method: "POST",
|
|
56897
|
+
headers: { "content-type": "application/json" },
|
|
56898
|
+
body: JSON.stringify({ conversationId, tool, args })
|
|
56899
|
+
});
|
|
56900
|
+
const data = await res.json();
|
|
56901
|
+
if (!res.ok || !data.ok) throw new Error(data.error ?? `tool forward failed: ${res.status}`);
|
|
56902
|
+
return data.result ?? "";
|
|
56903
|
+
}
|
|
56904
|
+
var ERR_TOOL = -32602;
|
|
56905
|
+
async function handleMessage(msg2) {
|
|
56906
|
+
const { id = null, method } = msg2;
|
|
56907
|
+
const params = typeof msg2.params === "object" && msg2.params !== null ? msg2.params : {};
|
|
56908
|
+
switch (method) {
|
|
56909
|
+
case "initialize": {
|
|
56910
|
+
const fromMeta = params._meta?.ui?.sessionId?.trim();
|
|
56911
|
+
if (fromMeta) conversationId ??= fromMeta;
|
|
56912
|
+
initialized2 = true;
|
|
56913
|
+
if (conversationId && !registered) {
|
|
56914
|
+
const registerFetch = fetch(`${PROXY_ORIGIN}/__bili/plugin/register`, {
|
|
56915
|
+
method: "POST",
|
|
56916
|
+
headers: { "content-type": "application/json" },
|
|
56917
|
+
body: JSON.stringify({ conversationId, agent: "mcp", identity: IDENTITY_BINDING })
|
|
56918
|
+
});
|
|
56919
|
+
registered = true;
|
|
56920
|
+
if (IDENTITY_BINDING) {
|
|
56921
|
+
void registerFetch.catch(() => {
|
|
56922
|
+
});
|
|
56923
|
+
} else {
|
|
56924
|
+
await registerFetch.catch(() => {
|
|
56925
|
+
});
|
|
56926
|
+
}
|
|
56927
|
+
}
|
|
56928
|
+
sendResult(id, {
|
|
56929
|
+
protocolVersion: "2025-06-18",
|
|
56930
|
+
serverInfo: { name: "bili", version: VERSION2 },
|
|
56931
|
+
capabilities: { tools: {} }
|
|
56932
|
+
});
|
|
56933
|
+
return;
|
|
56934
|
+
}
|
|
56935
|
+
case "notifications/initialized":
|
|
56936
|
+
return;
|
|
56937
|
+
case "tools/list": {
|
|
56938
|
+
if (!initialized2) {
|
|
56939
|
+
sendError2(id, -32002, "server not initialized");
|
|
56940
|
+
return;
|
|
56941
|
+
}
|
|
56942
|
+
sendResult(id, { tools: manifestTools });
|
|
56943
|
+
return;
|
|
56944
|
+
}
|
|
56945
|
+
case "tools/call": {
|
|
56946
|
+
const tool = typeof params.name === "string" ? params.name : "";
|
|
56947
|
+
const args = params.arguments && typeof params.arguments === "object" ? params.arguments : {};
|
|
56948
|
+
if (!tool) {
|
|
56949
|
+
sendError2(id, ERR_TOOL, "params.name is required");
|
|
56950
|
+
return;
|
|
56951
|
+
}
|
|
56952
|
+
if (!conversationId) {
|
|
56953
|
+
sendError2(id, ERR_TOOL, "no conversation id (set BILI_CONVERSATION_ID or connect via Claude Code MCP session meta)");
|
|
56954
|
+
return;
|
|
56955
|
+
}
|
|
56956
|
+
try {
|
|
56957
|
+
const text = await forwardTool(tool, args);
|
|
56958
|
+
sendResult(id, { content: [{ type: "text", text }], isError: false });
|
|
56959
|
+
} catch (err2) {
|
|
56960
|
+
sendResult(id, { content: [{ type: "text", text: `bili tool error: ${err2 instanceof Error ? err2.message : String(err2)}` }], isError: true });
|
|
56961
|
+
}
|
|
56962
|
+
return;
|
|
56963
|
+
}
|
|
56964
|
+
case "ping":
|
|
56965
|
+
sendResult(id, {});
|
|
56966
|
+
return;
|
|
56967
|
+
default:
|
|
56968
|
+
if (method?.startsWith("notifications/")) return;
|
|
56969
|
+
sendError2(id, -32601, `method not found: ${method ?? "(none)"}`);
|
|
56970
|
+
}
|
|
56971
|
+
}
|
|
56972
|
+
async function mcpMain() {
|
|
56973
|
+
try {
|
|
56974
|
+
await fetchManifest();
|
|
56975
|
+
} catch (err2) {
|
|
56976
|
+
console.error(`bili-mcp: ${err2 instanceof Error ? err2.message : String(err2)} (proxy at ${PROXY_ORIGIN})`);
|
|
56977
|
+
process.exit(1);
|
|
56978
|
+
}
|
|
56979
|
+
let buf = "";
|
|
56980
|
+
process.stdin.setEncoding("utf8");
|
|
56981
|
+
process.stdin.on("data", (chunk) => {
|
|
56982
|
+
buf += chunk;
|
|
56983
|
+
let nl;
|
|
56984
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
56985
|
+
const line = buf.slice(0, nl).trim();
|
|
56986
|
+
buf = buf.slice(nl + 1);
|
|
56987
|
+
if (!line) continue;
|
|
56988
|
+
let parsed;
|
|
56989
|
+
try {
|
|
56990
|
+
parsed = JSON.parse(line);
|
|
56991
|
+
} catch {
|
|
56992
|
+
continue;
|
|
56993
|
+
}
|
|
56994
|
+
if (parsed && typeof parsed === "object") {
|
|
56995
|
+
void handleMessage(parsed);
|
|
56996
|
+
}
|
|
56997
|
+
}
|
|
56998
|
+
});
|
|
56999
|
+
process.stdin.on("end", () => process.exit(0));
|
|
57000
|
+
}
|
|
57001
|
+
function runMcpStdio() {
|
|
57002
|
+
void mcpMain();
|
|
57003
|
+
}
|
|
57004
|
+
if (process.argv[1] && /(?:^|[\\/])mcp\.(?:ts|js)$/.test(process.argv[1])) {
|
|
57005
|
+
void mcpMain();
|
|
57006
|
+
}
|
|
57007
|
+
|
|
55960
57008
|
// src/launcher.ts
|
|
55961
|
-
import
|
|
57009
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
57010
|
+
import fs9 from "fs";
|
|
55962
57011
|
import net2 from "net";
|
|
55963
57012
|
import os4 from "os";
|
|
55964
|
-
import
|
|
57013
|
+
import path11 from "path";
|
|
55965
57014
|
import { spawn } from "child_process";
|
|
55966
57015
|
var LAUNCHER_DEFAULT_HOST = "127.0.0.1";
|
|
55967
57016
|
var LAUNCHER_DEFAULT_PORT = 8787;
|
|
@@ -56005,8 +57054,12 @@ function unwrapUpstream2(url) {
|
|
|
56005
57054
|
return idx >= 0 ? url.slice(idx + "/bili/".length) : url;
|
|
56006
57055
|
}
|
|
56007
57056
|
function resolveCaCertPath(env) {
|
|
56008
|
-
const base = env.XDG_DATA_HOME ||
|
|
56009
|
-
return
|
|
57057
|
+
const base = env.XDG_DATA_HOME || path11.join(os4.homedir(), ".local/share");
|
|
57058
|
+
return path11.join(base, "billion-context", "ca", "root-ca.pem");
|
|
57059
|
+
}
|
|
57060
|
+
function resolveCombinedCaPath(env) {
|
|
57061
|
+
const base = env.XDG_DATA_HOME || path11.join(os4.homedir(), ".local/share");
|
|
57062
|
+
return path11.join(base, "billion-context", "ca", "combined-ca.pem");
|
|
56010
57063
|
}
|
|
56011
57064
|
function discoverRoutes(client, config) {
|
|
56012
57065
|
const httpsDomains = [];
|
|
@@ -56060,10 +57113,10 @@ function discoverDomains(client, config) {
|
|
|
56060
57113
|
return discoverRoutes(client, config).httpsDomains;
|
|
56061
57114
|
}
|
|
56062
57115
|
function buildPiEnv(origin, caPath, baseEnv) {
|
|
56063
|
-
return { ...baseEnv, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: caPath };
|
|
57116
|
+
return { ...baseEnv, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: caPath, BILLION_CONTEXT_PROXY: origin };
|
|
56064
57117
|
}
|
|
56065
57118
|
function buildCodexEnv(origin, caPath, baseEnv) {
|
|
56066
|
-
return { ...baseEnv, HTTPS_PROXY: origin, SSL_CERT_FILE: caPath };
|
|
57119
|
+
return { ...baseEnv, HTTPS_PROXY: origin, SSL_CERT_FILE: caPath, BILLION_CONTEXT_PROXY: origin };
|
|
56067
57120
|
}
|
|
56068
57121
|
function buildCodexArgs(origin, httpRewrites, httpsRewrites, extra) {
|
|
56069
57122
|
const args = [];
|
|
@@ -56077,19 +57130,55 @@ function buildCodexArgs(origin, httpRewrites, httpsRewrites, extra) {
|
|
|
56077
57130
|
return args;
|
|
56078
57131
|
}
|
|
56079
57132
|
function buildClaudeEnv(origin, caPath, httpRewrites, httpsRewrites, baseEnv) {
|
|
56080
|
-
const env = { ...baseEnv, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: caPath };
|
|
57133
|
+
const env = { ...baseEnv, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: caPath, BILLION_CONTEXT_PROXY: origin };
|
|
56081
57134
|
const r = httpRewrites.find((rw) => rw.key === "ANTHROPIC_BASE_URL");
|
|
56082
57135
|
if (r) env.ANTHROPIC_BASE_URL = wrapUpstream(origin, r.realUpstream);
|
|
56083
57136
|
const hr2 = httpsRewrites.find((rw) => rw.key === "ANTHROPIC_BASE_URL");
|
|
56084
57137
|
if (hr2) env.ANTHROPIC_BASE_URL = hr2.realUpstream;
|
|
56085
57138
|
return env;
|
|
56086
57139
|
}
|
|
57140
|
+
function launcherDirectUrl(env) {
|
|
57141
|
+
return env.BILI_LAUNCHER_DIRECT === "1";
|
|
57142
|
+
}
|
|
57143
|
+
function launcherInjectMcp(env, base) {
|
|
57144
|
+
return base !== "pi" && env.BILI_LAUNCHER_PLUGIN === "1";
|
|
57145
|
+
}
|
|
57146
|
+
function buildMcpConfig(origin) {
|
|
57147
|
+
const script = process.argv[1] ? path11.resolve(path11.dirname(process.argv[1]), "mcp.js") : "bili-mcp";
|
|
57148
|
+
return {
|
|
57149
|
+
mcpServers: {
|
|
57150
|
+
bili: {
|
|
57151
|
+
command: process.execPath,
|
|
57152
|
+
args: [script],
|
|
57153
|
+
env: { BILI_MCP_PROXY: origin }
|
|
57154
|
+
}
|
|
57155
|
+
}
|
|
57156
|
+
};
|
|
57157
|
+
}
|
|
57158
|
+
function buildClaudePluginEnv(origin, directUrl, baseEnv) {
|
|
57159
|
+
if (!directUrl) return baseEnv;
|
|
57160
|
+
const upstream = baseEnv.BILI_CLAUDE_UPSTREAM?.trim() || "https://api.anthropic.com";
|
|
57161
|
+
return { ...baseEnv, ANTHROPIC_BASE_URL: wrapUpstream(origin, upstream) };
|
|
57162
|
+
}
|
|
57163
|
+
function buildCodexMcpArgs(origin, conversationId2) {
|
|
57164
|
+
const script = process.argv[1] ? path11.resolve(path11.dirname(process.argv[1]), "mcp.js") : "bili-mcp";
|
|
57165
|
+
return [
|
|
57166
|
+
"-c",
|
|
57167
|
+
`mcp_servers.bili.command=${JSON.stringify(process.execPath)}`,
|
|
57168
|
+
"-c",
|
|
57169
|
+
`mcp_servers.bili.args=${JSON.stringify([script])}`,
|
|
57170
|
+
"-c",
|
|
57171
|
+
`mcp_servers.bili.env.BILI_MCP_PROXY=${JSON.stringify(origin)}`,
|
|
57172
|
+
"-c",
|
|
57173
|
+
`mcp_servers.bili.env.BILI_CONVERSATION_ID=${JSON.stringify(conversationId2)}`
|
|
57174
|
+
];
|
|
57175
|
+
}
|
|
56087
57176
|
function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
56088
57177
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
|
|
56089
|
-
const modelsPath =
|
|
57178
|
+
const modelsPath = path11.join(piHome, "models.json");
|
|
56090
57179
|
let txt;
|
|
56091
57180
|
try {
|
|
56092
|
-
txt =
|
|
57181
|
+
txt = fs9.readFileSync(modelsPath, "utf8");
|
|
56093
57182
|
} catch {
|
|
56094
57183
|
return void 0;
|
|
56095
57184
|
}
|
|
@@ -56120,18 +57209,18 @@ function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
|
56120
57209
|
}
|
|
56121
57210
|
}
|
|
56122
57211
|
}
|
|
56123
|
-
const tmp =
|
|
57212
|
+
const tmp = fs9.mkdtempSync(path11.join(os4.tmpdir(), "bili-pi-"));
|
|
56124
57213
|
try {
|
|
56125
|
-
for (const entry of
|
|
57214
|
+
for (const entry of fs9.readdirSync(piHome)) {
|
|
56126
57215
|
if (entry === "models.json") continue;
|
|
56127
57216
|
try {
|
|
56128
|
-
|
|
57217
|
+
fs9.symlinkSync(path11.join(piHome, entry), path11.join(tmp, entry));
|
|
56129
57218
|
} catch {
|
|
56130
57219
|
}
|
|
56131
57220
|
}
|
|
56132
57221
|
} catch {
|
|
56133
57222
|
}
|
|
56134
|
-
|
|
57223
|
+
fs9.writeFileSync(path11.join(tmp, "models.json"), JSON.stringify(root));
|
|
56135
57224
|
return tmp;
|
|
56136
57225
|
}
|
|
56137
57226
|
function dedupeInOrder(list) {
|
|
@@ -56212,8 +57301,8 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
56212
57301
|
const spawnedOrigin = proxyOrigin(opts.host, port);
|
|
56213
57302
|
const script = process.argv[1];
|
|
56214
57303
|
if (!script) throw new Error("bili: cannot resolve launcher script path");
|
|
56215
|
-
const logPath2 =
|
|
56216
|
-
const logFd =
|
|
57304
|
+
const logPath2 = path11.join(os4.tmpdir(), `bili-proxy-${port}.log`);
|
|
57305
|
+
const logFd = fs9.openSync(logPath2, "a");
|
|
56217
57306
|
let child;
|
|
56218
57307
|
try {
|
|
56219
57308
|
child = spawnImpl(
|
|
@@ -56230,7 +57319,7 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
56230
57319
|
);
|
|
56231
57320
|
} finally {
|
|
56232
57321
|
try {
|
|
56233
|
-
|
|
57322
|
+
fs9.closeSync(logFd);
|
|
56234
57323
|
} catch {
|
|
56235
57324
|
}
|
|
56236
57325
|
}
|
|
@@ -56277,12 +57366,12 @@ var PATH_EXTS = process.platform === "win32" ? [".cmd", ".bat", ".exe", ""] : ["
|
|
|
56277
57366
|
function resolveOnPath(name, env) {
|
|
56278
57367
|
const p2 = env.PATH;
|
|
56279
57368
|
if (!p2) return void 0;
|
|
56280
|
-
for (const dir of p2.split(
|
|
57369
|
+
for (const dir of p2.split(path11.delimiter)) {
|
|
56281
57370
|
if (!dir) continue;
|
|
56282
57371
|
for (const ext of PATH_EXTS) {
|
|
56283
|
-
const f2 =
|
|
57372
|
+
const f2 = path11.join(dir, name + ext);
|
|
56284
57373
|
try {
|
|
56285
|
-
if (
|
|
57374
|
+
if (fs9.existsSync(f2) && fs9.statSync(f2).isFile()) return f2;
|
|
56286
57375
|
} catch {
|
|
56287
57376
|
}
|
|
56288
57377
|
}
|
|
@@ -56295,7 +57384,7 @@ function resolveClientCommand(client, env) {
|
|
|
56295
57384
|
if (piBin) return { command: piBin, prefixArgs: [] };
|
|
56296
57385
|
const piResolved = resolveOnPath("pi", env);
|
|
56297
57386
|
if (piResolved) return { command: piResolved, prefixArgs: [] };
|
|
56298
|
-
const cli =
|
|
57387
|
+
const cli = path11.join(
|
|
56299
57388
|
os4.homedir(),
|
|
56300
57389
|
".pi/agent/npm/node_modules/@earendil-works/pi-coding-agent/dist/cli.js"
|
|
56301
57390
|
);
|
|
@@ -56332,15 +57421,47 @@ async function runLaunch(params, deps = {}) {
|
|
|
56332
57421
|
let env;
|
|
56333
57422
|
let clientArgs = params.clientArgs;
|
|
56334
57423
|
let piTmpHome;
|
|
57424
|
+
const tmpFiles = [];
|
|
57425
|
+
const directUrl = launcherDirectUrl(process.env);
|
|
57426
|
+
if (directUrl) {
|
|
57427
|
+
if (base === "codex") {
|
|
57428
|
+
console.error(
|
|
57429
|
+
"bili: direct-URL mode \u2014 codex's LLM traffic does NOT go through the proxy, so compression is not applied (only the bili MCP tool calls do). For full compression use the default MITM mode (unset BILI_LAUNCHER_DIRECT)."
|
|
57430
|
+
);
|
|
57431
|
+
} else if (base === "claude") {
|
|
57432
|
+
console.error(
|
|
57433
|
+
"bili: direct-URL mode \u2014 claude's ANTHROPIC_BASE_URL is overridden to the proxy; a pre-configured relay is bypassed unless BILI_CLAUDE_UPSTREAM=<relay> is set. OAuth-subscription traffic requires the default MITM mode."
|
|
57434
|
+
);
|
|
57435
|
+
}
|
|
57436
|
+
}
|
|
57437
|
+
const injectMcp = launcherInjectMcp(process.env, base);
|
|
57438
|
+
if (!injectMcp && (base === "claude" || base === "codex")) {
|
|
57439
|
+
console.error("bili: plugin mode off \u2014 set BILI_LAUNCHER_PLUGIN=1 to enable native MCP tools (experimental; verified with claude 2.1.227 / codex 0.147.0).");
|
|
57440
|
+
}
|
|
57441
|
+
const origin = handle2.origin;
|
|
56335
57442
|
if (base === "pi") {
|
|
56336
|
-
env = buildPiEnv(
|
|
56337
|
-
piTmpHome = preparePiHttpRewrite(resolvePiHome(process.env),
|
|
57443
|
+
env = buildPiEnv(origin, ca, process.env);
|
|
57444
|
+
piTmpHome = preparePiHttpRewrite(resolvePiHome(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
|
|
56338
57445
|
if (piTmpHome) env.PI_CODING_AGENT_DIR = piTmpHome;
|
|
56339
57446
|
} else if (base === "codex") {
|
|
56340
|
-
|
|
56341
|
-
|
|
57447
|
+
const codexConversationId = injectMcp ? randomUUID2() : void 0;
|
|
57448
|
+
if (directUrl) {
|
|
57449
|
+
env = { ...process.env, BILLION_CONTEXT_PROXY: origin };
|
|
57450
|
+
if (codexConversationId) clientArgs = [...buildCodexMcpArgs(origin, codexConversationId), ...clientArgs];
|
|
57451
|
+
} else {
|
|
57452
|
+
env = buildCodexEnv(origin, resolveCombinedCaPath(process.env), process.env);
|
|
57453
|
+
clientArgs = buildCodexArgs(origin, routes.httpRewrites, routes.httpsRewrites, clientArgs);
|
|
57454
|
+
if (injectMcp && codexConversationId) clientArgs = [...buildCodexMcpArgs(origin, codexConversationId), ...clientArgs];
|
|
57455
|
+
}
|
|
56342
57456
|
} else {
|
|
56343
|
-
env = buildClaudeEnv(
|
|
57457
|
+
env = directUrl ? buildClaudePluginEnv(origin, true, process.env) : buildClaudeEnv(origin, ca, routes.httpRewrites, routes.httpsRewrites, process.env);
|
|
57458
|
+
if (directUrl) env.BILLION_CONTEXT_PROXY = origin;
|
|
57459
|
+
if (injectMcp) {
|
|
57460
|
+
const mcpFile = path11.join(os4.tmpdir(), `bili-mcp-${Date.now()}.json`);
|
|
57461
|
+
fs9.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
|
|
57462
|
+
tmpFiles.push(mcpFile);
|
|
57463
|
+
clientArgs = ["--mcp-config", mcpFile, ...clientArgs];
|
|
57464
|
+
}
|
|
56344
57465
|
}
|
|
56345
57466
|
const { command, prefixArgs } = resolveClientCommand(base, process.env);
|
|
56346
57467
|
const effectiveClientArgs = piTestArgs(params.client, clientArgs);
|
|
@@ -56356,7 +57477,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
56356
57477
|
if (!handle2.reused) stopProxy(handle2);
|
|
56357
57478
|
if (piTmpHome) {
|
|
56358
57479
|
try {
|
|
56359
|
-
|
|
57480
|
+
fs9.rmSync(piTmpHome, { recursive: true, force: true });
|
|
57481
|
+
} catch {
|
|
57482
|
+
}
|
|
57483
|
+
}
|
|
57484
|
+
for (const f2 of tmpFiles) {
|
|
57485
|
+
try {
|
|
57486
|
+
fs9.rmSync(f2, { force: true });
|
|
56360
57487
|
} catch {
|
|
56361
57488
|
}
|
|
56362
57489
|
}
|
|
@@ -56382,8 +57509,8 @@ async function runTestPi(params, deps = {}) {
|
|
|
56382
57509
|
}
|
|
56383
57510
|
const ca = resolveCaCertPath(process.env);
|
|
56384
57511
|
const env = buildPiEnv(handle2.origin, ca, process.env);
|
|
56385
|
-
const sessionDir =
|
|
56386
|
-
|
|
57512
|
+
const sessionDir = path11.join(os4.tmpdir(), `bili-pi-test-${Date.now()}`);
|
|
57513
|
+
fs9.mkdirSync(sessionDir, { recursive: true });
|
|
56387
57514
|
const args = [
|
|
56388
57515
|
"-p",
|
|
56389
57516
|
"--no-session",
|
|
@@ -56409,14 +57536,155 @@ async function runTestPi(params, deps = {}) {
|
|
|
56409
57536
|
process.exit(code ?? 0);
|
|
56410
57537
|
}
|
|
56411
57538
|
|
|
57539
|
+
// src/export.ts
|
|
57540
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
57541
|
+
import path12 from "path";
|
|
57542
|
+
function fmtDate(ms2) {
|
|
57543
|
+
return ms2 ? new Date(ms2).toISOString().replace("T", " ").slice(0, 19) + " UTC" : "\u2014";
|
|
57544
|
+
}
|
|
57545
|
+
async function listSessions2(opts = {}) {
|
|
57546
|
+
const store = new SessionStore({ dir: opts.dir, enabled: true });
|
|
57547
|
+
const sessions2 = [...(await store.loadAll()).values()];
|
|
57548
|
+
sessions2.sort((a, b2) => latestBlockTime(b2) - latestBlockTime(a));
|
|
57549
|
+
return sessions2.map((s3) => ({
|
|
57550
|
+
id: s3.id,
|
|
57551
|
+
title: s3.meta.title,
|
|
57552
|
+
label: s3.meta.label,
|
|
57553
|
+
protocol: s3.meta.protocol,
|
|
57554
|
+
upstreamOrigin: s3.meta.upstreamOrigin,
|
|
57555
|
+
savedAt: latestBlockTime(s3) || void 0,
|
|
57556
|
+
contextTokens: s3.stats.contextTokens,
|
|
57557
|
+
blocks: s3.state.blocks.length
|
|
57558
|
+
}));
|
|
57559
|
+
}
|
|
57560
|
+
function latestBlockTime(s3) {
|
|
57561
|
+
let latest = 0;
|
|
57562
|
+
for (const b2 of s3.state.blocks) if (b2.createdAt > latest) latest = b2.createdAt;
|
|
57563
|
+
return latest;
|
|
57564
|
+
}
|
|
57565
|
+
function renderHandoff(s3, full) {
|
|
57566
|
+
const lines = [];
|
|
57567
|
+
lines.push(`# billion-context session handoff`);
|
|
57568
|
+
lines.push("");
|
|
57569
|
+
lines.push(`- title: ${s3.meta.title ?? "(untitled)"}`);
|
|
57570
|
+
if (s3.meta.label) lines.push(`- label: ${s3.meta.label}`);
|
|
57571
|
+
lines.push(`- session id: ${s3.id}`);
|
|
57572
|
+
if (s3.meta.protocol) lines.push(`- protocol: ${s3.meta.protocol}`);
|
|
57573
|
+
if (s3.meta.upstreamOrigin) lines.push(`- upstream: ${s3.meta.upstreamOrigin}`);
|
|
57574
|
+
lines.push(`- requests: ${s3.stats.requests}`);
|
|
57575
|
+
if (s3.stats.contextTokens) lines.push(`- last context tokens: ~${s3.stats.contextTokens}`);
|
|
57576
|
+
lines.push(`- compression blocks: ${s3.state.blocks.length} (active ${s3.state.blocks.filter((b2) => b2.active).length})`);
|
|
57577
|
+
lines.push("");
|
|
57578
|
+
const messages = s3.lastMessages;
|
|
57579
|
+
if (messages && messages.length > 0) {
|
|
57580
|
+
lines.push(full ? `## Full conversation (${messages.length} messages)` : `## Conversation (folded view as the model saw it, ${messages.length} client messages)`);
|
|
57581
|
+
lines.push("");
|
|
57582
|
+
let lastRole = "";
|
|
57583
|
+
const view = full ? messages : prune(messages, s3.state);
|
|
57584
|
+
for (const m2 of view) {
|
|
57585
|
+
if (m2.role !== lastRole) {
|
|
57586
|
+
lines.push(`### ${m2.role}`);
|
|
57587
|
+
lines.push("");
|
|
57588
|
+
lastRole = m2.role;
|
|
57589
|
+
}
|
|
57590
|
+
lines.push(renderMessage2(m2));
|
|
57591
|
+
}
|
|
57592
|
+
lines.push("");
|
|
57593
|
+
return lines.join("\n");
|
|
57594
|
+
}
|
|
57595
|
+
const active = s3.state.blocks.filter((b2) => b2.active);
|
|
57596
|
+
if (active.length === 0) {
|
|
57597
|
+
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.");
|
|
57598
|
+
lines.push("");
|
|
57599
|
+
}
|
|
57600
|
+
for (const b2 of active) {
|
|
57601
|
+
lines.push(`## Block ${b2.blockId}${b2.topic ? ` \u2014 ${b2.topic}` : ""}`);
|
|
57602
|
+
lines.push("");
|
|
57603
|
+
lines.push(`tier ${b2.tier} \xB7 ~${b2.compressedTokens} tokens compressed \xB7 ${fmtDate(b2.createdAt)}`);
|
|
57604
|
+
lines.push("");
|
|
57605
|
+
lines.push(b2.summary.trim());
|
|
57606
|
+
lines.push("");
|
|
57607
|
+
const content = s3.blockContents.get(b2.blockId);
|
|
57608
|
+
if (full && content) {
|
|
57609
|
+
lines.push(`### Original messages (${content.full.count})`);
|
|
57610
|
+
lines.push("");
|
|
57611
|
+
lines.push(content.full.text.trim());
|
|
57612
|
+
lines.push("");
|
|
57613
|
+
}
|
|
57614
|
+
}
|
|
57615
|
+
if (active.length > 0) {
|
|
57616
|
+
lines.push("---");
|
|
57617
|
+
lines.push("");
|
|
57618
|
+
lines.push("Paste the block summaries above into a new session to continue without the proxy.");
|
|
57619
|
+
lines.push("");
|
|
57620
|
+
}
|
|
57621
|
+
return lines.join("\n");
|
|
57622
|
+
}
|
|
57623
|
+
function renderMessage2(m2) {
|
|
57624
|
+
const parts = [];
|
|
57625
|
+
switch (m2.contentType) {
|
|
57626
|
+
case "text":
|
|
57627
|
+
parts.push(m2.text ?? "");
|
|
57628
|
+
break;
|
|
57629
|
+
case "tool-call":
|
|
57630
|
+
parts.push(`\`${m2.toolName ?? "?"}(${m2.toolCallId ?? ""})\` args: ${m2.text ?? ""}`);
|
|
57631
|
+
break;
|
|
57632
|
+
case "tool-result":
|
|
57633
|
+
parts.push(`\`${m2.toolName ?? "?"}(${m2.toolCallId ?? ""})\` \u2192 ${m2.text ?? ""}`);
|
|
57634
|
+
break;
|
|
57635
|
+
case "reasoning":
|
|
57636
|
+
parts.push(`_reasoning_: ${m2.text ?? ""}`);
|
|
57637
|
+
break;
|
|
57638
|
+
}
|
|
57639
|
+
const body = parts.join("\n").trim();
|
|
57640
|
+
return body === "" ? "_(empty)_" : body + "\n";
|
|
57641
|
+
}
|
|
57642
|
+
function matchSession(sessions2, selector) {
|
|
57643
|
+
const exact = sessions2.filter((s3) => s3.id === selector);
|
|
57644
|
+
if (exact.length > 0) return exact;
|
|
57645
|
+
const byLabel = sessions2.filter((s3) => s3.meta.label === selector);
|
|
57646
|
+
if (byLabel.length > 0) return byLabel;
|
|
57647
|
+
const byPrefix = sessions2.filter((s3) => s3.id.startsWith(selector) || (s3.meta.label ?? "").startsWith(selector));
|
|
57648
|
+
return byPrefix;
|
|
57649
|
+
}
|
|
57650
|
+
async function exportSession(selector, opts = {}) {
|
|
57651
|
+
const store = new SessionStore({ dir: opts.dir, enabled: true });
|
|
57652
|
+
const all = [...(await store.loadAll()).values()];
|
|
57653
|
+
if (all.length === 0) {
|
|
57654
|
+
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).";
|
|
57655
|
+
}
|
|
57656
|
+
if (!selector) {
|
|
57657
|
+
const list = await listSessions2(opts);
|
|
57658
|
+
const rows = list.map(
|
|
57659
|
+
(s3) => `${s3.id}${s3.label ? ` label=${s3.label}` : ""}${s3.protocol ? ` [${s3.protocol}]` : ""} blocks=${s3.blocks}${s3.contextTokens ? ` ctx~${s3.contextTokens}` : ""} ${s3.title ?? ""}`
|
|
57660
|
+
);
|
|
57661
|
+
return ["Persisted sessions:", "", ...rows.map((r) => ` ${r}`), "", "Usage: bili export <session-id|label> [--output handoff.md] [--full]"].join("\n");
|
|
57662
|
+
}
|
|
57663
|
+
const matches = matchSession(all, selector);
|
|
57664
|
+
if (matches.length === 0) {
|
|
57665
|
+
throw new Error(`no session matches "${selector}" (run "bili export" to list sessions)`);
|
|
57666
|
+
}
|
|
57667
|
+
if (matches.length > 1) {
|
|
57668
|
+
const ids = matches.map((s3) => s3.id).join(", ");
|
|
57669
|
+
throw new Error(`selector "${selector}" matches ${matches.length} sessions (${ids}); use the full session id`);
|
|
57670
|
+
}
|
|
57671
|
+
const markdown = renderHandoff(matches[0], opts.full ?? false);
|
|
57672
|
+
if (opts.output) {
|
|
57673
|
+
mkdirSync6(path12.dirname(path12.resolve(opts.output)), { recursive: true });
|
|
57674
|
+
writeFileSync5(opts.output, markdown, "utf8");
|
|
57675
|
+
return `written to ${opts.output}`;
|
|
57676
|
+
}
|
|
57677
|
+
return markdown;
|
|
57678
|
+
}
|
|
57679
|
+
|
|
56412
57680
|
// src/cli.ts
|
|
56413
57681
|
import { readFileSync as readFileSync5 } from "fs";
|
|
56414
|
-
import { fileURLToPath as
|
|
56415
|
-
import
|
|
56416
|
-
var
|
|
57682
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
57683
|
+
import path13 from "path";
|
|
57684
|
+
var VERSION3 = (() => {
|
|
56417
57685
|
try {
|
|
56418
|
-
const here =
|
|
56419
|
-
const pkg =
|
|
57686
|
+
const here = fileURLToPath5(import.meta.url);
|
|
57687
|
+
const pkg = path13.join(path13.dirname(here), "..", "package.json");
|
|
56420
57688
|
return JSON.parse(readFileSync5(pkg, "utf8")).version ?? "dev";
|
|
56421
57689
|
} catch {
|
|
56422
57690
|
return "dev";
|
|
@@ -56424,14 +57692,14 @@ var VERSION = (() => {
|
|
|
56424
57692
|
})();
|
|
56425
57693
|
var PACKAGE_NAME = (() => {
|
|
56426
57694
|
try {
|
|
56427
|
-
const here =
|
|
56428
|
-
const pkg =
|
|
57695
|
+
const here = fileURLToPath5(import.meta.url);
|
|
57696
|
+
const pkg = path13.join(path13.dirname(here), "..", "package.json");
|
|
56429
57697
|
return JSON.parse(readFileSync5(pkg, "utf8")).name ?? "billion-context";
|
|
56430
57698
|
} catch {
|
|
56431
57699
|
return "billion-context";
|
|
56432
57700
|
}
|
|
56433
57701
|
})();
|
|
56434
|
-
var HELP = `bili ${
|
|
57702
|
+
var HELP = `bili ${VERSION3} \u2014 billion-context proxy
|
|
56435
57703
|
|
|
56436
57704
|
Usage:
|
|
56437
57705
|
bili [start] [options] start the proxy (default: reads ${configFile()})
|
|
@@ -56440,6 +57708,8 @@ Usage:
|
|
|
56440
57708
|
bili codex [opts --] [args] start a proxy + launch codex against it (cert-MITM)
|
|
56441
57709
|
bili claude [opts --] [args] start a proxy + launch claude against it (cert-MITM)
|
|
56442
57710
|
bili test pi non-polluting pi smoke test through the proxy
|
|
57711
|
+
bili export [session] [--full] list sessions / export one as a Markdown handoff
|
|
57712
|
+
(--full includes original messages; --output FILE)
|
|
56443
57713
|
bili update check for & install a newer version now
|
|
56444
57714
|
bili --version print version
|
|
56445
57715
|
bili --help show this help
|
|
@@ -56482,6 +57752,9 @@ function parseArgs(argv) {
|
|
|
56482
57752
|
let client;
|
|
56483
57753
|
let clientArgs = [];
|
|
56484
57754
|
const mitmDomains = [];
|
|
57755
|
+
let exportSelector;
|
|
57756
|
+
let exportOutput;
|
|
57757
|
+
let exportFull = false;
|
|
56485
57758
|
for (let i = 0; i < argv.length; i++) {
|
|
56486
57759
|
const a = argv[i];
|
|
56487
57760
|
if (!client && positional.length === 0 && isLaunchClient(a)) {
|
|
@@ -56519,6 +57792,18 @@ function parseArgs(argv) {
|
|
|
56519
57792
|
mitmDomains.push(val);
|
|
56520
57793
|
break;
|
|
56521
57794
|
}
|
|
57795
|
+
case "--full":
|
|
57796
|
+
exportFull = true;
|
|
57797
|
+
break;
|
|
57798
|
+
case "--output": {
|
|
57799
|
+
const val = argv[++i];
|
|
57800
|
+
if (val === void 0) {
|
|
57801
|
+
console.error(`bili: ${a} requires a value`);
|
|
57802
|
+
process.exit(2);
|
|
57803
|
+
}
|
|
57804
|
+
exportOutput = val;
|
|
57805
|
+
break;
|
|
57806
|
+
}
|
|
56522
57807
|
case "--port":
|
|
56523
57808
|
case "--host":
|
|
56524
57809
|
case "--config": {
|
|
@@ -56554,6 +57839,14 @@ function parseArgs(argv) {
|
|
|
56554
57839
|
command = command === "help" || command === "version" ? command : "start";
|
|
56555
57840
|
} else if (cmd === "update") {
|
|
56556
57841
|
command = "update";
|
|
57842
|
+
} else if (cmd === "export") {
|
|
57843
|
+
command = "export";
|
|
57844
|
+
exportSelector = positional[1];
|
|
57845
|
+
} else if (cmd === "plugin-register") {
|
|
57846
|
+
command = "plugin-register";
|
|
57847
|
+
exportSelector = positional[1];
|
|
57848
|
+
} else if (cmd === "mcp") {
|
|
57849
|
+
command = "mcp";
|
|
56557
57850
|
} else if (cmd === "test") {
|
|
56558
57851
|
const target = positional[1];
|
|
56559
57852
|
if (target && isLaunchClient(target)) {
|
|
@@ -56568,20 +57861,55 @@ function parseArgs(argv) {
|
|
|
56568
57861
|
process.exit(2);
|
|
56569
57862
|
}
|
|
56570
57863
|
}
|
|
56571
|
-
return { command, client, clientArgs, mitmDomains, overrides };
|
|
57864
|
+
return { command, client, clientArgs, mitmDomains, overrides, exportSelector, exportOutput, exportFull };
|
|
56572
57865
|
}
|
|
56573
57866
|
async function main() {
|
|
56574
|
-
const { command, client, clientArgs, mitmDomains, overrides } = parseArgs(process.argv.slice(2));
|
|
57867
|
+
const { command, client, clientArgs, mitmDomains, overrides, exportSelector, exportOutput, exportFull } = parseArgs(process.argv.slice(2));
|
|
56575
57868
|
if (command === "help") {
|
|
56576
57869
|
process.stdout.write(HELP);
|
|
56577
57870
|
return;
|
|
56578
57871
|
}
|
|
56579
57872
|
if (command === "version") {
|
|
56580
|
-
process.stdout.write(
|
|
57873
|
+
process.stdout.write(VERSION3 + "\n");
|
|
57874
|
+
return;
|
|
57875
|
+
}
|
|
57876
|
+
if (command === "plugin-register") {
|
|
57877
|
+
const conversationId2 = exportSelector?.trim();
|
|
57878
|
+
if (!conversationId2) {
|
|
57879
|
+
console.error('bili plugin-register: conversation id is required (e.g. bili plugin-register "$CLAUDE_SESSION_ID" --origin http://127.0.0.1:8787)');
|
|
57880
|
+
process.exit(2);
|
|
57881
|
+
}
|
|
57882
|
+
const origin = (overrides.BILI_MCP_PROXY ?? process.env.BILI_MCP_PROXY ?? "http://127.0.0.1:8787").replace(/\/$/, "");
|
|
57883
|
+
try {
|
|
57884
|
+
const res = await fetch(`${origin}/__bili/plugin/register`, {
|
|
57885
|
+
method: "POST",
|
|
57886
|
+
headers: { "content-type": "application/json" },
|
|
57887
|
+
body: JSON.stringify({ conversationId: conversationId2, agent: "claude", identity: true })
|
|
57888
|
+
});
|
|
57889
|
+
const data = await res.json();
|
|
57890
|
+
if (!res.ok || !data.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
57891
|
+
} catch (error) {
|
|
57892
|
+
console.error(`bili plugin-register: ${error instanceof Error ? error.message : String(error)}`);
|
|
57893
|
+
process.exit(1);
|
|
57894
|
+
}
|
|
57895
|
+
return;
|
|
57896
|
+
}
|
|
57897
|
+
if (command === "mcp") {
|
|
57898
|
+
runMcpStdio();
|
|
57899
|
+
return;
|
|
57900
|
+
}
|
|
57901
|
+
if (command === "export") {
|
|
57902
|
+
try {
|
|
57903
|
+
const text = await exportSession(exportSelector, { output: exportOutput, full: exportFull });
|
|
57904
|
+
process.stdout.write(text + "\n");
|
|
57905
|
+
} catch (error) {
|
|
57906
|
+
console.error(`bili export: ${error instanceof Error ? error.message : String(error)}`);
|
|
57907
|
+
process.exit(1);
|
|
57908
|
+
}
|
|
56581
57909
|
return;
|
|
56582
57910
|
}
|
|
56583
57911
|
if (command === "update") {
|
|
56584
|
-
await checkForUpdate({ packageName: PACKAGE_NAME, currentVersion:
|
|
57912
|
+
await checkForUpdate({ packageName: PACKAGE_NAME, currentVersion: VERSION3, autoUpdate: true }, true);
|
|
56585
57913
|
return;
|
|
56586
57914
|
}
|
|
56587
57915
|
if (command === "test") {
|
|
@@ -56603,7 +57931,7 @@ async function main() {
|
|
|
56603
57931
|
const opts = loadOptions();
|
|
56604
57932
|
await startServer(opts);
|
|
56605
57933
|
if (opts.autoUpdate) {
|
|
56606
|
-
startAutoUpdate({ packageName: PACKAGE_NAME, currentVersion:
|
|
57934
|
+
startAutoUpdate({ packageName: PACKAGE_NAME, currentVersion: VERSION3, autoUpdate: true });
|
|
56607
57935
|
}
|
|
56608
57936
|
}
|
|
56609
57937
|
|