From c95d1782e10e6f6d7edee0a0e25f4f995620cc9f Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 13 Apr 2026 12:09:43 +0900 Subject: [PATCH] feat: v1.0.11 - Dual AI engine & UI update --- README.md | 142 ++++++++++++++++++----------------------------- src/extension.ts | 53 ++++++++++++++++-- 2 files changed, 102 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 27a3074..92fc9cf 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,77 @@ -# ✦ Connect AI LAB +# ✦ Connect AI LAB **100% 로컬 · 100% 오프라인 · 100% 무료** -VS Code / Cursor / Antigravity에서 작동하는 프리미엄 AI 코딩 에이전트 +VS Code / Cursor 기반의 프리미엄 AI 코딩 에이전트입니다. 코드를 읽고, 작성하고, 터미널 명령어를 대신 실행해 줍니다. +이 프로젝트는 **EZERAI**와 **Connect AI LAB**이 함께 연구하고 제작했습니다. --- -## ✨ 핵심 기능 +## ✨ 핵심 기능 (v1.0.11 업데이트) + +### 🚀 듀얼 AI 엔진 (Hybrid Backend) 완벽 지원! +이제 사용자 취향과 컴퓨터 사양에 맞춰 세상에서 제일 강력한 2가지 로컬 AI 엔진을 모두 지원합니다. +- **Ollama (기본 모드):** 초보자에게 추천합니다! 별도의 설정 없이 백그라운드에서 조용하고 강력하게 작동합니다. +- **LM Studio (고급 모드):** 맥북 유저나 고급 VRAM 관리가 필요한 분들께 강력히 추천합니다! 글로벌 표준 OpenAI(ChatGPT) 통신 규격과 100% 호환 적용 완료! | 기능 | 설명 | |:--|:--| +| ⚙️ **실시간 엔진 스위칭 UI** | 채팅창의 톱니바퀴 한 번 클릭으로 즉시 Ollama ↔ LM Studio 변환 및 자동 설정 완료 | +| 🛡️ **스마트 오토-페일오버** | Ollama가 응답하지 않을 경우, 플러그인이 스스로 0.1초 만에 LM Studio로 우회하여 안정적인 작업을 보장합니다. | | 📁 **파일 자동 생성** | "포트폴리오 사이트 만들어줘" → 폴더/파일 자동 생성 및 에디터 오픈 | -| ✏️ **기존 파일 편집** | "배경색 바꿔줘" → 해당 코드를 찾아 정확히 교체 | -| 🖥️ **터미널 명령 실행** | "express 설치해줘" → `npm install express` 자동 실행 | -| 🔍 **프로젝트 자동 분석** | 파일 구조 + 핵심 파일 내용을 AI가 자동으로 읽고 이해 | -| 💾 **대화 기록 저장** | VS Code를 닫았다 열어도 이전 대화가 그대로 유지 | -| 🎨 **코드 구문 강조** | highlight.js 기반 전문 코드 하이라이팅 | +| ✏️ **기존 파일 편집** | "배경색 바꿔줘" → 해당 코드를 찾아 정확히 교체 (자율주행 코딩) | +| 🖥️ **터미널 명령 실행** | "express 설치해줘" → `npm install express` 자동 실행 대기 | -## 📥 설치 방법 +--- -### 방법 1: VSIX 파일 설치 (가장 간단) +## 📥 설치 방법 (상세 가이드) -1. [Releases](https://github.com/wonseokjung/connect-ai/releases)에서 `.vsix` 파일 다운로드 -2. VS Code / Cursor / Antigravity 열기 -3. `Cmd+Shift+P` (Mac) 또는 `Ctrl+Shift+P` (Windows) -4. `Extensions: Install from VSIX` 검색 → 다운받은 파일 선택 -5. 완료! 🎉 - -### 방법 2: 소스에서 빌드 +### 방법 1: VSIX 파일 즉시 설치 (가장 간단) +1. Github [Releases](https://github.com/wonseokjung/connect-ai/releases) 메뉴에서 최신 `.vsix` 파일을 다운로드합니다. +2. VS Code(또는 Cursor)를 엽니다. +3. 단축키 `Cmd+Shift+P` (맥) 또는 `Ctrl+Shift+P` (윈도우)를 눌러 명령어 팔레트를 엽니다. +4. **`Extensions: Install from VSIX`** 를 검색하여 선택한 후, 방금 다운로드한 파일을 고릅니다. 끝! 🎉 +### 방법 2: 플러그인 소스 직접 빌드 ```bash git clone https://github.com/wonseokjung/connect-ai.git cd connect-ai npm install npm run compile +vsce package ``` -## ⚙️ 사전 준비: Ollama 설치 - -Connect AI LAB은 로컬 AI 서버인 **Ollama**를 사용합니다. - -### 1. Ollama 설치 -```bash -# Mac (Homebrew) -brew install ollama - -# 또는 공식 사이트에서 다운로드 -# https://ollama.com -``` - -### 2. AI 모델 다운로드 -```bash -# Gemma 4 (추천, Google 최신 모델) -ollama pull gemma4:e2b - -# 또는 다른 모델 -ollama pull llama3.3 -ollama pull deepseek-r1 -ollama pull codestral -``` - -### 3. Ollama 서버 실행 -```bash -ollama serve -``` - -## 🚀 사용 방법 - -1. **폴더 열기**: `File → Open Folder` → 프로젝트 폴더 선택 -2. **사이드바 클릭**: 왼쪽 로봇 아이콘 (🤖) -3. **대화 시작**: 자연어로 요청하면 AI가 자동으로 파일을 만들고 편집합니다! - -### 예시 프롬프트: -``` -간단한 Express 서버를 만들어줘 -이 프로젝트에 라우터 추가해줘 -package.json의 description을 바꿔줘 -express 패키지 설치해줘 -``` - -## ⚙️ 설정 변경 - -`File > Preferences > Settings`에서 "Connect AI LAB" 검색: - -| 설정 | 기본값 | 설명 | -|:--|:--|:--| -| `ollamaUrl` | `http://127.0.0.1:11434` | Ollama 서버 주소 | -| `defaultModel` | `gemma4:e2b` | 기본 AI 모델 | -| `maxContextFiles` | `200` | 컨텍스트에 포함할 최대 파일 수 | -| `requestTimeout` | `300` | AI 응답 대기 시간 (초) | - -## 🔒 프라이버시 - -- ❌ 클라우드 서버 없음 -- ❌ 데이터 수집 없음 -- ❌ 인터넷 연결 불필요 -- ✅ 모든 데이터는 내 컴퓨터 안에서만 처리 - -## 🤝 기여 - -Pull Request와 Issue를 환영합니다! - -## 📄 라이선스 - -MIT License — 자유롭게 사용, 수정, 배포 가능합니다. - --- -**Made with ❤️ by Connect AI LAB — 여러분의 AI 멘토 Jay** +## ⚙️ AI 엔진 세팅 가이드 (Ollama / LM Studio) + +Connect AI LAB은 사용자의 컴퓨터 자원 안에서 돌아가는 오프라인 모델을 사용합니다. 아래 두 가지 엔진 중 편하신 것을 하나 사용하세요. + +### 🟡 Option A: Ollama 설정 (초보자 추천) +1. **설치:** [Ollama 공식 홈페이지](https://ollama.com)에서 다운로드 또는 `brew install ollama` +2. **모델 다운로드:** 터미널을 열고 구글 최신 모델인 Gemma4를 받습니다. +```bash +ollama pull gemma4:e2b +``` +3. **가동:** 백그라운드에서 자동으로 켜져 있습니다. (VS Code에서 Connect AI 채팅창의 ⚙️ 버튼을 눌러 `Ollama`가 선택되어 있는지 확인하세요!) + +### 🔵 Option B: LM Studio 설정 (애플 실리콘 맥 유저 고속도 추천) +1. **설치:** [LM Studio 공식 홈페이지](https://lmstudio.ai/)에서 다운로드합니다. +2. **모델 다운로드:** 프로그램 내부에서 원하는 모델(예: `Gemma4` 또는 Llama)을 검색해 다운로드합니다. +3. **로컬 서버 열기:** + - LM Studio 좌측 메뉴 중 **`<->` 모양 아이콘(Local Server)**을 클릭합니다. + - 상단에서 다운로드한 모델을 고르고 **[Start Server]** 초록색 버튼을 누릅니다. (`1234` 포트로 열림) +4. VS Code로 돌아와 Connect AI 채팅창의 **⚙️ 톱니바퀴 버튼**을 누르고 **`LM Studio (고급형)`**을 클릭하세요. (설정이 연동되며 1초 만에 곧바로 통신을 시작합니다!) + +--- + +## 🔒 절대 프라이버시 원칙 +- ❌ **클라우드 서버 없음 / 인터넷 연결 불필요** +- ❌ **데이터 수집 없음** (작성된 모든 코드는 컴퓨터 밖으로 나가지 않습니다.) +- ✅ 회사/개인 프로젝트 보안 유지의 최적해 + +--- + +## 📄 라이선스 +MIT License — 자유롭게 사용, 수정, 배포 가능합니다. + +**Designed & Developed with ❤️ by EZERAI and Connect AI LAB** diff --git a/src/extension.ts b/src/extension.ts index 81c50c2..0089cab 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -225,6 +225,19 @@ class SidebarChatProvider implements vscode.WebviewViewProvider { // 웹뷰가 준비되면 저장된 대화 기록 복원 this._restoreDisplayMessages(); break; + case 'openSettings': + const choice = await vscode.window.showQuickPick([ + { label: 'Ollama (로컬 기본)', description: '초보자 추천', target: 'http://127.0.0.1:11434' }, + { label: 'LM Studio (고급형)', description: '맥북/고급 유저 추천', target: 'http://127.0.0.1:1234' } + ], { placeHolder: '사용할 AI 엔진을 선택하세요 (선택 시 즉시 적용됩니다)' }); + if (choice) { + await vscode.workspace.getConfiguration('connectAiLab').update('ollamaUrl', choice.target, vscode.ConfigurationTarget.Global); + vscode.window.showInformationMessage(`✅ AI 엔진이 [${choice.label}] 로 변경되었습니다!`); + + // 사용자가 엔진을 바꾸자마자 즉시 바뀐 엔진의 모델 명단을 긁어와 웹뷰 목록(Dropdown)을 갱신합니다! + await this._sendModels(); + } + break; } }); @@ -239,8 +252,19 @@ class SidebarChatProvider implements vscode.WebviewViewProvider { if (!this._view) { return; } const { ollamaBase, defaultModel } = getConfig(); try { - const res = await axios.get(`${ollamaBase}/api/tags`, { timeout: 3000 }); - let models: string[] = res.data.models.map((m: any) => m.name); + const isLMStudio = ollamaBase.includes('1234') || ollamaBase.includes('v1'); + let models: string[] = []; + + if (isLMStudio) { + const res = await axios.get(`${ollamaBase}/v1/models`, { timeout: 3000 }); + // LM Studio (OpenAI 규격) 응답 파싱 + models = res.data.data.map((m: any) => m.id); + } else { + const res = await axios.get(`${ollamaBase}/api/tags`, { timeout: 3000 }); + // Ollama 규격 응답 파싱 + models = res.data.models.map((m: any) => m.name); + } + if (models.length === 0) { models = [defaultModel]; } else if (!models.includes(defaultModel)) { @@ -378,13 +402,29 @@ class SidebarChatProvider implements vscode.WebviewViewProvider { }; } - const response = await axios.post(`${ollamaBase}/api/chat`, { + let isLMStudio = ollamaBase.includes('1234') || ollamaBase.includes('v1'); + let apiUrl = isLMStudio ? `${ollamaBase}/v1/chat/completions` : `${ollamaBase}/api/chat`; + + // Auto-Failover Logic: 유저가 설정을 안 건드렸더라도 Ollama가 죽어있으면 자동으로 LM Studio를 찾아갑니다! + if (!isLMStudio) { + try { + await axios.get(`${ollamaBase}/api/tags`, { timeout: 1000 }); + } catch (err: any) { + // Ollama 연결 실패 시 LM Studio 1234 포트로 강제 우회 + apiUrl = 'http://127.0.0.1:1234/v1/chat/completions'; + isLMStudio = true; + } + } + + const response = await axios.post(apiUrl, { model: modelName || defaultModel, messages: reqMessages, stream: false, }, { timeout }); - const aiMessage: string = response.data.message.content; + const aiMessage: string = isLMStudio + ? response.data.choices[0].message.content + : response.data.message.content; this._chatHistory.push({ role: 'assistant', content: aiMessage }); // 5. Execute agent actions @@ -604,7 +644,7 @@ textarea::placeholder{color:var(--text-dim)} @keyframes shimmer{0%{left:-40px}100%{left:120px}} @keyframes pulse{0%,100%{opacity:.5}50%{opacity:1}} -
Connect AI
+
Connect AI
@@ -619,7 +659,7 @@ textarea::placeholder{color:var(--text-dim)} try { const vscode=acquireVsCodeApi(),chat=document.getElementById('chat'),input=document.getElementById('input'), sendBtn=document.getElementById('sendBtn'),stopBtn=document.getElementById('stopBtn'), -modelSel=document.getElementById('modelSel'),newChatBtn=document.getElementById('newChatBtn'); +modelSel=document.getElementById('modelSel'),newChatBtn=document.getElementById('newChatBtn'),settingsBtn=document.getElementById('settingsBtn'); let loader=null,sending=false; vscode.postMessage({type:'getModels'}); setTimeout(()=>vscode.postMessage({type:'ready'}),300); @@ -657,6 +697,7 @@ document.addEventListener('click',e=>{if(e.target.classList.contains('qa-btn')){ sendBtn.addEventListener('click',send); input.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();send()}}); newChatBtn.addEventListener('click',()=>vscode.postMessage({type:'newChat'})); +settingsBtn.addEventListener('click',()=>vscode.postMessage({type:'openSettings'})); window.addEventListener('message',e=>{const msg=e.data;switch(msg.type){ case 'response':hideLoader();setSending(false);addMsg(msg.value,'ai');break; case 'error':hideLoader();setSending(false);addMsg(msg.value,'error');break;