betahi-copilot-bridge 0.20.9 → 0.20.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  <h1 align="center">copilot-bridge</h1>
2
2
 
3
3
  <p align="center">
4
- <a href="https://www.npmjs.com/package/betahi-copilot-bridge"><img src="https://img.shields.io/npm/v/betahi-copilot-bridge.svg?v=0.20.8" alt="npm version"></a>
4
+ <a href="https://www.npmjs.com/package/betahi-copilot-bridge"><img src="https://img.shields.io/npm/v/betahi-copilot-bridge.svg?v=0.20.10" alt="npm version"></a>
5
5
  <a href="https://github.com/betahi/copilot-bridge/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/betahi-copilot-bridge.svg" alt="license"></a>
6
6
  </p>
7
7
 
@@ -97,6 +97,12 @@ requires_openai_auth = false
97
97
  Use `--no-codex-setup` to skip this writer if you manage
98
98
  `~/.codex/config.toml` yourself.
99
99
 
100
+ The managed config also keeps Codex CLI's `/status` context-window display in
101
+ sync with Copilot model metadata. For example, GPT-5.5 shows a 1.05M context
102
+ window through the bridge:
103
+
104
+ ![Codex context window](assets/screenshots/codex_2.png)
105
+
100
106
  ### Codex warning: "Model metadata ... not found"
101
107
 
102
108
  This is a Codex client-side metadata warning, not a bridge routing failure, requests can still complete through the bridge.
package/dist/main.js CHANGED
@@ -470,6 +470,12 @@ const BEGIN_MARK = "# >>> copilot-bridge managed block — auto-generated, do no
470
470
  const END_MARK = "# <<< copilot-bridge managed block — edits outside this block are preserved <<<";
471
471
  const LEGACY_BEGIN_MARK = "# >>> copilot-bridge managed (do not edit) >>>";
472
472
  const LEGACY_END_MARK = "# <<< copilot-bridge managed (do not edit) <<<";
473
+ const MANAGED_MARKERS = new Set([
474
+ BEGIN_MARK,
475
+ END_MARK,
476
+ LEGACY_BEGIN_MARK,
477
+ LEGACY_END_MARK
478
+ ]);
473
479
  function normalizeCodexConfigReasoningEffort(value) {
474
480
  switch (value?.toLowerCase()) {
475
481
  case "none":
@@ -528,6 +534,24 @@ function stripManagedBlock(content) {
528
534
  }
529
535
  return next;
530
536
  }
537
+ function removeStrayManagedMarkerLines(content) {
538
+ return content.split("\n").filter((line) => !MANAGED_MARKERS.has(line.trim())).join("\n");
539
+ }
540
+ function removeManagedProviderTables(content, providerId) {
541
+ const lines = content.split("\n");
542
+ const out = [];
543
+ const tableHeader = `[model_providers.${providerId}]`;
544
+ for (let i = 0; i < lines.length;) {
545
+ if (lines[i].trim() === tableHeader) {
546
+ i += 1;
547
+ while (i < lines.length && !/^\s*\[/.test(lines[i])) i += 1;
548
+ continue;
549
+ }
550
+ out.push(lines[i]);
551
+ i += 1;
552
+ }
553
+ return out.join("\n").replace(/\n{3,}/g, "\n\n");
554
+ }
531
555
  function splitTopSection(content) {
532
556
  const lines = content.split("\n");
533
557
  let cut = lines.length;
@@ -570,13 +594,16 @@ function normalizeModelContextWindow(value) {
570
594
  const normalized = Math.trunc(value);
571
595
  return normalized > 0 ? normalized : void 0;
572
596
  }
573
- function removeTopLevelContextWindowWhenManaged(content, input) {
574
- if (normalizeModelContextWindow(input.modelContextWindow) === void 0) return content;
597
+ function removeManagedTopLevelKeys(content, input) {
575
598
  const { top, rest } = splitTopSection(content);
576
- const nextTop = removeTopKey(top, "model_context_window");
599
+ let nextTop = top;
600
+ if (input.settings.setAsDefault) nextTop = removeTopKey(nextTop, "model_provider");
601
+ if (normalizeModelContextWindow(input.modelContextWindow) !== void 0) nextTop = removeTopKey(nextTop, "model_context_window");
602
+ nextTop = removeTopKey(nextTop, "model_supports_reasoning_summaries");
577
603
  if (nextTop === top) return content;
578
604
  if (rest.length === 0) return nextTop.endsWith("\n") ? nextTop : `${nextTop}\n`;
579
- return `${nextTop}${nextTop.endsWith("\n") ? "" : "\n"}${rest}`;
605
+ const sep = nextTop.endsWith("\n") ? "" : "\n";
606
+ return `${nextTop}${sep}${rest}`;
580
607
  }
581
608
  function sanitizeTopReasoningEffort(topSection) {
582
609
  const match = topSection.match(scalarRegex("model_reasoning_effort"));
@@ -607,8 +634,10 @@ async function applyCodexConfig(input) {
607
634
  created = true;
608
635
  }
609
636
  let stripped = stripManagedBlock(existing);
637
+ stripped = removeStrayManagedMarkerLines(stripped);
638
+ stripped = removeManagedProviderTables(stripped, input.settings.providerId);
610
639
  stripped = applyUserScalars(stripped, input);
611
- stripped = removeTopLevelContextWindowWhenManaged(stripped, input);
640
+ stripped = removeManagedTopLevelKeys(stripped, input);
612
641
  const block = buildManagedBlock(input);
613
642
  const { top, rest } = splitTopSection(stripped);
614
643
  const next = `${[