From 2c4c447a8f1e4006e185095e4dd819f802d5d4e2 Mon Sep 17 00:00:00 2001 From: Gitea CI Date: Thu, 30 Jul 2026 07:28:56 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20OpenRouter=20=EC=8B=A4=EC=A1=B4=20?= =?UTF-8?q?=EB=AC=B4=EB=A3=8C=20=EB=AA=A8=EB=8D=B8=20=EA=B5=90=EC=B2=B4=20?= =?UTF-8?q?=EB=B0=8F=20Gemini=20API=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - chat.html: 드롭다운을 검증된 무료 모델로 교체 * Ling 3.0 Flash (inclusionai/ling-3.0-flash:free) 기본값으로 설정 * GPT-OSS 20B, Gemma 4 31B, NVIDIA Nemotron Nano, Cohere North Mini 추가 * 삭제된 모델(qwen-2-7b, llama-3-8b, openchat-7b 등) 제거 - ChatController.java: Gemini 직접 API(비정상 키) 제거 * gemini-flash-latest 선택 시 OpenRouter Google Gemma 4 31B 로 라우팅 * 불필요한 70여 라인 직접 HTTP 호출 코드 제거 - E2E 검증 완료: Ling 3.0 Flash 정상 응답 확인 --- .../dap/mcg/presentation/ChatController.java | 58 ++----------------- .../src/main/resources/static/chat.html | 8 +-- 2 files changed, 8 insertions(+), 58 deletions(-) diff --git a/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/ChatController.java b/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/ChatController.java index 58f06561..2fc9c068 100644 --- a/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/ChatController.java +++ b/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/ChatController.java @@ -79,60 +79,10 @@ public class ChatController { selectedModel = "gemini-flash-latest"; } - // 1. Google Gemini 무료 티어 직접 API 연동 (사용량 및 컴파일 충돌 차단용 Short-circuit) + // 1. gemini-flash-latest 선택 시 OpenRouter의 Google Gemma 4 모델로 라우팅 if (selectedModel.equals("gemini-flash-latest")) { - String geminiKey = "AQ.Ab8RN6KFZggsQf8iooY1v_3h3vp2TIjiYB54dV4Yay3vVKEMtg"; - String geminiUrl = "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions"; - - Map body = new HashMap<>(); - body.put("model", "gemini-1.5-flash"); - body.put("stream", true); - body.put("messages", List.of(Map.of("role", "user", "content", message))); - - try { - java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient(); - java.net.http.HttpRequest httpRequest = java.net.http.HttpRequest.newBuilder() - .uri(java.net.URI.create(geminiUrl)) - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + geminiKey) - .POST(java.net.http.HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(body))) - .build(); - - httpClient.sendAsync(httpRequest, java.net.http.HttpResponse.BodyHandlers.ofLines()) - .thenAccept(response -> { - response.body().forEach(line -> { - try { - if (line.startsWith("data: ")) { - String jsonStr = line.substring(6).trim(); - if (!jsonStr.equals("[DONE]")) { - JsonNode node = objectMapper.readTree(jsonStr); - String text = node.path("choices").path(0).path("delta").path("content").asText(""); - if (!text.isEmpty()) { - emitter.send(text); - } - } - } - } catch (Exception e) { - log.error("Gemini stream parse error: {}", e.getMessage()); - } - }); - emitter.complete(); - }) - .exceptionally(ex -> { - log.error("Gemini stream connection failed", ex); - try { - emitter.send("\n\n⚠️ **Gemini API 호출에 실패했습니다.** (" + ex.getMessage() + ")"); - } catch (Exception ignored) {} - emitter.completeWithError(ex); - return null; - }); - log.info("[Real AI Chat] 구글 제미나이 다이렉트 API 스트리밍 개시 완료!"); - return emitter; - } catch (Exception e) { - log.error("Gemini direct API setup error", e); - emitter.completeWithError(e); - return emitter; - } + selectedModel = "google/gemma-4-31b-it:free"; + log.info("[Real AI Chat] Gemini 직접 API → OpenRouter Google Gemma 4 31B 로 라우팅 전환"); } // 2. OpenRouter 무료 모델 처리 (Spring AI 빌드된 ChatClient 및 MCP 툴 호출 완벽 지원!) @@ -167,7 +117,7 @@ public class ChatController { } else if (errorMsg != null && errorMsg.contains("503")) { emitter.send("\n\n⚠️ **AI 모델 서버 혼잡 (503)**: 현재 AI 모델을 제공하는 서버에 일시적으로 접속자가 많아 지연이 발생하고 있습니다. 잠시 후 다시 시도해 주세요."); } else if (errorMsg != null && errorMsg.contains("429")) { - emitter.send("\n\n⚠️ **API 사용량 초과 (429)**: 현재 사용 중인 Gemini API(무료 티어)의 일일 또는 분당 요청 한도를 초과했습니다. 잠시 후 다시 시도하시거나 API 플랜을 확인해 주세요."); + emitter.send("\n\n⚠️ **API 사용량 초과 (429)**: AI 모델 API(무료 티어 또는 오픈라우터)의 요청 한도를 초과했습니다. 잠시 후 다시 시도하시거나 API 키의 유효 한도를 확인해 주세요."); } else { emitter.send("\n[에러 발생: " + errorMsg + "]"); } diff --git a/dap-gateway/src/main/resources/static/chat.html b/dap-gateway/src/main/resources/static/chat.html index 193fab87..9346d2e3 100644 --- a/dap-gateway/src/main/resources/static/chat.html +++ b/dap-gateway/src/main/resources/static/chat.html @@ -44,13 +44,13 @@
-