@howaboua/pi-codex-conversion 1.0.19 → 1.0.21
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 +11 -5
- package/package.json +10 -6
- package/src/adapter/tool-set.ts +1 -0
- package/src/index.ts +39 -8
- package/src/prompt/build-system-prompt.ts +1 -0
- package/src/providers/openai-codex-custom-provider.ts +1551 -0
- package/src/providers/openai-responses-shared.ts +646 -0
- package/src/tools/apply-patch-tool.ts +1 -1
- package/src/tools/exec-command-tool.ts +1 -1
- package/src/tools/image-generation-tool.ts +112 -0
- package/src/tools/view-image-tool.ts +1 -1
- package/src/tools/web-search-tool.ts +2 -2
- package/src/tools/write-stdin-tool.ts +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext, ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { Container, Text } from "@mariozechner/pi-tui";
|
|
4
|
+
import { isOpenAICodexModel } from "../adapter/codex-model.ts";
|
|
5
|
+
|
|
6
|
+
export const IMAGE_GENERATION_UNSUPPORTED_MESSAGE =
|
|
7
|
+
"image_generation is only available with image-capable openai-codex models";
|
|
8
|
+
const IMAGE_GENERATION_LOCAL_EXECUTION_MESSAGE =
|
|
9
|
+
"image_generation is a native openai-codex provider tool and should not execute locally";
|
|
10
|
+
|
|
11
|
+
const IMAGE_GENERATION_PARAMETERS = Type.Unsafe<Record<string, never>>({
|
|
12
|
+
type: "object",
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
interface FunctionToolPayload {
|
|
17
|
+
type?: unknown;
|
|
18
|
+
name?: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ResponsesPayload {
|
|
22
|
+
tools?: unknown[];
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ResponsesImageGenerationTool {
|
|
27
|
+
type: "image_generation";
|
|
28
|
+
output_format: "png";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function supportsImageInputs(model: ExtensionContext["model"]): boolean {
|
|
32
|
+
return Array.isArray(model?.input) && model.input.includes("image");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function supportsNativeImageGeneration(model: ExtensionContext["model"]): boolean {
|
|
36
|
+
return isOpenAICodexModel(model) && supportsImageInputs(model);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isImageGenerationFunctionTool(tool: unknown): tool is FunctionToolPayload {
|
|
40
|
+
return !!tool && typeof tool === "object" && (tool as FunctionToolPayload).type === "function" && (tool as FunctionToolPayload).name === "image_generation";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function createEmptyResultComponent(): Container {
|
|
44
|
+
return new Container();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function rewriteNativeImageGenerationTool(payload: unknown, model: ExtensionContext["model"]): unknown {
|
|
48
|
+
if (!supportsNativeImageGeneration(model) || !payload || typeof payload !== "object") {
|
|
49
|
+
return payload;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const tools = (payload as ResponsesPayload).tools;
|
|
53
|
+
if (!Array.isArray(tools)) {
|
|
54
|
+
return payload;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let rewritten = false;
|
|
58
|
+
const nextTools = tools.map((tool) => {
|
|
59
|
+
if (!isImageGenerationFunctionTool(tool)) {
|
|
60
|
+
return tool;
|
|
61
|
+
}
|
|
62
|
+
rewritten = true;
|
|
63
|
+
const nativeTool: ResponsesImageGenerationTool = {
|
|
64
|
+
type: "image_generation",
|
|
65
|
+
output_format: "png",
|
|
66
|
+
};
|
|
67
|
+
return nativeTool;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!rewritten) {
|
|
71
|
+
return payload;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...(payload as ResponsesPayload),
|
|
76
|
+
tools: nextTools,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function createImageGenerationTool(): ToolDefinition<typeof IMAGE_GENERATION_PARAMETERS> {
|
|
81
|
+
const description =
|
|
82
|
+
"Generate an image. Native openai-codex image_generation outputs are saved under `.pi/openai-codex-images/` and mirrored to `.pi/openai-codex-images/latest.png`. Use `view_image` only when pixel-level inspection is necessary.";
|
|
83
|
+
return {
|
|
84
|
+
name: "image_generation",
|
|
85
|
+
label: "image_generation",
|
|
86
|
+
description,
|
|
87
|
+
promptSnippet: description,
|
|
88
|
+
parameters: IMAGE_GENERATION_PARAMETERS,
|
|
89
|
+
prepareArguments: () => ({}),
|
|
90
|
+
async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
|
|
91
|
+
if (!supportsNativeImageGeneration(ctx.model)) {
|
|
92
|
+
throw new Error(IMAGE_GENERATION_UNSUPPORTED_MESSAGE);
|
|
93
|
+
}
|
|
94
|
+
throw new Error(IMAGE_GENERATION_LOCAL_EXECUTION_MESSAGE);
|
|
95
|
+
},
|
|
96
|
+
renderCall(_args, theme) {
|
|
97
|
+
return new Text(`${theme.fg("toolTitle", theme.bold("image_generation"))}`, 0, 0);
|
|
98
|
+
},
|
|
99
|
+
renderResult(result, { expanded }, theme) {
|
|
100
|
+
if (!expanded) {
|
|
101
|
+
return createEmptyResultComponent();
|
|
102
|
+
}
|
|
103
|
+
const textBlock = result.content.find((item) => item.type === "text");
|
|
104
|
+
const text = textBlock?.type === "text" ? textBlock.text : "(no output)";
|
|
105
|
+
return new Text(theme.fg("dim", text), 0, 0);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function registerImageGenerationTool(pi: ExtensionAPI): void {
|
|
111
|
+
pi.registerTool(createImageGenerationTool());
|
|
112
|
+
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type ExtensionContext,
|
|
8
8
|
type ToolDefinition,
|
|
9
9
|
} from "@mariozechner/pi-coding-agent";
|
|
10
|
-
import { Type, type TSchema } from "
|
|
10
|
+
import { Type, type TSchema } from "typebox";
|
|
11
11
|
import { Text } from "@mariozechner/pi-tui";
|
|
12
12
|
|
|
13
13
|
const VIEW_IMAGE_UNSUPPORTED_MESSAGE = "view_image is not allowed because you do not support image inputs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext, ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { Type } from "
|
|
2
|
+
import { Type } from "typebox";
|
|
3
3
|
import { Box, Container, Text } from "@mariozechner/pi-tui";
|
|
4
4
|
import { isOpenAICodexModel } from "../adapter/codex-model.ts";
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ const WEB_SEARCH_LOCAL_EXECUTION_MESSAGE =
|
|
|
8
8
|
"web_search is a native openai-codex provider tool and should not execute locally";
|
|
9
9
|
export const WEB_SEARCH_SESSION_NOTE_TYPE = "codex-web-search-session-note";
|
|
10
10
|
export const WEB_SEARCH_SESSION_NOTE_TEXT =
|
|
11
|
-
"Native OpenAI Codex web search is enabled for this session. Search
|
|
11
|
+
"Native OpenAI Codex web search is enabled for this session. Search activity is surfaced as merged foldable status messages instead of native tool-call rows.";
|
|
12
12
|
const WEB_SEARCH_MULTIMODAL_CONTENT_TYPES = ["text", "image"] as const;
|
|
13
13
|
|
|
14
14
|
const WEB_SEARCH_PARAMETERS = Type.Unsafe<Record<string, never>>({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { Type } from "
|
|
2
|
+
import { Type } from "typebox";
|
|
3
3
|
import { Container, Text } from "@mariozechner/pi-tui";
|
|
4
4
|
import { renderWriteStdinCall } from "./codex-rendering.ts";
|
|
5
5
|
import type { ExecSessionManager, UnifiedExecResult } from "./exec-session-manager.ts";
|