chore: remove unused imports and dead locals (ruff F401, F841) (#17010)
Mechanical cleanup across 43 files — removes 46 unused imports (F401) and 14 unused local variables (F841) detected by `ruff check --select F401,F841`. Net: -49 lines. Also fixes a latent NameError in rl_cli.py where `get_hermes_home()` was called at module line 32 before its import at line 65 — the module never imported successfully on main. The ruff audit surfaced this because it correctly saw the symbol as imported-but-unused (the call happened before the import ran); the fix moves the import to the top of the file alongside other stdlib imports. One `# noqa: F401` kept in hermes_cli/status.py for `subprocess`: tests monkeypatch `hermes_cli.status.subprocess` as a regression guard that systemctl isn't called on Termux, so the name must exist at module scope even though the module body doesn't reference it. Docstring explains the reason. Also fixes an invalid `# noqa:` directive in gateway/platforms/discord.py:308 that lacked a rule code. Co-authored-by: teknium1 <teknium@users.noreply.github.com>
This commit is contained in:
parent
3d8be2c617
commit
6085d7a93e
@ -523,9 +523,6 @@ def _read_claude_code_credentials_from_keychain() -> Optional[Dict[str, Any]]:
|
|||||||
|
|
||||||
Returns dict with {accessToken, refreshToken?, expiresAt?} or None.
|
Returns dict with {accessToken, refreshToken?, expiresAt?} or None.
|
||||||
"""
|
"""
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
if platform.system() != "Darwin":
|
if platform.system() != "Darwin":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import random
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass, fields, replace
|
from dataclasses import dataclass, fields, replace
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|||||||
@ -47,7 +47,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
|
||||||
from typing import Callable, List, Optional
|
from typing import Callable, List, Optional
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
@ -42,7 +41,6 @@ from agent import google_oauth
|
|||||||
from agent.gemini_schema import sanitize_gemini_tool_parameters
|
from agent.gemini_schema import sanitize_gemini_tool_parameters
|
||||||
from agent.google_code_assist import (
|
from agent.google_code_assist import (
|
||||||
CODE_ASSIST_ENDPOINT,
|
CODE_ASSIST_ENDPOINT,
|
||||||
FREE_TIER_ID,
|
|
||||||
CodeAssistError,
|
CodeAssistError,
|
||||||
ProjectContext,
|
ProjectContext,
|
||||||
resolve_project_context,
|
resolve_project_context,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict
|
||||||
|
|
||||||
# Gemini's ``FunctionDeclaration.parameters`` field accepts the ``Schema``
|
# Gemini's ``FunctionDeclaration.parameters`` field accepts the ``Schema``
|
||||||
# object, which is only a subset of OpenAPI 3.0 / JSON Schema. Strip fields
|
# object, which is only a subset of OpenAPI 3.0 / JSON Schema. Strip fields
|
||||||
|
|||||||
@ -29,7 +29,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|||||||
@ -49,14 +49,13 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
import socket
|
|
||||||
import stat
|
import stat
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Optional, Tuple
|
from typing import Any, Dict, Optional, Tuple
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,6 @@ Usage in run_agent.py:
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import inspect
|
import inspect
|
||||||
|
|||||||
@ -8,7 +8,7 @@ streaming, or the _run_codex_stream() call path.
|
|||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from agent.transports.base import ProviderTransport
|
from agent.transports.base import ProviderTransport
|
||||||
from agent.transports.types import NormalizedResponse, ToolCall, Usage
|
from agent.transports.types import NormalizedResponse, ToolCall
|
||||||
|
|
||||||
|
|
||||||
class ResponsesApiTransport(ProviderTransport):
|
class ResponsesApiTransport(ProviderTransport):
|
||||||
@ -151,8 +151,6 @@ class ResponsesApiTransport(ProviderTransport):
|
|||||||
"""Normalize Codex Responses API response to NormalizedResponse."""
|
"""Normalize Codex Responses API response to NormalizedResponse."""
|
||||||
from agent.codex_responses_adapter import (
|
from agent.codex_responses_adapter import (
|
||||||
_normalize_codex_response,
|
_normalize_codex_response,
|
||||||
_extract_responses_message_text,
|
|
||||||
_extract_responses_reasoning_text,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# _normalize_codex_response returns (SimpleNamespace, finish_reason_str)
|
# _normalize_codex_response returns (SimpleNamespace, finish_reason_str)
|
||||||
|
|||||||
@ -305,7 +305,7 @@ class VoiceReceiver:
|
|||||||
encrypted = bytes(payload_with_nonce[:-4])
|
encrypted = bytes(payload_with_nonce[:-4])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import nacl.secret # noqa: delayed import – only in voice path
|
import nacl.secret # noqa: E402 — delayed import, only in voice path
|
||||||
box = nacl.secret.Aead(self._secret_key)
|
box = nacl.secret.Aead(self._secret_key)
|
||||||
decrypted = box.decrypt(encrypted, header, bytes(nonce))
|
decrypted = box.decrypt(encrypted, header, bytes(nonce))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -974,7 +974,6 @@ def build_whole_comment_prompt(
|
|||||||
|
|
||||||
def _resolve_model_and_runtime() -> Tuple[str, dict]:
|
def _resolve_model_and_runtime() -> Tuple[str, dict]:
|
||||||
"""Resolve model and provider credentials, same as gateway message handling."""
|
"""Resolve model and provider credentials, same as gateway message handling."""
|
||||||
import os
|
|
||||||
from gateway.run import _load_gateway_config, _resolve_gateway_model
|
from gateway.run import _load_gateway_config, _resolve_gateway_model
|
||||||
|
|
||||||
user_config = _load_gateway_config()
|
user_config = _load_gateway_config()
|
||||||
|
|||||||
@ -11,10 +11,10 @@ import logging
|
|||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Dict, Optional
|
from typing import TYPE_CHECKING, Dict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from gateway.platforms.base import BasePlatformAdapter, MessageEvent
|
from gateway.platforms.base import MessageEvent
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@ -412,7 +412,6 @@ class MattermostAdapter(BasePlatformAdapter):
|
|||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
last_exc = None
|
|
||||||
file_data = None
|
file_data = None
|
||||||
ct = "application/octet-stream"
|
ct = "application/octet-stream"
|
||||||
fname = url.rsplit("/", 1)[-1].split("?")[0] or f"{kind}.png"
|
fname = url.rsplit("/", 1)[-1].split("?")[0] or f"{kind}.png"
|
||||||
|
|||||||
@ -1957,7 +1957,7 @@ class QQAdapter(BasePlatformAdapter):
|
|||||||
self, openid: str, content: str, reply_to: Optional[str] = None
|
self, openid: str, content: str, reply_to: Optional[str] = None
|
||||||
) -> SendResult:
|
) -> SendResult:
|
||||||
"""Send text to a C2C user via REST API."""
|
"""Send text to a C2C user via REST API."""
|
||||||
msg_seq = self._next_msg_seq(reply_to or openid)
|
self._next_msg_seq(reply_to or openid)
|
||||||
body = self._build_text_body(content, reply_to)
|
body = self._build_text_body(content, reply_to)
|
||||||
if reply_to:
|
if reply_to:
|
||||||
body["msg_id"] = reply_to
|
body["msg_id"] = reply_to
|
||||||
@ -1970,7 +1970,7 @@ class QQAdapter(BasePlatformAdapter):
|
|||||||
self, group_openid: str, content: str, reply_to: Optional[str] = None
|
self, group_openid: str, content: str, reply_to: Optional[str] = None
|
||||||
) -> SendResult:
|
) -> SendResult:
|
||||||
"""Send text to a group via REST API."""
|
"""Send text to a group via REST API."""
|
||||||
msg_seq = self._next_msg_seq(reply_to or group_openid)
|
self._next_msg_seq(reply_to or group_openid)
|
||||||
body = self._build_text_body(content, reply_to)
|
body = self._build_text_body(content, reply_to)
|
||||||
if reply_to:
|
if reply_to:
|
||||||
body["msg_id"] = reply_to
|
body["msg_id"] = reply_to
|
||||||
@ -2135,11 +2135,6 @@ class QQAdapter(BasePlatformAdapter):
|
|||||||
|
|
||||||
# Route
|
# Route
|
||||||
chat_type = self._guess_chat_type(chat_id)
|
chat_type = self._guess_chat_type(chat_id)
|
||||||
target_path = (
|
|
||||||
f"/v2/users/{chat_id}/files"
|
|
||||||
if chat_type == "c2c"
|
|
||||||
else f"/v2/groups/{chat_id}/files"
|
|
||||||
)
|
|
||||||
|
|
||||||
if chat_type == "guild":
|
if chat_type == "guild":
|
||||||
# Guild channels don't support native media upload in the same way
|
# Guild channels don't support native media upload in the same way
|
||||||
|
|||||||
@ -90,7 +90,7 @@ from gateway.platforms.yuanbao_proto import (
|
|||||||
encode_get_group_member_list,
|
encode_get_group_member_list,
|
||||||
next_seq_no,
|
next_seq_no,
|
||||||
)
|
)
|
||||||
from gateway.session import SessionSource, build_session_key
|
from gateway.session import build_session_key
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -1897,7 +1897,7 @@ class OwnerCommandMiddleware(InboundMiddleware):
|
|||||||
return None, None, False
|
return None, None, False
|
||||||
|
|
||||||
# Sender identity check: bot owner <-> push.from_account == push.bot_owner_id
|
# Sender identity check: bot owner <-> push.from_account == push.bot_owner_id
|
||||||
owner_id = (push or {}).get("bot_owner_id") or ""
|
# owner_id = (push or {}).get("bot_owner_id") or ""
|
||||||
# is_owner = bool(owner_id) and owner_id == from_account
|
# is_owner = bool(owner_id) and owner_id == from_account
|
||||||
is_owner = True
|
is_owner = True
|
||||||
return cmd, cmd_line, is_owner
|
return cmd, cmd_line, is_owner
|
||||||
|
|||||||
@ -21,12 +21,10 @@ import hashlib
|
|||||||
import hmac
|
import hmac
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import secrets
|
import secrets
|
||||||
import struct
|
import struct
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from datetime import datetime, timezone, timedelta
|
|
||||||
from typing import Optional, Any
|
from typing import Optional, Any
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|||||||
@ -19,9 +19,8 @@ yuanbao_proto.py - Yuanbao WebSocket 协议编解码(纯 Python 实现)
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import struct
|
|
||||||
import threading
|
import threading
|
||||||
from typing import Optional, Union
|
from typing import Optional
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@ -7486,7 +7486,6 @@ class GatewayRunner:
|
|||||||
for m in history
|
for m in history
|
||||||
if m.get("role") in ("user", "assistant") and m.get("content")
|
if m.get("role") in ("user", "assistant") and m.get("content")
|
||||||
]
|
]
|
||||||
original_count = len(msgs)
|
|
||||||
approx_tokens = estimate_messages_tokens_rough(msgs)
|
approx_tokens = estimate_messages_tokens_rough(msgs)
|
||||||
|
|
||||||
tmp_agent = AIAgent(
|
tmp_agent = AIAgent(
|
||||||
|
|||||||
@ -62,7 +62,6 @@ from .config import (
|
|||||||
)
|
)
|
||||||
from .whatsapp_identity import (
|
from .whatsapp_identity import (
|
||||||
canonical_whatsapp_identifier,
|
canonical_whatsapp_identifier,
|
||||||
normalize_whatsapp_identifier,
|
|
||||||
)
|
)
|
||||||
from utils import atomic_replace
|
from utils import atomic_replace
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ from dataclasses import dataclass, field
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
from urllib import request as urllib_request
|
from urllib import request as urllib_request
|
||||||
from urllib.error import HTTPError, URLError
|
from urllib.error import HTTPError, URLError
|
||||||
from urllib.parse import urlparse, urlunparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@ -562,7 +562,6 @@ def build_welcome_banner(console: Console, model: str, cwd: str,
|
|||||||
right_content = "\n".join(right_lines)
|
right_content = "\n".join(right_lines)
|
||||||
layout_table.add_row(left_content, right_content)
|
layout_table.add_row(left_content, right_content)
|
||||||
|
|
||||||
agent_name = _skin_branding("agent_name", "Hermes Agent")
|
|
||||||
title_color = _skin_color("banner_title", "#FFD700")
|
title_color = _skin_color("banner_title", "#FFD700")
|
||||||
border_color = _skin_color("banner_border", "#CD7F32")
|
border_color = _skin_color("banner_border", "#CD7F32")
|
||||||
version_label = format_banner_version_label()
|
version_label = format_banner_version_label()
|
||||||
|
|||||||
@ -7,7 +7,6 @@ Currently supports:
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
|
|||||||
@ -13,7 +13,6 @@ automatically.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import io
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|||||||
@ -2953,7 +2953,7 @@ def _setup_sms():
|
|||||||
def _setup_dingtalk():
|
def _setup_dingtalk():
|
||||||
"""Configure DingTalk — QR scan (recommended) or manual credential entry."""
|
"""Configure DingTalk — QR scan (recommended) or manual credential entry."""
|
||||||
from hermes_cli.setup import (
|
from hermes_cli.setup import (
|
||||||
prompt_choice, prompt_yes_no, print_info, print_success, print_warning,
|
prompt_choice, prompt_yes_no, print_success, print_warning,
|
||||||
)
|
)
|
||||||
|
|
||||||
dingtalk_platform = next(p for p in _PLATFORMS if p["key"] == "dingtalk")
|
dingtalk_platform = next(p for p in _PLATFORMS if p["key"] == "dingtalk")
|
||||||
@ -3504,7 +3504,6 @@ def _setup_qqbot():
|
|||||||
method_idx = prompt_choice(" How would you like to set up QQ Bot?", method_choices, 0)
|
method_idx = prompt_choice(" How would you like to set up QQ Bot?", method_choices, 0)
|
||||||
|
|
||||||
credentials = None
|
credentials = None
|
||||||
used_qr = False
|
|
||||||
|
|
||||||
if method_idx == 0:
|
if method_idx == 0:
|
||||||
# ── QR scan-to-configure ──
|
# ── QR scan-to-configure ──
|
||||||
@ -3515,8 +3514,6 @@ def _setup_qqbot():
|
|||||||
print()
|
print()
|
||||||
print_warning(" QQ Bot setup cancelled.")
|
print_warning(" QQ Bot setup cancelled.")
|
||||||
return
|
return
|
||||||
if credentials:
|
|
||||||
used_qr = True
|
|
||||||
if not credentials:
|
if not credentials:
|
||||||
print_info(" QR setup did not complete. Continuing with manual input.")
|
print_info(" QR setup did not complete. Continuing with manual input.")
|
||||||
|
|
||||||
|
|||||||
@ -19,9 +19,8 @@ format) lives there.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
|
||||||
def hooks_command(args) -> None:
|
def hooks_command(args) -> None:
|
||||||
|
|||||||
@ -4732,7 +4732,6 @@ def _model_flow_anthropic(config, current_model=""):
|
|||||||
read_claude_code_credentials,
|
read_claude_code_credentials,
|
||||||
is_claude_code_token_valid,
|
is_claude_code_token_valid,
|
||||||
_is_oauth_token,
|
_is_oauth_token,
|
||||||
_resolve_claude_code_token_from_credentials,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_creds = read_claude_code_credentials()
|
cc_creds = read_claude_code_credentials()
|
||||||
@ -7137,7 +7136,7 @@ def _cmd_update_impl(args, gateway_mode: bool):
|
|||||||
print(
|
print(
|
||||||
f" ⚠ {svc_name} died after restart, retrying..."
|
f" ⚠ {svc_name} died after restart, retrying..."
|
||||||
)
|
)
|
||||||
retry = subprocess.run(
|
subprocess.run(
|
||||||
scope_cmd + ["restart", svc_name],
|
scope_cmd + ["restart", svc_name],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
|
|||||||
@ -46,7 +46,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|||||||
@ -999,7 +999,6 @@ def _run_composite_ui(curses, plugin_names, plugin_labels, plugin_selected,
|
|||||||
# We need to map logical cursor positions to screen rows
|
# We need to map logical cursor positions to screen rows
|
||||||
# accounting for non-navigable separator/headers
|
# accounting for non-navigable separator/headers
|
||||||
|
|
||||||
draw_row = 0 # tracks navigable item index
|
|
||||||
|
|
||||||
# --- General Plugins section ---
|
# --- General Plugins section ---
|
||||||
if n_plugins > 0:
|
if n_plugins > 0:
|
||||||
|
|||||||
@ -712,8 +712,6 @@ def setup_model_provider(config: dict, *, quick: bool = False):
|
|||||||
if isinstance(_m, dict):
|
if isinstance(_m, dict):
|
||||||
selected_provider = _m.get("provider")
|
selected_provider = _m.get("provider")
|
||||||
|
|
||||||
nous_subscription_selected = selected_provider == "nous"
|
|
||||||
|
|
||||||
# ── Same-provider fallback & rotation setup (full setup only) ──
|
# ── Same-provider fallback & rotation setup (full setup only) ──
|
||||||
if not quick and _supports_same_provider_pool_setup(selected_provider):
|
if not quick and _supports_same_provider_pool_setup(selected_provider):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Shows the status of all Hermes Agent components.
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess # noqa: F401 — re-exported for tests that monkeypatch status.subprocess to guard against regressions
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).parent.parent.resolve()
|
PROJECT_ROOT = Path(__file__).parent.parent.resolve()
|
||||||
|
|||||||
@ -736,7 +736,7 @@ async def get_sessions(limit: int = 20, offset: int = 0):
|
|||||||
return {"sessions": sessions, "total": total, "limit": limit, "offset": offset}
|
return {"sessions": sessions, "total": total, "limit": limit, "offset": offset}
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
_log.exception("GET /api/sessions failed")
|
_log.exception("GET /api/sessions failed")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
@ -968,7 +968,7 @@ async def update_config(body: ConfigUpdate):
|
|||||||
try:
|
try:
|
||||||
save_config(_denormalize_config_from_web(body.config))
|
save_config(_denormalize_config_from_web(body.config))
|
||||||
return {"ok": True}
|
return {"ok": True}
|
||||||
except Exception as e:
|
except Exception:
|
||||||
_log.exception("PUT /api/config failed")
|
_log.exception("PUT /api/config failed")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
@ -997,7 +997,7 @@ async def set_env_var(body: EnvVarUpdate):
|
|||||||
try:
|
try:
|
||||||
save_env_value(body.key, body.value)
|
save_env_value(body.key, body.value)
|
||||||
return {"ok": True, "key": body.key}
|
return {"ok": True, "key": body.key}
|
||||||
except Exception as e:
|
except Exception:
|
||||||
_log.exception("PUT /api/env failed")
|
_log.exception("PUT /api/env failed")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
@ -1011,7 +1011,7 @@ async def remove_env_var(body: EnvVarDelete):
|
|||||||
return {"ok": True, "key": body.key}
|
return {"ok": True, "key": body.key}
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception:
|
||||||
_log.exception("DELETE /api/env failed")
|
_log.exception("DELETE /api/env failed")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
@ -1568,7 +1568,6 @@ async def _start_device_code_flow(provider_id: str) -> Dict[str, Any]:
|
|||||||
then spawns a background poller. Returns the user-facing display fields
|
then spawns a background poller. Returns the user-facing display fields
|
||||||
so the UI can render the verification page link + user code.
|
so the UI can render the verification page link + user code.
|
||||||
"""
|
"""
|
||||||
from hermes_cli import auth as hauth
|
|
||||||
if provider_id == "nous":
|
if provider_id == "nous":
|
||||||
from hermes_cli.auth import _request_device_code, PROVIDER_REGISTRY
|
from hermes_cli.auth import _request_device_code, PROVIDER_REGISTRY
|
||||||
import httpx
|
import httpx
|
||||||
|
|||||||
@ -11,7 +11,6 @@ hot-reloaded by the webhook adapter without a gateway restart.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
import time
|
import time
|
||||||
|
|||||||
@ -27,6 +27,8 @@ from pathlib import Path
|
|||||||
import fire
|
import fire
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from hermes_constants import OPENROUTER_BASE_URL, get_hermes_home
|
||||||
|
|
||||||
# Load .env from ~/.hermes/.env first, then project root as dev fallback.
|
# Load .env from ~/.hermes/.env first, then project root as dev fallback.
|
||||||
# User-managed env files should override stale shell exports on restart.
|
# User-managed env files should override stale shell exports on restart.
|
||||||
_hermes_home = get_hermes_home()
|
_hermes_home = get_hermes_home()
|
||||||
@ -60,8 +62,6 @@ from tools.rl_training_tool import get_missing_keys
|
|||||||
# Config Loading
|
# Config Loading
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
from hermes_constants import get_hermes_home, OPENROUTER_BASE_URL
|
|
||||||
|
|
||||||
DEFAULT_MODEL = "anthropic/claude-opus-4.5"
|
DEFAULT_MODEL = "anthropic/claude-opus-4.5"
|
||||||
DEFAULT_BASE_URL = OPENROUTER_BASE_URL
|
DEFAULT_BASE_URL = OPENROUTER_BASE_URL
|
||||||
|
|
||||||
@ -412,7 +412,7 @@ def main(
|
|||||||
|
|
||||||
# Run the agent
|
# Run the agent
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
response = agent.run_conversation(user_input)
|
agent.run_conversation(user_input)
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
@ -429,7 +429,7 @@ def main(
|
|||||||
print("-" * 40)
|
print("-" * 40)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = agent.run_conversation(task)
|
agent.run_conversation(task)
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
print("✅ Task completed")
|
print("✅ Task completed")
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|||||||
@ -2720,7 +2720,6 @@ class AIAgent:
|
|||||||
eff_api_mode = api_mode if api_mode is not None else (self.api_mode or "")
|
eff_api_mode = api_mode if api_mode is not None else (self.api_mode or "")
|
||||||
eff_model = (model if model is not None else self.model) or ""
|
eff_model = (model if model is not None else self.model) or ""
|
||||||
|
|
||||||
base_lower = eff_base_url.lower()
|
|
||||||
model_lower = eff_model.lower()
|
model_lower = eff_model.lower()
|
||||||
provider_lower = eff_provider.lower()
|
provider_lower = eff_provider.lower()
|
||||||
is_claude = "claude" in model_lower
|
is_claude = "claude" in model_lower
|
||||||
|
|||||||
@ -20,7 +20,6 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from tools.registry import registry, tool_error
|
from tools.registry import registry, tool_error
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import websockets
|
import websockets
|
||||||
|
|||||||
@ -526,7 +526,6 @@ def _url_is_private(url: str) -> bool:
|
|||||||
backend is configured, which will surface the DNS error naturally).
|
backend is configured, which will surface the DNS error naturally).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
from tools.url_safety import is_safe_url
|
|
||||||
# is_safe_url returns False for private/loopback/link-local/CGNAT AND
|
# is_safe_url returns False for private/loopback/link-local/CGNAT AND
|
||||||
# for DNS failures. We only want the private-network case here, so
|
# for DNS failures. We only want the private-network case here, so
|
||||||
# we parse + check the host shape as a DNS-failure sieve first.
|
# we parse + check the host shape as a DNS-failure sieve first.
|
||||||
|
|||||||
@ -27,7 +27,6 @@ import time
|
|||||||
from concurrent.futures import (
|
from concurrent.futures import (
|
||||||
ThreadPoolExecutor,
|
ThreadPoolExecutor,
|
||||||
TimeoutError as FuturesTimeoutError,
|
TimeoutError as FuturesTimeoutError,
|
||||||
as_completed,
|
|
||||||
)
|
)
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@ from abc import ABC, abstractmethod
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import Optional, List, Dict, Any
|
from typing import Optional, List, Dict, Any
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from hermes_constants import get_hermes_home
|
|
||||||
from tools.binary_extensions import BINARY_EXTENSIONS
|
from tools.binary_extensions import BINARY_EXTENSIONS
|
||||||
|
|
||||||
from agent.file_safety import (
|
from agent.file_safety import (
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from agent.file_safety import get_read_block_error
|
from agent.file_safety import get_read_block_error
|
||||||
from tools.binary_extensions import has_binary_extension
|
from tools.binary_extensions import has_binary_extension
|
||||||
|
|||||||
@ -836,7 +836,6 @@ def transcribe_audio(file_path: str, model: Optional[str] = None) -> Dict[str, A
|
|||||||
return _transcribe_mistral(file_path, model_name)
|
return _transcribe_mistral(file_path, model_name)
|
||||||
|
|
||||||
if provider == "xai":
|
if provider == "xai":
|
||||||
xai_cfg = stt_config.get("xai", {})
|
|
||||||
# xAI Grok STT doesn't use a model parameter — pass through for logging
|
# xAI Grok STT doesn't use a model parameter — pass through for logging
|
||||||
model_name = model or "grok-stt"
|
model_name = model or "grok-stt"
|
||||||
return _transcribe_xai(file_path, model_name)
|
return _transcribe_xai(file_path, model_name)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -34,10 +34,6 @@ def _get_active_adapter():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from gateway.platforms.yuanbao import YuanbaoAdapter
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# 角色标签
|
# 角色标签
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -418,7 +414,7 @@ async def send_dm(
|
|||||||
# Registry registration
|
# Registry registration
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
from tools.registry import registry, tool_result, tool_error # noqa: E402
|
from tools.registry import registry, tool_result # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def _check_yuanbao():
|
def _check_yuanbao():
|
||||||
|
|||||||
@ -37,7 +37,7 @@ import yaml
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Dict, Any, Optional, Tuple, Callable
|
from typing import List, Dict, Any, Optional, Tuple
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user