You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
# backend/app/llm/provider.py
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class Classification:
|
|
type: str # task | event | idea
|
|
sphere: str # work | life
|
|
project_id: str | None = None
|
|
proj_label: str = ""
|
|
tone: str = "ink"
|
|
due_text: str = ""
|
|
when_text: str = ""
|
|
extra: str = ""
|
|
reason: str = "" # 한국어
|
|
confidence: float = 0.0
|
|
model: str = ""
|
|
|
|
|
|
class LLMProvider(ABC):
|
|
name: str = "base"
|
|
|
|
def tool_capable(self) -> bool:
|
|
"""tool-call(함수 호출) 가능한 모델인가. 기본 False → 에이전트는 scripted 폴백."""
|
|
return False
|
|
|
|
@abstractmethod
|
|
def health(self) -> dict: ...
|
|
|
|
@abstractmethod
|
|
def generate_json(self, prompt: str, schema: dict | None = None) -> dict: ...
|
|
|
|
@abstractmethod
|
|
def classify_capture(self, raw: str, context: dict) -> Classification: ...
|
|
|
|
def list_models(self) -> list[str]:
|
|
"""사용 가능한 모델 목록(설정 페이지 드롭다운용). 기본 빈 목록."""
|
|
return []
|
|
|
|
|
|
_cached: LLMProvider | None = None
|
|
|
|
|
|
def build_provider(
|
|
provider: str,
|
|
*,
|
|
host: str | None = None,
|
|
model: str | None = None,
|
|
api_key: str | None = None,
|
|
timeout: float | None = None,
|
|
) -> LLMProvider:
|
|
"""provider 종류로 구현 인스턴스를 만든다. 인자 None 이면 각 구현이 effective_llm 기본값 사용.
|
|
연결 테스트(저장 전)에서는 명시 인자(host/model/api_key)로 임시 구성한다."""
|
|
if provider == "openai":
|
|
from .openai_compat import OpenAICompatProvider
|
|
|
|
return OpenAICompatProvider(host=host, model=model, api_key=api_key, timeout=timeout)
|
|
if provider == "gemini":
|
|
from .gemini import GeminiProvider
|
|
|
|
return GeminiProvider(host=host, model=model, api_key=api_key, timeout=timeout)
|
|
from .ollama import OllamaProvider
|
|
|
|
return OllamaProvider(host=host, model=model, timeout=timeout)
|
|
|
|
|
|
def get_provider(force: str | None = None) -> LLMProvider:
|
|
"""유효 설정(오버레이>env)의 provider 로 실 LLM 구현을 만든다(ollama|openai|gemini).
|
|
미가동/미설정 시 호출부에서 예외(휴리스틱 폴백 없음, phase-16+).
|
|
|
|
테스트는 conftest 가 get_provider 의존성을 결정적 FakeLLM 으로 오버라이드한다.
|
|
force 로 provider 를 직접 지정할 수 있다(미지정 시 effective_llm().provider).
|
|
"""
|
|
from ..runtime_config import effective_llm
|
|
|
|
return build_provider(force or effective_llm().provider)
|
|
|
|
|
|
def reset_provider_cache():
|
|
global _cached
|
|
_cached = None
|