billion-context 0.1.46-pr.211.22 → 0.1.46-pr.211.24

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.
@@ -0,0 +1,54 @@
1
+ import { createRequire as __biliCreateRequire } from 'node:module';
2
+ const require = __biliCreateRequire(import.meta.url);
3
+
4
+ // src/agent/opencode.ts
5
+ var proxyBase = process.env.BILLION_CONTEXT_PROXY ?? "";
6
+ async function showText(ctx, sid, text) {
7
+ const prompt = ctx.client?.session?.prompt;
8
+ if (typeof prompt !== "function") return;
9
+ try {
10
+ await prompt({
11
+ path: { id: sid },
12
+ body: { noReply: true, parts: [{ type: "text", text, ignored: true }] }
13
+ });
14
+ } catch {
15
+ }
16
+ }
17
+ var server = async (ctx) => {
18
+ if (!proxyBase) return {};
19
+ console.log("[bili-opencode] plugin active (proxy " + proxyBase + ")");
20
+ return {
21
+ config: async (opencodeConfig) => {
22
+ opencodeConfig.command ??= {};
23
+ opencodeConfig.command["acp"] = {
24
+ template: "",
25
+ description: "Show ACP status (billion-context proxy)"
26
+ };
27
+ },
28
+ "command.execute.before": async (input) => {
29
+ if (input.command !== "acp") return;
30
+ const sid = input.sessionID;
31
+ let text;
32
+ try {
33
+ const res = await fetch(`${proxyBase}/__bili/plugin/status?conversationId=${encodeURIComponent(sid)}&fallback=latest`);
34
+ const status = await res.json();
35
+ if (typeof status.panel === "string" && status.panel.length > 0) {
36
+ text = status.panel;
37
+ } else if (status.ok === false) {
38
+ text = "bili: no ACP session yet (send a model request first, then run /acp)";
39
+ } else {
40
+ text = "bili: proxy returned no status panel";
41
+ }
42
+ } catch (err) {
43
+ text = `bili: /acp failed (${err instanceof Error ? err.message : String(err)})`;
44
+ }
45
+ await showText(ctx, sid, text);
46
+ throw new Error("__BILI_ACP_HANDLED__");
47
+ }
48
+ };
49
+ };
50
+ var opencode_default = server;
51
+ export {
52
+ opencode_default as default
53
+ };
54
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/agent/opencode.ts"],"sourcesContent":["// Thin opencode plugin for the billion-context proxy (`bili opencode`).\n//\n// Activates ONLY when BILLION_CONTEXT_PROXY is set (the launcher sets it);\n// otherwise it is a no-op so shipping it inside the package is harmless.\n// Mirrors the pi/omp plugin (src/agent/pi.ts):\n// - registers the /acp command (config hook + command.execute.before)\n// - binds the opencode session id to the proxy session via the\n// pending-register queue (POST /__bili/plugin/register on session.created)\n// - renders the proxy's buildStatusPanel via an ignored chat message\n\ninterface OpencodeCommandConfig {\n template: string;\n description?: string;\n}\n\ninterface OpencodeConfig {\n command?: Record<string, OpencodeCommandConfig>;\n [key: string]: unknown;\n}\n\ninterface OpencodeSessionInfo {\n id?: unknown;\n}\n\ninterface OpencodeEvent {\n type?: string;\n properties?: { info?: OpencodeSessionInfo; [key: string]: unknown };\n}\n\ninterface OpencodeEventInput {\n event?: OpencodeEvent;\n}\n\ninterface OpencodeCommandInput {\n command: string;\n sessionID: string;\n arguments?: string;\n}\n\ninterface OpencodePromptPart {\n type: string;\n text: string;\n ignored?: boolean;\n}\n\ninterface OpencodeClient {\n session?: {\n prompt?: (args: {\n path: { id: string };\n body: { noReply: boolean; parts: OpencodePromptPart[] };\n }) => Promise<unknown>;\n };\n}\n\ninterface OpencodePluginContext {\n client?: OpencodeClient;\n}\n\ninterface OpencodeHooks {\n config?: (input: OpencodeConfig) => Promise<void>;\n event?: (input: OpencodeEventInput) => Promise<void>;\n \"command.execute.before\"?: (input: OpencodeCommandInput, output: { parts: unknown[] }) => Promise<void>;\n}\n\nconst proxyBase = process.env.BILLION_CONTEXT_PROXY ?? \"\";\n\nasync function showText(ctx: OpencodePluginContext, sid: string, text: string): Promise<void> {\n const prompt = ctx.client?.session?.prompt;\n if (typeof prompt !== \"function\") return;\n try {\n await prompt({\n path: { id: sid },\n body: { noReply: true, parts: [{ type: \"text\", text, ignored: true }] },\n });\n } catch {}\n}\n\nconst server = async (ctx: OpencodePluginContext): Promise<OpencodeHooks> => {\n if (!proxyBase) return {};\n console.log(\"[bili-opencode] plugin active (proxy \" + proxyBase + \")\");\n return {\n config: async (opencodeConfig) => {\n opencodeConfig.command ??= {};\n opencodeConfig.command[\"acp\"] = {\n template: \"\",\n description: \"Show ACP status (billion-context proxy)\",\n };\n },\n \"command.execute.before\": async (input) => {\n if (input.command !== \"acp\") return;\n const sid = input.sessionID;\n let text: string;\n try {\n const res = await fetch(`${proxyBase}/__bili/plugin/status?conversationId=${encodeURIComponent(sid)}&fallback=latest`);\n const status = (await res.json()) as { ok?: boolean; panel?: string; error?: string };\n if (typeof status.panel === \"string\" && status.panel.length > 0) {\n text = status.panel;\n } else if (status.ok === false) {\n text = \"bili: no ACP session yet (send a model request first, then run /acp)\";\n } else {\n text = \"bili: proxy returned no status panel\";\n }\n } catch (err) {\n text = `bili: /acp failed (${err instanceof Error ? err.message : String(err)})`;\n }\n await showText(ctx, sid, text);\n throw new Error(\"__BILI_ACP_HANDLED__\");\n },\n };\n};\n\nexport default server;\n"],"mappings":";;;;AAgEA,IAAM,YAAY,QAAQ,IAAI,yBAAyB;AAEvD,eAAe,SAAS,KAA4B,KAAa,MAA6B;AACtF,QAAM,SAAS,IAAI,QAAQ,SAAS;AACpC,MAAI,OAAO,WAAW,WAAY;AAClC,MAAI;AACA,UAAM,OAAO;AAAA,MACT,MAAM,EAAE,IAAI,IAAI;AAAA,MAChB,MAAM,EAAE,SAAS,MAAM,OAAO,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,IAC1E,CAAC;AAAA,EACL,QAAQ;AAAA,EAAC;AACjB;AAEA,IAAM,SAAS,OAAO,QAAuD;AACzE,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,UAAQ,IAAI,0CAA0C,YAAY,GAAG;AACrE,SAAO;AAAA,IACH,QAAQ,OAAO,mBAAmB;AAC9B,qBAAe,YAAY,CAAC;AAC5B,qBAAe,QAAQ,KAAK,IAAI;AAAA,QAC5B,UAAU;AAAA,QACV,aAAa;AAAA,MACjB;AAAA,IACJ;AAAA,IACA,0BAA0B,OAAO,UAAU;AACvC,UAAI,MAAM,YAAY,MAAO;AAC7B,YAAM,MAAM,MAAM;AAClB,UAAI;AACJ,UAAI;AACA,cAAM,MAAM,MAAM,MAAM,GAAG,SAAS,wCAAwC,mBAAmB,GAAG,CAAC,kBAAkB;AACrH,cAAM,SAAU,MAAM,IAAI,KAAK;AAC/B,YAAI,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,SAAS,GAAG;AAC7D,iBAAO,OAAO;AAAA,QAClB,WAAW,OAAO,OAAO,OAAO;AAC5B,iBAAO;AAAA,QACX,OAAO;AACH,iBAAO;AAAA,QACX;AAAA,MACJ,SAAS,KAAK;AACV,eAAO,sBAAsB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACjF;AACA,YAAM,SAAS,KAAK,KAAK,IAAI;AAC7B,YAAM,IAAI,MAAM,sBAAsB;AAAA,IAC1C;AAAA,EACJ;AACJ;AAEA,IAAO,mBAAQ;","names":[]}
package/dist/index.js CHANGED
@@ -51706,15 +51706,23 @@ function handlePluginManifest(res) {
51706
51706
  statusEndpoint: "/__bili/plugin/status"
51707
51707
  }));
51708
51708
  }
51709
- function handlePluginStatus(conversationId2, res) {
51710
- const entry = conversations.get(conversationId2);
51711
- const session = entry ? peekSession(entry.sessionId) : void 0;
51712
- if (!entry || !session) {
51709
+ function handlePluginStatus(conversationId2, res, fallbackLatest = false) {
51710
+ let entry = conversations.get(conversationId2);
51711
+ let session = entry ? peekSession(entry.sessionId) : void 0;
51712
+ let viaFallback = false;
51713
+ if ((!entry || !session) && fallbackLatest) {
51714
+ const latest = listSessions().filter((s3) => typeof s3.lastSeen === "number").sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
51715
+ if (latest) {
51716
+ session = latest;
51717
+ viaFallback = true;
51718
+ }
51719
+ }
51720
+ if (!session) {
51713
51721
  res.writeHead(404, { "content-type": "application/json" });
51714
51722
  res.end(JSON.stringify({ ok: false, error: "unknown plugin conversation" }));
51715
51723
  return;
51716
51724
  }
51717
- entry.lastSeen = Date.now();
51725
+ if (entry) entry.lastSeen = Date.now();
51718
51726
  const limit = session.metadata.effectiveContextLimit;
51719
51727
  const mem = remembered.get(session.id);
51720
51728
  const modelContextLimit = typeof limit === "number" && limit > 0 ? limit : 2e5;
@@ -51736,7 +51744,7 @@ function handlePluginStatus(conversationId2, res) {
51736
51744
  res.end(JSON.stringify({
51737
51745
  ok: true,
51738
51746
  conversationId: conversationId2,
51739
- sessionId: session.id,
51747
+ fallback: viaFallback || void 0,
51740
51748
  label: session.meta.label ?? null,
51741
51749
  pluginAgent: session.metadata.pluginAgent ?? null,
51742
51750
  contextLimit: typeof limit === "number" ? limit : null,
@@ -53519,13 +53527,14 @@ async function handle(req, res, opts, core, config, log2) {
53519
53527
  if (req.method === "GET" && req.url === "/__bili/plugin/manifest") return handlePluginManifest(res);
53520
53528
  if (req.method === "GET" && req.url?.startsWith("/__bili/plugin/status")) {
53521
53529
  const query = req.url.slice(req.url.indexOf("?") + 1);
53522
- const conversationId2 = new URLSearchParams(query).get("conversationId")?.trim() ?? "";
53530
+ const params = new URLSearchParams(query);
53531
+ const conversationId2 = params.get("conversationId")?.trim() ?? "";
53523
53532
  if (!conversationId2) {
53524
53533
  res.writeHead(400, { "content-type": "application/json" });
53525
53534
  res.end(JSON.stringify({ ok: false, error: "conversationId query parameter is required" }));
53526
53535
  return;
53527
53536
  }
53528
- return handlePluginStatus(conversationId2, res);
53537
+ return handlePluginStatus(conversationId2, res, params.get("fallback") === "latest");
53529
53538
  }
53530
53539
  if (req.method === "POST" && req.url === "/__bili/plugin/tool") {
53531
53540
  try {
@@ -58381,6 +58390,9 @@ import net2 from "net";
58381
58390
  import os5 from "os";
58382
58391
  import path13 from "path";
58383
58392
  import { spawn } from "child_process";
58393
+ function selfDistFile(name) {
58394
+ return path13.join(selfPackageRoot(), "dist", name);
58395
+ }
58384
58396
  var LAUNCHER_DEFAULT_HOST = "127.0.0.1";
58385
58397
  var LAUNCHER_DEFAULT_PORT = 8787;
58386
58398
  var LAUNCH_CLIENTS = ["pi", "codex", "claude", "omp", "opencode", "pi-test"];
@@ -58521,7 +58533,7 @@ function launcherInjectMcp(env, base) {
58521
58533
  return base !== "pi" && base !== "omp" && base !== "opencode" && env.BILI_LAUNCHER_PLUGIN === "1";
58522
58534
  }
58523
58535
  function buildMcpConfig(origin) {
58524
- const script = process.argv[1] ? path13.resolve(path13.dirname(process.argv[1]), "mcp.js") : "bili-mcp";
58536
+ const script = selfDistFile("mcp.js");
58525
58537
  return {
58526
58538
  mcpServers: {
58527
58539
  bili: {
@@ -58538,7 +58550,7 @@ function buildClaudePluginEnv(origin, directUrl, baseEnv) {
58538
58550
  return { ...baseEnv, ANTHROPIC_BASE_URL: wrapUpstream(origin, upstream) };
58539
58551
  }
58540
58552
  function buildCodexMcpArgs(origin, conversationId2) {
58541
- const script = process.argv[1] ? path13.resolve(path13.dirname(process.argv[1]), "mcp.js") : "bili-mcp";
58553
+ const script = selfDistFile("mcp.js");
58542
58554
  return [
58543
58555
  "-c",
58544
58556
  `mcp_servers.bili.command=${JSON.stringify(process.execPath)}`,
@@ -58656,22 +58668,17 @@ function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
58656
58668
  fs10.writeFileSync(path13.join(tmp, "models.yml"), lines.join("\n"));
58657
58669
  return tmp;
58658
58670
  }
58659
- function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewrites) {
58660
- if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
58661
- let txt;
58662
- try {
58663
- txt = fs10.readFileSync(configFile2, "utf8");
58664
- } catch {
58665
- return void 0;
58666
- }
58667
- let parsed;
58671
+ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewrites, pluginPath) {
58672
+ if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
58673
+ let root = {};
58668
58674
  try {
58669
- parsed = JSON.parse(txt);
58675
+ const txt = fs10.readFileSync(configFile2, "utf8");
58676
+ const parsed = JSON.parse(txt);
58677
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
58678
+ root = { ...parsed };
58679
+ }
58670
58680
  } catch {
58671
- return void 0;
58672
58681
  }
58673
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
58674
- const root = parsed;
58675
58682
  const provRoot = root.provider;
58676
58683
  if (provRoot && typeof provRoot === "object" && !Array.isArray(provRoot)) {
58677
58684
  const providers = provRoot;
@@ -58688,6 +58695,11 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
58688
58695
  rewrite(httpRewrites, true);
58689
58696
  rewrite(httpsRewrites, false);
58690
58697
  }
58698
+ if (pluginPath) {
58699
+ const plugins = Array.isArray(root.plugin) ? root.plugin.filter((p2) => typeof p2 === "string") : [];
58700
+ if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
58701
+ root.plugin = plugins;
58702
+ }
58691
58703
  const tmp = fs10.mkdtempSync(path13.join(os5.tmpdir(), "bili-opencode-"));
58692
58704
  const tmpFile = path13.join(tmp, "opencode.json");
58693
58705
  fs10.writeFileSync(tmpFile, JSON.stringify(root));
@@ -58926,7 +58938,9 @@ async function runLaunch(params, deps = {}) {
58926
58938
  if (ompTmpHome) env.PI_CODING_AGENT_DIR = ompTmpHome;
58927
58939
  } else if (base === "opencode") {
58928
58940
  env = { ...process.env, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: ca, BILLION_CONTEXT_PROXY: origin };
58929
- opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites);
58941
+ const opencodePlugin = selfDistFile("agent/opencode.js");
58942
+ const opencodePluginPath = opencodePlugin && fs10.existsSync(opencodePlugin) ? opencodePlugin : void 0;
58943
+ opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
58930
58944
  if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
58931
58945
  } else if (base === "codex") {
58932
58946
  const codexConversationId = injectMcp ? randomUUID2() : void 0;