Files
2026-04-21 23:38:29 +08:00

115 lines
3.5 KiB
Python

import os
import sys
import tomllib
from dataclasses import dataclass, field
from pathlib import Path
from dotenv import load_dotenv
@dataclass
class HotkeyCfg:
capture: str = "<ctrl>+<shift>+a"
toggle: str = "<ctrl>+<shift>+h"
@dataclass
class OverlayCfg:
width: int = 460
height: int = 360
margin_right: int = 20
margin_bottom: int = 40
alpha: float = 0.93
font_size: int = 13
font_family: str = "Courier"
bg_color: str = "#0f0f1a"
fg_color: str = "#e2e2e2"
accent_color: str = "#4ade80"
@dataclass
class ScreenshotCfg:
delay_ms: int = 200
tmp_path: str = "/tmp/support_agent_screenshot.png"
@dataclass
class AICfg:
api_key: str = ""
base_url: str = ""
model: str = "gpt-4o"
max_tokens: int = 1500
system_prompt: str = "你是一个答题助手,请分析截图中的题目,给出答案和解析。"
@dataclass
class Config:
hotkeys: HotkeyCfg = field(default_factory=HotkeyCfg)
overlay: OverlayCfg = field(default_factory=OverlayCfg)
screenshot: ScreenshotCfg = field(default_factory=ScreenshotCfg)
ai: AICfg = field(default_factory=AICfg)
def _find_config_toml() -> Path | None:
candidates = [
Path.cwd() / "config.toml",
Path(__file__).parent.parent / "config.toml",
Path.home() / ".config" / "support-agent" / "config.toml",
]
for p in candidates:
if p.exists():
return p
return None
def load_config() -> Config:
load_dotenv()
cfg = Config()
toml_path = _find_config_toml()
if toml_path:
with open(toml_path, "rb") as f:
data = tomllib.load(f)
if "hotkeys" in data:
h = data["hotkeys"]
cfg.hotkeys.capture = h.get("capture", cfg.hotkeys.capture)
cfg.hotkeys.toggle = h.get("toggle", cfg.hotkeys.toggle)
if "overlay" in data:
o = data["overlay"]
cfg.overlay.width = o.get("width", cfg.overlay.width)
cfg.overlay.height = o.get("height", cfg.overlay.height)
cfg.overlay.margin_right = o.get("margin_right", cfg.overlay.margin_right)
cfg.overlay.margin_bottom = o.get("margin_bottom", cfg.overlay.margin_bottom)
cfg.overlay.alpha = o.get("alpha", cfg.overlay.alpha)
cfg.overlay.font_size = o.get("font_size", cfg.overlay.font_size)
cfg.overlay.font_family = o.get("font_family", cfg.overlay.font_family)
cfg.overlay.bg_color = o.get("bg_color", cfg.overlay.bg_color)
cfg.overlay.fg_color = o.get("fg_color", cfg.overlay.fg_color)
cfg.overlay.accent_color = o.get("accent_color", cfg.overlay.accent_color)
if "screenshot" in data:
s = data["screenshot"]
cfg.screenshot.delay_ms = s.get("delay_ms", cfg.screenshot.delay_ms)
cfg.screenshot.tmp_path = s.get("tmp_path", cfg.screenshot.tmp_path)
if "ai" in data:
a = data["ai"]
cfg.ai.base_url = a.get("base_url", cfg.ai.base_url)
cfg.ai.model = a.get("model", cfg.ai.model)
cfg.ai.max_tokens = a.get("max_tokens", cfg.ai.max_tokens)
cfg.ai.system_prompt = a.get("system_prompt", cfg.ai.system_prompt)
# 环境变量优先级高于 config.toml
cfg.ai.api_key = os.environ.get("OPENAI_API_KEY", "")
env_base_url = os.environ.get("OPENAI_BASE_URL", "")
if env_base_url:
cfg.ai.base_url = env_base_url
if not cfg.ai.api_key:
print("警告:未设置 OPENAI_API_KEY,请在 .env 文件中配置", file=sys.stderr)
return cfg