@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.
|
|
12
|
+
- targets modern Pi tool/rendering APIs and is aligned with Pi `0.70.x`
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@howaboua/pi-codex-conversion",
|
|
3
|
-
"version": "1.0.
|
|
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.
|
|
55
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
56
|
-
"@mariozechner/pi-tui": "^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.
|
|
61
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
62
|
-
"@mariozechner/pi-tui": "^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
|
-
|
|
531
|
-
|
|
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 (!
|
|
904
|
-
|
|
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
|
-
|
|
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;
|