Skip to content

Commit a2e6e1f

Browse files
committed
add retry logic to responsesAPI client
1 parent 9f8c7b2 commit a2e6e1f

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

src/server/routes/openai.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { FileSearchResultsStore } from '../services/azureFileSearch/fileSearchRe
1010
import { ResponsesClient } from '../util/azure/ResponsesAPI'
1111
import { DEFAULT_RAG_SYSTEM_PROMPT } from '../util/config'
1212
import logger from '../util/logger'
13-
import { isError } from '../util/parser'
13+
import { isError } from '../util/isError'
1414
import { pdfToText } from '../util/pdfToText'
1515
import getEncoding from '../util/tiktoken'
1616
import { getAllowedModels, getCourseModel, getMessageContext, getModelContextLimit } from '../util/util'
@@ -180,10 +180,6 @@ openaiRouter.post('/stream/v2', upload.single('file'), async (r, res) => {
180180
include: ragIndexId ? ['file_search_call.results'] : [],
181181
})
182182

183-
if (isError(events)) {
184-
throw new ApplicationError('Error creating a response stream', 424)
185-
}
186-
187183
res.setHeader('content-type', 'text/event-stream')
188184

189185
const result = await responsesClient.handleResponse({

src/server/util/azure/ResponsesAPI.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { createFileSearchTool } from './util'
1212
import { FileSearchResultsStore } from '../../services/azureFileSearch/fileSearchResultsStore'
1313
import { getAzureOpenAIClient } from './client'
1414
import { RagIndex } from '../../db/models'
15+
import OpenAI, { APIError } from 'openai'
16+
import { ApplicationError } from '../ApplicationError'
1517

1618
const client = getAzureOpenAIClient(process.env.GPT_4O_MINI ?? '')
1719

@@ -68,10 +70,12 @@ export class ResponsesClient {
6870
input,
6971
prevResponseId,
7072
include,
73+
attemptNumber = 1,
7174
}: {
7275
input: ResponseInput
7376
prevResponseId?: string
7477
include?: ResponseIncludable[]
78+
attemptNumber?: number
7579
}): Promise<Stream<ResponseStreamEvent> | APIError> {
7680
try {
7781
const sanitizedInput = validatedInputSchema.parse(input)
@@ -102,10 +106,16 @@ export class ResponsesClient {
102106
*/
103107
// background: true,
104108
})
105-
} catch (error: any) {
106-
logger.error(error)
107-
108-
return { error } as any as APIError
109+
} catch (error: unknown) {
110+
if (error instanceof OpenAI.APIError && attemptNumber < 3) {
111+
const retryDelay = 2 ** attemptNumber * 200
112+
logger.error(`Failed to create a response stream after ${attemptNumber} attempts. Retrying after ${retryDelay}ms`, { error })
113+
// Retry the request after a delay
114+
await new Promise((resolve) => setTimeout(resolve, retryDelay))
115+
return await this.createResponse({ prevResponseId, input, attemptNumber: attemptNumber + 1 })
116+
} else {
117+
throw ApplicationError.InternalServerError(`Failed to create a response stream after ${attemptNumber} attempts, sorry`, { extra: { error } })
118+
}
109119
}
110120
}
111121

File renamed without changes.

0 commit comments

Comments
 (0)