@oai404iao/pi-codex-minimal-tools 1.4.0 → 2.0.0

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.
Files changed (99) hide show
  1. package/README.md +44 -17
  2. package/THIRD_PARTY_NOTICES.md +20 -0
  3. package/config.schema.json +1 -2
  4. package/index.ts +2 -0
  5. package/package.json +14 -13
  6. package/provenance/openai-codex-ddea03ad-astra.json +54 -0
  7. package/src/activation.ts +1 -56
  8. package/src/adapter/compaction/checkpoint.ts +1 -0
  9. package/src/adapter/compaction/collect.ts +1 -0
  10. package/src/adapter/compaction/http.ts +1 -0
  11. package/src/adapter/compaction/request.ts +1 -0
  12. package/src/adapter/compaction/transport.ts +1 -0
  13. package/src/adapter/compaction/websocket.ts +1 -0
  14. package/src/background-image-generation.ts +1 -574
  15. package/src/capabilities.ts +1 -146
  16. package/src/codex-http.ts +1 -133
  17. package/src/codex-identity-extension.ts +1 -339
  18. package/src/codex-request-profile.ts +1 -45
  19. package/src/codex-reserved-tools.ts +1 -323
  20. package/src/codex-wire-identity.ts +1 -596
  21. package/src/extension/prewarm-snapshot.ts +1 -0
  22. package/src/extension/provider-presentation.ts +1 -0
  23. package/src/extension/provider-runtime.ts +1 -0
  24. package/src/extension/register.ts +36 -0
  25. package/src/extension/startup-prewarm.ts +1 -0
  26. package/src/fast-mode.ts +1 -124
  27. package/src/glyphs.ts +1 -70
  28. package/src/index.ts +8 -331
  29. package/src/model-catalog/catalog.ts +1 -636
  30. package/src/model-catalog/default-models.json +8 -0
  31. package/src/model-catalog/runtime.ts +1 -113
  32. package/src/model-catalog/types.ts +1 -95
  33. package/src/native-compaction.ts +1 -393
  34. package/src/patch/apply.ts +1 -338
  35. package/src/patch/parser.ts +1 -224
  36. package/src/patch/render.ts +1 -201
  37. package/src/provider-headers.ts +1 -54
  38. package/src/provider-native-tools.ts +1 -71
  39. package/src/provider-shim.ts +20 -4511
  40. package/src/providers/codex-apply-patch-tool.ts +1 -23
  41. package/src/providers/openai-codex/cache-key.ts +1 -0
  42. package/src/providers/openai-codex/captured-stream.ts +1 -0
  43. package/src/providers/openai-codex/constants.ts +1 -0
  44. package/src/providers/openai-codex/continuation.ts +1 -0
  45. package/src/providers/openai-codex/errors.ts +1 -0
  46. package/src/providers/openai-codex/events.ts +1 -0
  47. package/src/providers/openai-codex/headers.ts +1 -0
  48. package/src/providers/openai-codex/lite.ts +1 -0
  49. package/src/providers/openai-codex/message.ts +1 -0
  50. package/src/providers/openai-codex/prewarm.ts +1 -0
  51. package/src/providers/openai-codex/proxy.ts +1 -0
  52. package/src/providers/openai-codex/reasoning.ts +1 -0
  53. package/src/providers/openai-codex/request-body.ts +1 -0
  54. package/src/providers/openai-codex/request-context.ts +1 -0
  55. package/src/providers/openai-codex/request-metadata.ts +1 -0
  56. package/src/providers/openai-codex/retry.ts +1 -0
  57. package/src/providers/openai-codex/runtime.ts +1 -0
  58. package/src/providers/openai-codex/sse.ts +1 -0
  59. package/src/providers/openai-codex/stream-effects.ts +1 -0
  60. package/src/providers/openai-codex/stream.ts +1 -0
  61. package/src/providers/openai-codex/types.ts +1 -0
  62. package/src/providers/openai-codex/urls.ts +1 -0
  63. package/src/providers/openai-codex/usage.ts +1 -0
  64. package/src/providers/openai-codex/websocket-connection.ts +1 -0
  65. package/src/providers/openai-codex/websocket-events.ts +1 -0
  66. package/src/providers/openai-codex/websocket-session.ts +1 -0
  67. package/src/providers/openai-codex/websocket-socket.ts +1 -0
  68. package/src/providers/openai-codex/websocket-stream.ts +1 -0
  69. package/src/providers/openai-responses-shared.ts +7 -1463
  70. package/src/providers/responses/citations.ts +1 -0
  71. package/src/providers/responses/history.ts +1 -0
  72. package/src/providers/responses/items.ts +1 -0
  73. package/src/providers/responses/markdown.ts +1 -0
  74. package/src/providers/responses/messages.ts +1 -0
  75. package/src/providers/responses/signatures.ts +1 -0
  76. package/src/providers/responses/stream-state.ts +1 -0
  77. package/src/providers/responses/stream.ts +1 -0
  78. package/src/providers/responses/text-renderer.ts +1 -0
  79. package/src/providers/responses/text.ts +1 -0
  80. package/src/providers/responses/tool-identity.ts +1 -0
  81. package/src/providers/responses/tools.ts +1 -0
  82. package/src/providers/responses/types.ts +1 -0
  83. package/src/providers/responses/usage.ts +1 -0
  84. package/src/settings.ts +1 -247
  85. package/src/subagent-inline.ts +1 -8
  86. package/src/tools/apply-patch.ts +1 -84
  87. package/src/tools/image-generation/capture.ts +1 -0
  88. package/src/tools/image-generation/display.ts +1 -0
  89. package/src/tools/image-generation/preview.ts +1 -0
  90. package/src/tools/image-generation/storage.ts +1 -0
  91. package/src/tools/image-generation/types.ts +1 -0
  92. package/src/tools/image-generation.ts +1 -274
  93. package/src/tools/view-image.ts +1 -98
  94. package/src/tools/web-search/activity.ts +1 -0
  95. package/src/tools/web-search/capture.ts +1 -0
  96. package/src/tools/web-search/render.ts +1 -0
  97. package/src/tools/web-search.ts +1 -554
  98. package/src/utils/images.ts +1 -73
  99. package/src/utils/theme.ts +1 -0
@@ -1,201 +1 @@
1
- import { Box, Container, Spacer, Text, type Component } from "@earendil-works/pi-tui";
2
- import { previewApplyPatch, type ApplyPatchPreviewFile } from "./apply.js";
3
-
4
- const PREVIEW_INTERVAL_MS = 500;
5
-
6
- type RenderPreview = { complete: boolean; files: ApplyPatchPreviewFile[] } | { error: string };
7
-
8
- interface PreviewRequest {
9
- input: string;
10
- cwd: string;
11
- complete: boolean;
12
- invalidate: () => void;
13
- }
14
-
15
- interface ApplyPatchRenderBox extends Box {
16
- preview?: RenderPreview;
17
- request?: PreviewRequest;
18
- requestKey?: string;
19
- previewPending: boolean;
20
- previewTimer?: ReturnType<typeof setTimeout>;
21
- lastPreviewStartedAt: number;
22
- executionStarted: boolean;
23
- settledFiles?: Array<{ kind: ApplyPatchPreviewFile["kind"]; path: string; moveTo?: string }>;
24
- settledError: boolean;
25
- settledSuccess: boolean;
26
- }
27
-
28
- async function computePreview(request: PreviewRequest): Promise<RenderPreview> {
29
- try {
30
- const preview = await previewApplyPatch(request.input, {
31
- cwd: request.cwd,
32
- }, request.complete);
33
- return {
34
- complete: preview.complete,
35
- files: preview.files,
36
- };
37
- } catch (error) {
38
- return { error: error instanceof Error ? error.message : String(error) };
39
- }
40
- }
41
-
42
- function createRenderBox(): ApplyPatchRenderBox {
43
- return Object.assign(new Box(1, 1, (text: string) => text), {
44
- previewPending: false,
45
- lastPreviewStartedAt: 0,
46
- executionStarted: false,
47
- settledError: false,
48
- settledSuccess: false,
49
- });
50
- }
51
-
52
- function getRenderBox(state: Record<string, unknown>, lastComponent: Component | undefined): ApplyPatchRenderBox {
53
- if (lastComponent instanceof Box) {
54
- state.callComponent = lastComponent;
55
- return lastComponent as ApplyPatchRenderBox;
56
- }
57
- if (state.callComponent instanceof Box) return state.callComponent as ApplyPatchRenderBox;
58
- const component = createRenderBox();
59
- state.callComponent = component;
60
- return component;
61
- }
62
-
63
- function requestKey(request: Omit<PreviewRequest, "invalidate">): string {
64
- return `${request.complete ? "complete" : "partial"}\u0000${request.cwd}\u0000${request.input}`;
65
- }
66
-
67
- function schedulePreview(component: ApplyPatchRenderBox, immediate = false): void {
68
- if (!component.request || component.previewPending) return;
69
- if (component.previewTimer) {
70
- if (!immediate) return;
71
- clearTimeout(component.previewTimer);
72
- component.previewTimer = undefined;
73
- }
74
- const delay = immediate ? 0 : Math.max(0, PREVIEW_INTERVAL_MS - (Date.now() - component.lastPreviewStartedAt));
75
- component.previewTimer = setTimeout(() => {
76
- component.previewTimer = undefined;
77
- const request = component.request;
78
- if (!request) return;
79
- const key = component.requestKey;
80
- component.previewPending = true;
81
- component.lastPreviewStartedAt = Date.now();
82
- void computePreview(request).then((preview) => {
83
- if (!component.executionStarted && component.requestKey === key) {
84
- component.preview = preview;
85
- }
86
- }).finally(() => {
87
- component.previewPending = false;
88
- request.invalidate();
89
- if (!component.executionStarted && component.requestKey !== key) schedulePreview(component, Boolean(component.request?.complete));
90
- });
91
- }, delay);
92
- component.previewTimer.unref?.();
93
- }
94
-
95
- function updatePreviewRequest(component: ApplyPatchRenderBox, request: PreviewRequest): void {
96
- const key = requestKey(request);
97
- if (component.requestKey === key) return;
98
- component.request = request;
99
- component.requestKey = key;
100
- schedulePreview(component, request.complete);
101
- }
102
-
103
- function contentLineCount(content: string): number {
104
- if (!content) return 0;
105
- const lines = content.replace(/\r\n/g, "\n").split("\n");
106
- if (lines[lines.length - 1] === "") lines.pop();
107
- return lines.length;
108
- }
109
-
110
- function operationLine(file: ApplyPatchPreviewFile, theme: any, expanded: boolean): string {
111
- const marker = file.kind === "add" ? "A" : file.kind === "delete" ? "D" : "M";
112
- const markerColor = file.kind === "delete" ? "error" : file.kind === "add" ? "success" : "accent";
113
- const path = file.moveTo ? `${file.path} → ${file.moveTo}` : file.path;
114
- const before = contentLineCount(file.previousContent);
115
- const after = contentLineCount(file.content);
116
- const size = file.kind === "add" ? `+${after} lines` : file.kind === "delete" ? `-${before} lines` : `${before}→${after} lines`;
117
- const detail = expanded && file.moveTo ? ` (${file.path} moved)` : "";
118
- return `${theme.fg(markerColor, marker)} ${theme.fg("accent", path)} ${theme.fg("dim", `${size}${detail}`)}`;
119
- }
120
-
121
- function settledOperationLine(file: { kind: ApplyPatchPreviewFile["kind"]; path: string; moveTo?: string }, theme: any): string {
122
- const marker = file.kind === "add" ? "A" : file.kind === "delete" ? "D" : "M";
123
- const markerColor = file.kind === "delete" ? "error" : file.kind === "add" ? "success" : "accent";
124
- const path = file.moveTo ? `${file.path} → ${file.moveTo}` : file.path;
125
- return `${theme.fg(markerColor, marker)} ${theme.fg("accent", path)}`;
126
- }
127
-
128
- function rebuildCall(component: ApplyPatchRenderBox, theme: any, expanded: boolean): ApplyPatchRenderBox {
129
- component.setBgFn(component.settledError
130
- ? (text: string) => theme.bg("toolErrorBg", text)
131
- : component.settledSuccess
132
- ? (text: string) => theme.bg("toolSuccessBg", text)
133
- : (text: string) => theme.bg("toolPendingBg", text));
134
- component.clear();
135
- const status = component.settledError
136
- ? "failed"
137
- : component.settledSuccess
138
- ? "applied"
139
- : component.executionStarted
140
- ? "applying"
141
- : component.previewPending
142
- ? "previewing"
143
- : component.preview && "complete" in component.preview && component.preview.complete ? "ready" : "streaming";
144
- component.addChild(new Text(`${theme.fg("toolTitle", theme.bold("apply_patch"))} ${theme.fg("dim", status)}`, 0, 0));
145
- if (component.settledFiles) {
146
- for (const file of component.settledFiles) component.addChild(new Text(settledOperationLine(file, theme), 0, 0));
147
- return component;
148
- }
149
- if (!component.preview) return component;
150
- if ("error" in component.preview) {
151
- component.addChild(new Spacer(1));
152
- component.addChild(new Text(theme.fg("error", component.preview.error), 0, 0));
153
- return component;
154
- }
155
- for (const file of component.preview.files) component.addChild(new Text(operationLine(file, theme, expanded), 0, 0));
156
- return component;
157
- }
158
-
159
- export function createApplyPatchRenderers() {
160
- return {
161
- renderCall(args: { input?: string } | undefined, theme: any, context: any) {
162
- const component = getRenderBox(context.state, context.lastComponent);
163
- if (context.executionStarted && !component.executionStarted) {
164
- component.executionStarted = true;
165
- if (component.previewTimer) clearTimeout(component.previewTimer);
166
- component.previewTimer = undefined;
167
- component.request = undefined;
168
- component.requestKey = undefined;
169
- }
170
- const input = typeof args?.input === "string" ? args.input : "";
171
- if (input && !component.executionStarted) {
172
- updatePreviewRequest(component, {
173
- input,
174
- cwd: context.cwd,
175
- complete: Boolean(context.argsComplete),
176
- invalidate: context.invalidate,
177
- });
178
- }
179
- return rebuildCall(component, theme, Boolean(context.expanded));
180
- },
181
- renderResult(result: {
182
- content?: Array<{ type?: string; text?: string }>;
183
- details?: { files?: Array<{ kind?: string; path?: string; moveTo?: string }> };
184
- }, _options: unknown, theme: any, context: any) {
185
- const component = getRenderBox(context.state, context.state.callComponent);
186
- component.settledError = Boolean(context.isError);
187
- component.settledSuccess = !context.isError;
188
- if (!context.isError && Array.isArray(result.details?.files)) {
189
- component.settledFiles = result.details.files.flatMap((file) =>
190
- (file.kind === "add" || file.kind === "update" || file.kind === "delete") && typeof file.path === "string"
191
- ? [{ kind: file.kind, path: file.path, ...(typeof file.moveTo === "string" ? { moveTo: file.moveTo } : {}) }]
192
- : []);
193
- component.preview = undefined;
194
- }
195
- rebuildCall(component, theme, Boolean(context.expanded));
196
- const message = result.content?.filter((item) => item.type === "text").map((item) => item.text ?? "").join("\n") ?? "";
197
- if (context.isError) return message ? new Text(theme.fg("error", message), 0, 0) : new Container();
198
- return new Text(theme.fg("success", context.expanded && message ? message : "Applied"), 0, 0);
199
- },
200
- };
201
- }
1
+ export * from "@oai404iao/pi-codex-core/internal/patch/render";
@@ -1,54 +1 @@
1
- import type { ProviderHeaders } from "@earendil-works/pi-ai";
2
-
3
- const suppressedHeaders = new WeakMap<Headers, Set<string>>();
4
-
5
- function normalizedName(name: string): string {
6
- return name.trim().toLowerCase();
7
- }
8
-
9
- export function providerHeaderDirective(
10
- headers: ProviderHeaders | undefined,
11
- name: string,
12
- ): string | null | undefined {
13
- const target = normalizedName(name);
14
- let directive: string | null | undefined;
15
- for (const [candidate, value] of Object.entries(headers ?? {})) {
16
- if (normalizedName(candidate) === target) directive = value;
17
- }
18
- return directive;
19
- }
20
-
21
- export function mergeProviderHeaders(...layers: Array<ProviderHeaders | undefined>): Headers {
22
- const headers = new Headers();
23
- const suppressed = new Set<string>();
24
- for (const layer of layers) {
25
- for (const [name, value] of Object.entries(layer ?? {})) {
26
- const normalized = normalizedName(name);
27
- if (value === null) {
28
- headers.delete(name);
29
- suppressed.add(normalized);
30
- } else {
31
- headers.set(name, value);
32
- suppressed.delete(normalized);
33
- }
34
- }
35
- }
36
- suppressedHeaders.set(headers, suppressed);
37
- return headers;
38
- }
39
-
40
- export function isProviderHeaderSuppressed(headers: Headers, name: string): boolean {
41
- return suppressedHeaders.get(headers)?.has(normalizedName(name)) ?? false;
42
- }
43
-
44
- export function setProviderDefaultHeader(headers: Headers, name: string, value: string): boolean {
45
- if (isProviderHeaderSuppressed(headers, name) || headers.has(name)) return false;
46
- headers.set(name, value);
47
- return true;
48
- }
49
-
50
- export function setProviderGeneratedHeader(headers: Headers, name: string, value: string): boolean {
51
- if (isProviderHeaderSuppressed(headers, name)) return false;
52
- headers.set(name, value);
53
- return true;
54
- }
1
+ export * from "@oai404iao/pi-codex-runtime/internal/provider-headers";
@@ -1,71 +1 @@
1
- import { createCodexReservedNamespaceTool } from "./codex-reserved-tools.js";
2
-
3
- export interface NativeToolRewriteResult<T = unknown> {
4
- payload: T;
5
- rewritten: string[];
6
- }
7
-
8
- export interface NativeToolRewriteOptions {
9
- imageModel?: string;
10
- imageGeneration?: boolean | "hosted" | "standalone";
11
- webSearch?: boolean | {
12
- implementation?: "hosted" | "standalone";
13
- contentTypes?: readonly ("text" | "image")[];
14
- };
15
- }
16
-
17
- function isRecord(value: unknown): value is Record<string, unknown> {
18
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
19
- }
20
-
21
- function toolName(tool: Record<string, unknown>): string | undefined {
22
- if (typeof tool.name === "string") return tool.name;
23
- const nested = isRecord(tool.function) ? tool.function : undefined;
24
- return typeof nested?.name === "string" ? nested.name : undefined;
25
- }
26
-
27
- function imageToolConfig(tool: Record<string, unknown>, options: NativeToolRewriteOptions): Record<string, unknown> {
28
- const parameters = isRecord(tool.parameters) ? tool.parameters : isRecord(isRecord(tool.function) ? tool.function.parameters : undefined) ? (tool.function as Record<string, unknown>).parameters as Record<string, unknown> : {};
29
- const config: Record<string, unknown> = { type: "image_generation" };
30
- if (typeof options.imageModel === "string" && options.imageModel.trim()) config.model = options.imageModel.trim();
31
- for (const key of ["size", "quality", "background", "output_format"]) {
32
- const value = parameters[key];
33
- if (typeof value === "string") config[key] = value;
34
- }
35
- if (!config.output_format) config.output_format = "png";
36
- if (!config.action) config.action = "auto";
37
- return config;
38
- }
39
-
40
- export function rewriteNativeOpenAiTools<T>(payload: T, options: NativeToolRewriteOptions = {}): NativeToolRewriteResult<T> {
41
- if (!isRecord(payload) || !Array.isArray(payload.tools)) return { payload, rewritten: [] };
42
- const rewritten: string[] = [];
43
- const tools = payload.tools.map((candidate) => {
44
- if (!isRecord(candidate)) return candidate;
45
- const name = toolName(candidate);
46
- if (name === "image_generation" && options.imageGeneration !== false) {
47
- rewritten.push(name);
48
- if (options.imageGeneration === "standalone") {
49
- return createCodexReservedNamespaceTool("image_generation");
50
- }
51
- return imageToolConfig(candidate, options);
52
- }
53
- if (name === "web_search" && options.webSearch) {
54
- rewritten.push(name);
55
- if (typeof options.webSearch === "object" && options.webSearch.implementation === "standalone") {
56
- return createCodexReservedNamespaceTool("web_search");
57
- }
58
- const contentTypes = typeof options.webSearch === "object"
59
- ? options.webSearch.contentTypes
60
- : undefined;
61
- return {
62
- type: "web_search",
63
- ...(contentTypes && contentTypes.length > 0
64
- ? { search_content_types: [...contentTypes] }
65
- : {}),
66
- };
67
- }
68
- return candidate;
69
- });
70
- return { payload: { ...payload, tools } as T, rewritten };
71
- }
1
+ export * from "@oai404iao/pi-codex-core/internal/provider-native-tools";