@howaboua/pi-codex-conversion 1.0.21 → 1.0.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.
package/README.md CHANGED
@@ -9,7 +9,7 @@ This package replaces Pi's default Codex/GPT experience with a narrower Codex-li
9
9
  - preserves Pi's composed system prompt and applies a narrow Codex-oriented delta on top
10
10
  - renders exec activity with Codex-style command and background-terminal labels
11
11
  - renders `apply_patch` calls with Codex-style `Added` / `Edited` / `Deleted` diff blocks and Pi-style colored diff lines
12
- - targets modern Pi tool/rendering APIs and is aligned with Pi `0.69.x`
12
+ - targets modern Pi tool/rendering APIs and is aligned with Pi `0.70.x`
13
13
 
14
14
  ![Available tools](./available-tools.png)
15
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howaboua/pi-codex-conversion",
3
- "version": "1.0.21",
3
+ "version": "1.0.24",
4
4
  "description": "Codex-oriented tool and prompt adapter for pi coding agent",
5
5
  "type": "module",
6
6
  "repository": {
@@ -51,15 +51,15 @@
51
51
  "access": "public"
52
52
  },
53
53
  "peerDependencies": {
54
- "@mariozechner/pi-ai": "^0.69.0",
55
- "@mariozechner/pi-coding-agent": "^0.69.0",
56
- "@mariozechner/pi-tui": "^0.69.0",
54
+ "@mariozechner/pi-ai": "^0.70.0",
55
+ "@mariozechner/pi-coding-agent": "^0.70.0",
56
+ "@mariozechner/pi-tui": "^0.70.0",
57
57
  "typebox": "^1.1.24"
58
58
  },
59
59
  "devDependencies": {
60
- "@mariozechner/pi-ai": "^0.69.0",
61
- "@mariozechner/pi-coding-agent": "^0.69.0",
62
- "@mariozechner/pi-tui": "^0.69.0",
60
+ "@mariozechner/pi-ai": "^0.70.0",
61
+ "@mariozechner/pi-coding-agent": "^0.70.0",
62
+ "@mariozechner/pi-tui": "^0.70.0",
63
63
  "tsx": "^4.20.5",
64
64
  "typebox": "^1.1.24",
65
65
  "typescript": "^5.9.3"
@@ -118,7 +118,6 @@ interface ResponsesBody {
118
118
  input: unknown;
119
119
  text: { verbosity: string };
120
120
  include: string[];
121
- max_output_tokens?: number;
122
121
  prompt_cache_key?: string;
123
122
  tool_choice: "auto";
124
123
  parallel_tool_calls: boolean;
@@ -481,19 +480,19 @@ function clampReasoningEffort(modelId: string, effort: string): string {
481
480
  return effort;
482
481
  }
483
482
 
484
- function getServiceTierCostMultiplier(serviceTier: ServiceTier): number {
483
+ function getServiceTierCostMultiplier(model: Model<Api>, serviceTier: ServiceTier): number {
485
484
  switch (serviceTier) {
486
485
  case "flex":
487
486
  return 0.5;
488
487
  case "priority":
489
- return 2;
488
+ return model.id === "gpt-5.5" ? 2.5 : 2;
490
489
  default:
491
490
  return 1;
492
491
  }
493
492
  }
494
493
 
495
- function applyServiceTierPricing(usage: AssistantMessage["usage"], serviceTier: ServiceTier): void {
496
- const multiplier = getServiceTierCostMultiplier(serviceTier);
494
+ function applyServiceTierPricing(usage: AssistantMessage["usage"], serviceTier: ServiceTier, model: Model<Api>): void {
495
+ const multiplier = getServiceTierCostMultiplier(model, serviceTier);
497
496
  if (multiplier === 1) return;
498
497
  usage.cost.input *= multiplier;
499
498
  usage.cost.output *= multiplier;
@@ -527,9 +526,10 @@ function buildRequestBody<TApi extends Api>(model: Model<TApi>, context: Context
527
526
  parallel_tool_calls: true,
528
527
  };
529
528
 
530
- if (options?.maxTokens !== undefined) {
531
- body.max_output_tokens = options.maxTokens;
532
- }
529
+ // The Codex ChatGPT-backed endpoint rejects output-token cap fields with
530
+ // `Unsupported parameter: max_output_tokens`. Pi's branch summarizer passes
531
+ // `maxTokens`, so forwarding it breaks `/tree` summaries and extensions that
532
+ // use `ctx.navigateTree(..., { summarize: true })`.
533
533
 
534
534
  if ((options as { temperature?: number } | undefined)?.temperature !== undefined) {
535
535
  body.temperature = (options as { temperature?: number }).temperature;
@@ -848,6 +848,7 @@ async function* parseWebSocket(socket: WebSocketLike, signal: AbortSignal | unde
848
848
  let pending: (() => void) | null = null;
849
849
  let done = false;
850
850
  let failed: Error | null = null;
851
+ let closeError: Error | null = null;
851
852
  let sawCompletion = false;
852
853
  let pendingMessages = 0;
853
854
  let messageChain = Promise.resolve();
@@ -871,6 +872,7 @@ async function* parseWebSocket(socket: WebSocketLike, signal: AbortSignal | unde
871
872
  const type = typeof parsed.type === "string" ? parsed.type : "";
872
873
  if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
873
874
  sawCompletion = true;
875
+ closeError = null;
874
876
  done = true;
875
877
  }
876
878
  queue.push(parsed);
@@ -900,8 +902,8 @@ async function* parseWebSocket(socket: WebSocketLike, signal: AbortSignal | unde
900
902
  wake();
901
903
  return;
902
904
  }
903
- if (!failed) {
904
- failed = extractWebSocketCloseError(event);
905
+ if (!closeError) {
906
+ closeError = extractWebSocketCloseError(event);
905
907
  }
906
908
  done = true;
907
909
  wake();
@@ -934,6 +936,7 @@ async function* parseWebSocket(socket: WebSocketLike, signal: AbortSignal | unde
934
936
  }
935
937
 
936
938
  if (failed) throw failed;
939
+ if (closeError && !sawCompletion) throw closeError;
937
940
  if (!sawCompletion) {
938
941
  throw new Error("WebSocket stream closed before response.completed");
939
942
  }
@@ -1077,7 +1080,7 @@ async function processCapturedResponsesStream<TApi extends Api>(
1077
1080
  await processResponsesStream(tappedEvents as AsyncIterable<never>, output, stream, model, {
1078
1081
  serviceTier: (options as { serviceTier?: ServiceTier } | undefined)?.serviceTier,
1079
1082
  resolveServiceTier: resolveCodexServiceTier,
1080
- applyServiceTierPricing,
1083
+ applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model as Model<Api>),
1081
1084
  });
1082
1085
  }
1083
1086
 
@@ -613,7 +613,8 @@ export async function processResponsesStream<TApi extends Api>(
613
613
  output.stopReason = "toolUse";
614
614
  }
615
615
  } else if (event.type === "error") {
616
- throw new Error(`Error Code ${event.code}: ${event.message}` || "Unknown error");
616
+ const details = [event.code, event.message].filter(Boolean).join(": ");
617
+ throw new Error(details || "Unknown error");
617
618
  } else if (event.type === "response.failed") {
618
619
  const error = event.response?.error;
619
620
  const details = (event.response as { incomplete_details?: { reason?: string } } | undefined)?.incomplete_details;