| 1 | import { ChatOpenAIResponses } from '@langchain/openai' |
| 2 | import type { OpenAI } from 'openai' |
| 3 | |
| 4 | export const OPENAI_RESPONSES_FORMAT_ERROR_ZH = |
| 5 | '当前 provider 返回的不是 OpenAI Responses API 格式。请确认 base_url 填写到 /v1(不要追加 /responses),并确认该服务支持 /v1/responses;如果只支持 /v1/chat/completions,请选择 OpenAI / 兼容 Chat Completions。' |
| 6 | export const OPENAI_RESPONSES_FORMAT_ERROR_EN = |
| 7 | 'The provider did not return an OpenAI Responses API payload. Use a base_url ending at /v1, confirm the service supports /v1/responses, or choose OpenAI / compatible Chat Completions if it only supports /v1/chat/completions.' |
| 8 | |
| 9 | export const OPENAI_RESPONSES_FORMAT_ERROR_CODE = 'OPENAI_RESPONSES_INVALID_PAYLOAD' |
| 10 | |
| 11 | export class OpenAIResponsesFormatError extends Error { |
| 12 | constructor() { |
| 13 | super(OPENAI_RESPONSES_FORMAT_ERROR_ZH) |
| 14 | this.name = OPENAI_RESPONSES_FORMAT_ERROR_CODE |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | export const isOpenAIResponsesFormatError = (error: unknown): boolean => { |
| 19 | if (error instanceof OpenAIResponsesFormatError) return true |
| 20 | if (error instanceof Error && error.name === OPENAI_RESPONSES_FORMAT_ERROR_CODE) return true |
| 21 | const message = error instanceof Error ? error.message : '' |
| 22 | return /Cannot read propert(?:y|ies).*undefined.*map|Cannot read propert(?:y|ies).*map.*undefined/i.test( |
| 23 | message |
| 24 | ) |
| 25 | } |
| 26 | |
| 27 | export class CompatibleChatOpenAIResponses extends ChatOpenAIResponses { |
| 28 | async completionWithRetry( |
| 29 | request: OpenAI.Responses.ResponseCreateParamsStreaming, |
| 30 | requestOptions?: OpenAI.RequestOptions |
| 31 | ): Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent>> |
| 32 | async completionWithRetry( |
| 33 | request: OpenAI.Responses.ResponseCreateParamsNonStreaming, |
| 34 | requestOptions?: OpenAI.RequestOptions |
| 35 | ): Promise<OpenAI.Responses.Response> |
| 36 | async completionWithRetry( |
| 37 | request: OpenAI.Responses.ResponseCreateParams, |
| 38 | requestOptions?: OpenAI.RequestOptions |
| 39 | ): Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent> | OpenAI.Responses.Response> { |
| 40 | const response = await super.completionWithRetry(request as never, requestOptions) |
| 41 | if (request?.stream === true) { |
| 42 | return response as AsyncIterable<OpenAI.Responses.ResponseStreamEvent> |
| 43 | } |
| 44 | |
| 45 | const responseRecord = response as { output?: unknown } |
| 46 | if (!responseRecord || !Array.isArray(responseRecord.output)) { |
| 47 | throw new OpenAIResponsesFormatError() |
| 48 | } |
| 49 | return response |
| 50 | } |
| 51 | } |
| 52 |