@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.
- package/LICENSE +21 -21
- package/README.md +140 -140
- package/cordis.patch.yml +4 -4
- package/lib/cli.js +13269 -11860
- package/lib/plugin.js +3 -50
- package/package.json +89 -88
- package/src/adapters/base.ts +16 -16
- package/src/adapters/chatgpt-web/adapter-error.ts +59 -59
- package/src/adapters/chatgpt-web/browser-helper-main.ts +513 -513
- package/src/adapters/chatgpt-web/browser-helper-prompt-selection.ts +27 -27
- package/src/adapters/chatgpt-web/browser-worker.ts +4944 -4944
- package/src/adapters/chatgpt-web/codex-rollout-environment.ts +628 -628
- package/src/adapters/chatgpt-web/compaction-handoff.ts +533 -533
- package/src/adapters/chatgpt-web/compaction-transaction.ts +142 -142
- package/src/adapters/chatgpt-web/concurrency.ts +6 -6
- package/src/adapters/chatgpt-web/conversation-key.ts +58 -58
- package/src/adapters/chatgpt-web/environment.ts +669 -669
- package/src/adapters/chatgpt-web/index.ts +1544 -1544
- package/src/adapters/chatgpt-web/input-tokens.ts +74 -74
- package/src/adapters/chatgpt-web/launcher-helper-client.ts +695 -695
- package/src/adapters/chatgpt-web/markdown.ts +418 -418
- package/src/adapters/chatgpt-web/mcp-main.ts +25 -25
- package/src/adapters/chatgpt-web/mcp-server.ts +933 -933
- package/src/adapters/chatgpt-web/model.ts +70 -70
- package/src/adapters/chatgpt-web/native-compaction-control.ts +74 -74
- package/src/adapters/chatgpt-web/output-validation.ts +62 -62
- package/src/adapters/chatgpt-web/process-line-writer.ts +46 -46
- package/src/adapters/chatgpt-web/prompt.ts +702 -702
- package/src/adapters/chatgpt-web/retry-policy.ts +73 -73
- package/src/adapters/chatgpt-web/rolling-checkpoint.ts +384 -384
- package/src/adapters/chatgpt-web/thread-environment.ts +238 -238
- package/src/adapters/chatgpt-web/tool-stream-parser.ts +1 -1
- package/src/adapters/chatgpt-web/turn-broker.ts +1481 -1481
- package/src/adapters/chatgpt-web/turn-execution.ts +816 -816
- package/src/adapters/chatgpt-web/turn-progress.ts +292 -292
- package/src/adapters/chatgpt-web/usage.ts +121 -121
- package/src/adapters/image.ts +9 -9
- package/src/bridge.ts +1083 -1083
- package/src/browser-login.ts +521 -521
- package/src/chatgpt-session.ts +240 -240
- package/src/chatgpt-web-models.ts +400 -400
- package/src/cli.ts +568 -568
- package/src/codex-integration-document.ts +824 -824
- package/src/codex-integration-journal.ts +212 -212
- package/src/codex-integration-route.ts +515 -515
- package/src/codex-integration-shared.ts +332 -332
- package/src/codex-integration.ts +529 -529
- package/src/codex-interrupt-hook.ts +158 -158
- package/src/config.ts +616 -616
- package/src/dev-chat/cli.ts +432 -432
- package/src/dev-chat/constants.ts +3 -3
- package/src/dev-chat/driver.ts +655 -655
- package/src/dev-chat/profile.ts +223 -223
- package/src/dev-chat/session.ts +287 -287
- package/src/dev-chat/transport.ts +54 -54
- package/src/doctor.ts +237 -237
- package/src/event-queue.ts +45 -45
- package/src/http-body.ts +30 -30
- package/src/launcher-browser-host.ts +695 -695
- package/src/lib/errors.ts +281 -281
- package/src/lib/token-estimate.ts +42 -42
- package/src/login-helper.cjs +1 -1
- package/src/model-catalog.ts +197 -197
- package/src/native-passthrough.ts +261 -261
- package/src/plugin.ts +191 -191
- package/src/process.ts +45 -45
- package/src/responses/compaction.ts +199 -199
- package/src/responses/parser.ts +633 -633
- package/src/responses/reasoning-envelope.ts +49 -49
- package/src/responses/schema.ts +172 -172
- package/src/responses/state.ts +230 -230
- package/src/server.ts +1111 -1111
- package/src/service.ts +315 -315
- package/src/setup.ts +671 -671
- package/src/stall-timeout.ts +23 -23
- package/src/tunnel-service.ts +160 -160
- package/src/tunnel.ts +417 -417
- package/src/turndown-plugin-gfm.d.ts +5 -5
- package/src/types.ts +307 -307
- package/src/usage/totals.ts +12 -12
- 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
|
+
}
|
package/src/responses/schema.ts
CHANGED
|
@@ -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
|
+
});
|