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

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 {
@@ -58656,22 +58665,17 @@ function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
58656
58665
  fs10.writeFileSync(path13.join(tmp, "models.yml"), lines.join("\n"));
58657
58666
  return tmp;
58658
58667
  }
58659
- function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewrites) {
58660
- if (httpRewrites.length === 0 && httpsRewrites.length === 0) return void 0;
58661
- let txt;
58668
+ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewrites, pluginPath) {
58669
+ if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
58670
+ let root = {};
58662
58671
  try {
58663
- txt = fs10.readFileSync(configFile2, "utf8");
58664
- } catch {
58665
- return void 0;
58666
- }
58667
- let parsed;
58668
- try {
58669
- parsed = JSON.parse(txt);
58672
+ const txt = fs10.readFileSync(configFile2, "utf8");
58673
+ const parsed = JSON.parse(txt);
58674
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
58675
+ root = { ...parsed };
58676
+ }
58670
58677
  } catch {
58671
- return void 0;
58672
58678
  }
58673
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
58674
- const root = parsed;
58675
58679
  const provRoot = root.provider;
58676
58680
  if (provRoot && typeof provRoot === "object" && !Array.isArray(provRoot)) {
58677
58681
  const providers = provRoot;
@@ -58688,6 +58692,11 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
58688
58692
  rewrite(httpRewrites, true);
58689
58693
  rewrite(httpsRewrites, false);
58690
58694
  }
58695
+ if (pluginPath) {
58696
+ const plugins = Array.isArray(root.plugin) ? root.plugin.filter((p2) => typeof p2 === "string") : [];
58697
+ if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
58698
+ root.plugin = plugins;
58699
+ }
58691
58700
  const tmp = fs10.mkdtempSync(path13.join(os5.tmpdir(), "bili-opencode-"));
58692
58701
  const tmpFile = path13.join(tmp, "opencode.json");
58693
58702
  fs10.writeFileSync(tmpFile, JSON.stringify(root));
@@ -58926,7 +58935,9 @@ async function runLaunch(params, deps = {}) {
58926
58935
  if (ompTmpHome) env.PI_CODING_AGENT_DIR = ompTmpHome;
58927
58936
  } else if (base === "opencode") {
58928
58937
  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);
58938
+ const opencodePlugin = process.argv[1] ? path13.resolve(path13.dirname(process.argv[1]), "agent", "opencode.js") : void 0;
58939
+ const opencodePluginPath = opencodePlugin && fs10.existsSync(opencodePlugin) ? opencodePlugin : void 0;
58940
+ opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
58930
58941
  if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
58931
58942
  } else if (base === "codex") {
58932
58943
  const codexConversationId = injectMcp ? randomUUID2() : void 0;