Commit
Retry interview turn once on schema mismatch
commit
643b481
1 changed file with +20 and −11
modified server/providers/llmAnthropic.ts +20 −11
| @@ -44,18 +44,27 @@export function createLlmAnthropic(): InterviewLlm { | ||
| 44 | 44 | |
| 45 | 45 | return { |
| 46 | 46 | async nextTurn(context: InterviewContext): Promise<InterviewTurn> { |
| 47 | - const message = await client.messages.parse({ | |
| 48 | - model, | |
| 49 | - max_tokens: INTERVIEW_MAX_TOKENS, | |
| 50 | - thinking: { type: 'adaptive' }, | |
| 51 | - system: buildInterviewSystemPrompt(context), | |
| 52 | - messages: [{ role: 'user', content: buildInterviewUserMessage(context) }], | |
| 53 | - output_config: { format: zodOutputFormat(InterviewTurnSchema) }, | |
| 54 | - }) | |
| 55 | - if (!message.parsed_output) { | |
| 56 | - throw new Error('Anthropic response did not include a parsed InterviewTurn') | |
| 47 | + const runTurn = async (): Promise<InterviewTurn> => { | |
| 48 | + const message = await client.messages.parse({ | |
| 49 | + model, | |
| 50 | + max_tokens: INTERVIEW_MAX_TOKENS, | |
| 51 | + thinking: { type: 'adaptive' }, | |
| 52 | + system: buildInterviewSystemPrompt(context), | |
| 53 | + messages: [{ role: 'user', content: buildInterviewUserMessage(context) }], | |
| 54 | + output_config: { format: zodOutputFormat(InterviewTurnSchema) }, | |
| 55 | + }) | |
| 56 | + if (!message.parsed_output) { | |
| 57 | + throw new Error('Anthropic response did not include a parsed InterviewTurn') | |
| 58 | + } | |
| 59 | + return message.parsed_output | |
| 60 | + } | |
| 61 | + try { | |
| 62 | + return await runTurn() | |
| 63 | + } catch (err) { | |
| 64 | + // API errors were already retried by the SDK; retry once only on schema/parse failures | |
| 65 | + if (err instanceof Anthropic.APIError) throw err | |
| 66 | + return runTurn() | |
| 57 | 67 | } |
| 58 | - return message.parsed_output | |
| 59 | 68 | }, |
| 60 | 69 | |
| 61 | 70 | async generateFile(request: GenerateFileRequest): Promise<string> { |