# Nexus Agent Platform

> **Nexus** — 라틴어 *nectere*(묶다, 연결하다)에서 유래한 말로 **'연결', '결속', '중심점'**을 뜻합니다.

**Nexus Agent**는 AI와 실제 업무 사이의 간극을 연결하기 위해 만들어진 풀스택 AI 에이전트 플랫폼입니다. 파편화된 도구, 문서, 코드, 워크스페이스를 하나의 대화형 인터페이스로 묶어 — AI가 단순한 챗봇이 아니라 **실무를 함께 수행하는 동료**가 되도록 설계되었습니다.

MCP(Model Context Protocol)를 통해 외부 도구와 연결하고, Agent Skills로 반복 업무를 자동화하며, Workspace를 통해 실제 프로젝트 파일을 직접 읽고 쓰고 실행합니다. 대화 속에서 축적되는 장기 기억(Memory)은 사용자의 맥락을 기억하여 매번 처음부터 설명할 필요 없이 연속적인 협업을 가능하게 합니다.

하나의 명령으로 설치하고, 하나의 명령으로 프론트엔드+백엔드를 실행합니다.

```bash
uv tool install nexus-agent-platform   # 설치 (Python 3.13 자동 관리)
nexus-agent init                       # 초기 설정
nexus-agent start                      # 실행 → http://localhost:8000
```

---

## 설치

### 사전 준비: uv 설치

[uv](https://docs.astral.sh/uv/)는 Python 패키지 관리 도구입니다. 먼저 uv를 설치합니다.

**macOS / Linux:**

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

**Windows (PowerShell):**

```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

> 설치 후 터미널을 재시작하거나 `source ~/.bashrc` (macOS/Linux) 또는 새 PowerShell 창을 엽니다.

### 방법 1: uv (권장)

```bash
uv tool install nexus-agent-platform
```

> uv는 Python 3.13을 자동으로 설치·관리하므로 별도의 Python 설치가 필요 없습니다.

### 방법 2: pipx

```bash
pipx install nexus-agent-platform
```

> pipx도 격리된 환경에서 설치하지만, 시스템에 Python 3.13 이상이 필요합니다.

### 요구사항

- **Python 3.13** 이상 — uv 사용 시 자동 관리, pipx/pip 사용 시 직접 설치 필요
- 지원 프로바이더 중 최소 1개의 **API Key** (아래 [API 키 설정](#2-api-키-설정) 참고)

> **참고:** `pip install nexus-agent-platform`은 시스템 Python이 3.13 이상이어야 동작합니다. Python 버전이 낮다면 `uv tool install`을 사용하세요.

### 플랫폼 지원

| OS | 상태 | 데이터 디렉토리 |
|----|------|-----------------|
| macOS | 테스트 완료 | `~/.nexus-agent/` |
| Linux | 지원 | `~/.nexus-agent/` |
| Windows | 지원 | `C:\Users\<사용자>\.nexus-agent\` |

---

## 빠른 시작

### 1. 초기 설정

```bash
nexus-agent init
```

`~/.nexus-agent/` 디렉토리에 설정 파일이 생성됩니다:

```
~/.nexus-agent/
├── .env              # API 키 설정
├── settings.json     # LLM 설정 (모델, 온도, 시스템 프롬프트)
├── mcp.json          # MCP 서버 설정
├── skills.json       # 스킬 활성화 상태
├── pages.json        # 페이지 메타데이터
├── workspaces.json   # 워크스페이스 등록 정보
├── memories.json     # 장기 기억 데이터
├── skills/           # Agent Skills 저장 디렉토리
└── pages/            # 업로드된 HTML 저장 디렉토리
```

### 2. API 키 설정

`~/.nexus-agent/.env` 파일에 사용할 프로바이더의 API 키를 설정합니다.
**사용할 프로바이더만 설정하면 됩니다** (전부 설정할 필요 없음).

```env
# Google Gemini — https://aistudio.google.com/apikey
GOOGLE_API_KEY=AIzaSy...

# OpenAI — https://platform.openai.com/api-keys
OPENAI_API_KEY=sk-proj-...

# Anthropic (Claude) — https://console.anthropic.com/settings/keys
ANTHROPIC_API_KEY=sk-ant-...

# xAI (Grok) — https://console.x.ai
XAI_API_KEY=xai-...
```

**macOS / Linux:**

```bash
# 예시: Google Gemini만 사용하는 경우
echo "GOOGLE_API_KEY=your-api-key-here" > ~/.nexus-agent/.env

# 여러 프로바이더를 사용하는 경우
cat > ~/.nexus-agent/.env << 'EOF'
GOOGLE_API_KEY=AIzaSy...
OPENAI_API_KEY=sk-proj-...
ANTHROPIC_API_KEY=sk-ant-...
XAI_API_KEY=xai-...
EOF
```

**Windows (PowerShell):**

```powershell
# 예시: Google Gemini만 사용하는 경우
Set-Content "$env:USERPROFILE\.nexus-agent\.env" "GOOGLE_API_KEY=your-api-key-here"
```

> Settings 페이지(`/settings`)에서 모델을 선택하면, 해당 프로바이더의 API 키가 자동으로 사용됩니다.

### 3. 서버 시작

```bash
nexus-agent start
```

브라우저에서 **http://localhost:8000** 을 열면 UI가 표시됩니다.

```
$ nexus-agent start
Nexus Agent v0.3.3 starting on http://0.0.0.0:8000
INFO:     Loading settings...
INFO:     Loading MCP config and connecting servers...
INFO:     Loading skills...
INFO:     Loading pages...
INFO:     Uvicorn running on http://0.0.0.0:8000
```

### 4. 옵션

```bash
nexus-agent start --port 9000      # 포트 변경
nexus-agent start --host 127.0.0.1 # 로컬만 허용
nexus-agent start --dev            # 개발 모드 (CORS 허용, 자동 리로드)
```

---

## CLI 명령어

| 명령어 | 설명 |
|--------|------|
| `nexus-agent init` | `~/.nexus-agent/` 초기 설정 파일 생성 |
| `nexus-agent start` | 서버 시작 (UI + API 단일 포트) |
| `nexus-agent start --dev` | 개발 모드 (CORS 허용, 자동 리로드) |
| `nexus-agent start --port 9000` | 커스텀 포트로 시작 |
| `nexus-agent config` | 현재 설정 경로 및 상태 표시 |
| `nexus-agent update` | 최신 버전으로 업데이트 |
| `nexus-agent --version` | 버전 확인 |
| `nexus-agent --help` | 도움말 표시 |

---

## 주요 기능

### Chat (`/`)

- 멀티 LLM 기반 AI 채팅 (LiteLLM 추상화 — Gemini, OpenAI, Claude, Grok 등)
- **SSE 실시간 스트리밍** — 도구 호출/결과/사고 과정을 실시간으로 표시
- 이미지 첨부 지원 (base64 인코딩)
- MCP 도구 + Agent Skills + Workspace 도구 자동 라우팅
- **세션 관리** — 대화 히스토리 저장/복원/삭제
- 커스텀 배경 이미지 (배율/위치/투명도 조정)

### Long-term Memory (Memory Bank)

- 대화에서 **자동 추출** — LLM이 핵심 사실/선호/패턴/맥락을 자동 인식
- 수동 추가/편집/삭제
- **메모리 고정(Pin)** — 중요한 메모리를 핀 고정하여 자동 삭제/압축에서 보호
- **자동 압축** — 용량 임계치 도달 시 유사 메모리를 LLM으로 병합 (핀 메모리 제외)
- **자동 교체** — 최대 용량 초과 시 가장 오래된 비핀 메모리 자동 삭제
- 카테고리 분류: preference, context, pattern, fact
- 시스템 프롬프트에 자동 주입하여 대화 연속성 유지

### MCP Servers (`/tools`)

- MCP 서버 등록/연결/재시작/삭제
- stdio, SSE, streamable-http 전송 지원
- 서버별 도구 목록 자동 탐색
- 연결 상태 실시간 모니터링 및 토글

### Agent Skills (`/skills`)

- SKILL.md 기반 스킬 정의 (YAML frontmatter + Markdown 지시사항)
- 스킬 내 스크립트 실행 (Python, Shell, JS)
- 스킬 내 참조 문서 로드
- ZIP 업로드 및 로컬 경로 임포트

### Custom Pages (`/pages`)

- HTML 파일 업로드 및 뷰어
- URL 북마크 등록 (iframe 지원 여부 자동 체크)
- 폴더 트리 구조로 정리
- 브레드크럼 네비게이션

### Workspace (`/workspace`)

- 로컬 디렉토리 등록/활성화/삭제
- 파일 트리 탐색 + 읽기 전용 파일 뷰어 (이미지/바이너리/미디어 파일 지원)
- 활성 워크스페이스 설정 시 AI가 파일 읽기/쓰기/편집/검색/셸 실행 가능
- 경로 순회 방지, 위험 셸 명령 차단 등 보안 장치 내장

### Settings (`/settings`)

- 테마 커스터마이징: 액센트 컬러, 다크/라이트 모드, 배경 톤
- 채팅 배경 이미지: 프리셋 선택, 커스텀 업로드
- LLM 설정: 모델 선택, API 키, 온도, 최대 토큰, 시스템 프롬프트
- **플랫폼 브랜딩**: 플랫폼 이름, 서브타이틀 커스터마이징
- **사용자 프로필**: 이름, 아바타 설정
- **AI 봇 프로필**: 봇 이름, 봇 아바타 설정
- **장기 기억 (Memory)**: 활성화/비활성화 토글, 용량/압축 임계치 설정

---

## 아키텍처

```
User → ChatInterface (React) → POST /api/chat/stream (SSE) → AgentOrchestrator.run_stream()
  → system prompt에 <available_skills> XML + <memories> 주입
  → MCP tools + skill tools + workspace tools 병합
  → LLMClient (LiteLLM) → Gemini / OpenAI / Claude / Grok API
  → SSE 이벤트 실시간 스트리밍:
      → thinking: "LLM 호출 중..."
      → tool_call: 도구 호출 정보
      → tool_result: 도구 실행 결과
      → content: 최종 응답 텍스트
  → tool_calls 라우팅:
      → skill tool → SkillManager → ~/.nexus-agent/skills/*/SKILL.md
      → workspace_* → workspace_tools → 파일/셸 도구 (활성 워크스페이스)
      → namespaced tool (server__tool) → MCPClientManager → MCP Server
  → Tool 결과를 메시지에 추가 → 2차 LLM 호출
  → 최종 응답 → ChatInterface (장기 기억 자동 추출)
```

### 기술 스택

| 계층 | 기술 |
|------|------|
| Frontend | Next.js 16, React 19, TypeScript, Tailwind CSS, shadcn/ui |
| Backend | Python 3.13, FastAPI, Pydantic |
| LLM | Gemini, OpenAI, Claude, Grok (LiteLLM 추상화) |
| Tool System | MCP (Model Context Protocol) + Agent Skills + Workspace Tools |
| CLI | Click, Rich |
| 패키지 | PyPI (`nexus-agent-platform`), Hatchling |

### 프로젝트 구조

```
track_platform/
├── pyproject.toml              # 패키지 설정 및 의존성
├── uv.lock                     # uv 락 파일
├── README.md                   # 이 파일
├── CLAUDE.md                   # Claude Code 가이드
├── .github/
│   └── workflows/
│       └── publish.yml         # PyPI 자동 배포 (GitHub Actions)
├── .claude/
│   └── skills/                 # Claude Code 커스텀 스킬
├── nexus_agent/                # Python 백엔드 패키지
│   ├── __init__.py             # 패키지 버전
│   ├── __main__.py             # python -m nexus_agent 지원
│   ├── cli.py                  # Click CLI 엔트리포인트 (nexus-agent 명령)
│   ├── server.py               # FastAPI 앱 + 정적 파일 서빙
│   ├── config.py               # ~/.nexus-agent/ 데이터 디렉토리 관리
│   ├── core/                   # 핵심 비즈니스 로직
│   │   ├── agent.py            # AgentOrchestrator (도구 라우팅 + SSE 스트리밍)
│   │   ├── llm.py              # LLMClient (LiteLLM 래퍼)
│   │   ├── mcp_manager.py      # MCP 서버 연결 관리
│   │   ├── skill_manager.py    # Agent Skills 관리
│   │   ├── page_manager.py     # Pages 폴더 트리 관리
│   │   ├── settings_manager.py # LLM 설정 관리
│   │   ├── session_manager.py  # 세션 히스토리 관리
│   │   ├── workspace_manager.py # 워크스페이스 CRUD + 파일 관리
│   │   ├── workspace_tools.py  # LLM용 워크스페이스 도구 + 보안
│   │   └── memory_manager.py   # 장기 기억 추출/압축/고정/관리
│   ├── api/endpoints/          # FastAPI REST API 라우터
│   │   ├── chat.py             # SSE 스트리밍 채팅
│   │   ├── mcp.py              # MCP 서버 관리
│   │   ├── skills.py           # 스킬 관리
│   │   ├── pages.py            # 페이지/폴더 관리
│   │   ├── sessions.py         # 세션 히스토리
│   │   ├── settings.py         # 설정 관리
│   │   ├── workspace.py        # 워크스페이스 관리
│   │   └── memory.py           # 메모리 CRUD + 핀 토글
│   ├── models/                 # Pydantic 데이터 모델
│   │   ├── mcp.py              # MCP 서버/도구 모델
│   │   ├── skill.py            # 스킬 모델
│   │   ├── page.py             # 페이지/폴더 모델
│   │   ├── session.py          # 세션 모델
│   │   ├── settings.py         # 설정 모델
│   │   ├── workspace.py        # 워크스페이스 모델
│   │   └── memory.py           # 메모리 모델 (is_pinned 포함)
│   └── static/                 # 빌드된 프론트엔드 (wheel에 포함, git 제외)
├── frontend/                   # Next.js 프론트엔드
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── pnpm-workspace.yaml
│   ├── next.config.ts          # static export 설정
│   ├── tsconfig.json
│   ├── components.json         # shadcn/ui 설정
│   ├── eslint.config.mjs
│   ├── postcss.config.mjs
│   └── src/                    # 소스 코드 (상세는 frontend/README.md 참조)
├── backend/                    # 초기 단독 백엔드 (레거시, 참고용)
│   ├── main.py
│   └── README.md
└── scripts/
    ├── build.sh                # 통합 빌드 스크립트 (shell)
    └── build.py                # 통합 빌드 스크립트 (python)
```

---

## MCP 서버 등록

프론트엔드 **MCP Servers** 대시보드(`/tools`)에서 등록하거나, `~/.nexus-agent/mcp.json`에 직접 추가합니다.

```json
{
  "mcpServers": {
    "example": {
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-everything"],
      "enabled": true
    }
  }
}
```

### 전송 방식

| transport | 필수 필드 | 예시 |
|-----------|-----------|------|
| `stdio` | `command`, `args` | `"command": "npx", "args": ["-y", "some-mcp-server"]` |
| `sse` | `url` | `"url": "http://localhost:3001/sse"` |
| `streamable-http` | `url` | `"url": "http://localhost:3001/mcp"` |

---

## Agent Skill 등록

프론트엔드 **Agent Skills** 대시보드(`/skills`)에서 등록하거나, `~/.nexus-agent/skills/` 디렉토리에 스킬 폴더를 생성합니다.

```
~/.nexus-agent/skills/
└── my-skill/
    ├── SKILL.md            # 필수: YAML frontmatter + 지시사항
    ├── scripts/            # 선택: 실행 스크립트 (.py, .sh, .js)
    └── references/         # 선택: 참조 문서
```

**SKILL.md 예시:**

```yaml
---
name: my-skill
description: >
  이 스킬이 하는 일과 언제 사용해야 하는지 설명합니다.
---

# My Skill

## 사용 방법

1. 사용자가 관련 질문을 하면 이 스킬이 활성화됩니다
2. scripts/ 에 있는 스크립트를 실행할 수 있습니다
3. references/ 에 있는 문서를 참조할 수 있습니다
```

---

## 환경 변수

### `~/.nexus-agent/.env`

| 변수 | 필수 | 설명 | 발급 |
|------|------|------|------|
| `GOOGLE_API_KEY` | 선택 | Google Gemini API 키 | [AI Studio](https://aistudio.google.com/apikey) |
| `OPENAI_API_KEY` | 선택 | OpenAI API 키 | [Platform](https://platform.openai.com/api-keys) |
| `ANTHROPIC_API_KEY` | 선택 | Anthropic Claude API 키 | [Console](https://console.anthropic.com/settings/keys) |
| `XAI_API_KEY` | 선택 | xAI Grok API 키 | [Console](https://console.x.ai) |

> 사용할 프로바이더의 키만 설정하면 됩니다. Settings 페이지에서 모델을 선택하면 해당 프로바이더의 키가 자동으로 사용됩니다.

### 지원 모델 (프로바이더별)

Settings 페이지(`/settings`)에서 모델을 선택하거나, `settings.json`의 `model` 필드에 직접 입력합니다.

| 프로바이더 | 모델 예시 | 환경변수 |
|-----------|----------|----------|
| Google Gemini | `gemini/gemini-3-flash-preview`, `gemini/gemini-2.5-pro` | `GOOGLE_API_KEY` |
| OpenAI | `openai/gpt-5`, `openai/gpt-4.1`, `openai/o3` | `OPENAI_API_KEY` |
| Anthropic | `anthropic/claude-opus-4-6`, `anthropic/claude-sonnet-4-5-20250929` | `ANTHROPIC_API_KEY` |
| xAI | `xai/grok-4-1-fast-reasoning`, `xai/grok-3` | `XAI_API_KEY` |
| Self-hosted | `openai/<모델명>` + API Base URL 설정 | (아래 참고) |

### LLM 설정 (`~/.nexus-agent/settings.json`)

웹 UI의 Settings 페이지에서 변경하거나 직접 편집합니다:

```json
{
  "llm": {
    "model": "gemini/gemini-2.5-flash",
    "temperature": 0.7,
    "max_tokens": 4096,
    "system_prompt": ""
  }
}
```

### 사내 vLLM / Self-hosted 사용

사내 네트워크에 vLLM으로 호스팅된 OpenAI 호환 API 서버에 연결할 수 있습니다.

**1. `.env` 설정:**

```env
# OpenAI-compatible H200 MIG API 120B LLM Configuration (for vLLM)
OPENAI_API_BASE=http://192.168.1.120:11436/v1

# API Key (dummy for local hosted vLLM - required by LiteLLM)
OPENAI_API_KEY=dummy
```

**2. Settings 페이지 또는 `settings.json`에서 모델 설정:**

| 설정 항목 | 값 |
|-----------|-----|
| Model | `hosted_vllm/openai/gpt-oss-120b` |
| API Base URL | `http://192.168.1.120:11436/v1` |

```json
{
  "llm": {
    "model": "hosted_vllm/openai/gpt-oss-120b",
    "api_base": "http://192.168.1.120:11436/v1",
    "api_key": "dummy",
    "temperature": 0.7,
    "max_tokens": 4096
  }
}
```

> LiteLLM 추상화 계층을 사용하므로 OpenAI 호환 API를 제공하는 모든 서버(vLLM, Ollama, TGI 등)에 연결 가능합니다.

---

## 개발 환경

프론트엔드와 백엔드를 분리하여 개발할 수 있습니다.

### 백엔드 개발

```bash
git clone https://github.com/EJCHO-salary/track_platform.git
cd track_platform
uv sync
uv run nexus-agent init
uv run nexus-agent start --dev    # 개발 모드 (리로드 + CORS 허용)
```

### 프론트엔드 개발

```bash
cd frontend
pnpm install
pnpm dev    # http://localhost:3000 (백엔드는 별도로 실행 필요)
```

프론트엔드 개발 시 백엔드 주소가 다르면 `frontend/.env.local`을 생성합니다:

```env
NEXT_PUBLIC_API_URL=http://localhost:8000
```

### 프론트엔드 포함 빌드 (wheel)

```bash
./scripts/build.sh
# 1. frontend/ 빌드 (static export)
# 2. nexus_agent/static/ 에 복사
# 3. uv build → dist/ 에 wheel 생성
```

---

## 포트

| 서비스 | URL | 용도 |
|--------|-----|------|
| `nexus-agent start` | http://localhost:8000 | 프로덕션 (UI + API 통합) |
| `nexus-agent start --dev` | http://localhost:8000 | 개발 (API only, CORS 허용) |
| `pnpm dev` | http://localhost:3000 | 프론트엔드 개발 서버 |
| Swagger Docs | http://localhost:8000/docs | API 문서 |

---

## 버전 확인

```bash
nexus-agent --version
```

## 업데이트 (업그레이드)

```bash
# CLI 명령으로 업데이트
nexus-agent update

# 또는 설치 도구로 직접 업그레이드
uv tool upgrade nexus-agent-platform    # uv 사용 시
pipx upgrade nexus-agent-platform       # pipx 사용 시
```

업데이트 후 서버를 재시작하면 적용됩니다:

```bash
nexus-agent start
```

> `~/.nexus-agent/` 디렉토리의 설정 파일은 업데이트 시 유지됩니다. `nexus-agent init`을 다시 실행할 필요는 없습니다.

---

## CI/CD (자동 배포)

GitHub에 태그를 push하면 자동으로 PyPI에 배포됩니다.

### 사전 설정 (1회)

1. [PyPI](https://pypi.org) → 프로젝트 → Settings → Publishing → **Add a new publisher**
2. 아래 정보를 입력:
   - **Owner**: `EJCHO-salary`
   - **Repository**: `track_platform`
   - **Workflow name**: `publish.yml`
   - **Environment**: *(비워둠)*

### 배포 방법

```bash
# 1. pyproject.toml과 __init__.py의 버전을 올린다
# 2. 커밋하고 태그를 생성한다
git tag v0.3.3
git push origin main --tags

# GitHub Actions가 자동으로:
# - 프론트엔드 빌드
# - 정적 파일 복사
# - wheel 빌드
# - PyPI 배포
```

### 수동 배포

```bash
./scripts/build.sh
uv publish -t pypi-YOUR_TOKEN
```

---

## 라이선스

MIT
