meeting_memory/core_agent/config.py

105 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from __future__ import annotations
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
try:
from dotenv import load_dotenv
except Exception: # pragma: no cover
load_dotenv = None
@dataclass(slots=True)
class CoreAgentConfig:
model: str
api_key: Optional[str]
base_url: Optional[str]
timeout: float = 120.0
temperature: float = 0.2
max_iterations: int = 12
user_name: str = "User"
agent_name: str = "MeetingAgent"
def load_core_agent_env(env_dir: str | Path | None = None) -> Optional[Path]:
candidates = []
if env_dir:
candidates.append(Path(env_dir) / ".env")
candidates.append(Path.cwd() / ".env")
for path in candidates:
if not path.exists():
continue
if load_dotenv is not None:
load_dotenv(path, override=False)
else:
_load_env_without_dependency(path)
return path
return None
def apply_compat_env_aliases() -> None:
if not os.getenv("OPENAI_API_KEY") and os.getenv("API_KEY"):
os.environ["OPENAI_API_KEY"] = os.environ["API_KEY"]
if not os.getenv("OPENAI_BASE_URL") and os.getenv("BASE_URL"):
os.environ["OPENAI_BASE_URL"] = os.environ["BASE_URL"]
if not os.getenv("CORE_AGENT_MODEL") and os.getenv("MODEL_NAME"):
os.environ["CORE_AGENT_MODEL"] = os.environ["MODEL_NAME"]
def build_core_agent_config() -> CoreAgentConfig:
return CoreAgentConfig(
model=os.getenv("CORE_AGENT_MODEL") or os.getenv("MODEL_NAME") or os.getenv("MODEL") or "",
api_key=os.getenv("OPENAI_API_KEY") or os.getenv("API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL") or os.getenv("BASE_URL"),
timeout=float(os.getenv("OPENAI_TIMEOUT", "120")),
temperature=float(os.getenv("OPENAI_TEMPERATURE", "0.2")),
max_iterations=int(os.getenv("CORE_AGENT_MAX_ITERATIONS", "12")),
user_name=os.getenv("USER_NAME", "User"),
agent_name=os.getenv("AGENT_NAME", "MeetingAgent"),
)
def require_model_config(config: CoreAgentConfig) -> None:
missing = []
if _is_missing_or_placeholder(config.api_key):
missing.append("OPENAI_API_KEY")
if _is_missing_or_placeholder(config.base_url):
missing.append("OPENAI_BASE_URL")
if _is_missing_or_placeholder(config.model):
missing.append("MODEL_NAME or CORE_AGENT_MODEL")
if missing:
joined = ", ".join(missing)
raise RuntimeError(
"缺少大模型配置:" + joined + "。请复制 .env.example 为 .env并填写 OpenAI-compatible API 配置;"
"如果只想本地演示工具流程,请加 --offline。"
)
def _load_env_without_dependency(path: Path) -> None:
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
if key and key not in os.environ:
os.environ[key] = value
def _is_missing_or_placeholder(value: Optional[str]) -> bool:
if value is None or not str(value).strip():
return True
normalized = str(value).strip().lower()
placeholders = {
"your-api-key-here",
"your-base-url-here",
"your-model-name-here",
"sk-xxx",
"xxx",
"changeme",
}
return normalized in placeholders or normalized.startswith("your-")