fix(anime): 파이프라인 5건 수정 — 에피소드 정규식(v2/S01E), 릴리스 그룹 필터, 자막 보호, 배치 다운로드, 타임아웃
This commit is contained in:
80
core/orchestrator.py
Normal file
80
core/orchestrator.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""Orchestrator — 인터페이스 무관 작업 오케스트레이터.
|
||||
|
||||
사용자 입력을 받아 NLU 분류 → 모드 분기.
|
||||
Discord, API, CLI 등 어떤 인터페이스에서든 동일한 로직을 실행합니다.
|
||||
|
||||
도구 실행은 Gemini CLI agent가 SKILL.md를 참조하여 직접 수행합니다.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
from core.gemini_caller import GeminiCaller, GeminiCallError
|
||||
|
||||
logger = logging.getLogger("variet.orchestrator")
|
||||
|
||||
|
||||
class Orchestrator:
|
||||
"""인터페이스-무관 오케스트레이터.
|
||||
|
||||
흐름:
|
||||
1. 사용자 입력 + 히스토리 → NLU 통합 분류
|
||||
2. mode에 따라 분기:
|
||||
- chat → 즉답 반환
|
||||
- clarify → 질문 반환
|
||||
- anime → AnimePipeline 직접 호출
|
||||
- task → TaskPipeline 실행 (핸들러에서 처리)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
async def classify(
|
||||
self,
|
||||
user_input: str,
|
||||
history: str = "",
|
||||
project_path: str = "",
|
||||
) -> dict:
|
||||
"""통합 프롬프트로 의도 분류.
|
||||
|
||||
Returns:
|
||||
분류 결과 dict: {mode, response?, action?, title?, ...}
|
||||
"""
|
||||
gemini = GeminiCaller(project_path)
|
||||
|
||||
from core.docs_manager import DocsManager
|
||||
docs = DocsManager(project_path) if project_path else None
|
||||
docs_index = docs.get_docs_index() if docs else ""
|
||||
|
||||
context = (
|
||||
f"{history}"
|
||||
f"## Workspace\nPath: {project_path}\n\n"
|
||||
f"## Project Docs\n{docs_index}\n\n"
|
||||
f"## User Message\n{user_input}"
|
||||
)
|
||||
|
||||
raw = await gemini.call("unified", context, timeout=120)
|
||||
|
||||
# JSON 추출
|
||||
try:
|
||||
match = re.search(r'```json\s*\n(.*?)\n\s*```', raw, re.DOTALL)
|
||||
if match:
|
||||
return json.loads(match.group(1))
|
||||
|
||||
brace_depth = 0
|
||||
start = -1
|
||||
for i, ch in enumerate(raw):
|
||||
if ch == '{':
|
||||
if brace_depth == 0:
|
||||
start = i
|
||||
brace_depth += 1
|
||||
elif ch == '}':
|
||||
brace_depth -= 1
|
||||
if brace_depth == 0 and start >= 0:
|
||||
return json.loads(raw[start:i + 1])
|
||||
except (json.JSONDecodeError, AttributeError):
|
||||
pass
|
||||
|
||||
logger.warning(f"통합 프롬프트 JSON 파싱 실패: {raw[:100]}")
|
||||
return {"mode": "chat", "response": raw}
|
||||
Reference in New Issue
Block a user