Showing the changes to apps/server/src/provider/codex (2 of 5 files). Show all
Unified · Split
| @@ -171,6 +171,27 @@ describe("isRecoverableThreadResumeError", () => { · 170 unmodified lines | |||
| 171 | false, | 171 | false, |
| 172 | ); | 172 | ); |
| 173 | }); | 173 | }); |
| 174 | |||
| 175 | it("ignores unrelated missing-resource errors that do not mention threads", () => { | ||
| 176 | assert.equal( | ||
| 177 | isRecoverableThreadResumeError( | ||
| 178 | new CodexErrors.CodexAppServerRequestError({ | ||
| 179 | code: -32603, | ||
| 180 | errorMessage: "Config file not found", | ||
| 181 | }), | ||
| 182 | ), | ||
| 183 | false, | ||
| 184 | ); | ||
| 185 | assert.equal( | ||
| 186 | isRecoverableThreadResumeError( | ||
| 187 | new CodexErrors.CodexAppServerRequestError({ | ||
| 188 | code: -32603, | ||
| 189 | errorMessage: "Model does not exist", | ||
| 190 | }), | ||
| 191 | ), | ||
| 192 | false, | ||
| 193 | ); | ||
| 194 | }); | ||
| 174 | }); | 195 | }); |
| 175 | 196 | ||
| 176 | describe("openCodexThread", () => { | 197 | describe("openCodexThread", () => { |
| @@ -383,6 +383,9 @@ function classifyCodexStderrLine(rawLine: string): { readonly message: string } · 382 unmodified lines | |||
| 383 | 383 | ||
| 384 | export function isRecoverableThreadResumeError(error: unknown): boolean { | 384 | export function isRecoverableThreadResumeError(error: unknown): boolean { |
| 385 | const message = (error instanceof Error ? error.message : String(error)).toLowerCase(); | 385 | const message = (error instanceof Error ? error.message : String(error)).toLowerCase(); |
| 386 | if (!message.includes("thread")) { | ||
| 387 | return false; | ||
| 388 | } | ||
| 386 | return RECOVERABLE_THREAD_RESUME_ERROR_SNIPPETS.some((snippet) => message.includes(snippet)); | 389 | return RECOVERABLE_THREAD_RESUME_ERROR_SNIPPETS.some((snippet) => message.includes(snippet)); |
| 387 | } | 390 | } |
| 388 | 391 | ||
| @@ -390,8 +393,17 @@ type CodexThreadOpenResponse = · 1 unmodified line | |||
| 390 | | CodexRpc.ClientRequestResponsesByMethod["thread/start"] | 393 | | CodexRpc.ClientRequestResponsesByMethod["thread/start"] |
| 391 | | CodexRpc.ClientRequestResponsesByMethod["thread/resume"]; | 394 | | CodexRpc.ClientRequestResponsesByMethod["thread/resume"]; |
| 392 | 395 | ||
| 396 | type CodexThreadOpenMethod = "thread/start" | "thread/resume"; | ||
| 397 | |||
| 398 | interface CodexThreadOpenClient { | ||
| 399 | readonly request: <M extends CodexThreadOpenMethod>( | ||
| 400 | method: M, | ||
| 401 | payload: CodexRpc.ClientRequestParamsByMethod[M], | ||
| 402 | ) => Effect.Effect<CodexRpc.ClientRequestResponsesByMethod[M], CodexErrors.CodexAppServerError>; | ||
| 403 | } | ||
| 404 | |||
| 393 | export const openCodexThread = (input: { | 405 | export const openCodexThread = (input: { |
| 394 | readonly client: CodexClient.CodexAppServerClientShape; | 406 | readonly client: CodexThreadOpenClient; |
| 395 | readonly threadId: ThreadId; | 407 | readonly threadId: ThreadId; |
| 396 | readonly runtimeMode: RuntimeMode; | 408 | readonly runtimeMode: RuntimeMode; |
| 397 | readonly cwd: string; | 409 | readonly cwd: string; |
| @@ -1288,6 +1300,7 @@ export const makeCodexSessionRuntime = ( · 890 unmodified lines | |||
| 1288 | requestId, | 1300 | requestId, |
| 1289 | }); | 1301 | }); |
| 1290 | } | 1302 | } |
| 1303 | const codexAnswers = yield* toCodexUserInputAnswers(answers); | ||
| 1291 | yield* Ref.update(pendingUserInputsRef, (current) => { | 1304 | yield* Ref.update(pendingUserInputsRef, (current) => { |
| 1292 | const next = new Map(current); | 1305 | const next = new Map(current); |
| 1293 | next.delete(requestId); | 1306 | next.delete(requestId); |
| @@ -1302,7 +1315,7 @@ export const makeCodexSessionRuntime = ( · 8 unmodified lines | |||
| 1302 | ...(pending.turnId ? { turnId: pending.turnId } : {}), | 1315 | ...(pending.turnId ? { turnId: pending.turnId } : {}), |
| 1303 | ...(pending.itemId ? { itemId: pending.itemId } : {}), | 1316 | ...(pending.itemId ? { itemId: pending.itemId } : {}), |
| 1304 | payload: { | 1317 | payload: { |
| 1305 | answers: yield* toCodexUserInputAnswers(answers), | 1318 | answers: codexAnswers, |
| 1306 | }, | 1319 | }, |
| 1307 | }); | 1320 | }); |
| 1308 | }), | 1321 | }), |