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 @@
-