billion-context 0.1.6 → 0.1.8

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 CHANGED
@@ -41,7 +41,8 @@ function defaultLogFile() {
41
41
  // src/config.ts
42
42
  function safeReadJson(path6) {
43
43
  try {
44
- return JSON.parse(readFileSync(path6, "utf8"));
44
+ const raw = readFileSync(path6, "utf8").replace(/^\uFEFF/, "");
45
+ return JSON.parse(raw);
45
46
  } catch (e) {
46
47
  if (e.code !== "ENOENT") {
47
48
  console.error(`[acp-config] failed to parse ${path6}: ${String(e)}`);
@@ -148,6 +149,7 @@ function parseRouteEntry(v) {
148
149
  // src/server.ts
149
150
  import http from "http";
150
151
  import fs2 from "fs";
152
+ import { tmpdir as tmpdir2 } from "os";
151
153
  import { createCore, estimateTokensFast as estimateTokensFast3, renderNudgeText, deactivateBlock as deactivateBlock4 } from "acp-kernel";
152
154
 
153
155
  // src/fetch-util.ts
@@ -837,8 +839,18 @@ var SessionStore = class {
837
839
  }
838
840
  const tmp = this.tempPath(session.id);
839
841
  const data = JSON.stringify(record);
840
- await fs.writeFile(tmp, data, "utf8");
841
- await fs.rename(tmp, file);
842
+ try {
843
+ await fs.writeFile(tmp, data, "utf8");
844
+ await fs.rename(tmp, file);
845
+ } catch (e) {
846
+ try {
847
+ await fs.unlink(tmp).catch(() => {
848
+ });
849
+ } catch {
850
+ }
851
+ this.log("error", `[persist] write failed for ${session.id}: ${msg(e)}`);
852
+ throw e;
853
+ }
842
854
  }
843
855
  /** Synchronous flush for a single session. Used on memory eviction so a
844
856
  * dirty evicted session is not lost. Sync because eviction runs in the
@@ -2624,6 +2636,22 @@ async function startServer(opts) {
2624
2636
  `acp-proxy listening on http://${opts.host}:${opts.port}` + (Object.keys(opts.routes).length ? ` \u2014 routes: ${Object.entries(opts.routes).map(([n, u]) => `${n}=${typeof u === "string" ? u : u.url}`).join(", ")}` : ` \u2192 ${opts.upstream}`)
2625
2637
  );
2626
2638
  });
2639
+ server.on("error", (err) => {
2640
+ const hint = err.code === "EADDRINUSE" ? ` \u2014 port ${opts.port} is already in use. Stop the other process or use --port <N>.` : err.code === "EACCES" ? ` \u2014 port ${opts.port} requires privileges. Use a port >= 1024.` : "";
2641
+ log2("error", `listen failed: ${err.code ?? ""} ${err.message}${hint}`);
2642
+ shuttingDown = true;
2643
+ server.close();
2644
+ void flushAllSessions().finally(() => {
2645
+ closeLogger();
2646
+ process.exit(1);
2647
+ });
2648
+ });
2649
+ process.on("uncaughtException", (err) => {
2650
+ log2("error", `uncaughtException: ${String(err?.stack ?? err)}`);
2651
+ });
2652
+ process.on("unhandledRejection", (reason) => {
2653
+ log2("error", `unhandledRejection: ${String(reason)}`);
2654
+ });
2627
2655
  let shuttingDown = false;
2628
2656
  const shutdown = (sig) => {
2629
2657
  if (shuttingDown) return;
@@ -2637,6 +2665,9 @@ async function startServer(opts) {
2637
2665
  };
2638
2666
  process.on("SIGTERM", () => shutdown("SIGTERM"));
2639
2667
  process.on("SIGINT", () => shutdown("SIGINT"));
2668
+ if (process.platform === "win32") {
2669
+ process.on("SIGBREAK", () => shutdown("SIGBREAK"));
2670
+ }
2640
2671
  return server;
2641
2672
  }
2642
2673
  async function handle(req, res, opts, core, config, log2) {
@@ -2940,7 +2971,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
2940
2971
  });
2941
2972
  log2("info", `[debug] tools=[${toolNames.join(",")}] msgs=${parsed.messages?.length ?? 0} stream=${parsed.stream ?? false} system_len=${JSON.stringify(parsed.messages?.find((m) => m.role === "system")?.content ?? "").length}`);
2942
2973
  if (process.env.ACP_DUMP_REQ === "1") {
2943
- const out = `/tmp/acp-proxy-debug-req-${Date.now()}.json`;
2974
+ const out = `${tmpdir2()}/acp-proxy-debug-req-${Date.now()}.json`;
2944
2975
  fs2.writeFileSync(out, body.slice(0, 5e4));
2945
2976
  log2("info", `[debug] forwarded body written to ${out}`);
2946
2977
  }
@@ -3221,31 +3252,46 @@ async function checkForUpdate(opts, force = false) {
3221
3252
  inFlight = true;
3222
3253
  try {
3223
3254
  const now = Date.now();
3224
- if (!force && now - await readLastCheck() < CHECK_INTERVAL_MS) return;
3255
+ const lastCheck = await readLastCheck();
3256
+ if (!force && now - lastCheck < CHECK_INTERVAL_MS) {
3257
+ log("info", `[update] check skipped (throttled, ${(CHECK_INTERVAL_MS - (now - lastCheck)) / 1e3 | 0}s until next)`);
3258
+ return;
3259
+ }
3225
3260
  await writeLastCheck(now);
3261
+ log("info", `[update] checking npm registry for ${opts.packageName}\u2026`);
3226
3262
  const url = `${REGISTRY_BASE}/${opts.packageName}/latest`;
3227
3263
  const res = await fetch(url, {
3228
3264
  signal: AbortSignal.timeout(5e3),
3229
3265
  headers: { Accept: "application/json" }
3230
3266
  });
3231
- if (!res.ok) return;
3267
+ if (!res.ok) {
3268
+ log("warn", `[update] registry returned ${res.status} ${res.statusText}, skipping`);
3269
+ return;
3270
+ }
3232
3271
  const data = await res.json();
3233
3272
  const latest = data.version;
3234
- if (!latest || !isNewer(latest, opts.currentVersion)) return;
3235
- if (notified.has(latest)) return;
3273
+ if (!latest) {
3274
+ log("warn", `[update] registry response had no version, skipping`);
3275
+ return;
3276
+ }
3277
+ if (!isNewer(latest, opts.currentVersion)) {
3278
+ log("info", `[update] current=${opts.currentVersion} latest=${latest} (up to date)`);
3279
+ return;
3280
+ }
3281
+ if (notified.has(latest)) {
3282
+ log("info", `[update] latest=${latest} already installed this run, awaiting restart`);
3283
+ return;
3284
+ }
3285
+ log("info", `[update] new version found: ${opts.currentVersion} \u2192 ${latest}, installing\u2026`);
3236
3286
  const installed = await installLatest(opts.packageName, latest);
3287
+ notified.add(latest);
3237
3288
  if (installed) {
3238
- notified.add(latest);
3239
- console.error(
3240
- `\x1B[32m\u2714 ${opts.packageName} auto-updated ${opts.currentVersion} \u2192 ${latest}. Restart bili to finish.\x1B[0m`
3241
- );
3289
+ log("info", `[update] installed ${opts.packageName} ${opts.currentVersion} \u2192 ${latest}. Restart to finish.`);
3242
3290
  } else {
3243
- notified.add(latest);
3244
- console.error(
3245
- `\x1B[33m${opts.packageName} ${latest} is available (you have ${opts.currentVersion}). Update with: npm install -g ${opts.packageName}@latest\x1B[0m`
3246
- );
3291
+ log("warn", `[update] install failed; run manually: npm install -g ${opts.packageName}@${latest}`);
3247
3292
  }
3248
- } catch {
3293
+ } catch (e) {
3294
+ log("warn", `[update] check failed: ${String(e)}`);
3249
3295
  } finally {
3250
3296
  inFlight = false;
3251
3297
  }
@@ -3267,6 +3313,7 @@ async function installLatest(packageName, latest) {
3267
3313
  }
3268
3314
  }
3269
3315
  function startAutoUpdate(opts) {
3316
+ log("info", `[update] auto-update enabled (checking every ${CHECK_INTERVAL_MS / 1e3 | 0}s)`);
3270
3317
  setTimeout(() => {
3271
3318
  void checkForUpdate(opts);
3272
3319
  }, 1e4);