diff --git a/src/main/kotlin/pw/binom/llmproxy/Main.kt b/src/main/kotlin/pw/binom/llmproxy/Main.kt index 2bcfe2e..ed4bbd1 100644 --- a/src/main/kotlin/pw/binom/llmproxy/Main.kt +++ b/src/main/kotlin/pw/binom/llmproxy/Main.kt @@ -103,6 +103,10 @@ private suspend fun handleChat( return } + val start = System.currentTimeMillis() + val model = try { + json.parseToJsonElement(patched).jsonObject["model"]?.jsonPrimitive?.content ?: "?" + } catch (e: Exception) { "?" } val req = HttpRequest.newBuilder() .uri(URI.create(upstream.trimEnd('/') + "/chat/completions")) .header("Authorization", "Bearer $apiKey") @@ -111,17 +115,27 @@ private suspend fun handleChat( .build() val stream = json.parseToJsonElement(raw).jsonObject["stream"]?.jsonPrimitive?.content == "true" - if (stream) { - // SSE-стрим: транслируем как есть, чанк за чанком. - val resp = http.send(req, HttpResponse.BodyHandlers.ofInputStream()) - val ct = resp.headers().firstValue("content-type").orElse("text/event-stream") - call.respondOutputStream(ContentType.parse(ct), HttpStatusCode.fromValue(resp.statusCode())) { - resp.body().use { input -> input.copyTo(this, 8192) } + try { + if (stream) { + // SSE-стрим: транслируем как есть, чанк за чанком. + val resp = http.send(req, HttpResponse.BodyHandlers.ofInputStream()) + val ct = resp.headers().firstValue("content-type").orElse("text/event-stream") + call.respondOutputStream(ContentType.parse(ct), HttpStatusCode.fromValue(resp.statusCode())) { + resp.body().use { input -> input.copyTo(this, 8192) } + } + println("[llm-proxy] chat model=$model status=${resp.statusCode()} в ${System.currentTimeMillis() - start}ms stream=true") + } else { + val resp = http.send(req, HttpResponse.BodyHandlers.ofByteArray()) + val ct = resp.headers().firstValue("content-type").orElse("application/json") + call.respondBytes(resp.body(), ContentType.parse(ct), HttpStatusCode.fromValue(resp.statusCode())) + println("[llm-proxy] chat model=$model status=${resp.statusCode()} в ${System.currentTimeMillis() - start}ms stream=false") } - } else { - val resp = http.send(req, HttpResponse.BodyHandlers.ofByteArray()) - val ct = resp.headers().firstValue("content-type").orElse("application/json") - call.respondBytes(resp.body(), ContentType.parse(ct), HttpStatusCode.fromValue(resp.statusCode())) + } catch (e: Exception) { + println("[llm-proxy] chat model=$model ОШИБКА: ${e.message} в ${System.currentTimeMillis() - start}ms") + call.respondBytes( + """{"error":{"message":"upstream: ${e.message}"}}""".toByteArray(), + ContentType.Application.Json, HttpStatusCode.BadGateway, + ) } }