From 73b907df6be68f22dee50bc129ff16c11f0a7438 Mon Sep 17 00:00:00 2001 From: hc00125 <3168354288@qq.com> Date: Wed, 6 May 2026 22:51:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6=E6=89=93?= =?UTF-8?q?=E5=BC=80=E6=96=B9=E5=BC=8F=E4=BB=A5=E6=94=AF=E6=8C=81=20UTF-8?= =?UTF-8?q?=20=E7=BC=96=E7=A0=81=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=20Dee?= =?UTF-8?q?pSeek=20=E6=A8=A1=E5=9E=8B=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/context_manager/manager.py | 2 +- agent/core/agent_loop.py | 6 ++++-- agent/core/model_switcher.py | 2 ++ agent/core/session.py | 6 +++--- agent/core/session_uploader.py | 32 +++++++++++++++++++++---------- run_test.py | Bin 0 -> 104 bytes test_litellm.py | 1 + 7 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 run_test.py create mode 100644 test_litellm.py diff --git a/agent/context_manager/manager.py b/agent/context_manager/manager.py index 85e96af0..c6b9290a 100644 --- a/agent/context_manager/manager.py +++ b/agent/context_manager/manager.py @@ -213,7 +213,7 @@ def _load_system_prompt( """Load and render the system prompt from YAML file with Jinja2""" prompt_file = Path(__file__).parent.parent / "prompts" / f"{prompt_file_suffix}" - with open(prompt_file, "r") as f: + with open(prompt_file, "r", encoding="utf-8") as f: prompt_data = yaml.safe_load(f) template_str = prompt_data.get("system_prompt", "") diff --git a/agent/core/agent_loop.py b/agent/core/agent_loop.py index 88fe1492..ac22338a 100644 --- a/agent/core/agent_loop.py +++ b/agent/core/agent_loop.py @@ -682,8 +682,10 @@ def _extract_thinking_state( def _should_replay_thinking_state(model_name: str | None) -> bool: - """Only Anthropic's native adapter accepts replayed thinking metadata.""" - return bool(model_name and model_name.startswith("anthropic/")) + """Only Anthropic and DeepSeek accept/require replayed thinking metadata.""" + if not model_name: + return False + return model_name.startswith("anthropic/") or "deepseek" in model_name.lower() def _is_invalid_thinking_signature_error(exc: Exception) -> bool: diff --git a/agent/core/model_switcher.py b/agent/core/model_switcher.py index 14b5233d..6c9c939d 100644 --- a/agent/core/model_switcher.py +++ b/agent/core/model_switcher.py @@ -24,6 +24,8 @@ # ":cheapest" / ":preferred" / ":" to override the default # routing policy (auto = fastest with failover). SUGGESTED_MODELS = [ + {"id": "openai/deepseek-v4-flash", "label": "deepseek-v4-flash (Custom API)"}, + {"id": "openai/deepseek-v4-pro", "label": "deepseek-v4-pro (Custom API)"}, {"id": "openai/gpt-5.5", "label": "GPT-5.5"}, {"id": "openai/gpt-5.4", "label": "GPT-5.4"}, {"id": "anthropic/claude-opus-4-7", "label": "Claude Opus 4.7"}, diff --git a/agent/core/session.py b/agent/core/session.py index fb08c75f..9ee2d8f4 100644 --- a/agent/core/session.py +++ b/agent/core/session.py @@ -473,7 +473,7 @@ def save_trajectory_local( # Atomic-ish write: stage to .tmp then rename so a crash mid-write # doesn't leave a truncated JSON that breaks the retry scanner. tmp_path = filepath.with_suffix(filepath.suffix + ".tmp") - with open(tmp_path, "w") as f: + with open(tmp_path, "w", encoding="utf-8") as f: json.dump(trajectory, f, indent=2) tmp_path.replace(filepath) @@ -487,14 +487,14 @@ def update_local_save_status( ) -> bool: """Update the upload status of an existing local save file""" try: - with open(filepath, "r") as f: + with open(filepath, "r", encoding="utf-8") as f: data = json.load(f) data["upload_status"] = upload_status data["upload_url"] = dataset_url data["last_save_time"] = datetime.now().isoformat() - with open(filepath, "w") as f: + with open(filepath, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) return True diff --git a/agent/core/session_uploader.py b/agent/core/session_uploader.py index 404fd224..ba2618e7 100644 --- a/agent/core/session_uploader.py +++ b/agent/core/session_uploader.py @@ -276,7 +276,7 @@ def _write_row_payload(data: dict, tmp_path: str) -> None: "tools": json.dumps(scrubbed["tools"]), } - with open(tmp_path, "w") as tmp: + with open(tmp_path, "w", encoding="utf-8") as tmp: json.dump(session_row, tmp) @@ -285,7 +285,7 @@ def _write_claude_code_payload(data: dict, tmp_path: str) -> None: # Scrub before conversion so secrets never reach the upload temp file. scrubbed = _scrub_session_for_upload(data) events = to_claude_code_jsonl(scrubbed) - with open(tmp_path, "w") as tmp: + with open(tmp_path, "w", encoding="utf-8") as tmp: for event in events: tmp.write(json.dumps(event)) tmp.write("\n") @@ -302,14 +302,20 @@ def _url_field(format: str) -> str: def _read_session_file(session_file: str) -> dict: """Read a local session file while respecting uploader file locks.""" - import fcntl + has_fcntl = True + try: + import fcntl + except ImportError: + has_fcntl = False - with open(session_file, "r") as f: - fcntl.flock(f, fcntl.LOCK_SH) + with open(session_file, "r", encoding="utf-8") as f: + if has_fcntl: + fcntl.flock(f, fcntl.LOCK_SH) try: return json.load(f) finally: - fcntl.flock(f, fcntl.LOCK_UN) + if has_fcntl: + fcntl.flock(f, fcntl.LOCK_UN) def _update_upload_status( @@ -325,10 +331,15 @@ def _update_upload_status( local session JSON file. Re-read under an exclusive lock so one uploader cannot clobber fields written by the other. """ - import fcntl + has_fcntl = True + try: + import fcntl + except ImportError: + has_fcntl = False - with open(session_file, "r+") as f: - fcntl.flock(f, fcntl.LOCK_EX) + with open(session_file, "r+", encoding="utf-8") as f: + if has_fcntl: + fcntl.flock(f, fcntl.LOCK_EX) try: data = json.load(f) data[status_key] = status @@ -341,7 +352,8 @@ def _update_upload_status( f.flush() os.fsync(f.fileno()) finally: - fcntl.flock(f, fcntl.LOCK_UN) + if has_fcntl: + fcntl.flock(f, fcntl.LOCK_UN) def dataset_card_readme(repo_id: str) -> str: diff --git a/run_test.py b/run_test.py new file mode 100644 index 0000000000000000000000000000000000000000..d8084385b66f65580732fa6825d629d76386ddc4 GIT binary patch literal 104 zcmY+5I}UKtw;vF1i@dBKN5H%$7iL!WkwS>v7eXo6=K%|g4sZ2O7ZW5j#W<@rc btW9$}t6XJKcUmOT|KD?nv|mp%hLM2}vYHdl literal 0 HcmV?d00001 diff --git a/test_litellm.py b/test_litellm.py new file mode 100644 index 00000000..77e59be1 --- /dev/null +++ b/test_litellm.py @@ -0,0 +1 @@ +import os, litellm; from litellm import completion; from dotenv import load_dotenv; load_dotenv(); response = completion(model='openai/deepseek-chat', messages=[{'role': 'user', 'content': 'hello'}]); print(response)