Commit Graph

33 Commits

Author SHA1 Message Date
Hyungi Ahn
a057e9a358 fix: Synology Chat rate limit 대응 — 최소 1.5초 간격 + 재시도
"create post too fast" 에러로 응답이 누락되던 문제.
전송 간 최소 1.5초 간격 보장 + API success:false 시 2초 후 1회 재시도.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:05:16 +09:00
Hyungi Ahn
8eeec87857 debug: synology_sender에 전송 내용 로그 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:00:13 +09:00
Hyungi Ahn
1e3f9d83eb feat: 시스템 상태 질문 사전 라우팅 — 추론 모델/서버 상태 조회
"추론 모델 일하고 있어?" → backend health 체크 후 직접 응답

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:56:07 +09:00
Hyungi Ahn
37c5616735 feat: 이메일 폴더 필터링 — 테크니컬코리아/Gmail/개인 지정 가능
"테크니컬코리아 메일만" → Technicalkorea 폴더만 검색
"구글 메일" → Gmail만, "개인 메일" → INBOX만
폴더 미지정 시 전체 검색 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:49:54 +09:00
Hyungi Ahn
12ca8f19d9 fix: 이메일 멀티 폴더 조회 + Synology 무응답 방지
- email_tool: INBOX/Gmail/Technicalkorea 3개 폴더 순회
  - 폴더별 try/except isolation (하나 실패해도 나머지 조회)
  - UID → folder:uid 형식 (폴더간 충돌 방지)
  - 날짜 parsedate_to_datetime 정렬
  - 폴더 라벨 표시 (개인/Gmail/회사)
- worker: response_sent 플래그 + finally 무응답 방지
  - 어떤 에러 경로에서든 Synology에 최소 1회 응답 보장

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:38:35 +09:00
Hyungi Ahn
f73c46de3a fix: 캘린더 종료 시간(end_time) 지원 — 1시간 고정 제거
create_draft/create_confirmed에 end_time 파라미터 추가.
없으면 기본 1시간, 있으면 사용자 지정 종료 시간 사용.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:12:07 +09:00
Hyungi Ahn
131022eb12 fix: 도구 결과 포맷팅에 평문 프롬프트 사용 — JSON 출력 방지
분류기 system prompt가 JSON 강제라서 결과 포맷도 JSON으로 나옴.
도구 결과 정리 시 별도 평문 프롬프트를 messages로 직접 전달.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:02:33 +09:00
Hyungi Ahn
0b260eec5e fix: vobject 의존성 추가 + calendar 파싱 icalendar fallback
CalDAV 3.x에서 vobject 분리됨 → 이벤트 파싱 실패 원인.
vobject 설치 + icalendar fallback 파싱 추가.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:50:44 +09:00
Hyungi Ahn
f72eef6e31 feat: 키워드 사전 라우팅 — EXAONE 분류기 한계 보완
EXAONE 7.8B가 복잡한 JSON 분류를 안정적으로 못함.
키워드 매칭으로 일정/메일/문서/확인 요청을 사전 감지하여
분류기를 건너뛰고 바로 도구로 라우팅.
날짜 계산(오늘/내일/이번주)도 코드에서 처리.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:46:07 +09:00
Hyungi Ahn
e786307a07 fix: JSON 파싱 견고화 + 분류기 프롬프트 강화
- _parse_classification: 어떤 형태든 첫{~마지막} 추출, 백틱 잔재 제거
- 분류기: 판단 예시 추가 (일정→tools, 인사→direct 등), 백틱/코드블록 금지 명시

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:43:01 +09:00
Hyungi Ahn
6e24da56a4 feat: 이드 도구 확장 — 캘린더/메일/문서 연동 (read-only + 캘린더 생성 확인)
- tools/calendar_tool.py: CalDAV search/today/create_draft/create_confirmed
- tools/email_tool.py: IMAP search/read (전송 비활성화)
- tools/document_tool.py: Document Server search/read (read-only)
- tools/registry.py: 도구 디스패처 + WRITE_OPS 안전장치 + 에러 표준화
- 분류기: "tools" 액션 추가, 도구 목록/파라미터 스키마/규칙 명시
- Worker: tools 분기 + tool timeout 10초 + payload 2000자 제한
- conversation: pending_draft (TTL 5분) + create 확인 플로우
- 현재 시간을 분류기에 전달 (날짜 질문 대응)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:39:15 +09:00
Hyungi Ahn
40c5d3cf21 fix: Synology 응답에서 마크다운 제거 — **bold**, # header, - list → 순수 텍스트
상태 메시지(이모지)는 raw=True로 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:57:50 +09:00
Hyungi Ahn
a16ff2ea88 fix: max_tokens 추가 — Gemma 16000, EXAONE 4096
응답이 중간에 끊기는 문제 해결. ModelAdapter에 max_tokens
파라미터 추가, stream/complete 양쪽 payload에 반영.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:52:31 +09:00
Hyungi Ahn
74f8df48fc fix: Synology UX — "🤔 생각 중..." + route시 "📝 더 깊이 살펴볼게요..."
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:47:02 +09:00
Hyungi Ahn
53d3e8e056 fix: Synology 응답 길이 1500→4000자 (모닝 브리핑 대비)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:45:21 +09:00
Hyungi Ahn
21f6869898 feat: EXAONE 분류기 — direct/route/clarify 라우팅 + 대화 기억
- EXAONE: 분류기+프롬프트엔지니어+직접응답 (JSON 출력)
- 간단한 질문은 EXAONE이 직접 답변 (파이프라인 스킵)
- 복잡한 질문은 AI 최적화 프롬프트로 Gemma에 전달
- 모호한 질문은 사용자에게 추가 질문 (clarify)
- user별 최근 대화 기억 (최대 10개, 1시간 TTL)
- ModelAdapter: messages 직접 전달 옵션 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:40:39 +09:00
Hyungi Ahn
1ac4832bdc fix: 프롬프트 튜닝 v2 — 자기 인식 + rewrite 과잉 방지
- reasoner: EXAONE+Gemma4 파이프라인 자기 인식 추가
- rewriter: 간단한 질문/인사는 원문 그대로 통과, 복잡한 것만 재구성

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:36:43 +09:00
Hyungi Ahn
9b8059ca38 fix: 시스템 프롬프트 튜닝 — 상냥하고 간결한 대화 스타일
- reasoner: "이드" 페르소나, 간결+상냥, 불필요한 구조화 금지
- rewriter: 인사/잡담은 그대로 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:33:39 +09:00
Hyungi Ahn
193c3249fc fix: python-multipart 추가 — form parsing 의존성
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:27:23 +09:00
Hyungi Ahn
a44f6446cf feat: NanoClaude Phase 3 — Synology Chat 연동
- POST /webhook/synology: outgoing webhook 수신 + token 검증
- 파이프라인 완료 시 incoming webhook으로 응답 자동 전송
- "분석 중..." typing 메시지 선전송
- 응답 길이 1500자 제한 (Synology Chat 제한 대응)
- 에러/실패 시에도 사용자에게 알림 메시지 전송
- 중복 요청 방지 (30초 TTL dedup)
- Synology에서 rewrite 이벤트 숨김 (SSE에서만 노출)
- callback 구조로 확장 가능 (Slack, Discord 등)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:25:48 +09:00
Hyungi Ahn
9f0c527442 fix: health_check timeout 3→5초 — MLX cold start 대응
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:08:28 +09:00
Hyungi Ahn
2b4d182b24 fix: job_queue 모듈 import 방식 수정 — None 참조 해결
모듈 레벨 변수를 직접 import하면 init_queue() 이후에도
None 참조가 유지됨. 모듈 자체를 import하여 접근.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:06:48 +09:00
Hyungi Ahn
c4c32170f1 feat: NanoClaude Phase 2 — EXAONE→Gemma 파이프라인, 큐, 상태 API
- ModelAdapter: 범용 OpenAI-compat 어댑터 (stream/complete/health)
- BackendRegistry: rewriter(EXAONE) + reasoner(Gemma4) 헬스체크 루프
- 2단계 파이프라인: EXAONE rewrite → Gemma reasoning (SSE rewrite 이벤트 노출)
- Fallback: 맥미니 다운 시 EXAONE 단독 모드, stream 중간 실패 시 자동 전환
- Cancel-safe: rewrite 전/후, streaming loop 내, fallback 경로 모두 체크
- Rewrite heartbeat: complete_chat 대기 중 2초 간격 processing 이벤트
- JobQueue: Semaphore(3) 기반 동시성 제한, 정확한 queue position
- GET /chat/{job_id}/status, GET /queue/stats 엔드포인트
- DB: rewrite_model, reasoning_model, rewritten_message 컬럼 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:04:15 +09:00
Hyungi Ahn
8c41a5dead fix: CancelledError/Exception 경로에도 DB log_completion 추가
task.cancel()로 인한 CancelledError는 streaming loop 바깥에서
잡히므로 별도 log_completion 필요

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:24:29 +09:00
Hyungi Ahn
72c488d85d fix: cancel된 job도 DB에 상태 기록
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:21:07 +09:00
Hyungi Ahn
e970ebdbea feat: NanoClaude 프로덕션 통합 — Docker, Caddy, aiosqlite 로깅
- docker-compose에 nanoclaude 서비스 추가 (포트 8100)
- Caddy /nano/* → nanoclaude 리버스 프록시 (SSE flush)
- aiosqlite 요청/응답 로깅 (request_logs 테이블)
- .env.example, CLAUDE.md 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:19:15 +09:00
Hyungi Ahn
1e427bc98a fix: EXAONE 모델 ID 수정 — exaone3.5:7.8b-instruct-q8_0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:12:51 +09:00
Hyungi Ahn
d946b769e5 feat: NanoClaude Phase 1 — 비동기 job 기반 AI Gateway 코어 구현
POST /chat → job_id ACK, GET /chat/{job_id}/stream → SSE 스트리밍,
EXAONE Ollama adapter, JobManager, StateStream, Worker 구조

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:12:04 +09:00
Hyungi Ahn
4917fd568f fix: Bearer 토큰 인증으로 전환 — 쿠키 프록시 이슈 해결
Caddy 프록시를 거치면서 httpOnly 쿠키가 제대로 전달 안 되는 문제.
로그인 시 받은 토큰을 메모리에 저장하고 Authorization: Bearer 헤더로
전송하는 방식으로 변경. 쿠키 의존성 제거.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 07:49:38 +09:00
Hyungi Ahn
72dd6ac4d1 feat: Phase 2 웹 UI — Dashboard + Chat 페이지
- hub-web: Vite + React + Tailwind + React Router
- Dashboard: 백엔드 상태 카드, GPU 모니터, 모델 테이블 (15초 자동 갱신)
- Chat: 모델 선택 드롭다운 + SSE 스트리밍 + Markdown 렌더링
- Login: 비밀번호 인증 (httpOnly 쿠키)
- Docker: nginx 기반 정적 서빙 + Caddy 연동
- Caddyfile: flush_interval -1 (SSE 버퍼링 방지)
- proxy_ollama: embed usage 더미값 0→1 (SDK 호환)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 07:40:16 +09:00
Hyungi Ahn
2dab682e21 fix: backend_model_id 매핑 추가 — MLX 모델 ID 불일치 해결
MLX 서버 모델 ID(mlx-community/Qwen3.5-35B-A3B-4bit)와
사용자 노출 ID(qwen3.5:35b-a3b)가 달라 500 에러 발생.
registry에 backend_model_id 필드 추가하여 프록시 시 변환.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:14:55 +09:00
Hyungi Ahn
7b28252d4f feat: 맥미니 MLX 연동 — OpenAI-compat 프록시 + 모델 배치 정정
- proxy_openai.py 추가: MLX 서버 SSE 패스스루
- chat.py: openai-compat 백엔드 타입 라우팅 추가
- backends.json: GPU=embed(bge-m3)만, 맥미니MLX=채팅(qwen3.5:35b-a3b)
- LAN IP(192.168.1.122) 사용 (같은 서브넷, Tailscale 불필요)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:09:21 +09:00
Hyungi Ahn
3794afff95 feat: AI Gateway Phase 1 - FastAPI 코어 구현
GPU 서버 중앙 AI 라우팅 서비스 초기 구현:
- OpenAI 호환 API (/v1/chat/completions, /v1/models, /v1/embeddings)
- 모델 레지스트리 + 백엔드 헬스체크 (30초 루프)
- Ollama SSE 프록시 (NDJSON → OpenAI SSE 변환)
- JWT 인증 이중 경로 (httpOnly 쿠키 + Bearer 토큰)
- owner/guest 역할 분리, 로그인 rate limiting
- 백엔드별 rate limiting (NanoClaude 대비)
- SQLite 스키마 사전 정의 (aiosqlite + WAL)
- Docker Compose + Caddy 리버스 프록시

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:41:46 +09:00