billion-context 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +81 -81
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38,65 +38,6 @@ function defaultLogFile() {
|
|
|
38
38
|
return path.join(stateDir(), "bili.log");
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// src/logger.ts
|
|
42
|
-
import { createWriteStream, mkdirSync, statSync, renameSync } from "fs";
|
|
43
|
-
import path2 from "path";
|
|
44
|
-
var MAX_BYTES = 10 * 1024 * 1024;
|
|
45
|
-
var stream;
|
|
46
|
-
var logPath;
|
|
47
|
-
var bytesWritten = 0;
|
|
48
|
-
function open(pathStr) {
|
|
49
|
-
mkdirSync(path2.dirname(pathStr), { recursive: true });
|
|
50
|
-
let existingSize = 0;
|
|
51
|
-
try {
|
|
52
|
-
existingSize = statSync(pathStr).size;
|
|
53
|
-
if (existingSize >= MAX_BYTES) {
|
|
54
|
-
rotate(pathStr);
|
|
55
|
-
existingSize = 0;
|
|
56
|
-
}
|
|
57
|
-
} catch {
|
|
58
|
-
}
|
|
59
|
-
const s = createWriteStream(pathStr, { flags: "a" });
|
|
60
|
-
bytesWritten = existingSize;
|
|
61
|
-
return s;
|
|
62
|
-
}
|
|
63
|
-
function rotate(pathStr) {
|
|
64
|
-
try {
|
|
65
|
-
renameSync(pathStr, pathStr + ".old");
|
|
66
|
-
} catch {
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function configureLogger(file) {
|
|
70
|
-
if (!file || file === "off") {
|
|
71
|
-
logPath = void 0;
|
|
72
|
-
stream = void 0;
|
|
73
|
-
return void 0;
|
|
74
|
-
}
|
|
75
|
-
logPath = file;
|
|
76
|
-
stream = open(file);
|
|
77
|
-
return file;
|
|
78
|
-
}
|
|
79
|
-
var log = (level, msg2) => {
|
|
80
|
-
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
81
|
-
const line = `${ts} [${level}] ${msg2}
|
|
82
|
-
`;
|
|
83
|
-
process.stderr.write(line);
|
|
84
|
-
if (stream && logPath) {
|
|
85
|
-
if (bytesWritten >= MAX_BYTES) {
|
|
86
|
-
stream.end();
|
|
87
|
-
rotate(logPath);
|
|
88
|
-
stream = open(logPath);
|
|
89
|
-
}
|
|
90
|
-
stream.write(line);
|
|
91
|
-
bytesWritten += Buffer.byteLength(line);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
function closeLogger() {
|
|
95
|
-
stream?.end();
|
|
96
|
-
stream = void 0;
|
|
97
|
-
bytesWritten = 0;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
41
|
// src/config.ts
|
|
101
42
|
function safeReadJson(path6) {
|
|
102
43
|
try {
|
|
@@ -104,7 +45,7 @@ function safeReadJson(path6) {
|
|
|
104
45
|
return JSON.parse(raw);
|
|
105
46
|
} catch (e) {
|
|
106
47
|
if (e.code !== "ENOENT") {
|
|
107
|
-
|
|
48
|
+
console.error(`[acp-config] failed to parse ${path6}: ${String(e)}`);
|
|
108
49
|
}
|
|
109
50
|
return void 0;
|
|
110
51
|
}
|
|
@@ -743,9 +684,9 @@ import { createInitialState as createInitialState2 } from "acp-kernel";
|
|
|
743
684
|
|
|
744
685
|
// src/persist.ts
|
|
745
686
|
import { promises as fs } from "fs";
|
|
746
|
-
import { existsSync, mkdirSync
|
|
687
|
+
import { existsSync, mkdirSync, readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
747
688
|
import { createHash as createHash2 } from "crypto";
|
|
748
|
-
import * as
|
|
689
|
+
import * as path2 from "path";
|
|
749
690
|
import { createInitialState } from "acp-kernel";
|
|
750
691
|
var PERSIST_VERSION = 1;
|
|
751
692
|
function mergeState(parsed) {
|
|
@@ -771,7 +712,7 @@ function hostLabel(upstreamOrigin) {
|
|
|
771
712
|
function relPathFor(id, protocol, upstreamOrigin) {
|
|
772
713
|
const proto = protocol ?? "_unknown";
|
|
773
714
|
const host = protocol ? hostLabel(upstreamOrigin) + "_" : "";
|
|
774
|
-
return
|
|
715
|
+
return path2.join(proto, `${host}${createHash2("sha256").update(id, "utf8").digest("hex").slice(0, 24)}.json`);
|
|
775
716
|
}
|
|
776
717
|
function legacyFileNameFor(id) {
|
|
777
718
|
return createHash2("sha256").update(id, "utf8").digest("hex").slice(0, 24) + ".json";
|
|
@@ -791,13 +732,13 @@ var SessionStore = class {
|
|
|
791
732
|
this.log = opts?.log ?? defaultLogger;
|
|
792
733
|
}
|
|
793
734
|
filePath(id, protocol, upstreamOrigin) {
|
|
794
|
-
return
|
|
735
|
+
return path2.join(this.dir, relPathFor(id, protocol, upstreamOrigin));
|
|
795
736
|
}
|
|
796
737
|
/** A unique temp path per write (per process). Two overlapping writes for
|
|
797
738
|
* the same session must not share a temp file, or one rename invalidates
|
|
798
739
|
* the other. */
|
|
799
740
|
tempPath(id) {
|
|
800
|
-
return
|
|
741
|
+
return path2.join(this.dir, `.tmp-${legacyFileNameFor(id)}-${process.pid}-${this.tmpSeq++}`);
|
|
801
742
|
}
|
|
802
743
|
/** Bulk-load every persisted session from disk into a map keyed by the
|
|
803
744
|
* REAL session id (read from the file body, not the filename). Called once
|
|
@@ -821,7 +762,7 @@ var SessionStore = class {
|
|
|
821
762
|
}
|
|
822
763
|
for (const e of entries) {
|
|
823
764
|
if (e.name.startsWith(".tmp-")) continue;
|
|
824
|
-
const full =
|
|
765
|
+
const full = path2.join(dir, e.name);
|
|
825
766
|
if (e.isDirectory()) {
|
|
826
767
|
await walk(full);
|
|
827
768
|
} else if (e.isFile() && e.name.endsWith(".json")) {
|
|
@@ -831,13 +772,13 @@ var SessionStore = class {
|
|
|
831
772
|
};
|
|
832
773
|
await walk(this.dir);
|
|
833
774
|
for (const full of files) {
|
|
834
|
-
const name =
|
|
775
|
+
const name = path2.basename(full);
|
|
835
776
|
try {
|
|
836
777
|
const parsed = JSON.parse(await fs.readFile(full, "utf8"));
|
|
837
778
|
if (!isValidRecord(parsed)) continue;
|
|
838
779
|
const proto = parsed.protocol;
|
|
839
780
|
const origin = parsed.upstreamOrigin;
|
|
840
|
-
const expectedNamespaced =
|
|
781
|
+
const expectedNamespaced = path2.basename(relPathFor(parsed.id, proto, origin));
|
|
841
782
|
const expectedLegacy = legacyFileNameFor(parsed.id);
|
|
842
783
|
if (name !== expectedNamespaced && name !== expectedLegacy) {
|
|
843
784
|
this.log("warn", `[persist] skipping ${full}: filename does not match body id (expected ${expectedNamespaced})`);
|
|
@@ -892,7 +833,7 @@ var SessionStore = class {
|
|
|
892
833
|
const record = buildRecord(session);
|
|
893
834
|
const file = this.filePath(session.id, session.protocol, session.upstreamOrigin);
|
|
894
835
|
try {
|
|
895
|
-
await fs.mkdir(
|
|
836
|
+
await fs.mkdir(path2.dirname(file), { recursive: true });
|
|
896
837
|
} catch (e) {
|
|
897
838
|
this.log("warn", `[persist] could not create session dir ${this.dir}: ${msg(e)}`);
|
|
898
839
|
}
|
|
@@ -926,14 +867,14 @@ var SessionStore = class {
|
|
|
926
867
|
const record = buildRecord(session);
|
|
927
868
|
const file = this.filePath(session.id, session.protocol, session.upstreamOrigin);
|
|
928
869
|
try {
|
|
929
|
-
|
|
870
|
+
mkdirSync(path2.dirname(file), { recursive: true });
|
|
930
871
|
} catch (e) {
|
|
931
872
|
this.log("warn", `[persist] could not create session dir ${this.dir}: ${msg(e)}`);
|
|
932
873
|
}
|
|
933
874
|
const tmp = this.tempPath(session.id);
|
|
934
875
|
try {
|
|
935
876
|
writeFileSync(tmp, JSON.stringify(record), "utf8");
|
|
936
|
-
|
|
877
|
+
renameSync(tmp, file);
|
|
937
878
|
return true;
|
|
938
879
|
} catch (e) {
|
|
939
880
|
this.log("error", `[persist] flushSync FAILED for ${session.id}: ${msg(e)} \u2014 session NOT evicted to prevent loss`);
|
|
@@ -1031,12 +972,12 @@ function persistEnabled() {
|
|
|
1031
972
|
return true;
|
|
1032
973
|
}
|
|
1033
974
|
function defaultLogger(level, m) {
|
|
1034
|
-
|
|
975
|
+
console.error(`[${level}] ${m}`);
|
|
1035
976
|
}
|
|
1036
977
|
var _store = null;
|
|
1037
978
|
function getStore() {
|
|
1038
979
|
if (!_store) {
|
|
1039
|
-
_store = new SessionStore({ enabled: persistEnabled()
|
|
980
|
+
_store = new SessionStore({ enabled: persistEnabled() });
|
|
1040
981
|
}
|
|
1041
982
|
return _store;
|
|
1042
983
|
}
|
|
@@ -1176,17 +1117,17 @@ var COMPRESS_TOOL = {
|
|
|
1176
1117
|
};
|
|
1177
1118
|
function parseCompressInput(input) {
|
|
1178
1119
|
if (!input || typeof input !== "object") {
|
|
1179
|
-
|
|
1120
|
+
console.error(`[acp-compress-input] rejected: not object (${typeof input})`);
|
|
1180
1121
|
return [];
|
|
1181
1122
|
}
|
|
1182
1123
|
const obj = input;
|
|
1183
1124
|
if (Array.isArray(obj.content)) {
|
|
1184
1125
|
const out = obj.content.map((r) => toRange(r)).filter((r) => r !== null);
|
|
1185
|
-
if (out.length === 0)
|
|
1126
|
+
if (out.length === 0) console.error(`[acp-compress-input] content array but 0 valid ranges. keys per item: ${obj.content.map((c) => Object.keys(c ?? {}).join(",")).join(" | ")}`);
|
|
1186
1127
|
return out;
|
|
1187
1128
|
}
|
|
1188
1129
|
const single = toRange(obj);
|
|
1189
|
-
if (!single)
|
|
1130
|
+
if (!single) console.error(`[acp-compress-input] no content array, single-parse failed. top keys: ${Object.keys(obj).join(",")}`);
|
|
1190
1131
|
return single ? [single] : [];
|
|
1191
1132
|
}
|
|
1192
1133
|
function toRange(r) {
|
|
@@ -1608,7 +1549,7 @@ import {
|
|
|
1608
1549
|
collectBlockContent as collectBlockContent2,
|
|
1609
1550
|
deactivateBlock
|
|
1610
1551
|
} from "acp-kernel";
|
|
1611
|
-
import { mkdirSync as
|
|
1552
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1612
1553
|
import { dirname as dirname2, join as join2 } from "path";
|
|
1613
1554
|
import { tmpdir } from "os";
|
|
1614
1555
|
function resolveDecompress(args, ctx) {
|
|
@@ -1641,7 +1582,7 @@ function resolveDecompress(args, ctx) {
|
|
|
1641
1582
|
const outPath = body.length > 1e4 ? join2(tmpdir(), `acp-decompress-${safeBlockId}-${Date.now()}.txt`) : null;
|
|
1642
1583
|
if (outPath) {
|
|
1643
1584
|
try {
|
|
1644
|
-
|
|
1585
|
+
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
1645
1586
|
writeFileSync2(outPath, body, "utf8");
|
|
1646
1587
|
return `${header}
|
|
1647
1588
|
Content (${body.length} chars) written to: ${outPath}
|
|
@@ -1656,6 +1597,65 @@ ${body.slice(0, 4e3)}...`;
|
|
|
1656
1597
|
${body}`;
|
|
1657
1598
|
}
|
|
1658
1599
|
|
|
1600
|
+
// src/logger.ts
|
|
1601
|
+
import { createWriteStream, mkdirSync as mkdirSync3, statSync, renameSync as renameSync2 } from "fs";
|
|
1602
|
+
import path3 from "path";
|
|
1603
|
+
var MAX_BYTES = 10 * 1024 * 1024;
|
|
1604
|
+
var stream;
|
|
1605
|
+
var logPath;
|
|
1606
|
+
var bytesWritten = 0;
|
|
1607
|
+
function open(pathStr) {
|
|
1608
|
+
mkdirSync3(path3.dirname(pathStr), { recursive: true });
|
|
1609
|
+
let existingSize = 0;
|
|
1610
|
+
try {
|
|
1611
|
+
existingSize = statSync(pathStr).size;
|
|
1612
|
+
if (existingSize >= MAX_BYTES) {
|
|
1613
|
+
rotate(pathStr);
|
|
1614
|
+
existingSize = 0;
|
|
1615
|
+
}
|
|
1616
|
+
} catch {
|
|
1617
|
+
}
|
|
1618
|
+
const s = createWriteStream(pathStr, { flags: "a" });
|
|
1619
|
+
bytesWritten = existingSize;
|
|
1620
|
+
return s;
|
|
1621
|
+
}
|
|
1622
|
+
function rotate(pathStr) {
|
|
1623
|
+
try {
|
|
1624
|
+
renameSync2(pathStr, pathStr + ".old");
|
|
1625
|
+
} catch {
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
function configureLogger(file) {
|
|
1629
|
+
if (!file || file === "off") {
|
|
1630
|
+
logPath = void 0;
|
|
1631
|
+
stream = void 0;
|
|
1632
|
+
return void 0;
|
|
1633
|
+
}
|
|
1634
|
+
logPath = file;
|
|
1635
|
+
stream = open(file);
|
|
1636
|
+
return file;
|
|
1637
|
+
}
|
|
1638
|
+
var log = (level, msg2) => {
|
|
1639
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
1640
|
+
const line = `${ts} [${level}] ${msg2}
|
|
1641
|
+
`;
|
|
1642
|
+
process.stderr.write(line);
|
|
1643
|
+
if (stream && logPath) {
|
|
1644
|
+
if (bytesWritten >= MAX_BYTES) {
|
|
1645
|
+
stream.end();
|
|
1646
|
+
rotate(logPath);
|
|
1647
|
+
stream = open(logPath);
|
|
1648
|
+
}
|
|
1649
|
+
stream.write(line);
|
|
1650
|
+
bytesWritten += Buffer.byteLength(line);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
function closeLogger() {
|
|
1654
|
+
stream?.end();
|
|
1655
|
+
stream = void 0;
|
|
1656
|
+
bytesWritten = 0;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
1659
|
// src/compress-loop.ts
|
|
1660
1660
|
function executeProxyTool(toolName, args, ctx) {
|
|
1661
1661
|
if (toolName === "compress") {
|
|
@@ -2350,7 +2350,7 @@ async function* compressLoopResponsesStream(initialUpstream, ctx, requestBody, r
|
|
|
2350
2350
|
const allCalls = [...fcByItemId.values()].filter((c) => c.name.length > 0);
|
|
2351
2351
|
const proxyCalls = allCalls.filter((c) => PROXY_TOOL_NAMES.has(c.name));
|
|
2352
2352
|
const realCalls = allCalls.filter((c) => !PROXY_TOOL_NAMES.has(c.name));
|
|
2353
|
-
|
|
2353
|
+
console.error(`[acp-diag] round ${loopCount} allCalls=[${allCalls.map((c) => c.name).join(",")}] realCalls=[${realCalls.map((c) => c.name).join(",")}] text=${JSON.stringify(contentText.slice(0, 120))}`);
|
|
2354
2354
|
const hasOnlyProxy = proxyCalls.length > 0 && realCalls.length === 0;
|
|
2355
2355
|
if (!hasOnlyProxy) {
|
|
2356
2356
|
let oi = nextOutputIndex;
|
|
@@ -2393,11 +2393,11 @@ async function* compressLoopResponsesStream(initialUpstream, ctx, requestBody, r
|
|
|
2393
2393
|
try {
|
|
2394
2394
|
args = JSON.parse(fc.arguments);
|
|
2395
2395
|
} catch (e) {
|
|
2396
|
-
|
|
2396
|
+
console.error(`[acp-compress-args] ${fc.name} JSON.parse failed: ${String(e)}. raw arguments (len=${fc.arguments.length}): ${fc.arguments.slice(0, 300)}`);
|
|
2397
2397
|
args = {};
|
|
2398
2398
|
}
|
|
2399
2399
|
if (fc.name === "compress") {
|
|
2400
|
-
|
|
2400
|
+
console.error(`[acp-compress-args] compress args parsed: ${JSON.stringify(args).slice(0, 400)}`);
|
|
2401
2401
|
}
|
|
2402
2402
|
const result = executeProxyTool2(fc.name, args, ctx);
|
|
2403
2403
|
const preview = result.length > 120 ? result.slice(0, 120) + "..." : result;
|