@wlv-zedd/dsh-chatgpt-web 1.0.0 → 1.0.2

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 (81) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +140 -140
  3. package/cordis.patch.yml +4 -4
  4. package/lib/cli.js +13269 -11860
  5. package/lib/plugin.js +3 -50
  6. package/package.json +89 -88
  7. package/src/adapters/base.ts +16 -16
  8. package/src/adapters/chatgpt-web/adapter-error.ts +59 -59
  9. package/src/adapters/chatgpt-web/browser-helper-main.ts +513 -513
  10. package/src/adapters/chatgpt-web/browser-helper-prompt-selection.ts +27 -27
  11. package/src/adapters/chatgpt-web/browser-worker.ts +4944 -4944
  12. package/src/adapters/chatgpt-web/codex-rollout-environment.ts +628 -628
  13. package/src/adapters/chatgpt-web/compaction-handoff.ts +533 -533
  14. package/src/adapters/chatgpt-web/compaction-transaction.ts +142 -142
  15. package/src/adapters/chatgpt-web/concurrency.ts +6 -6
  16. package/src/adapters/chatgpt-web/conversation-key.ts +58 -58
  17. package/src/adapters/chatgpt-web/environment.ts +669 -669
  18. package/src/adapters/chatgpt-web/index.ts +1544 -1544
  19. package/src/adapters/chatgpt-web/input-tokens.ts +74 -74
  20. package/src/adapters/chatgpt-web/launcher-helper-client.ts +695 -695
  21. package/src/adapters/chatgpt-web/markdown.ts +418 -418
  22. package/src/adapters/chatgpt-web/mcp-main.ts +25 -25
  23. package/src/adapters/chatgpt-web/mcp-server.ts +933 -933
  24. package/src/adapters/chatgpt-web/model.ts +70 -70
  25. package/src/adapters/chatgpt-web/native-compaction-control.ts +74 -74
  26. package/src/adapters/chatgpt-web/output-validation.ts +62 -62
  27. package/src/adapters/chatgpt-web/process-line-writer.ts +46 -46
  28. package/src/adapters/chatgpt-web/prompt.ts +702 -702
  29. package/src/adapters/chatgpt-web/retry-policy.ts +73 -73
  30. package/src/adapters/chatgpt-web/rolling-checkpoint.ts +384 -384
  31. package/src/adapters/chatgpt-web/thread-environment.ts +238 -238
  32. package/src/adapters/chatgpt-web/tool-stream-parser.ts +1 -1
  33. package/src/adapters/chatgpt-web/turn-broker.ts +1481 -1481
  34. package/src/adapters/chatgpt-web/turn-execution.ts +816 -816
  35. package/src/adapters/chatgpt-web/turn-progress.ts +292 -292
  36. package/src/adapters/chatgpt-web/usage.ts +121 -121
  37. package/src/adapters/image.ts +9 -9
  38. package/src/bridge.ts +1083 -1083
  39. package/src/browser-login.ts +521 -521
  40. package/src/chatgpt-session.ts +240 -240
  41. package/src/chatgpt-web-models.ts +400 -400
  42. package/src/cli.ts +568 -568
  43. package/src/codex-integration-document.ts +824 -824
  44. package/src/codex-integration-journal.ts +212 -212
  45. package/src/codex-integration-route.ts +515 -515
  46. package/src/codex-integration-shared.ts +332 -332
  47. package/src/codex-integration.ts +529 -529
  48. package/src/codex-interrupt-hook.ts +158 -158
  49. package/src/config.ts +616 -616
  50. package/src/dev-chat/cli.ts +432 -432
  51. package/src/dev-chat/constants.ts +3 -3
  52. package/src/dev-chat/driver.ts +655 -655
  53. package/src/dev-chat/profile.ts +223 -223
  54. package/src/dev-chat/session.ts +287 -287
  55. package/src/dev-chat/transport.ts +54 -54
  56. package/src/doctor.ts +237 -237
  57. package/src/event-queue.ts +45 -45
  58. package/src/http-body.ts +30 -30
  59. package/src/launcher-browser-host.ts +695 -695
  60. package/src/lib/errors.ts +281 -281
  61. package/src/lib/token-estimate.ts +42 -42
  62. package/src/login-helper.cjs +1 -1
  63. package/src/model-catalog.ts +197 -197
  64. package/src/native-passthrough.ts +261 -261
  65. package/src/plugin.ts +191 -191
  66. package/src/process.ts +45 -45
  67. package/src/responses/compaction.ts +199 -199
  68. package/src/responses/parser.ts +633 -633
  69. package/src/responses/reasoning-envelope.ts +49 -49
  70. package/src/responses/schema.ts +172 -172
  71. package/src/responses/state.ts +230 -230
  72. package/src/server.ts +1111 -1111
  73. package/src/service.ts +315 -315
  74. package/src/setup.ts +671 -671
  75. package/src/stall-timeout.ts +23 -23
  76. package/src/tunnel-service.ts +160 -160
  77. package/src/tunnel.ts +417 -417
  78. package/src/turndown-plugin-gfm.d.ts +5 -5
  79. package/src/types.ts +307 -307
  80. package/src/usage/totals.ts +12 -12
  81. package/src/version.ts +1 -1
@@ -1,49 +1,49 @@
1
- /**
2
- * Opaque signed-reasoning metadata round-trip through Codex's `encrypted_content` slot.
3
- *
4
- * Some Responses histories contain signed or redacted reasoning metadata that must be replayed
5
- * verbatim. Codex round-trips `encrypted_content`, so the bridge preserves that metadata inside
6
- * the inherited `ocxr1:` + base64(JSON) envelope format.
7
- *
8
- * Native OpenAI-encrypted blobs (no ocxr1 prefix) are left untouched by the decoder, and the
9
- * passthrough scrub strips ocxr1 envelopes before native forwarding.
10
- */
11
-
12
- export const BRIDGE_REASONING_PREFIX = "ocxr1:";
13
-
14
- export interface ReasoningEnvelope {
15
- /** Opaque reasoning-block signature, if captured. */
16
- sig?: string;
17
- /** Raw redacted_thinking block data payloads, order preserved. */
18
- red?: string[];
19
- /**
20
- * Hidden thinking text (hideThinkingSummary providers): the signature signs this exact text,
21
- * so replay needs it even though the visible summary was suppressed.
22
- */
23
- txt?: string;
24
- }
25
-
26
- export function encodeReasoningEnvelope(envelope: ReasoningEnvelope): string {
27
- return BRIDGE_REASONING_PREFIX + Buffer.from(JSON.stringify(envelope), "utf-8").toString("base64");
28
- }
29
-
30
- /** Decode an ocxr1 envelope; returns null for native (OpenAI-encrypted) blobs or garbage. */
31
- export function decodeReasoningEnvelope(encryptedContent: string): ReasoningEnvelope | null {
32
- if (!encryptedContent.startsWith(BRIDGE_REASONING_PREFIX)) return null;
33
- try {
34
- const parsed: unknown = JSON.parse(Buffer.from(encryptedContent.slice(BRIDGE_REASONING_PREFIX.length), "base64").toString("utf-8"));
35
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
36
- const obj = parsed as { sig?: unknown; red?: unknown };
37
- const envelope: ReasoningEnvelope = {};
38
- if (typeof obj.sig === "string") envelope.sig = obj.sig;
39
- if (Array.isArray(obj.red)) {
40
- const red = obj.red.filter((r): r is string => typeof r === "string");
41
- if (red.length > 0) envelope.red = red;
42
- }
43
- const txt = (parsed as { txt?: unknown }).txt;
44
- if (typeof txt === "string" && txt.length > 0) envelope.txt = txt;
45
- return envelope.sig || envelope.red || envelope.txt ? envelope : null;
46
- } catch {
47
- return null;
48
- }
49
- }
1
+ /**
2
+ * Opaque signed-reasoning metadata round-trip through Codex's `encrypted_content` slot.
3
+ *
4
+ * Some Responses histories contain signed or redacted reasoning metadata that must be replayed
5
+ * verbatim. Codex round-trips `encrypted_content`, so the bridge preserves that metadata inside
6
+ * the inherited `ocxr1:` + base64(JSON) envelope format.
7
+ *
8
+ * Native OpenAI-encrypted blobs (no ocxr1 prefix) are left untouched by the decoder, and the
9
+ * passthrough scrub strips ocxr1 envelopes before native forwarding.
10
+ */
11
+
12
+ export const BRIDGE_REASONING_PREFIX = "ocxr1:";
13
+
14
+ export interface ReasoningEnvelope {
15
+ /** Opaque reasoning-block signature, if captured. */
16
+ sig?: string;
17
+ /** Raw redacted_thinking block data payloads, order preserved. */
18
+ red?: string[];
19
+ /**
20
+ * Hidden thinking text (hideThinkingSummary providers): the signature signs this exact text,
21
+ * so replay needs it even though the visible summary was suppressed.
22
+ */
23
+ txt?: string;
24
+ }
25
+
26
+ export function encodeReasoningEnvelope(envelope: ReasoningEnvelope): string {
27
+ return BRIDGE_REASONING_PREFIX + Buffer.from(JSON.stringify(envelope), "utf-8").toString("base64");
28
+ }
29
+
30
+ /** Decode an ocxr1 envelope; returns null for native (OpenAI-encrypted) blobs or garbage. */
31
+ export function decodeReasoningEnvelope(encryptedContent: string): ReasoningEnvelope | null {
32
+ if (!encryptedContent.startsWith(BRIDGE_REASONING_PREFIX)) return null;
33
+ try {
34
+ const parsed: unknown = JSON.parse(Buffer.from(encryptedContent.slice(BRIDGE_REASONING_PREFIX.length), "base64").toString("utf-8"));
35
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
36
+ const obj = parsed as { sig?: unknown; red?: unknown };
37
+ const envelope: ReasoningEnvelope = {};
38
+ if (typeof obj.sig === "string") envelope.sig = obj.sig;
39
+ if (Array.isArray(obj.red)) {
40
+ const red = obj.red.filter((r): r is string => typeof r === "string");
41
+ if (red.length > 0) envelope.red = red;
42
+ }
43
+ const txt = (parsed as { txt?: unknown }).txt;
44
+ if (typeof txt === "string" && txt.length > 0) envelope.txt = txt;
45
+ return envelope.sig || envelope.red || envelope.txt ? envelope : null;
46
+ } catch {
47
+ return null;
48
+ }
49
+ }
@@ -1,172 +1,172 @@
1
- import * as z from "zod/v4";
2
-
3
- const inputTextSchema = z.object({ type: z.literal("input_text"), text: z.string() });
4
- const plainTextSchema = z.object({ type: z.literal("text"), text: z.string() });
5
- const inputImageBlockSchema = z.object({
6
- type: z.literal("input_image"),
7
- // codex-rs ImageDetail: auto|low|high|original (view_image --detail original).
8
- detail: z.enum(["auto", "low", "high", "original"]).optional(),
9
- image_url: z.string().optional(),
10
- file_id: z.string().optional(),
11
- }).refine(v => typeof v.image_url === "string" || typeof v.file_id === "string", {
12
- message: "input_image requires at least one of image_url or file_id",
13
- });
14
- const inputFileBlockSchema = z.object({
15
- type: z.literal("input_file"),
16
- file_id: z.string().optional(),
17
- filename: z.string().optional(),
18
- file_data: z.string().optional(),
19
- });
20
- const outputTextSchema = z.object({ type: z.literal("output_text"), text: z.string() });
21
- const outputRefusalSchema = z.object({ type: z.literal("refusal"), refusal: z.string() });
22
- const summaryTextSchema = z.object({ type: z.literal("summary_text"), text: z.string() });
23
- const reasoningTextSchema = z.object({ type: z.literal("reasoning_text"), text: z.string() });
24
- // codex-rs FunctionCallOutputContentItem (protocol/src/models.rs): input_text | input_image | encrypted_content.
25
- const encryptedContentBlockSchema = z.object({ type: z.literal("encrypted_content"), encrypted_content: z.string() });
26
-
27
- const inputContentBlockSchema = z.union([inputTextSchema, plainTextSchema, inputImageBlockSchema, inputFileBlockSchema]);
28
- const outputContentBlockSchema = z.union([outputTextSchema, plainTextSchema, outputRefusalSchema]);
29
- // Codex tool outputs can contain both input-shaped and output-shaped content blocks.
30
- const toolOutputContentBlockSchema = z.union([
31
- outputTextSchema, plainTextSchema, outputRefusalSchema,
32
- inputTextSchema, inputImageBlockSchema, encryptedContentBlockSchema,
33
- ]);
34
- const toolOutputSchema = z.union([z.string(), z.array(toolOutputContentBlockSchema)]);
35
-
36
- const userMessageItemSchema = z.object({
37
- type: z.literal("message").optional(),
38
- role: z.union([z.literal("user"), z.literal("developer")]),
39
- content: z.union([z.string(), z.array(inputContentBlockSchema)]).optional(),
40
- });
41
- const systemMessageItemSchema = z.object({
42
- type: z.literal("message").optional(),
43
- role: z.literal("system"),
44
- content: z.union([z.string(), z.array(inputContentBlockSchema)]).optional(),
45
- });
46
- const assistantMessageItemSchema = z.object({
47
- type: z.literal("message").optional(),
48
- role: z.literal("assistant"),
49
- content: z.union([z.string(), z.array(outputContentBlockSchema)]).optional(),
50
- phase: z.enum(["commentary", "final_answer"]).optional(),
51
- });
52
- const agentMessageItemSchema = z.object({
53
- type: z.literal("agent_message"),
54
- author: z.string().optional(),
55
- recipient: z.string().optional(),
56
- // MultiAgent V1 sends normal input content. V2 may send only encrypted_content; accept that
57
- // shape so the HTTP boundary can reject it before constructing a browser adapter instead of
58
- // silently manufacturing an empty task or starting a retryable SSE stream.
59
- content: z.union([
60
- z.string(),
61
- z.array(z.union([inputContentBlockSchema, encryptedContentBlockSchema])),
62
- ]).optional(),
63
- }).loose();
64
- const reasoningItemSchema = z.object({
65
- type: z.literal("reasoning"),
66
- id: z.string().optional(),
67
- summary: z.array(summaryTextSchema).optional(),
68
- content: z.array(reasoningTextSchema).optional(),
69
- // Round-tripped opaque payload (native OpenAI encryption OR the proxy's ocxr1 envelope).
70
- encrypted_content: z.string().optional(),
71
- });
72
- const functionCallItemSchema = z.object({
73
- type: z.literal("function_call"),
74
- id: z.string().optional(),
75
- call_id: z.string().min(1),
76
- name: z.string().min(1),
77
- namespace: z.string().optional(),
78
- arguments: z.string().optional(),
79
- });
80
- const functionCallOutputItemSchema = z.object({
81
- type: z.literal("function_call_output"),
82
- call_id: z.string().min(1),
83
- output: toolOutputSchema.optional(),
84
- });
85
- const customToolCallItemSchema = z.object({
86
- type: z.literal("custom_tool_call"),
87
- id: z.string().optional(),
88
- call_id: z.string().min(1),
89
- name: z.string().min(1),
90
- input: z.string(),
91
- });
92
- const customToolCallOutputItemSchema = z.object({
93
- type: z.literal("custom_tool_call_output"),
94
- call_id: z.string().min(1),
95
- // codex-rs CustomToolCallOutput carries FunctionCallOutputPayload: string OR content items.
96
- output: toolOutputSchema,
97
- });
98
-
99
- export const inputItemSchema = z.union([
100
- userMessageItemSchema,
101
- systemMessageItemSchema,
102
- assistantMessageItemSchema,
103
- agentMessageItemSchema,
104
- reasoningItemSchema,
105
- functionCallItemSchema,
106
- functionCallOutputItemSchema,
107
- customToolCallItemSchema,
108
- customToolCallOutputItemSchema,
109
- z.object({ type: z.string() }).loose(),
110
- ]);
111
-
112
- export const toolSchema = z.object({
113
- type: z.literal("function"),
114
- name: z.string().min(1),
115
- description: z.string().optional(),
116
- parameters: z.record(z.string(), z.unknown()).optional(),
117
- strict: z.boolean().optional(),
118
- });
119
-
120
- const builtinToolSchema = z.object({ type: z.string() }).loose();
121
-
122
- const hostedToolType = z.enum([
123
- "web_search_preview", "file_search", "computer_use_preview",
124
- "code_interpreter", "image_generation", "mcp",
125
- ]);
126
-
127
- const allowedToolEntrySchema = z.object({ type: z.string(), name: z.string().optional() });
128
-
129
- export const toolChoiceSchema = z.union([
130
- z.literal("auto"),
131
- z.literal("none"),
132
- z.literal("required"),
133
- z.object({ type: z.literal("function"), name: z.string().min(1) }),
134
- z.object({ type: z.literal("custom"), name: z.string().min(1) }),
135
- z.object({ type: hostedToolType }),
136
- z.object({ type: z.literal("allowed_tools"), mode: z.enum(["auto", "required"]), tools: z.array(allowedToolEntrySchema) }),
137
- ]);
138
-
139
- export const reasoningConfigSchema = z.object({
140
- effort: z.string().optional(),
141
- summary: z.enum(["auto", "concise", "detailed", "none"]).optional(),
142
- });
143
-
144
- export const stopSchema = z.union([z.string(), z.array(z.string()), z.null()]);
145
-
146
- export const responsesRequestSchema = z.object({
147
- model: z.string().min(1),
148
- input: z.union([z.string(), z.array(inputItemSchema)]).optional(),
149
- instructions: z.union([z.string(), z.null()]).optional(),
150
- tools: z.array(z.union([toolSchema, builtinToolSchema])).optional(),
151
- tool_choice: toolChoiceSchema.optional(),
152
- max_output_tokens: z.number().optional(),
153
- temperature: z.number().optional(),
154
- top_p: z.number().optional(),
155
- stop: stopSchema.optional(),
156
- stream: z.boolean().optional(),
157
- reasoning: reasoningConfigSchema.nullable().optional(),
158
- store: z.boolean().optional(),
159
- previous_response_id: z.string().optional(),
160
- parallel_tool_calls: z.boolean().optional(),
161
- prompt_cache_key: z.string().optional(),
162
- metadata: z.unknown().optional(),
163
- user: z.string().optional(),
164
- service_tier: z.string().optional(),
165
- presence_penalty: z.number().optional(),
166
- frequency_penalty: z.number().optional(),
167
- background: z.unknown().optional(),
168
- include: z.unknown().optional(),
169
- prompt: z.unknown().optional(),
170
- text: z.unknown().optional(),
171
- truncation: z.unknown().optional(),
172
- });
1
+ import * as z from "zod/v4";
2
+
3
+ const inputTextSchema = z.object({ type: z.literal("input_text"), text: z.string() });
4
+ const plainTextSchema = z.object({ type: z.literal("text"), text: z.string() });
5
+ const inputImageBlockSchema = z.object({
6
+ type: z.literal("input_image"),
7
+ // codex-rs ImageDetail: auto|low|high|original (view_image --detail original).
8
+ detail: z.enum(["auto", "low", "high", "original"]).optional(),
9
+ image_url: z.string().optional(),
10
+ file_id: z.string().optional(),
11
+ }).refine(v => typeof v.image_url === "string" || typeof v.file_id === "string", {
12
+ message: "input_image requires at least one of image_url or file_id",
13
+ });
14
+ const inputFileBlockSchema = z.object({
15
+ type: z.literal("input_file"),
16
+ file_id: z.string().optional(),
17
+ filename: z.string().optional(),
18
+ file_data: z.string().optional(),
19
+ });
20
+ const outputTextSchema = z.object({ type: z.literal("output_text"), text: z.string() });
21
+ const outputRefusalSchema = z.object({ type: z.literal("refusal"), refusal: z.string() });
22
+ const summaryTextSchema = z.object({ type: z.literal("summary_text"), text: z.string() });
23
+ const reasoningTextSchema = z.object({ type: z.literal("reasoning_text"), text: z.string() });
24
+ // codex-rs FunctionCallOutputContentItem (protocol/src/models.rs): input_text | input_image | encrypted_content.
25
+ const encryptedContentBlockSchema = z.object({ type: z.literal("encrypted_content"), encrypted_content: z.string() });
26
+
27
+ const inputContentBlockSchema = z.union([inputTextSchema, plainTextSchema, inputImageBlockSchema, inputFileBlockSchema]);
28
+ const outputContentBlockSchema = z.union([outputTextSchema, plainTextSchema, outputRefusalSchema]);
29
+ // Codex tool outputs can contain both input-shaped and output-shaped content blocks.
30
+ const toolOutputContentBlockSchema = z.union([
31
+ outputTextSchema, plainTextSchema, outputRefusalSchema,
32
+ inputTextSchema, inputImageBlockSchema, encryptedContentBlockSchema,
33
+ ]);
34
+ const toolOutputSchema = z.union([z.string(), z.array(toolOutputContentBlockSchema)]);
35
+
36
+ const userMessageItemSchema = z.object({
37
+ type: z.literal("message").optional(),
38
+ role: z.union([z.literal("user"), z.literal("developer")]),
39
+ content: z.union([z.string(), z.array(inputContentBlockSchema)]).optional(),
40
+ });
41
+ const systemMessageItemSchema = z.object({
42
+ type: z.literal("message").optional(),
43
+ role: z.literal("system"),
44
+ content: z.union([z.string(), z.array(inputContentBlockSchema)]).optional(),
45
+ });
46
+ const assistantMessageItemSchema = z.object({
47
+ type: z.literal("message").optional(),
48
+ role: z.literal("assistant"),
49
+ content: z.union([z.string(), z.array(outputContentBlockSchema)]).optional(),
50
+ phase: z.enum(["commentary", "final_answer"]).optional(),
51
+ });
52
+ const agentMessageItemSchema = z.object({
53
+ type: z.literal("agent_message"),
54
+ author: z.string().optional(),
55
+ recipient: z.string().optional(),
56
+ // MultiAgent V1 sends normal input content. V2 may send only encrypted_content; accept that
57
+ // shape so the HTTP boundary can reject it before constructing a browser adapter instead of
58
+ // silently manufacturing an empty task or starting a retryable SSE stream.
59
+ content: z.union([
60
+ z.string(),
61
+ z.array(z.union([inputContentBlockSchema, encryptedContentBlockSchema])),
62
+ ]).optional(),
63
+ }).loose();
64
+ const reasoningItemSchema = z.object({
65
+ type: z.literal("reasoning"),
66
+ id: z.string().optional(),
67
+ summary: z.array(summaryTextSchema).optional(),
68
+ content: z.array(reasoningTextSchema).optional(),
69
+ // Round-tripped opaque payload (native OpenAI encryption OR the proxy's ocxr1 envelope).
70
+ encrypted_content: z.string().optional(),
71
+ });
72
+ const functionCallItemSchema = z.object({
73
+ type: z.literal("function_call"),
74
+ id: z.string().optional(),
75
+ call_id: z.string().min(1),
76
+ name: z.string().min(1),
77
+ namespace: z.string().optional(),
78
+ arguments: z.string().optional(),
79
+ });
80
+ const functionCallOutputItemSchema = z.object({
81
+ type: z.literal("function_call_output"),
82
+ call_id: z.string().min(1),
83
+ output: toolOutputSchema.optional(),
84
+ });
85
+ const customToolCallItemSchema = z.object({
86
+ type: z.literal("custom_tool_call"),
87
+ id: z.string().optional(),
88
+ call_id: z.string().min(1),
89
+ name: z.string().min(1),
90
+ input: z.string(),
91
+ });
92
+ const customToolCallOutputItemSchema = z.object({
93
+ type: z.literal("custom_tool_call_output"),
94
+ call_id: z.string().min(1),
95
+ // codex-rs CustomToolCallOutput carries FunctionCallOutputPayload: string OR content items.
96
+ output: toolOutputSchema,
97
+ });
98
+
99
+ export const inputItemSchema = z.union([
100
+ userMessageItemSchema,
101
+ systemMessageItemSchema,
102
+ assistantMessageItemSchema,
103
+ agentMessageItemSchema,
104
+ reasoningItemSchema,
105
+ functionCallItemSchema,
106
+ functionCallOutputItemSchema,
107
+ customToolCallItemSchema,
108
+ customToolCallOutputItemSchema,
109
+ z.object({ type: z.string() }).loose(),
110
+ ]);
111
+
112
+ export const toolSchema = z.object({
113
+ type: z.literal("function"),
114
+ name: z.string().min(1),
115
+ description: z.string().optional(),
116
+ parameters: z.record(z.string(), z.unknown()).optional(),
117
+ strict: z.boolean().optional(),
118
+ });
119
+
120
+ const builtinToolSchema = z.object({ type: z.string() }).loose();
121
+
122
+ const hostedToolType = z.enum([
123
+ "web_search_preview", "file_search", "computer_use_preview",
124
+ "code_interpreter", "image_generation", "mcp",
125
+ ]);
126
+
127
+ const allowedToolEntrySchema = z.object({ type: z.string(), name: z.string().optional() });
128
+
129
+ export const toolChoiceSchema = z.union([
130
+ z.literal("auto"),
131
+ z.literal("none"),
132
+ z.literal("required"),
133
+ z.object({ type: z.literal("function"), name: z.string().min(1) }),
134
+ z.object({ type: z.literal("custom"), name: z.string().min(1) }),
135
+ z.object({ type: hostedToolType }),
136
+ z.object({ type: z.literal("allowed_tools"), mode: z.enum(["auto", "required"]), tools: z.array(allowedToolEntrySchema) }),
137
+ ]);
138
+
139
+ export const reasoningConfigSchema = z.object({
140
+ effort: z.string().optional(),
141
+ summary: z.enum(["auto", "concise", "detailed", "none"]).optional(),
142
+ });
143
+
144
+ export const stopSchema = z.union([z.string(), z.array(z.string()), z.null()]);
145
+
146
+ export const responsesRequestSchema = z.object({
147
+ model: z.string().min(1),
148
+ input: z.union([z.string(), z.array(inputItemSchema)]).optional(),
149
+ instructions: z.union([z.string(), z.null()]).optional(),
150
+ tools: z.array(z.union([toolSchema, builtinToolSchema])).optional(),
151
+ tool_choice: toolChoiceSchema.optional(),
152
+ max_output_tokens: z.number().optional(),
153
+ temperature: z.number().optional(),
154
+ top_p: z.number().optional(),
155
+ stop: stopSchema.optional(),
156
+ stream: z.boolean().optional(),
157
+ reasoning: reasoningConfigSchema.nullable().optional(),
158
+ store: z.boolean().optional(),
159
+ previous_response_id: z.string().optional(),
160
+ parallel_tool_calls: z.boolean().optional(),
161
+ prompt_cache_key: z.string().optional(),
162
+ metadata: z.unknown().optional(),
163
+ user: z.string().optional(),
164
+ service_tier: z.string().optional(),
165
+ presence_penalty: z.number().optional(),
166
+ frequency_penalty: z.number().optional(),
167
+ background: z.unknown().optional(),
168
+ include: z.unknown().optional(),
169
+ prompt: z.unknown().optional(),
170
+ text: z.unknown().optional(),
171
+ truncation: z.unknown().optional(),
172
+ });