Spaces:
Runtime error
Runtime error
| import type { Context } from "hono" | |
| import consola from "consola" | |
| import { streamSSE } from "hono/streaming" | |
| import { awaitApproval } from "~/lib/approval" | |
| import { checkRateLimit } from "~/lib/rate-limit" | |
| import { state } from "~/lib/state" | |
| import { | |
| createChatCompletions, | |
| type ChatCompletionChunk, | |
| type ChatCompletionResponse, | |
| } from "~/services/copilot/create-chat-completions" | |
| import { | |
| type AnthropicMessagesPayload, | |
| type AnthropicStreamState, | |
| } from "./anthropic-types" | |
| import { | |
| translateToAnthropic, | |
| translateToOpenAI, | |
| } from "./non-stream-translation" | |
| import { translateChunkToAnthropicEvents } from "./stream-translation" | |
| export async function handleCompletion(c: Context) { | |
| await checkRateLimit(state) | |
| const anthropicPayload = await c.req.json<AnthropicMessagesPayload>() | |
| consola.debug("Anthropic request payload:", JSON.stringify(anthropicPayload)) | |
| const openAIPayload = translateToOpenAI(anthropicPayload) | |
| consola.debug( | |
| "Translated OpenAI request payload:", | |
| JSON.stringify(openAIPayload), | |
| ) | |
| if (state.manualApprove) { | |
| await awaitApproval() | |
| } | |
| const response = await createChatCompletions(openAIPayload) | |
| if (isNonStreaming(response)) { | |
| consola.debug( | |
| "Non-streaming response from Copilot:", | |
| JSON.stringify(response).slice(-400), | |
| ) | |
| const anthropicResponse = translateToAnthropic(response) | |
| consola.debug( | |
| "Translated Anthropic response:", | |
| JSON.stringify(anthropicResponse), | |
| ) | |
| return c.json(anthropicResponse) | |
| } | |
| consola.debug("Streaming response from Copilot") | |
| return streamSSE(c, async (stream) => { | |
| const streamState: AnthropicStreamState = { | |
| messageStartSent: false, | |
| contentBlockIndex: 0, | |
| contentBlockOpen: false, | |
| toolCalls: {}, | |
| } | |
| for await (const rawEvent of response) { | |
| consola.debug("Copilot raw stream event:", JSON.stringify(rawEvent)) | |
| if (rawEvent.data === "[DONE]") { | |
| break | |
| } | |
| if (!rawEvent.data) { | |
| continue | |
| } | |
| const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk | |
| const events = translateChunkToAnthropicEvents(chunk, streamState) | |
| for (const event of events) { | |
| consola.debug("Translated Anthropic event:", JSON.stringify(event)) | |
| await stream.writeSSE({ | |
| event: event.type, | |
| data: JSON.stringify(event), | |
| }) | |
| } | |
| } | |
| }) | |
| } | |
| const isNonStreaming = ( | |
| response: Awaited<ReturnType<typeof createChatCompletions>>, | |
| ): response is ChatCompletionResponse => Object.hasOwn(response, "choices") | |