From f45ed0d11c7f351c5e0b35fe3a83db5ade55a37d Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 20 Aug 2026 17:39:18 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3-=D0=BB=D0=BE=D0=B3=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D0=BE=D0=B2=20([llm-proxy]=20chat=20model=3D...=20status?= =?UTF-8?q?=3D...=20=D0=B2=20Nms)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/pw/binom/llmproxy/Main.kt | 34 ++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) 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, + ) } }