billion-context-pi 0.1.59 → 0.1.60-pr.334.130

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/config.d.ts CHANGED
@@ -206,6 +206,12 @@ export interface AdapterConfig {
206
206
  * disables) or a ThrottleRetryConfig object. Default: enabled, 10 retries,
207
207
  * 60s exponential base capped at 300s per kick. */
208
208
  throttleRetry?: boolean | ThrottleRetryConfig;
209
+ /** Cap on the output-headroom reservation as a fraction of the context
210
+ * window: reserved = min(model.maxTokens, pct * window). Accepts a ratio
211
+ * (0.25) or percent string ("25%"). Default: 0.25. Set 0 to disable the
212
+ * reservation entirely; >= 1 restores the legacy full-capability
213
+ * reservation (issue #207). */
214
+ outputHeadroomMaxPct?: number | string;
209
215
  /** Generic tool-call repetition guard (see RepetitionGuardConfig). Accepts a
210
216
  * boolean shorthand (`false` disables) or an object. Default: enabled,
211
217
  * warn=3, abort=5. Stops greedy small models looping on byte-identical
package/dist/index.js CHANGED
@@ -4192,10 +4192,10 @@ var SessionStateStore = class {
4192
4192
  }
4193
4193
  async save(state, sessionFile, sessionId) {
4194
4194
  const file = stateFileFor(sessionFile);
4195
- if (!file) return;
4196
4195
  const key = cacheKey(sessionFile, sessionId);
4197
4196
  const liveRefOrigins = this.cache.get(key)?.liveRefOrigins ?? [];
4198
4197
  this.cache.set(key, { state, liveRefOrigins });
4198
+ if (!file) return;
4199
4199
  const dir = path2.dirname(file);
4200
4200
  await fs.mkdir(dir, { recursive: true }).catch((e) => {
4201
4201
  logError("state", { event: "save-mkdir-failed", dir, error: e instanceof Error ? e.message : String(e) });
@@ -4462,6 +4462,7 @@ var KNOWN = /* @__PURE__ */ new Set([
4462
4462
  "compress",
4463
4463
  "displayUsage",
4464
4464
  "throttleRetry",
4465
+ "outputHeadroomMaxPct",
4465
4466
  "prompts",
4466
4467
  "acknowledgePromptsRisk"
4467
4468
  ]);
@@ -4699,19 +4700,25 @@ function toTokenNumber(raw) {
4699
4700
  const n = Number(raw.replace(/,/g, ""));
4700
4701
  return Number.isFinite(n) && n >= 1e3 ? n : void 0;
4701
4702
  }
4702
- function reserveOutputHeadroom(window, maxOutput) {
4703
+ var DEFAULT_OUTPUT_HEADROOM_MAX_PCT = 0.25;
4704
+ function resolveOutputHeadroomCap(value) {
4705
+ return value === void 0 ? DEFAULT_OUTPUT_HEADROOM_MAX_PCT : parsePercent(value);
4706
+ }
4707
+ function reserveOutputHeadroom(window, maxOutput, capPct = 1) {
4703
4708
  if (Number.isFinite(window) && window > 0 && Number.isFinite(maxOutput) && maxOutput > 0 && maxOutput < window) {
4704
- return window - maxOutput;
4709
+ const cap = Number.isFinite(capPct) ? Math.max(0, Math.min(capPct, 1)) : 1;
4710
+ const reserved = Math.min(maxOutput, cap * window);
4711
+ return reserved > 0 ? window - reserved : window;
4705
4712
  }
4706
4713
  return window;
4707
4714
  }
4708
4715
  function shouldReserveOutputHeadroom(api) {
4709
4716
  return api !== "anthropic-messages";
4710
4717
  }
4711
- function applyOutputHeadroom(config, model) {
4718
+ function applyOutputHeadroom(config, model, capPct = 1) {
4712
4719
  const maxOutput = model?.maxTokens ?? 0;
4713
4720
  if (shouldReserveOutputHeadroom(model?.api)) {
4714
- const reserved = reserveOutputHeadroom(config.modelContextLimit, maxOutput);
4721
+ const reserved = reserveOutputHeadroom(config.modelContextLimit, maxOutput, capPct);
4715
4722
  if (reserved !== config.modelContextLimit) return { ...config, modelContextLimit: reserved };
4716
4723
  }
4717
4724
  return config;
@@ -12025,7 +12032,7 @@ function makeStatusTool(runtime) {
12025
12032
  }
12026
12033
  async function handleStatus(args, runtime, ctx) {
12027
12034
  const { state, coreMessages, entries } = await runtime.stateFor(ctx);
12028
- const config = applyOutputHeadroom(runtime.configFor(ctx), ctx.model);
12035
+ const config = applyOutputHeadroom(runtime.configFor(ctx), ctx.model, resolveOutputHeadroomCap(runtime.adapter.outputHeadroomMaxPct));
12029
12036
  const coveredIds = collectCoveredMessageIds(state);
12030
12037
  const systemPromptText = getSystemPromptText(ctx);
12031
12038
  const systemPromptTokens = systemPromptText ? defaultCountTokens(systemPromptText) : 0;
@@ -16521,7 +16528,7 @@ ${text}`);
16521
16528
  }
16522
16529
  async function statusReport(runtime, ctx) {
16523
16530
  const { state, coreMessages, entries } = await runtime.stateFor(ctx);
16524
- const config = applyOutputHeadroom(runtime.configFor(ctx), ctx.model);
16531
+ const config = applyOutputHeadroom(runtime.configFor(ctx), ctx.model, resolveOutputHeadroomCap(runtime.adapter.outputHeadroomMaxPct));
16525
16532
  const realUsage = ctx.getContextUsage?.();
16526
16533
  const anchorStale = usageAnchorPredatesCompression(entries ?? []);
16527
16534
  const systemPromptText = getSystemPromptText(ctx);
@@ -16533,7 +16540,7 @@ async function statusReport(runtime, ctx) {
16533
16540
  const sentTokens = estimateTokens(coreMessages, coveredIds, imageTokens) + systemPromptTokens;
16534
16541
  const viewSentTokens = adjustedTokenCount(runtime.core, coreMessages, state, config, sentTokens, imageTokens, systemPromptTokens);
16535
16542
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: anchorStale ? viewSentTokens : Math.max(viewSentTokens, realUsage?.tokens ?? 0) });
16536
- const versionStr = "0.1.59" ? `billion-context-pi@${"0.1.59"}` : void 0;
16543
+ const versionStr = "0.1.60" ? `billion-context-pi@${"0.1.60"}` : void 0;
16537
16544
  let text = buildStatusPanel({
16538
16545
  version: versionStr,
16539
16546
  tokenCount: sessionTokens,
@@ -17067,7 +17074,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17067
17074
  "--no-fund",
17068
17075
  "--no-save"
17069
17076
  ];
17070
- const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.59";
17077
+ const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.60";
17071
17078
  const { code, stderr } = await runNpmImpl(installArgs(latest), { cwd: npmDir, timeout: 6e4 });
17072
17079
  if (code !== 0) {
17073
17080
  logWarn("update", {
@@ -17085,7 +17092,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17085
17092
  }
17086
17093
  const verify = await verifyInstall(npmDir, latest);
17087
17094
  if (!verify.ok) {
17088
- const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.59";
17095
+ const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.60";
17089
17096
  logWarn("update", { event: "auto-install-verify-failed", latest, reason: verify.reason, rollbackTo });
17090
17097
  const rb = await runNpmImpl(installArgs(rollbackTo), { cwd: npmDir, timeout: 6e4 });
17091
17098
  logInfo("update", { event: "rollback", from: latest, to: rollbackTo, ok: rb.code === 0 });
@@ -17160,7 +17167,7 @@ async function checkForUpdate(autoUpdate, notify) {
17160
17167
  }
17161
17168
  const latest = await fetchLatestVersion(tag);
17162
17169
  if (!latest) return;
17163
- const current = runtimeVersion ?? "0.1.59";
17170
+ const current = runtimeVersion ?? "0.1.60";
17164
17171
  const hasUpdate = isVersionNewer(latest, current);
17165
17172
  debug.event("update-check", {
17166
17173
  current,
@@ -17338,7 +17345,7 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
17338
17345
  setDelegatePolicy(DEFAULT_DELEGATE_POLICY);
17339
17346
  const sid = ctx.sessionManager.getSessionId();
17340
17347
  const modelInfo = ctx.model;
17341
- logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.59" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
17348
+ logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.60" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
17342
17349
  try {
17343
17350
  await runtime.reloadConfig(ctx.cwd);
17344
17351
  const delegateCfg = resolveDelegate(runtime.adapter);
@@ -17399,10 +17406,11 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
17399
17406
  config = { ...config, modelContextLimit: learnedWindow };
17400
17407
  logInfo("overflow-selfheal", { sid, modelId, event: "window-recenter", resolved: configBase.modelContextLimit, learned: learnedWindow });
17401
17408
  }
17402
- const beforeHeadroom = config.modelContextLimit;
17403
- config = applyOutputHeadroom(config, ctx.model);
17404
- if (config.modelContextLimit !== beforeHeadroom) {
17405
- logInfo("overflow-selfheal", { sid, event: "output-headroom", before: beforeHeadroom, after: config.modelContextLimit, maxOutput: ctx.model?.maxTokens ?? 0 });
17409
+ const headroomCap = resolveOutputHeadroomCap(runtime.adapter.outputHeadroomMaxPct);
17410
+ const fullWindow = config.modelContextLimit;
17411
+ config = applyOutputHeadroom(config, ctx.model, headroomCap);
17412
+ if (config.modelContextLimit !== fullWindow) {
17413
+ logInfo("overflow-selfheal", { sid, event: "output-headroom", before: fullWindow, after: config.modelContextLimit, maxOutput: ctx.model?.maxTokens ?? 0, cap: headroomCap });
17406
17414
  }
17407
17415
  const coveredIds = collectCoveredMessageIds(state);
17408
17416
  const realUsage = ctx.getContextUsage?.();
@@ -17456,6 +17464,7 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
17456
17464
  tokens: tokenCount,
17457
17465
  pct: config.modelContextLimit > 0 ? Number((tokenCount / config.modelContextLimit * 100).toFixed(2)) : null,
17458
17466
  limit: config.modelContextLimit,
17467
+ ...fullWindow !== config.modelContextLimit ? { fullWindow } : {},
17459
17468
  nudge: turn.nudge?.shouldInject ? turn.nudge.breakdown?.emergencyOverride === 1 ? "emergency" : "active" : "idle",
17460
17469
  nudgeReason: turn.nudge?.reason ?? null,
17461
17470
  blocks: turn.state.blocks.length,