"""系统设置(大模型 + 学习方式)读写。""" from study_tool import store from study_tool.webapp import app from study_tool.config import * from study_tool.models import * from study_tool.runtime import log # ------------------------------------------------------------------ settings SETTINGS_NAME = "llm" DEFAULT_LLM = { "base_url": "https://api.openai.com/v1", "api_key": "", "model": "gpt-4o-mini", "temperature": 0.2, "timeout": 120, "prompt": "", } # 学习方式:fast = 只调 study/log 接口,不开浏览器;normal = 真播视频(可多路并发) DEFAULT_STUDY = { "mode": "fast", "parallel": 2, } DEFAULT_ANSWER_PROMPT = ( "你是考试答题助手。根据题干和选项判断正确答案。\n" "单选题返回一个选项字母;多选题返回多个字母,用 # 连接(如 A#C);判断题只返回 A 或 B(A=正确,B=错误)。\n" "只输出 JSON:{\"answers\":{\"题号\":\"答案\"}},不要输出解释或多余文字。" ) TYPE_LABEL = {"01": "单选", "02": "多选", "03": "判断", "04": "问答"} def load_settings(): data = store.get_setting(SETTINGS_NAME) or {} llm = dict(DEFAULT_LLM) study = dict(DEFAULT_STUDY) if isinstance(data, dict): raw = data.get("llm") if isinstance(raw, dict): llm.update({k: v for k, v in raw.items() if k in DEFAULT_LLM and v is not None}) st = data.get("study") if isinstance(st, dict): study.update({k: v for k, v in st.items() if v is not None}) study["mode"] = study.get("mode") if study.get("mode") in ("fast", "normal") else "fast" try: study["parallel"] = max(1, min(int(study.get("parallel") or 2), 5)) except (TypeError, ValueError): study["parallel"] = 2 return {"llm": llm, "study": study} def save_settings(data): store.set_setting(SETTINGS_NAME, {"llm": data.get("llm") or {}, "study": data.get("study") or {}}) @app.get("/api/settings") def api_get_settings(): cfg = load_settings() llm = cfg["llm"] key = llm.get("api_key") or "" out = dict(llm) out["api_key"] = "" out["has_key"] = bool(key) out["key_hint"] = (key[:4] + "…" + key[-4:]) if len(key) > 10 else ("已设置" if key else "") return {"ok": True, "llm": out, "study": cfg["study"]} @app.post("/api/settings") def api_set_settings(b: LlmCfgIn): cur = load_settings() llm = cur["llm"] if b.base_url.strip(): llm["base_url"] = b.base_url.strip() if b.api_key.strip(): # 留空 = 保留原 key,前端不回显明文 llm["api_key"] = b.api_key.strip() if b.model.strip(): llm["model"] = b.model.strip() llm["temperature"] = max(0.0, min(2.0, float(b.temperature or 0))) llm["timeout"] = max(10, min(600, int(b.timeout or 120))) llm["prompt"] = b.prompt or "" if b.study_mode in ("fast", "normal"): # 空串 = 不改 cur["study"]["mode"] = b.study_mode if b.study_parallel: # 0 = 不改 cur["study"]["parallel"] = max(1, min(int(b.study_parallel), 5)) save_settings(cur) log("system", "设置已更新:模型 %s(%s),学习方式 %s/%s 路" % ( cur["llm"]["model"], cur["llm"]["base_url"], cur["study"]["mode"], cur["study"]["parallel"])) return {"ok": True, "study": cur["study"]}