GovOn Deploy
sync: PR#584 RAG removal + ReAct architecture
1635ec4
"""Capability timeout/retry ๊ธฐ๋ณธ๊ฐ’ ๋ชจ๋“ˆ.
Issue #163: capability๋ณ„ timeout๊ณผ retry ๊ธฐ๋ณธ๊ฐ’์„ ์ค‘์•™ ์ง‘์ค‘ ๊ด€๋ฆฌ.
ํ™˜๊ฒฝ๋ณ€์ˆ˜ GOVON_TOOL_TIMEOUT_{CAPABILITY_NAME} ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ ๊ฐ€๋Šฅ.
์˜ˆ: GOVON_TOOL_TIMEOUT_API_LOOKUP=20 -> api_lookup timeout์„ 20์ดˆ๋กœ ๋ณ€๊ฒฝ
"""
from __future__ import annotations
import os
from dataclasses import dataclass
from typing import Dict
from loguru import logger
@dataclass(frozen=True)
class CapabilityDefaults:
"""capability๋ณ„ timeout/retry ๊ธฐ๋ณธ๊ฐ’."""
timeout_sec: float
max_retries: int
# -----------------------------------------------------------------------
# ๊ธฐ๋ณธ๊ฐ’ ์ •์˜ (์ฝ”๋“œ๋ฒ ์ด์Šค capability metadata์—์„œ ์ถ”์ถœ)
# -----------------------------------------------------------------------
_DEFAULTS: Dict[str, CapabilityDefaults] = {
"api_lookup": CapabilityDefaults(timeout_sec=10.0, max_retries=1),
"issue_detector": CapabilityDefaults(timeout_sec=15.0, max_retries=0),
"stats_lookup": CapabilityDefaults(timeout_sec=15.0, max_retries=0),
"keyword_analyzer": CapabilityDefaults(timeout_sec=10.0, max_retries=0),
"demographics_lookup": CapabilityDefaults(timeout_sec=15.0, max_retries=0),
}
def get_timeout(capability_name: str) -> float:
"""capability์˜ timeout(์ดˆ)์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
ํ™˜๊ฒฝ๋ณ€์ˆ˜ ``GOVON_TOOL_TIMEOUT_{CAPABILITY_NAME_UPPER}`` ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด
ํ•ด๋‹น ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ณ , ์—†์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Parameters
----------
capability_name : str
capability ์ด๋ฆ„ (์˜ˆ: "api_lookup").
Returns
-------
float
timeout ์ดˆ. ์•Œ ์ˆ˜ ์—†๋Š” capability๋Š” 10.0์ดˆ.
"""
env_key = f"GOVON_TOOL_TIMEOUT_{capability_name.upper()}"
env_val = os.environ.get(env_key)
if env_val is not None:
try:
val = float(env_val)
if val > 0:
return val
logger.warning(
f"GOVON_TOOL_TIMEOUT_{capability_name.upper()} ๊ฐ’์ด ์–‘์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค: {env_val}"
)
except ValueError:
logger.warning(f"{env_key} ๊ฐ’์„ ์ˆซ์ž๋กœ ํŒŒ์‹ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค: {env_val!r}")
defaults = _DEFAULTS.get(capability_name)
return defaults.timeout_sec if defaults else 10.0
def get_max_retries(capability_name: str) -> int:
"""capability์˜ ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Parameters
----------
capability_name : str
capability ์ด๋ฆ„.
Returns
-------
int
์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜. ์•Œ ์ˆ˜ ์—†๋Š” capability๋Š” 0.
"""
defaults = _DEFAULTS.get(capability_name)
return defaults.max_retries if defaults else 0
def get_all_defaults() -> Dict[str, CapabilityDefaults]:
"""๋“ฑ๋ก๋œ ๋ชจ๋“  capability ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค."""
return dict(_DEFAULTS)