billion-context 0.1.71 → 0.1.72-pr.378.288
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 +175 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50241,6 +50241,9 @@ var RENDER_TAG_DETECT = /\x3c\/?acp(?=[\s>])|\\u003c\/?acp(?=[\s>\\])/;
|
|
|
50241
50241
|
function containsRenderTagText(s3) {
|
|
50242
50242
|
return RENDER_TAG_DETECT.test(s3);
|
|
50243
50243
|
}
|
|
50244
|
+
function mayStartRenderTag(s3) {
|
|
50245
|
+
return RENDER_TAG_DETECT.test(s3) || PARTIAL_TAIL.test(s3);
|
|
50246
|
+
}
|
|
50244
50247
|
var TOOL_CALL_XML = /\x3c\/?(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b[^<>]*\x3e|\\u003c\/?(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b|\x3c\/?antml:[a-z_]+/i;
|
|
50245
50248
|
function containsToolCallXmlFragment(s3) {
|
|
50246
50249
|
return TOOL_CALL_XML.test(s3);
|
|
@@ -53251,6 +53254,86 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
53251
53254
|
return current;
|
|
53252
53255
|
}
|
|
53253
53256
|
|
|
53257
|
+
// src/fake-completion.ts
|
|
53258
|
+
var FAKE_COMPLETION_HINT = "[billion-context] Your last reply described a tool call as plain text instead of invoking it, so no tool actually ran. To act, invoke the tool through the proper tool-calling mechanism (emit a tool_use / tool_calls / function_call block). Do not write tool-call markup as text in your reply.";
|
|
53259
|
+
function maxFakeCompletionRetries() {
|
|
53260
|
+
const n = Number.parseInt(process.env.BILI_FAKE_COMPLETION_RETRIES ?? "0", 10);
|
|
53261
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
53262
|
+
}
|
|
53263
|
+
function fakeBufCap() {
|
|
53264
|
+
const n = Number.parseInt(process.env.BILI_FAKE_BUF_CAP ?? String(16 * 1024 * 1024), 10);
|
|
53265
|
+
return Number.isFinite(n) && n > 0 ? n : 16 * 1024 * 1024;
|
|
53266
|
+
}
|
|
53267
|
+
var ANTHROPIC_TOOL_BLOCK = /"type"\s*:\s*"tool_use"/;
|
|
53268
|
+
var OPENAI_TOOL_BLOCK = /"tool_calls"\s*:\s*\[\s*\{/;
|
|
53269
|
+
var RESPONSES_TOOL_BLOCK = /"type"\s*:\s*"function_call"/;
|
|
53270
|
+
function hasToolBlock(protocol, rawText) {
|
|
53271
|
+
switch (protocol) {
|
|
53272
|
+
case "anthropic":
|
|
53273
|
+
return ANTHROPIC_TOOL_BLOCK.test(rawText);
|
|
53274
|
+
case "openai":
|
|
53275
|
+
return OPENAI_TOOL_BLOCK.test(rawText);
|
|
53276
|
+
case "responses":
|
|
53277
|
+
return RESPONSES_TOOL_BLOCK.test(rawText);
|
|
53278
|
+
}
|
|
53279
|
+
}
|
|
53280
|
+
var TOOL_OPEN = /\x3c(?!\s*\/)(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b|\\u003c(?!\s*\/)(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b/i;
|
|
53281
|
+
var TOOL_CLOSE_GLOBAL = /\x3c\/(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b|\\u003c\/(?:antml:)?(invoke|tool_calls|tool_call|parameter|parameters)\b/gi;
|
|
53282
|
+
function hasToolCallStructure(text) {
|
|
53283
|
+
if (!containsToolCallXmlFragment(text)) return false;
|
|
53284
|
+
if (TOOL_OPEN.test(text)) return true;
|
|
53285
|
+
const closes = /* @__PURE__ */ new Set();
|
|
53286
|
+
for (const m2 of text.matchAll(TOOL_CLOSE_GLOBAL)) {
|
|
53287
|
+
const name = m2[1] ?? m2[2];
|
|
53288
|
+
if (name) closes.add(name.toLowerCase());
|
|
53289
|
+
}
|
|
53290
|
+
return closes.size >= 2;
|
|
53291
|
+
}
|
|
53292
|
+
function isFakeCompletion(protocol, rawText) {
|
|
53293
|
+
return hasToolCallStructure(rawText) && !hasToolBlock(protocol, rawText);
|
|
53294
|
+
}
|
|
53295
|
+
function injectFakeCompletionHint(protocol, body) {
|
|
53296
|
+
const raw = typeof body === "string" ? body : body.toString("utf8");
|
|
53297
|
+
let obj;
|
|
53298
|
+
try {
|
|
53299
|
+
obj = JSON.parse(raw);
|
|
53300
|
+
} catch {
|
|
53301
|
+
return null;
|
|
53302
|
+
}
|
|
53303
|
+
if (protocol === "responses") {
|
|
53304
|
+
const input = obj.input;
|
|
53305
|
+
if (!Array.isArray(input)) return null;
|
|
53306
|
+
const arr2 = input;
|
|
53307
|
+
const last2 = arr2[arr2.length - 1];
|
|
53308
|
+
if (last2 && typeof last2 === "object" && last2.role === "user") {
|
|
53309
|
+
const c = last2.content;
|
|
53310
|
+
if (typeof c === "string") last2.content = `${c}
|
|
53311
|
+
|
|
53312
|
+
${FAKE_COMPLETION_HINT}`;
|
|
53313
|
+
else if (Array.isArray(c)) last2.content = [...c, { type: "input_text", text: FAKE_COMPLETION_HINT }];
|
|
53314
|
+
else last2.content = FAKE_COMPLETION_HINT;
|
|
53315
|
+
} else {
|
|
53316
|
+
arr2.push({ role: "user", content: [{ type: "input_text", text: FAKE_COMPLETION_HINT }] });
|
|
53317
|
+
}
|
|
53318
|
+
return JSON.stringify(obj);
|
|
53319
|
+
}
|
|
53320
|
+
const messages = obj.messages;
|
|
53321
|
+
if (!Array.isArray(messages)) return null;
|
|
53322
|
+
const arr = messages;
|
|
53323
|
+
const last = arr[arr.length - 1];
|
|
53324
|
+
if (last && typeof last === "object" && last.role === "user") {
|
|
53325
|
+
const c = last.content;
|
|
53326
|
+
if (typeof c === "string") last.content = `${c}
|
|
53327
|
+
|
|
53328
|
+
${FAKE_COMPLETION_HINT}`;
|
|
53329
|
+
else if (Array.isArray(c)) last.content = [...c, { type: "text", text: FAKE_COMPLETION_HINT }];
|
|
53330
|
+
else last.content = FAKE_COMPLETION_HINT;
|
|
53331
|
+
} else {
|
|
53332
|
+
arr.push({ role: "user", content: FAKE_COMPLETION_HINT });
|
|
53333
|
+
}
|
|
53334
|
+
return JSON.stringify(obj);
|
|
53335
|
+
}
|
|
53336
|
+
|
|
53254
53337
|
// src/stream-openai.ts
|
|
53255
53338
|
function rewriteOpenaiJsonResponse(body, ctx) {
|
|
53256
53339
|
if (!body || typeof body !== "object") return body;
|
|
@@ -54218,7 +54301,7 @@ function mergeUsageSample(acc, sample) {
|
|
|
54218
54301
|
if (sample.cachedTokens !== void 0) acc.cachedTokens = sample.cachedTokens;
|
|
54219
54302
|
if (sample.outputTokens !== void 0) acc.outputTokens = sample.outputTokens;
|
|
54220
54303
|
}
|
|
54221
|
-
async function pipePluginChatWithStrip(stream2, res,
|
|
54304
|
+
async function pipePluginChatWithStrip(stream2, res, protocol, session, log2) {
|
|
54222
54305
|
const reader = stream2.getReader();
|
|
54223
54306
|
const decoder = new TextDecoder("utf-8");
|
|
54224
54307
|
let buf = "";
|
|
@@ -54282,6 +54365,7 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54282
54365
|
}
|
|
54283
54366
|
let rebuilt = null;
|
|
54284
54367
|
let droppedText = false;
|
|
54368
|
+
let keptText = false;
|
|
54285
54369
|
let hadText = false;
|
|
54286
54370
|
for (let ci2 = 0; ci2 < choices.length; ci2++) {
|
|
54287
54371
|
const ch = choices[ci2];
|
|
@@ -54292,10 +54376,14 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54292
54376
|
const v2 = dd[field];
|
|
54293
54377
|
if (typeof v2 !== "string") continue;
|
|
54294
54378
|
hadText = true;
|
|
54295
|
-
if (!
|
|
54379
|
+
if (!mayStartRenderTag(v2) && !anyPending()) {
|
|
54380
|
+
if (v2.length > 0) keptText = true;
|
|
54381
|
+
continue;
|
|
54382
|
+
}
|
|
54296
54383
|
const index = typeof ch?.["index"] === "number" ? ch["index"] : ci2;
|
|
54297
54384
|
const [clean, changed] = pushField(field, index, v2);
|
|
54298
54385
|
if (clean.length === 0) droppedText = true;
|
|
54386
|
+
else keptText = true;
|
|
54299
54387
|
if (changed) {
|
|
54300
54388
|
if (!rebuilt) {
|
|
54301
54389
|
rebuilt = { ...ev, choices: choices.map((c) => ({ ...c, delta: { ...c["delta"] } })) };
|
|
@@ -54305,7 +54393,7 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54305
54393
|
}
|
|
54306
54394
|
}
|
|
54307
54395
|
if (rebuilt) {
|
|
54308
|
-
if (droppedText && !hadTextOtherThanTextFields(rebuilt["choices"])) {
|
|
54396
|
+
if (droppedText && !keptText && !hadTextOtherThanTextFields(rebuilt["choices"])) {
|
|
54309
54397
|
return "";
|
|
54310
54398
|
}
|
|
54311
54399
|
return rebuildEvent(rawEvent, rebuilt);
|
|
@@ -54324,7 +54412,7 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54324
54412
|
return rawEvent + "\n\n";
|
|
54325
54413
|
}
|
|
54326
54414
|
const raw = d[field];
|
|
54327
|
-
if (!
|
|
54415
|
+
if (!mayStartRenderTag(raw) && !anyPending()) {
|
|
54328
54416
|
return rawEvent + "\n\n";
|
|
54329
54417
|
}
|
|
54330
54418
|
const [clean, changed] = pushField(field, index, raw);
|
|
@@ -54367,7 +54455,7 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54367
54455
|
}
|
|
54368
54456
|
const rest = flushTails();
|
|
54369
54457
|
if (rest.length > 0 && !res.destroyed && !res.writableEnded) await write(rest);
|
|
54370
|
-
if (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0) {
|
|
54458
|
+
if (session && (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0)) {
|
|
54371
54459
|
applyUsageSample(session, acc, protocol);
|
|
54372
54460
|
markDirty(session);
|
|
54373
54461
|
}
|
|
@@ -54453,7 +54541,7 @@ async function pipePluginResponsesWithStrip(stream2, res, session, log2) {
|
|
|
54453
54541
|
await write(rawEvent + "\n\n");
|
|
54454
54542
|
continue;
|
|
54455
54543
|
}
|
|
54456
|
-
if (!
|
|
54544
|
+
if (!mayStartRenderTag(delta) && !tagFilter.pending()) {
|
|
54457
54545
|
await write(rawEvent + "\n\n");
|
|
54458
54546
|
continue;
|
|
54459
54547
|
}
|
|
@@ -54476,7 +54564,7 @@ async function pipePluginResponsesWithStrip(stream2, res, session, log2) {
|
|
|
54476
54564
|
const rest = flushTail("");
|
|
54477
54565
|
if (rest.length > 0) await write(rest);
|
|
54478
54566
|
}
|
|
54479
|
-
if (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0) {
|
|
54567
|
+
if (session && (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0)) {
|
|
54480
54568
|
applyUsageSample(session, acc, "responses");
|
|
54481
54569
|
markDirty(session);
|
|
54482
54570
|
}
|
|
@@ -57503,7 +57591,7 @@ ${hdrText}
|
|
|
57503
57591
|
if (prepared.protocol === "responses") {
|
|
57504
57592
|
await pipePluginResponsesWithStrip(upstream.body, res, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
|
|
57505
57593
|
} else {
|
|
57506
|
-
await pipePluginChatWithStrip(upstream.body, res, prepared.
|
|
57594
|
+
await pipePluginChatWithStrip(upstream.body, res, prepared.protocol, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
|
|
57507
57595
|
}
|
|
57508
57596
|
} else {
|
|
57509
57597
|
await pipePluginJson(upstream.body, res, prepared.session, prepared.protocol);
|
|
@@ -57511,10 +57599,24 @@ ${hdrText}
|
|
|
57511
57599
|
clearUpstreamTimer();
|
|
57512
57600
|
return;
|
|
57513
57601
|
}
|
|
57602
|
+
let responseBody = upstream.body;
|
|
57603
|
+
if (prepared !== null && prepared.stream && maxFakeCompletionRetries() > 0) {
|
|
57604
|
+
const resolvedBuf = await resolveFakeCompletion(upstream.body, {
|
|
57605
|
+
protocol: prepared.protocol,
|
|
57606
|
+
body,
|
|
57607
|
+
upstreamUrl,
|
|
57608
|
+
reqHeaders: buildForwardHeaders(headers),
|
|
57609
|
+
proxyUrl,
|
|
57610
|
+
signal: clientAbort.signal,
|
|
57611
|
+
session: prepared.session,
|
|
57612
|
+
log: log2
|
|
57613
|
+
});
|
|
57614
|
+
responseBody = bufferToStream(resolvedBuf);
|
|
57615
|
+
}
|
|
57514
57616
|
const useRewriter = prepared !== null && prepared.compressInjected && prepared.processedMessages.length > 0;
|
|
57515
57617
|
if (!useRewriter || prepared === null) {
|
|
57516
57618
|
if (prepared && prepared.resetAfterSuccess) {
|
|
57517
|
-
const [toClient, toObserve] =
|
|
57619
|
+
const [toClient, toObserve] = responseBody.tee();
|
|
57518
57620
|
const observed = observeResponsesTerminalState(toObserve, prepared.stream);
|
|
57519
57621
|
await pipeThrough(toClient, res);
|
|
57520
57622
|
clearUpstreamTimer();
|
|
@@ -57525,8 +57627,17 @@ ${hdrText}
|
|
|
57525
57627
|
} else {
|
|
57526
57628
|
log2("warn", `[${prepared.session.id}] native compact response terminal=${terminal}; rebase NOT scheduled`);
|
|
57527
57629
|
}
|
|
57630
|
+
} else if (prepared && prepared.stream && (upstream.headers.get("content-type") ?? "").includes("text/event-stream")) {
|
|
57631
|
+
const p2 = prepared;
|
|
57632
|
+
const tagLog = (msg) => log2("info", `[${p2.session.id}] ${msg}`);
|
|
57633
|
+
if (p2.protocol === "responses") {
|
|
57634
|
+
await pipePluginResponsesWithStrip(responseBody, res, void 0, tagLog);
|
|
57635
|
+
} else {
|
|
57636
|
+
await pipePluginChatWithStrip(responseBody, res, p2.protocol, void 0, tagLog);
|
|
57637
|
+
}
|
|
57638
|
+
clearUpstreamTimer();
|
|
57528
57639
|
} else {
|
|
57529
|
-
await pipeThrough(
|
|
57640
|
+
await pipeThrough(responseBody, res);
|
|
57530
57641
|
clearUpstreamTimer();
|
|
57531
57642
|
}
|
|
57532
57643
|
return;
|
|
@@ -57540,10 +57651,10 @@ ${hdrText}
|
|
|
57540
57651
|
debug: opts.debug
|
|
57541
57652
|
};
|
|
57542
57653
|
if (prepared.stream) {
|
|
57543
|
-
let streamToRead =
|
|
57654
|
+
let streamToRead = responseBody;
|
|
57544
57655
|
let dumpRaw;
|
|
57545
57656
|
if (opts.dumpSse) {
|
|
57546
|
-
const [a, b2] =
|
|
57657
|
+
const [a, b2] = responseBody.tee();
|
|
57547
57658
|
streamToRead = a;
|
|
57548
57659
|
dumpRaw = dumpStreamToFile(b2, opts.dumpSse, `${Date.now()}-${safeSessionId(prepared.session.id)}-raw.sse`);
|
|
57549
57660
|
}
|
|
@@ -57669,6 +57780,58 @@ async function readStreamToBuffer(stream2, maxBytes = 1 << 20) {
|
|
|
57669
57780
|
}
|
|
57670
57781
|
return Buffer.concat(chunks);
|
|
57671
57782
|
}
|
|
57783
|
+
function bufferToStream(buf) {
|
|
57784
|
+
return new ReadableStream({
|
|
57785
|
+
start(controller) {
|
|
57786
|
+
controller.enqueue(new Uint8Array(buf));
|
|
57787
|
+
controller.close();
|
|
57788
|
+
}
|
|
57789
|
+
});
|
|
57790
|
+
}
|
|
57791
|
+
async function resolveFakeCompletion(stream2, opts) {
|
|
57792
|
+
let buffer = await readStreamToBuffer(stream2, fakeBufCap());
|
|
57793
|
+
const max = maxFakeCompletionRetries();
|
|
57794
|
+
const sid = opts.session.id;
|
|
57795
|
+
const priorStreak = opts.session.metadata.fakeCompletionStreak ?? 0;
|
|
57796
|
+
if (max > 0 && priorStreak < max && isFakeCompletion(opts.protocol, buffer.toString("utf8"))) {
|
|
57797
|
+
for (let attempt = 1; attempt <= max && !opts.signal.aborted; attempt++) {
|
|
57798
|
+
const hinted = injectFakeCompletionHint(opts.protocol, opts.body);
|
|
57799
|
+
if (hinted === null) break;
|
|
57800
|
+
opts.log("warn", `[${sid}] fake completion (tool-call XML, no tool block); retry ${attempt}/${max} with corrective hint`);
|
|
57801
|
+
let r;
|
|
57802
|
+
try {
|
|
57803
|
+
r = await fetchWithTimeout(
|
|
57804
|
+
opts.upstreamUrl,
|
|
57805
|
+
{
|
|
57806
|
+
method: "POST",
|
|
57807
|
+
headers: opts.reqHeaders,
|
|
57808
|
+
body: hinted,
|
|
57809
|
+
...opts.proxyUrl ? { dispatcher: proxyDispatcher(opts.proxyUrl) } : {}
|
|
57810
|
+
},
|
|
57811
|
+
void 0,
|
|
57812
|
+
opts.signal
|
|
57813
|
+
);
|
|
57814
|
+
} catch (e) {
|
|
57815
|
+
opts.log("warn", `[${sid}] fake-completion retry failed: ${String(e)}; presenting original`);
|
|
57816
|
+
break;
|
|
57817
|
+
}
|
|
57818
|
+
try {
|
|
57819
|
+
if (!r.response.ok || !r.response.body) {
|
|
57820
|
+
opts.log("warn", `[${sid}] fake-completion retry rejected (HTTP ${r.response.status}); presenting original`);
|
|
57821
|
+
break;
|
|
57822
|
+
}
|
|
57823
|
+
buffer = await readStreamToBuffer(r.response.body, fakeBufCap());
|
|
57824
|
+
} finally {
|
|
57825
|
+
r.clearTimer();
|
|
57826
|
+
}
|
|
57827
|
+
if (!isFakeCompletion(opts.protocol, buffer.toString("utf8"))) break;
|
|
57828
|
+
}
|
|
57829
|
+
}
|
|
57830
|
+
const stillFake = isFakeCompletion(opts.protocol, buffer.toString("utf8"));
|
|
57831
|
+
opts.session.metadata.fakeCompletionStreak = stillFake ? priorStreak + 1 : 0;
|
|
57832
|
+
markDirty(opts.session);
|
|
57833
|
+
return buffer;
|
|
57834
|
+
}
|
|
57672
57835
|
async function pipeThrough(stream2, res) {
|
|
57673
57836
|
const reader = stream2.getReader();
|
|
57674
57837
|
try {
|