(
prompt: string,
referenceImage?: { buffer: Buffer; mimeType: string },
updateStatus?: StatusUpdater,
deadlineAt: number = Date.now() + CODEX_MAX_WAIT_MS,
)
| 139 | `缺少鉴权,请先使用 ${mainPrefix}cximg token 你的codex access token(通常在 .codex/auth.json) 保存 Token`, |
| 140 | ); |
| 141 | } |
| 142 | |
| 143 | const content = referenceImage |
| 144 | ? [ |
| 145 | { type: "input_text", text: prompt }, |
| 146 | { |
| 147 | type: "input_image", |
| 148 | image_url: `data:${referenceImage.mimeType};base64,${referenceImage.buffer.toString("base64")}`, |
| 149 | }, |
| 150 | ] |
| 151 | : prompt; |
| 152 | |
| 153 | const payload = { |
| 154 | model: CODEX_MODEL, |
| 155 | instructions: "You are a helpful assistant. Use tools when available.", |
| 156 | input: [ |
| 157 | { |
| 158 | role: "user", |
| 159 | content, |
| 160 | }, |
| 161 | ], |
| 162 | store: false, |
| 163 | tools: [{ type: "image_generation" }], |
| 164 | reasoning: { effort: "low" }, |
| 165 | include: [], |
| 166 | tool_choice: "auto", |
| 167 | parallel_tool_calls: true, |
| 168 | prompt_cache_key: null, |
| 169 | stream: true, |
| 170 | }; |
| 171 | |
| 172 | const headers = { |
| 173 | Authorization: `Bearer ${token}`, |
| 174 | "Content-Type": "application/json", |
| 175 | }; |
| 176 | |
| 177 | const readStreamResult = async (): Promise<CodexResponseResult> => { |
| 178 | const response = await axios.post(CODEX_URL, payload, { |
| 179 | responseType: "stream", |
| 180 | timeout: Math.max(1000, deadlineAt - Date.now()), |
| 181 | headers, |
| 182 | }); |
| 183 | |
| 184 | let buffer = ""; |
| 185 | let imageBase64: string | null = null; |
| 186 | let revisedPrompt: string | null = null; |
| 187 | let status: string | null = null; |
| 188 | let responseId: string | null = null; |
| 189 | |
| 190 | for await (const chunk of response.data) { |
| 191 | buffer += chunk.toString("utf8"); |
| 192 | |
| 193 | let delimiterIndex = buffer.indexOf("\n\n"); |
| 194 | while (delimiterIndex !== -1) { |
| 195 | const rawEvent = buffer.slice(0, delimiterIndex); |
| 196 | buffer = buffer.slice(delimiterIndex + 2); |
| 197 | |
| 198 | const dataLines = rawEvent |
no test coverage detected