feat: OCI 배포 듀얼 LLM 스위칭 및 신규 툴 DTO 의존성 주입 병합

This commit is contained in:
hjgram
2026-07-30 06:19:06 +09:00
parent 752aae4dde
commit 204dd04d5f
28 changed files with 1059 additions and 21 deletions

View File

@@ -43,12 +43,23 @@
<p class="text-[11px] text-slate-500">Powered by Mock Engine & MCP Tools</p>
</div>
</div>
<div class="flex items-center gap-2">
<span class="relative flex h-2.5 w-2.5">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
</span>
<span class="text-xs text-slate-400">Online</span>
<div class="flex items-center gap-4">
<!-- 모델 선택 Select Box 신설 -->
<select id="model-select" class="bg-[#1e2128] text-slate-300 text-xs px-3 py-1.5 rounded-lg border border-white/10 focus:outline-none focus:border-emerald-500/50 cursor-pointer">
<option value="gemini-flash-latest">Gemini 1.5 Flash (기본 - Google)</option>
<option value="google/gemma-4-31b-it:free">Gemma 4 31B (무료 - OpenRouter)</option>
<option value="inclusionai/ling-3.0-flash:free">Ling 3.0 Flash (무료 - OpenRouter)</option>
<option value="openai/gpt-oss-20b:free">GPT-OSS 20B (무료 - OpenRouter)</option>
<option value="cohere/north-mini-code:free">Cohere North Mini (무료 - OpenRouter)</option>
</select>
<div class="flex items-center gap-2">
<span class="relative flex h-2.5 w-2.5">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
</span>
<span class="text-xs text-slate-400">Online</span>
</div>
</div>
</div>
@@ -173,14 +184,12 @@
.replace(/'/g, "&#039;");
}
function removeMarkdownEmphasis(text) {
return text.replace(/\*\*/g, '');
}
async function sendMessage() {
const text = chatInput.value.trim();
if (!text || isLoading) return;
const selectedModel = document.getElementById('model-select').value;
// 1. 유저 메시지 추가
appendUserMessage(text);
chatInput.value = '';
@@ -197,7 +206,7 @@
'Content-Type': 'application/json',
'X-Agent-Id': 'TESTER-DEV' // 권한 통과를 위한 테스트 Agent ID
},
body: JSON.stringify({ message: text })
body: JSON.stringify({ message: text, model: selectedModel })
});
if (!response.ok) throw new Error('Network response was not ok');
@@ -209,7 +218,6 @@
// 5. 스트림 읽기
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
let responseText = '';
while (true) {
const { done, value } = await reader.read();
@@ -220,8 +228,7 @@
for (const line of lines) {
if (line.startsWith('data:')) {
const data = line.substring(5);
responseText += data;
textContainer.textContent = removeMarkdownEmphasis(responseText);
textContainer.innerHTML += escapeHtml(data);
scrollToBottom();
}
}