billion-context 0.1.101 → 0.1.102-pr.641.518
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 +2 -1
- package/dist/index.js +345 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -158,7 +158,7 @@ rewrite until dsh gains a settings-path env or an upstream loopback opt-out.
|
|
|
158
158
|
Overlay dirs created by older versions are left in place and never merged back
|
|
159
159
|
into the real home.
|
|
160
160
|
|
|
161
|
-
### Option 1 — Launcher (`bili pi` / `bili codex` / `bili claude` / `bili omp` / `bili opencode` / `bili hermes` / `bili dsh`)
|
|
161
|
+
### Option 1 — Launcher (`bili pi` / `bili codex` / `bili claude` / `bili omp` / `bili opencode` / `bili hermes` / `bili dsh` / `bili codebuddy`)
|
|
162
162
|
|
|
163
163
|
The launcher wraps a client in one command: it starts a proxy on an
|
|
164
164
|
independent port (a fresh instance is always spawned — a port is never
|
|
@@ -177,6 +177,7 @@ bili omp # pi-style, file-free (#535): env + extens
|
|
|
177
177
|
bili opencode # MITM for HTTPS + temp opencode.json (/bili/ for HTTP) + thin /acp plugin
|
|
178
178
|
bili hermes # file-free (#535): hermes proxy env (HTTPS_PROXY + HERMES_CA_BUNDLE) — https via CONNECT MITM, http via absolute-form forward proxy; real ~/.hermes untouched
|
|
179
179
|
bili dsh # deepseek-harness: non-loopback upstreams ride proxy envs (https MITM, http absolute-form), loopback keeps the overlay DSH_HOME (~/.dsh-bili) rewrite (#535), built-in deepseek route via DEEPSEEK_BASE_URL, native /acp command injected via --patch
|
|
180
|
+
bili codebuddy # Tencent CodeBuddy Code CLI: CODEBUDDY_BASE_URL /bili/ rewrite (OpenAI chat completions wire), budget aligned via CODEBUDDY_AUTO_COMPACT_WINDOW; real ~/.codebuddy untouched
|
|
180
181
|
bili pi --mitm-domain api.foo.com # add a domain to the MITM whitelist
|
|
181
182
|
```
|
|
182
183
|
|
package/dist/index.js
CHANGED
|
@@ -43467,7 +43467,7 @@ var require_lib = __commonJS({
|
|
|
43467
43467
|
}
|
|
43468
43468
|
});
|
|
43469
43469
|
|
|
43470
|
-
// node_modules/acp-kernel/dist/chunk-
|
|
43470
|
+
// node_modules/acp-kernel/dist/chunk-6TAK7DSI.js
|
|
43471
43471
|
import { createRequire } from "module";
|
|
43472
43472
|
var require2 = createRequire(import.meta.url);
|
|
43473
43473
|
function defaultCountTokens(text) {
|
|
@@ -43476,6 +43476,12 @@ function defaultCountTokens(text) {
|
|
|
43476
43476
|
const cjkCount = cjk?.length ?? 0;
|
|
43477
43477
|
return cjkCount + Math.ceil((text.length - cjkCount) / 4);
|
|
43478
43478
|
}
|
|
43479
|
+
function thinkingTokenValue(thinking) {
|
|
43480
|
+
return typeof thinking === "number" && Number.isFinite(thinking) && thinking > 0 ? thinking : 0;
|
|
43481
|
+
}
|
|
43482
|
+
function countMessageTokens(message, countTokens = defaultCountTokens) {
|
|
43483
|
+
return countTokens(message.text ?? "") + thinkingTokenValue(message.thinkingTokens);
|
|
43484
|
+
}
|
|
43479
43485
|
function estimateTokensFast(text) {
|
|
43480
43486
|
if (!text) return 0;
|
|
43481
43487
|
return Math.ceil(text.length / 4);
|
|
@@ -45283,7 +45289,8 @@ function renderMessage(message, map, countTokens, strategy, snapshot = null) {
|
|
|
45283
45289
|
"^" + escapeRegex(TAG_OPEN) + "[^>]*" + GT + escapeRegex(ref) + escapeRegex(TAG_CLOSE) + "\\n?"
|
|
45284
45290
|
);
|
|
45285
45291
|
const cleanText = (message.text || "").replace(ownTagRe, "");
|
|
45286
|
-
const
|
|
45292
|
+
const textTokens = snapshot ? snapshot[ref] ?? (snapshot[ref] = countTokens(cleanText)) : countTokens(cleanText);
|
|
45293
|
+
const tokens = textTokens + thinkingTokenValue(message.thinkingTokens);
|
|
45287
45294
|
const type = classifyType(message);
|
|
45288
45295
|
const prefix = acpTag(ref, tokens, type) + "\n";
|
|
45289
45296
|
if (!cleanText) return { ...message, text: prefix };
|
|
@@ -45362,8 +45369,12 @@ function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
|
|
|
45362
45369
|
j2++;
|
|
45363
45370
|
}
|
|
45364
45371
|
const companion = messages[j2 + 1];
|
|
45365
|
-
if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call")
|
|
45366
|
-
|
|
45372
|
+
if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call")) {
|
|
45373
|
+
let e = j2 + 1;
|
|
45374
|
+
while (e + 1 < messages.length && messages[e + 1].role === "assistant" && (messages[e + 1].contentType === "text" || messages[e + 1].contentType === "tool-call")) {
|
|
45375
|
+
e++;
|
|
45376
|
+
}
|
|
45377
|
+
if (e > newEndIndex) newEndIndex = e;
|
|
45367
45378
|
}
|
|
45368
45379
|
}
|
|
45369
45380
|
if (msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call")) {
|
|
@@ -45379,6 +45390,64 @@ function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
|
|
|
45379
45390
|
}
|
|
45380
45391
|
return { startIndex: newStartIndex, endIndex: newEndIndex };
|
|
45381
45392
|
}
|
|
45393
|
+
function isAssistantAct(msg) {
|
|
45394
|
+
return msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call");
|
|
45395
|
+
}
|
|
45396
|
+
function computeTurnGroups(messages) {
|
|
45397
|
+
const resultIdByCallId = /* @__PURE__ */ new Map();
|
|
45398
|
+
for (const msg of messages) {
|
|
45399
|
+
if (msg.contentType === "tool-result" && typeof msg.toolCallId === "string" && msg.id) {
|
|
45400
|
+
if (!resultIdByCallId.has(msg.toolCallId))
|
|
45401
|
+
resultIdByCallId.set(msg.toolCallId, msg.id);
|
|
45402
|
+
}
|
|
45403
|
+
}
|
|
45404
|
+
const grouped = /* @__PURE__ */ new Set();
|
|
45405
|
+
const groups = [];
|
|
45406
|
+
for (let i = 0; i < messages.length; i++) {
|
|
45407
|
+
const msg = messages[i];
|
|
45408
|
+
if (!msg.id || grouped.has(msg.id)) continue;
|
|
45409
|
+
if (!(msg.contentType === "reasoning" || isAssistantAct(msg))) continue;
|
|
45410
|
+
let reasoningStart = i;
|
|
45411
|
+
if (msg.contentType === "reasoning") {
|
|
45412
|
+
while (reasoningStart > 0 && messages[reasoningStart - 1].contentType === "reasoning") {
|
|
45413
|
+
reasoningStart--;
|
|
45414
|
+
}
|
|
45415
|
+
} else {
|
|
45416
|
+
let s3 = i;
|
|
45417
|
+
while (s3 > 0 && isAssistantAct(messages[s3 - 1])) s3--;
|
|
45418
|
+
reasoningStart = s3;
|
|
45419
|
+
while (reasoningStart > 0 && messages[reasoningStart - 1].contentType === "reasoning") {
|
|
45420
|
+
reasoningStart--;
|
|
45421
|
+
}
|
|
45422
|
+
}
|
|
45423
|
+
const burstStart = (() => {
|
|
45424
|
+
let s3 = reasoningStart;
|
|
45425
|
+
while (s3 < messages.length && messages[s3].contentType === "reasoning")
|
|
45426
|
+
s3++;
|
|
45427
|
+
return s3;
|
|
45428
|
+
})();
|
|
45429
|
+
if (burstStart >= messages.length || !isAssistantAct(messages[burstStart])) {
|
|
45430
|
+
continue;
|
|
45431
|
+
}
|
|
45432
|
+
let burstEnd = burstStart;
|
|
45433
|
+
while (burstEnd + 1 < messages.length && isAssistantAct(messages[burstEnd + 1])) {
|
|
45434
|
+
burstEnd++;
|
|
45435
|
+
}
|
|
45436
|
+
const members = /* @__PURE__ */ new Set();
|
|
45437
|
+
for (let k2 = reasoningStart; k2 <= burstEnd; k2++) {
|
|
45438
|
+
const m2 = messages[k2];
|
|
45439
|
+
if (!m2.id) continue;
|
|
45440
|
+
members.add(m2.id);
|
|
45441
|
+
if (m2.role === "assistant" && m2.contentType === "tool-call" && typeof m2.toolCallId === "string") {
|
|
45442
|
+
const rid = resultIdByCallId.get(m2.toolCallId);
|
|
45443
|
+
if (rid) members.add(rid);
|
|
45444
|
+
}
|
|
45445
|
+
}
|
|
45446
|
+
for (const id of members) grouped.add(id);
|
|
45447
|
+
groups.push([...members]);
|
|
45448
|
+
}
|
|
45449
|
+
return groups;
|
|
45450
|
+
}
|
|
45382
45451
|
function estimateTextTokens(text) {
|
|
45383
45452
|
return Math.ceil(text.length / 4);
|
|
45384
45453
|
}
|
|
@@ -45402,7 +45471,7 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
|
|
|
45402
45471
|
if (isNeverPreserveRecent(msg)) continue;
|
|
45403
45472
|
const ref = state.messageRefs.byRaw[msg.id];
|
|
45404
45473
|
if (!ref || ref === "BLOCKED") continue;
|
|
45405
|
-
visible.push({ ref, tokens:
|
|
45474
|
+
visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
|
|
45406
45475
|
}
|
|
45407
45476
|
if (preserveN > 0) {
|
|
45408
45477
|
for (const m2 of visible.slice(-preserveN)) {
|
|
@@ -45445,7 +45514,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
45445
45514
|
protectedMsgs.push({
|
|
45446
45515
|
ref,
|
|
45447
45516
|
gapBefore: skipSinceProtected,
|
|
45448
|
-
tokens:
|
|
45517
|
+
tokens: countMessageTokens(msg, countTokens),
|
|
45449
45518
|
tools: msg.toolName ? [msg.toolName] : []
|
|
45450
45519
|
});
|
|
45451
45520
|
skipSinceProtected = false;
|
|
@@ -45460,7 +45529,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
45460
45529
|
compressibleMsgs.push({
|
|
45461
45530
|
ref,
|
|
45462
45531
|
gapBefore: skipSinceCompressible,
|
|
45463
|
-
tokens:
|
|
45532
|
+
tokens: countMessageTokens(msg, countTokens),
|
|
45464
45533
|
chars: (msg.text ?? "").length,
|
|
45465
45534
|
isTool: isToolMessage(msg),
|
|
45466
45535
|
isUser: msg.role === "user"
|
|
@@ -46093,6 +46162,42 @@ function applySingleRange(input) {
|
|
|
46093
46162
|
)} from compression range (recent/last-user zone).`
|
|
46094
46163
|
);
|
|
46095
46164
|
}
|
|
46165
|
+
{
|
|
46166
|
+
const reasoningIds = /* @__PURE__ */ new Set();
|
|
46167
|
+
const callIds = /* @__PURE__ */ new Set();
|
|
46168
|
+
for (const m2 of input.messages) {
|
|
46169
|
+
if (!m2.id) continue;
|
|
46170
|
+
if (m2.contentType === "reasoning") reasoningIds.add(m2.id);
|
|
46171
|
+
if (m2.role === "assistant" && m2.contentType === "tool-call") callIds.add(m2.id);
|
|
46172
|
+
}
|
|
46173
|
+
const withdrawIds = /* @__PURE__ */ new Set();
|
|
46174
|
+
let splitTurnCount = 0;
|
|
46175
|
+
for (const group of computeTurnGroups(input.messages)) {
|
|
46176
|
+
const foldHasReasoning = group.some(
|
|
46177
|
+
(id) => effectiveMessageIds.has(id) && reasoningIds.has(id)
|
|
46178
|
+
);
|
|
46179
|
+
if (!foldHasReasoning) continue;
|
|
46180
|
+
const keptHasCall = group.some(
|
|
46181
|
+
(id) => !effectiveMessageIds.has(id) && callIds.has(id)
|
|
46182
|
+
);
|
|
46183
|
+
if (!keptHasCall) continue;
|
|
46184
|
+
splitTurnCount++;
|
|
46185
|
+
for (const id of group) withdrawIds.add(id);
|
|
46186
|
+
}
|
|
46187
|
+
if (withdrawIds.size > 0) {
|
|
46188
|
+
for (const id of withdrawIds) effectiveMessageIds.delete(id);
|
|
46189
|
+
const beforeWithdraw = filteredIds.length;
|
|
46190
|
+
filteredIds = filteredIds.filter((id) => !withdrawIds.has(id));
|
|
46191
|
+
if (filteredIds.length === 0 && consumedBlockIds.length === 0) {
|
|
46192
|
+
throw new Error(
|
|
46193
|
+
`Range would split ${splitTurnCount} turn(s) at the protected-zone boundary: a visible tool-call must keep its reasoning run (strict-echo providers reject a rebuilt request that lost it). Shrink the range to end before the turn starts, or wait until the whole turn ages out of the protected zone.`
|
|
46194
|
+
);
|
|
46195
|
+
}
|
|
46196
|
+
warnings.push(
|
|
46197
|
+
`Withdrawn ${beforeWithdraw - filteredIds.length} message(s) from compression range to keep ${splitTurnCount} turn(s) intact (visible tool-call would lose its reasoning run).`
|
|
46198
|
+
);
|
|
46199
|
+
}
|
|
46200
|
+
}
|
|
46096
46201
|
if (!isBlockBoundary && filteredIds.length === 0 && consumedBlockIds.length > 0) {
|
|
46097
46202
|
const first = consumedBlockIds[0];
|
|
46098
46203
|
const last = consumedBlockIds[consumedBlockIds.length - 1];
|
|
@@ -46106,7 +46211,7 @@ function applySingleRange(input) {
|
|
|
46106
46211
|
let compressedTokens = 0;
|
|
46107
46212
|
for (const id of filteredIds) {
|
|
46108
46213
|
const message = input.messages.find((entry) => entry.id === id);
|
|
46109
|
-
compressedTokens += input.countTokens
|
|
46214
|
+
compressedTokens += message ? countMessageTokens(message, input.countTokens) : 0;
|
|
46110
46215
|
}
|
|
46111
46216
|
for (const consumedId of consumedBlockIds) {
|
|
46112
46217
|
const consumed = blockById(input.state, consumedId);
|
|
@@ -46436,7 +46541,7 @@ function computeContextBreakdown(messages, total, growth, countTokens) {
|
|
|
46436
46541
|
const count = countTokens ?? ((t) => Math.ceil(t.length / 4));
|
|
46437
46542
|
let system = 0, tool = 0, summaries = 0, code = 0, text = 0;
|
|
46438
46543
|
for (const msg of messages) {
|
|
46439
|
-
const tokens =
|
|
46544
|
+
const tokens = countMessageTokens(msg, count);
|
|
46440
46545
|
if (msg.text?.startsWith("[Compressed conversation section]")) {
|
|
46441
46546
|
summaries += tokens;
|
|
46442
46547
|
} else if (msg.contentType === "tool-call" || msg.contentType === "tool-result") {
|
|
@@ -46622,7 +46727,7 @@ function collectVisible(messages, state, countTokens) {
|
|
|
46622
46727
|
if (coveredIds.has(message.id)) return;
|
|
46623
46728
|
const ref = refForRaw(state.messageRefs, message.id);
|
|
46624
46729
|
if (!ref) return;
|
|
46625
|
-
const tokens =
|
|
46730
|
+
const tokens = countMessageTokens(message, countTokens);
|
|
46626
46731
|
const tool = isToolMessage(message) ? message.toolName ?? (message.toolCallId ? toolCallNames.get(message.toolCallId) : void 0) ?? "tool" : "text";
|
|
46627
46732
|
if (tokens > 0) visible.push({ ref, tokens, tool, index });
|
|
46628
46733
|
});
|
|
@@ -53721,6 +53826,11 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
53721
53826
|
}
|
|
53722
53827
|
} catch (e) {
|
|
53723
53828
|
if (!(e instanceof UpstreamHttpError)) throw e;
|
|
53829
|
+
if (e.status === 400 && /reasoning_content/i.test(e.body) && ctx.session.metadata.strictReasoningEcho !== true) {
|
|
53830
|
+
ctx.session.metadata.strictReasoningEcho = true;
|
|
53831
|
+
ctx.log(`[acp-loop] 400 mentions reasoning_content \u2014 learned strict reasoning echo for this session; #651 reasoning-drop disabled (#684)`);
|
|
53832
|
+
log("warn", `[acp-loop] learned strictReasoningEcho (session ${ctx.session.id}); reasoning-drop disabled (#684)`);
|
|
53833
|
+
}
|
|
53724
53834
|
const suffix = e.attempts > 1 ? ` after ${e.attempts} attempt(s)` : "";
|
|
53725
53835
|
ctx.log(`[acp-proxy: compress loop upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}]`);
|
|
53726
53836
|
log("error", `[acp-loop] upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}`);
|
|
@@ -57204,6 +57314,98 @@ function resolveCodexHome(env) {
|
|
|
57204
57314
|
const h = os.homedir();
|
|
57205
57315
|
return nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path10.join(h, ".codex");
|
|
57206
57316
|
}
|
|
57317
|
+
function resolveCodebuddyHome(env) {
|
|
57318
|
+
const h = os.homedir();
|
|
57319
|
+
return nonEmpty2(env.CODEBUDDY_CONFIG_DIR) ? env.CODEBUDDY_CONFIG_DIR : path10.join(h, ".codebuddy");
|
|
57320
|
+
}
|
|
57321
|
+
function parseCodebuddyModelsJson(obj) {
|
|
57322
|
+
const out = { models: [], urls: [] };
|
|
57323
|
+
const seenUrl = /* @__PURE__ */ new Set();
|
|
57324
|
+
const collect = (id, entry) => {
|
|
57325
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
|
|
57326
|
+
const e = entry;
|
|
57327
|
+
const url = e.url;
|
|
57328
|
+
if (typeof url === "string" && url.length > 0 && !seenUrl.has(url)) {
|
|
57329
|
+
seenUrl.add(url);
|
|
57330
|
+
out.urls.push(url);
|
|
57331
|
+
}
|
|
57332
|
+
const win = toModelWindow(id, e.maxInputTokens);
|
|
57333
|
+
if (win) out.models.push(win);
|
|
57334
|
+
};
|
|
57335
|
+
if (!obj) return out;
|
|
57336
|
+
if (Array.isArray(obj)) {
|
|
57337
|
+
for (const item of obj) {
|
|
57338
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
57339
|
+
const it2 = item;
|
|
57340
|
+
collect(it2.id ?? it2.name, it2);
|
|
57341
|
+
}
|
|
57342
|
+
return out;
|
|
57343
|
+
}
|
|
57344
|
+
if (typeof obj !== "object") return out;
|
|
57345
|
+
const root = obj;
|
|
57346
|
+
const modelsField = root.models;
|
|
57347
|
+
if (Array.isArray(modelsField)) {
|
|
57348
|
+
for (const item of modelsField) {
|
|
57349
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
57350
|
+
const it2 = item;
|
|
57351
|
+
collect(it2.id ?? it2.name, it2);
|
|
57352
|
+
}
|
|
57353
|
+
return out;
|
|
57354
|
+
}
|
|
57355
|
+
if (modelsField && typeof modelsField === "object") {
|
|
57356
|
+
for (const [id, val] of Object.entries(modelsField)) collect(id, val);
|
|
57357
|
+
return out;
|
|
57358
|
+
}
|
|
57359
|
+
for (const [id, val] of Object.entries(root)) collect(id, val);
|
|
57360
|
+
return out;
|
|
57361
|
+
}
|
|
57362
|
+
function readJsonFile(filePath) {
|
|
57363
|
+
try {
|
|
57364
|
+
return JSON.parse(fs6.readFileSync(filePath, "utf8"));
|
|
57365
|
+
} catch {
|
|
57366
|
+
return null;
|
|
57367
|
+
}
|
|
57368
|
+
}
|
|
57369
|
+
function readCodebuddyConfig(codebuddyHome, cwd, env = process.env) {
|
|
57370
|
+
let codebuddyBaseUrl;
|
|
57371
|
+
let model;
|
|
57372
|
+
let autoCompactWindow;
|
|
57373
|
+
const settings = readJsonObject(path10.join(codebuddyHome, "settings.json"));
|
|
57374
|
+
const settingsEnv = settings?.env;
|
|
57375
|
+
if (settingsEnv && typeof settingsEnv === "object" && !Array.isArray(settingsEnv)) {
|
|
57376
|
+
const e = settingsEnv;
|
|
57377
|
+
const v2 = e.CODEBUDDY_BASE_URL;
|
|
57378
|
+
if (nonEmpty2(v2)) codebuddyBaseUrl = v2;
|
|
57379
|
+
}
|
|
57380
|
+
const tm = settings?.model;
|
|
57381
|
+
if (nonEmpty2(tm)) model = String(tm);
|
|
57382
|
+
const tacw = Number(settings?.autoCompactWindow);
|
|
57383
|
+
if (Number.isFinite(tacw) && tacw > 0) autoCompactWindow = tacw;
|
|
57384
|
+
if (!codebuddyBaseUrl && nonEmpty2(env.CODEBUDDY_BASE_URL)) codebuddyBaseUrl = env.CODEBUDDY_BASE_URL;
|
|
57385
|
+
const windowByModel = /* @__PURE__ */ new Map();
|
|
57386
|
+
const urls = [];
|
|
57387
|
+
const seenUrl = /* @__PURE__ */ new Set();
|
|
57388
|
+
for (const f2 of [
|
|
57389
|
+
path10.join(codebuddyHome, "models.json"),
|
|
57390
|
+
path10.join(cwd, ".codebuddy", "models.json")
|
|
57391
|
+
]) {
|
|
57392
|
+
const parsed = parseCodebuddyModelsJson(readJsonFile(f2));
|
|
57393
|
+
for (const w2 of parsed.models) windowByModel.set(w2.id, w2.contextWindow);
|
|
57394
|
+
for (const u2 of parsed.urls) {
|
|
57395
|
+
if (!seenUrl.has(u2)) {
|
|
57396
|
+
seenUrl.add(u2);
|
|
57397
|
+
urls.push(u2);
|
|
57398
|
+
}
|
|
57399
|
+
}
|
|
57400
|
+
}
|
|
57401
|
+
return {
|
|
57402
|
+
...codebuddyBaseUrl ? { codebuddyBaseUrl } : {},
|
|
57403
|
+
...model ? { model } : {},
|
|
57404
|
+
...autoCompactWindow ? { autoCompactWindow } : {},
|
|
57405
|
+
...windowByModel.size > 0 ? { models: [...windowByModel.entries()].map(([id, contextWindow]) => ({ id, contextWindow })) } : {},
|
|
57406
|
+
...urls.length > 0 ? { modelUrls: urls } : {}
|
|
57407
|
+
};
|
|
57408
|
+
}
|
|
57207
57409
|
function parseDshSettingsYaml(text) {
|
|
57208
57410
|
const out = [];
|
|
57209
57411
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -57577,6 +57779,7 @@ function loadClientConfig(env, cwd) {
|
|
|
57577
57779
|
config.opencode = readOpencodeConfig(resolveOpencodeConfigFile(env));
|
|
57578
57780
|
config.hermes = readHermesConfig(resolveHermesHome(env));
|
|
57579
57781
|
config.dsh = readDshConfig(resolveDshHome(env));
|
|
57782
|
+
config.codebuddy = readCodebuddyConfig(resolveCodebuddyHome(env), cwd, env);
|
|
57580
57783
|
return config;
|
|
57581
57784
|
}
|
|
57582
57785
|
function collectModelWindows(config, scope) {
|
|
@@ -57591,12 +57794,14 @@ function collectModelWindows(config, scope) {
|
|
|
57591
57794
|
else if (scope === "pi") for (const p2 of Object.values(config.pi?.providers ?? {})) add(p2.models);
|
|
57592
57795
|
else if (scope === "omp") for (const p2 of Object.values(config.omp?.providers ?? {})) add(p2.models);
|
|
57593
57796
|
else if (scope === "opencode") for (const p2 of Object.values(config.opencode?.providers ?? {})) add(p2.models);
|
|
57797
|
+
else if (scope === "codebuddy") add(config.codebuddy?.models);
|
|
57594
57798
|
return out;
|
|
57595
57799
|
}
|
|
57596
57800
|
for (const p2 of Object.values(config.pi?.providers ?? {})) add(p2.models);
|
|
57597
57801
|
for (const p2 of Object.values(config.omp?.providers ?? {})) add(p2.models);
|
|
57598
57802
|
for (const p2 of Object.values(config.opencode?.providers ?? {})) add(p2.models);
|
|
57599
57803
|
add(config.codex?.modelWindows);
|
|
57804
|
+
add(config.codebuddy?.models);
|
|
57600
57805
|
return out;
|
|
57601
57806
|
}
|
|
57602
57807
|
|
|
@@ -57634,18 +57839,26 @@ function extractHttpsHosts(config) {
|
|
|
57634
57839
|
if (config.zcode) {
|
|
57635
57840
|
for (const prov of Object.values(config.zcode.providers)) push(prov.baseURL);
|
|
57636
57841
|
}
|
|
57842
|
+
if (config.codebuddy) {
|
|
57843
|
+
push(config.codebuddy.codebuddyBaseUrl);
|
|
57844
|
+
for (const u2 of config.codebuddy.modelUrls ?? []) push(u2);
|
|
57845
|
+
}
|
|
57637
57846
|
return out;
|
|
57638
57847
|
}
|
|
57639
57848
|
function configFilePaths(env) {
|
|
57640
57849
|
const home = os2.homedir();
|
|
57641
57850
|
const codexHome = nonEmpty2(env.CODEX_HOME) ? env.CODEX_HOME : path11.join(home, ".codex");
|
|
57642
57851
|
const zcodeHome = nonEmpty2(env.ZCODE_DATA_BASE_DIR) ? env.ZCODE_DATA_BASE_DIR : path11.join(home, ".zcode");
|
|
57852
|
+
const codebuddyHome = resolveCodebuddyHome(env);
|
|
57643
57853
|
return [
|
|
57644
57854
|
path11.join(home, ".claude", "settings.json"),
|
|
57645
57855
|
path11.join(process.cwd(), ".claude", "settings.json"),
|
|
57646
57856
|
path11.join(codexHome, "config.toml"),
|
|
57647
57857
|
path11.join(resolvePiHome(env), "models.json"),
|
|
57648
|
-
path11.join(zcodeHome, "v2", "config.json")
|
|
57858
|
+
path11.join(zcodeHome, "v2", "config.json"),
|
|
57859
|
+
path11.join(codebuddyHome, "settings.json"),
|
|
57860
|
+
path11.join(codebuddyHome, "models.json"),
|
|
57861
|
+
path11.join(process.cwd(), ".codebuddy", "models.json")
|
|
57649
57862
|
];
|
|
57650
57863
|
}
|
|
57651
57864
|
function readMtimes(paths) {
|
|
@@ -59536,7 +59749,7 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
59536
59749
|
log2("info", `[debug] strip-images: dropped ${stripped.removed} historical image part(s), kept last ${keepRecent} (session=${session.id})`);
|
|
59537
59750
|
}
|
|
59538
59751
|
const work = stripped.body;
|
|
59539
|
-
return countTokens ? prepareCountTokens(work, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, reasoningCfg) : protocol === "openai" ? prepareOpenai(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, nativeWindow, reasoningCfg) : responsesCompact ? prepareResponsesCompact(stripped.removed > 0 ? Buffer.from(JSON.stringify(work)) : bodyBuffer, work, session, req, core, reqConfig, log2) : prepareResponses(work, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin, nativeWindow, reasoningCfg);
|
|
59752
|
+
return countTokens ? prepareCountTokens(work, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, upstreamOrigin, reasoningCfg) : protocol === "openai" ? prepareOpenai(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, upstreamOrigin, nativeWindow, reasoningCfg) : responsesCompact ? prepareResponsesCompact(stripped.removed > 0 ? Buffer.from(JSON.stringify(work)) : bodyBuffer, work, session, req, core, reqConfig, log2) : prepareResponses(work, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin, nativeWindow, reasoningCfg);
|
|
59540
59753
|
};
|
|
59541
59754
|
const isCodexCompactTrigger = protocol === "responses" && !responsesCompact && isCodexClient(req.headers) && hasCompactionTrigger(parsed.input);
|
|
59542
59755
|
if (isCodexCompactTrigger) {
|
|
@@ -59624,13 +59837,64 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
59624
59837
|
}
|
|
59625
59838
|
}
|
|
59626
59839
|
var ACP_TAG_MARK = "<acp ";
|
|
59627
|
-
function withReasoningDrop(msgs, reasoning, log2, sessionId) {
|
|
59840
|
+
function withReasoningDrop(msgs, reasoning, log2, sessionId, strictEcho) {
|
|
59841
|
+
if (strictEcho) return msgs;
|
|
59628
59842
|
const out = dropCompressReasoning(msgs, reasoning);
|
|
59629
59843
|
if (out.length !== msgs.length) {
|
|
59630
59844
|
log2("info", `[${sessionId}] compress-reasoning: dropped ${msgs.length - out.length} reasoning message(s) from closed compress turns (#651)`);
|
|
59631
59845
|
}
|
|
59632
59846
|
return out;
|
|
59633
59847
|
}
|
|
59848
|
+
function isStrictReasoningEcho(session, upstreamOrigin) {
|
|
59849
|
+
if (session.metadata.strictReasoningEcho === true) return true;
|
|
59850
|
+
return upstreamOrigin !== void 0 && /deepseek/i.test(upstreamOrigin);
|
|
59851
|
+
}
|
|
59852
|
+
function warnReasoningPairs(wireMessages, log2, sessionId) {
|
|
59853
|
+
let withRc = 0;
|
|
59854
|
+
let split = 0;
|
|
59855
|
+
for (const m2 of wireMessages) {
|
|
59856
|
+
const msg = m2;
|
|
59857
|
+
if (msg?.role !== "assistant") continue;
|
|
59858
|
+
const hasRc = typeof msg.reasoning_content === "string" && msg.reasoning_content.length > 0;
|
|
59859
|
+
if (hasRc) withRc++;
|
|
59860
|
+
else if (Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) split++;
|
|
59861
|
+
}
|
|
59862
|
+
if (withRc > 0 && split > 0) {
|
|
59863
|
+
log2("warn", `[${sessionId}] reasoning-pair-violated: ${split} assistant tool-call message(s) lack reasoning_content while ${withRc} carry it \u2014 strict-echo upstreams (DeepSeek thinking mode) will reject the request (#684)`);
|
|
59864
|
+
}
|
|
59865
|
+
}
|
|
59866
|
+
function warnAnthropicThinkingPairs(wireMessages, log2, sessionId) {
|
|
59867
|
+
let withThinking = 0;
|
|
59868
|
+
let split = 0;
|
|
59869
|
+
for (const m2 of wireMessages) {
|
|
59870
|
+
const msg = m2;
|
|
59871
|
+
if (msg?.role !== "assistant" || !Array.isArray(msg.content)) continue;
|
|
59872
|
+
const hasThinking = msg.content.some((b2) => b2?.type === "thinking");
|
|
59873
|
+
if (hasThinking) withThinking++;
|
|
59874
|
+
else if (msg.content.some((b2) => b2?.type === "tool_use")) split++;
|
|
59875
|
+
}
|
|
59876
|
+
if (withThinking > 0 && split > 0) {
|
|
59877
|
+
log2("warn", `[${sessionId}] thinking-pair-violated: ${split} assistant tool_use message(s) lack a thinking block while ${withThinking} carry one \u2014 extended-thinking tool use requires preserved thinking (#684)`);
|
|
59878
|
+
}
|
|
59879
|
+
}
|
|
59880
|
+
function warnResponsesReasoningPairs(input, log2, sessionId) {
|
|
59881
|
+
let withReasoning = 0;
|
|
59882
|
+
let split = 0;
|
|
59883
|
+
let prevWasReasoning = false;
|
|
59884
|
+
for (const item of input) {
|
|
59885
|
+
const it2 = item;
|
|
59886
|
+
if (it2?.type === "reasoning") {
|
|
59887
|
+
withReasoning++;
|
|
59888
|
+
prevWasReasoning = true;
|
|
59889
|
+
continue;
|
|
59890
|
+
}
|
|
59891
|
+
if (it2?.type === "function_call" && !prevWasReasoning) split++;
|
|
59892
|
+
prevWasReasoning = false;
|
|
59893
|
+
}
|
|
59894
|
+
if (withReasoning > 0 && split > 0) {
|
|
59895
|
+
log2("warn", `[${sessionId}] reasoning-pair-violated: ${split} function_call item(s) lack a preceding reasoning item while ${withReasoning} exist \u2014 strict-echo upstreams will reject the request (#684)`);
|
|
59896
|
+
}
|
|
59897
|
+
}
|
|
59634
59898
|
function stripKernelSummaries(messages, state) {
|
|
59635
59899
|
const carried = /* @__PURE__ */ new Set();
|
|
59636
59900
|
for (const b2 of state.blocks) {
|
|
@@ -59734,13 +59998,13 @@ function effectiveTokenCount(session, msgs) {
|
|
|
59734
59998
|
if (!session.metadata.anonymousPrefixAffinity) return 0;
|
|
59735
59999
|
return estimateCoreMessagesUpper(msgs);
|
|
59736
60000
|
}
|
|
59737
|
-
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode, reasoning) {
|
|
60001
|
+
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode, upstreamOrigin, reasoning) {
|
|
59738
60002
|
const sessionId = session.id;
|
|
59739
60003
|
const stream2 = parsed.stream === true;
|
|
59740
60004
|
++session.stats.requests;
|
|
59741
60005
|
session.hostCreditTokens = 0;
|
|
59742
60006
|
const injectTools = opts.compress.injectTool && !pluginMode;
|
|
59743
|
-
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
60007
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
|
|
59744
60008
|
if (isAutoModeClassifier(parsed)) {
|
|
59745
60009
|
log2("info", `[${sessionId}] auto-mode classifier passthrough (skipping compress injection)`);
|
|
59746
60010
|
return { body: JSON.stringify(parsed), session, processedMessages: [], originalMessages: [], anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: false, pluginMode, nudge: void 0, prompts };
|
|
@@ -59803,6 +60067,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
59803
60067
|
snapshotMessages(session, originalMessages);
|
|
59804
60068
|
markDirty(session);
|
|
59805
60069
|
const rebuilt = { ...parsed, messages: rebuiltMessages, system: systemOut, tools: toolsOut };
|
|
60070
|
+
warnAnthropicThinkingPairs(rebuiltMessages, log2, sessionId);
|
|
59806
60071
|
delete rebuilt.prompt_cache_key;
|
|
59807
60072
|
armHostUsageCredit(session, originalMessages, processedMessages, req.headers, opts.hostUsageCredit, log2);
|
|
59808
60073
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, renderTags: "text-only" };
|
|
@@ -59860,13 +60125,13 @@ function clampOutgoingOutput(rebuilt, field, ctx, sessionId, log2) {
|
|
|
59860
60125
|
log2("info", `[${sessionId}] output budget clamped ${raw} -> ${capped} (input~${inputEstimate}, window=${ctx.nativeWindow}); prevents input+output overflow (#453)`);
|
|
59861
60126
|
}
|
|
59862
60127
|
}
|
|
59863
|
-
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode, nativeWindow, reasoning) {
|
|
60128
|
+
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode, upstreamOrigin, nativeWindow, reasoning) {
|
|
59864
60129
|
const sessionId = session.id;
|
|
59865
60130
|
const stream2 = parsed.stream === true;
|
|
59866
60131
|
++session.stats.requests;
|
|
59867
60132
|
session.hostCreditTokens = 0;
|
|
59868
60133
|
let openaiSystemText = "";
|
|
59869
|
-
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
60134
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
|
|
59870
60135
|
let openaiOutboundSystem;
|
|
59871
60136
|
let processedMessages = [];
|
|
59872
60137
|
let originalMessages = [];
|
|
@@ -59931,6 +60196,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
59931
60196
|
processedMessages = [];
|
|
59932
60197
|
}
|
|
59933
60198
|
const rebuilt = { ...parsed, messages: rebuiltMessages, tools: toolsOut };
|
|
60199
|
+
warnReasoningPairs(rebuiltMessages, log2, sessionId);
|
|
59934
60200
|
clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("openai", rebuilt) }, sessionId, log2);
|
|
59935
60201
|
delete rebuilt.prompt_cache_retention;
|
|
59936
60202
|
if (stream2 && rebuilt.stream_options === void 0) {
|
|
@@ -59949,7 +60215,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
59949
60215
|
const stream2 = parsed.stream === true;
|
|
59950
60216
|
++session.stats.requests;
|
|
59951
60217
|
session.hostCreditTokens = 0;
|
|
59952
|
-
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
60218
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId, isStrictReasoningEcho(session, upstreamOrigin));
|
|
59953
60219
|
if (reconcileNativeCompactionBoundary(session)) {
|
|
59954
60220
|
log2("info", `[${sessionId}] reconciled ACP state after native Responses compact boundary`);
|
|
59955
60221
|
}
|
|
@@ -60067,6 +60333,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
60067
60333
|
log2("info", `[${sessionId}] codex compact intercepted (trigger); forged SSE with ${summaries.length} block summary(s), upstream not contacted`);
|
|
60068
60334
|
}
|
|
60069
60335
|
const rebuilt = { ...parsed, input: rebuiltInput, tools: toolsOut };
|
|
60336
|
+
warnResponsesReasoningPairs(Array.isArray(rebuiltInput) ? rebuiltInput : [], log2, sessionId);
|
|
60070
60337
|
if (!isCompactionTrigger) {
|
|
60071
60338
|
clampOutgoingOutput(rebuilt, "max_output_tokens", { systemText: (responsesProjection?.systemParts ?? []).join("\n"), tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("responses", rebuilt) }, sessionId, log2);
|
|
60072
60339
|
}
|
|
@@ -65219,7 +65486,7 @@ function selfDistFile(name) {
|
|
|
65219
65486
|
return path15.join(selfPackageRoot(), "dist", name);
|
|
65220
65487
|
}
|
|
65221
65488
|
var LAUNCHER_DEFAULT_HOST = "127.0.0.1";
|
|
65222
|
-
var LAUNCH_CLIENTS = ["pi", "codex", "claude", "omp", "opencode", "hermes", "dsh", "pi-test"];
|
|
65489
|
+
var LAUNCH_CLIENTS = ["pi", "codex", "claude", "omp", "opencode", "hermes", "dsh", "codebuddy", "pi-test"];
|
|
65223
65490
|
var HEALTH_PATH = "/__bili/health";
|
|
65224
65491
|
var HEALTH_POLL_INTERVAL_MS = 200;
|
|
65225
65492
|
var SPAWN_WAIT_MS = 2e4;
|
|
@@ -65307,6 +65574,29 @@ function discoverRoutes(client, config) {
|
|
|
65307
65574
|
}
|
|
65308
65575
|
} catch {
|
|
65309
65576
|
}
|
|
65577
|
+
} else if (client === "codebuddy") {
|
|
65578
|
+
const raw = nonEmpty2(config.codebuddy?.codebuddyBaseUrl) ? config.codebuddy.codebuddyBaseUrl : "https://tencent.sso.codebuddy.cn/v2";
|
|
65579
|
+
const real = unwrapUpstream2(raw);
|
|
65580
|
+
try {
|
|
65581
|
+
const url = new URL(real);
|
|
65582
|
+
if ((url.protocol === "https:" || url.protocol === "http:") && !rewriteKeys.has("CODEBUDDY_BASE_URL")) {
|
|
65583
|
+
rewriteKeys.add("CODEBUDDY_BASE_URL");
|
|
65584
|
+
httpRewrites.push({ key: "CODEBUDDY_BASE_URL", realUpstream: real });
|
|
65585
|
+
}
|
|
65586
|
+
} catch {
|
|
65587
|
+
}
|
|
65588
|
+
for (const rawModelUrl of config.codebuddy?.modelUrls ?? []) {
|
|
65589
|
+
try {
|
|
65590
|
+
const url = new URL(unwrapUpstream2(rawModelUrl));
|
|
65591
|
+
if (url.protocol !== "https:") continue;
|
|
65592
|
+
const host = url.hostname;
|
|
65593
|
+
if (host && !httpsSeen.has(host.toLowerCase())) {
|
|
65594
|
+
httpsSeen.add(host.toLowerCase());
|
|
65595
|
+
httpsDomains.push(host);
|
|
65596
|
+
}
|
|
65597
|
+
} catch {
|
|
65598
|
+
}
|
|
65599
|
+
}
|
|
65310
65600
|
} else if (client === "pi") {
|
|
65311
65601
|
for (const [name, prov] of Object.entries(config.pi?.providers ?? {})) {
|
|
65312
65602
|
classify(prov.baseUrl, name);
|
|
@@ -65450,6 +65740,21 @@ function buildClaudeEnv(origin, caPath, httpRewrites, httpsRewrites, baseEnv) {
|
|
|
65450
65740
|
if (hr2) env.ANTHROPIC_BASE_URL = hr2.realUpstream;
|
|
65451
65741
|
return env;
|
|
65452
65742
|
}
|
|
65743
|
+
async function resolveCodebuddyBudgetEnv(opts) {
|
|
65744
|
+
const { model, userAutoCompactWindow, shellAutoCompactWindow, routes, upstreamUrl } = opts;
|
|
65745
|
+
if (!model || userAutoCompactWindow !== void 0 || nonEmpty2(shellAutoCompactWindow)) return {};
|
|
65746
|
+
const window2 = await resolveLauncherWindow(model, routes, upstreamUrl);
|
|
65747
|
+
if (!window2) return {};
|
|
65748
|
+
return { CODEBUDDY_AUTO_COMPACT_WINDOW: String(window2) };
|
|
65749
|
+
}
|
|
65750
|
+
function buildCodebuddyEnv(origin, caPath, httpRewrites, httpsRewrites, baseEnv) {
|
|
65751
|
+
const env = { ...baseEnv, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: caPath, BILLION_CONTEXT_PROXY: origin };
|
|
65752
|
+
const r = httpRewrites.find((rw) => rw.key === "CODEBUDDY_BASE_URL");
|
|
65753
|
+
if (r) env.CODEBUDDY_BASE_URL = wrapUpstream(origin, r.realUpstream);
|
|
65754
|
+
const hr2 = httpsRewrites.find((rw) => rw.key === "CODEBUDDY_BASE_URL");
|
|
65755
|
+
if (hr2) env.CODEBUDDY_BASE_URL = hr2.realUpstream;
|
|
65756
|
+
return env;
|
|
65757
|
+
}
|
|
65453
65758
|
function launcherDirectUrl(env) {
|
|
65454
65759
|
return env.BILI_LAUNCHER_DIRECT === "1";
|
|
65455
65760
|
}
|
|
@@ -65490,7 +65795,7 @@ function isPrivateIPv4(host) {
|
|
|
65490
65795
|
return false;
|
|
65491
65796
|
}
|
|
65492
65797
|
function launcherInjectMcp(env, base, codexUpstream) {
|
|
65493
|
-
if (base === "pi" || base === "omp" || base === "opencode" || base === "hermes" || base === "dsh") return false;
|
|
65798
|
+
if (base === "pi" || base === "omp" || base === "opencode" || base === "hermes" || base === "dsh" || base === "codebuddy") return false;
|
|
65494
65799
|
if (env.BILI_LAUNCHER_PLUGIN === "0") return false;
|
|
65495
65800
|
if (base === "codex" && env.BILI_LAUNCHER_PLUGIN === void 0 && codexUpstream !== void 0 && isPrivateUpstreamHost(codexUpstream)) {
|
|
65496
65801
|
return false;
|
|
@@ -66313,6 +66618,10 @@ function resolveClientCommand(client, env) {
|
|
|
66313
66618
|
);
|
|
66314
66619
|
return { command: process.execPath, prefixArgs: [cli] };
|
|
66315
66620
|
}
|
|
66621
|
+
if (client === "codebuddy") {
|
|
66622
|
+
const resolved2 = resolveOnPath("codebuddy", env) ?? resolveOnPath("cbc", env);
|
|
66623
|
+
return { command: resolved2 ?? "codebuddy", prefixArgs: [] };
|
|
66624
|
+
}
|
|
66316
66625
|
const resolved = resolveOnPath(client, env);
|
|
66317
66626
|
return { command: resolved ?? client, prefixArgs: [] };
|
|
66318
66627
|
}
|
|
@@ -66478,6 +66787,19 @@ async function runLaunch(params, deps = {}) {
|
|
|
66478
66787
|
Object.assign(env, inj.envPatch);
|
|
66479
66788
|
if (inj.warning) console.error(`bili: ${inj.warning}`);
|
|
66480
66789
|
}
|
|
66790
|
+
} else if (base === "codebuddy") {
|
|
66791
|
+
env = buildCodebuddyEnv(origin, ca, routes.httpRewrites, routes.httpsRewrites, process.env);
|
|
66792
|
+
const codebuddyBudget = await resolveCodebuddyBudgetEnv({
|
|
66793
|
+
model: config.codebuddy?.model,
|
|
66794
|
+
userAutoCompactWindow: config.codebuddy?.autoCompactWindow,
|
|
66795
|
+
shellAutoCompactWindow: process.env.CODEBUDDY_AUTO_COMPACT_WINDOW,
|
|
66796
|
+
routes: biliRoutes,
|
|
66797
|
+
upstreamUrl: config.codebuddy?.codebuddyBaseUrl ?? "https://tencent.sso.codebuddy.cn/v2"
|
|
66798
|
+
});
|
|
66799
|
+
Object.assign(env, codebuddyBudget);
|
|
66800
|
+
if (codebuddyBudget.CODEBUDDY_AUTO_COMPACT_WINDOW !== void 0) {
|
|
66801
|
+
console.error(`bili: codebuddy budget aligned \u2014 CODEBUDDY_AUTO_COMPACT_WINDOW=${codebuddyBudget.CODEBUDDY_AUTO_COMPACT_WINDOW}`);
|
|
66802
|
+
}
|
|
66481
66803
|
} else {
|
|
66482
66804
|
env = directUrl ? buildClaudePluginEnv(origin, true, process.env) : buildClaudeEnv(origin, ca, routes.httpRewrites, routes.httpsRewrites, process.env);
|
|
66483
66805
|
if (directUrl) env.BILLION_CONTEXT_PROXY = origin;
|
|
@@ -66732,6 +67054,7 @@ Usage:
|
|
|
66732
67054
|
bili opencode [opts --] [args] start a proxy + launch opencode against it (cert-MITM)
|
|
66733
67055
|
bili hermes [opts --] [args] start a proxy + launch hermes-agent against it (/bili/ rewrite)
|
|
66734
67056
|
bili dsh [opts --] [args] start a proxy + launch deepseek-harness against it (/bili/ rewrite)
|
|
67057
|
+
bili codebuddy [opts --] [args] start a proxy + launch codebuddy against it (/bili/ rewrite)
|
|
66735
67058
|
bili test pi non-polluting pi smoke test through the proxy
|
|
66736
67059
|
bili export [session] [--full] list sessions / export one as a Markdown handoff
|
|
66737
67060
|
(--full includes original messages; --output FILE)
|
|
@@ -66746,7 +67069,7 @@ Usage:
|
|
|
66746
67069
|
bili --version print version
|
|
66747
67070
|
bili --help show this help
|
|
66748
67071
|
|
|
66749
|
-
Launcher (bili pi / bili codex / bili claude / bili omp / bili opencode / bili hermes / bili dsh):
|
|
67072
|
+
Launcher (bili pi / bili codex / bili claude / bili omp / bili opencode / bili hermes / bili dsh / bili codebuddy):
|
|
66750
67073
|
Brings up a proxy on an independent port (a fresh instance every launch), then runs the client pointed at it via HTTPS_PROXY + the proxy's
|
|
66751
67074
|
MITM CA \u2014 no config-file edits. Discovered HTTPS upstream domains are
|
|
66752
67075
|
auto-whitelisted for MITM so the proxy TLS-terminates exactly the hosts the
|
|
@@ -66762,6 +67085,7 @@ Launcher (bili pi / bili codex / bili claude / bili omp / bili opencode / bili h
|
|
|
66762
67085
|
bili omp # launch omp through the proxy (pi-based; /bili/ rewrite)
|
|
66763
67086
|
bili hermes # launch hermes-agent through the proxy (/bili/ rewrite of ~/.hermes/config.yaml)
|
|
66764
67087
|
bili dsh --profile web "task" # launch deepseek-harness through the proxy (/bili/ rewrite of ~/.dsh/settings.yaml)
|
|
67088
|
+
bili codebuddy # launch codebuddy through the proxy (CODEBUDDY_BASE_URL /bili/ rewrite)
|
|
66765
67089
|
bili test pi # quick end-to-end check of the pi path
|
|
66766
67090
|
bili --mitm-domain api.foo.com pi # add a domain to the MITM whitelist (flags precede the client)
|
|
66767
67091
|
bili -F http://127.0.0.1:7897 codex # route bili's upstream through a proxy (gost-style -F)
|