chore: remove unused imports and dead locals (ruff F401/F841 sweep)

Cleans F401 unused imports and F841 dead local assignments across
root *.py, agent/, hermes_cli/, tools/, gateway/, cron/, tui_gateway/
(tests/, plugins/, skills/ excluded).

Intentionally KEPT (false positives / test-patch surfaces):
- agent/transports/__init__.py package re-exports
- cli.py browser_connect re-exports (DEFAULT_BROWSER_CDP_URL area,
  used by tests/cli/test_cli_browser_connect.py)
- hermes_cli/main.py _prompt_auth_credentials_choice /
  _model_flow_bedrock_api_key (accessed via main_mod attr in tests)
- gateway/run.py aliased replay_cleanup + whatsapp_identity re-exports
  and _PORT_BINDING_PLATFORM_VALUES (test-referenced)
- hermes_cli/web_server.py get_running_pid (tests monkeypatch it) and
  _OAUTH_TOKEN_URL availability probe
- hermes_cli/config.py get_process_hermes_home re-export (noqa'd F811
  chain) and yaml availability-probe import
- hermes_cli/nous_subscription.py managed_nous_tools_enabled
  (tests patch hermes_cli.nous_subscription.managed_nous_tools_enabled)
- try/except ImportError availability probes (env_loader, tts_tool,
  mcp_tool, web_server anthropic OAuth block)
- tools/web_tools.py noqa F401 re-exports
- hermes_cli/setup_whatsapp_cloud.py:263 'proceed' skipped: possible
  missing-guard bug, flagged for separate review
- unused function parameters (signature changes out of scope)

Side-effect RHS calls preserved where only the binding was dead
(e.g. web_server proc = _spawn_hermes_action -> bare call).
This commit is contained in:
teknium1 2026-07-29 09:10:02 -07:00 committed by Teknium
parent c3ffe27383
commit 5b751dc0ad
58 changed files with 18 additions and 98 deletions

View file

@ -34,7 +34,7 @@ from __future__ import annotations
import logging
import math
import os
from dataclasses import dataclass, field
from dataclasses import dataclass
from typing import Any, Optional
logger = logging.getLogger(__name__)

View file

@ -17,7 +17,7 @@ from __future__ import annotations
import logging
import os
import uuid
from dataclasses import dataclass, field
from dataclasses import dataclass
from decimal import Decimal, InvalidOperation
from typing import Any, Optional

View file

@ -18,7 +18,6 @@ from __future__ import annotations
import json
import logging
import os
import time
from types import SimpleNamespace
from typing import Any, Callable, Dict, List

View file

@ -22,9 +22,7 @@ import os
import random
import re
import ssl
import threading
import time
import uuid
from typing import Any, Dict, List, Optional
from agent.codex_responses_adapter import _summarize_user_message_for_log
@ -40,7 +38,6 @@ from agent.conversation_compression import (
from agent.context_engine import automatic_compaction_status_message
from agent.display import KawaiiSpinner
from agent.error_classifier import FailoverReason, classify_api_error
from agent.iteration_budget import IterationBudget
from agent.turn_context import (
_compression_warrants_another_preflight_pass,
build_turn_context,

View file

@ -902,7 +902,6 @@ def _reconcile_classification(
Every removed skill is placed in exactly one bucket.
"""
heur_cons = {e["name"]: e for e in heuristic.get("consolidated", [])}
heur_pruned = {e["name"] for e in heuristic.get("pruned", [])}
model_cons = {e["from"]: e for e in model_block.get("consolidations", [])}
model_pruned = {e["name"]: e for e in model_block.get("prunings", [])}

View file

@ -403,7 +403,6 @@ def _category_counts(payload: dict[str, Any]) -> list[tuple[str, int]]:
def category_color_map(payload: dict[str, Any]) -> dict[str, str]:
"""Deterministic, evenly-spread hue per skill category (theme-independent)."""
clusters = _category_counts(payload)
n = max(1, len(clusters))
# Golden-angle hue spacing so adjacent categories never collide in color.
return {cat: rgb_to_hex(_hsl_to_rgb((i * 137.508) % 360, 0.55, 0.62)) for i, (cat, _c) in enumerate(clusters)}

View file

@ -55,7 +55,7 @@ def register_subparser(subparsers: argparse._SubParsersAction) -> None:
help="Even attempt servers marked manual-install (best effort)",
)
sub_restart = sub.add_parser(
sub.add_parser(
"restart",
help="Tear down running LSP clients (next edit re-spawns)",
)

View file

@ -30,7 +30,6 @@ import logging
import os
import shutil
import subprocess
import sys
import threading
from pathlib import Path
from typing import Any, Dict, Optional

View file

@ -18,7 +18,7 @@ import secrets
import threading
import time
from contextlib import contextmanager
from concurrent.futures import Future, ThreadPoolExecutor, TimeoutError
from concurrent.futures import Future, TimeoutError
from typing import Any, Callable, Mapping, Optional

View file

@ -32,7 +32,6 @@ from agent.display import (
redact_tool_args_for_display as _redact_tool_args_for_display,
_detect_tool_failure,
)
from agent.tool_guardrails import ToolGuardrailDecision
from agent.tool_dispatch_helpers import (
_is_destructive_command,
_is_multimodal_tool_result,

View file

@ -378,7 +378,6 @@ class ChatCompletionsTransport(ProviderTransport):
ephemeral = params.get("ephemeral_max_output_tokens")
max_tokens = params.get("max_tokens")
anthropic_max_out = params.get("anthropic_max_output")
is_nvidia_nim = params.get("is_nvidia_nim", False)
is_kimi = params.get("is_kimi", False)
is_tokenhub = params.get("is_tokenhub", False)
reasoning_config = _reasoning_config_for_model(model, params.get("reasoning_config"))
@ -436,7 +435,6 @@ class ChatCompletionsTransport(ProviderTransport):
extra_body: dict[str, Any] = {}
is_openrouter = params.get("is_openrouter", False)
is_nous = params.get("is_nous", False)
is_github_models = params.get("is_github_models", False)
provider_name = str(params.get("provider_name") or "").strip().lower()
base_url = params.get("base_url")

3
cli.py
View file

@ -50,8 +50,6 @@ logger = logging.getLogger(__name__)
# Suppress startup messages for clean CLI experience
os.environ["HERMES_QUIET"] = "1" # Our own modules
import yaml
from hermes_cli.fallback_config import get_fallback_chain
from hermes_cli.cli_agent_setup_mixin import CLIAgentSetupMixin
from hermes_cli.cli_commands_mixin import CLICommandsMixin
@ -11635,7 +11633,6 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
# it must commit at least the same line.
if function_name and self.tool_progress_mode in {"new", "all", "verbose"}:
duration = kwargs.get("duration", 0.0)
is_error = kwargs.get("is_error", False)
# Pop stored args from tool.started for this function
stored = self._pending_tool_info.get(function_name)
stored_args = stored.pop(0) if stored else {}

View file

@ -7,13 +7,11 @@ proved gone. Terminal states are immutable.
from __future__ import annotations
import json
import os
import sqlite3
import threading
import uuid
from contextlib import contextmanager
from pathlib import Path
from typing import Any, Dict, Iterator, List, Optional
from hermes_constants import get_hermes_home

View file

@ -3001,7 +3001,6 @@ def run_job(
if prompt is None:
logger.info("Job '%s': script produced no output, skipping AI call.", job_name)
return True, "", SILENT_MARKER, None
origin = _resolve_origin(job)
_cron_session_id = f"cron_{job_id}_{_hermes_now().strftime('%Y%m%d_%H%M%S')}"
logger.info("Running job '%s' (ID: %s)", job_name, job_id)

View file

@ -2128,7 +2128,6 @@ def _apply_env_overrides(config: GatewayConfig) -> None:
)
# API Server
api_server_enabled = is_truthy_value(getenv("API_SERVER_ENABLED", ""))
api_server_key = getenv("API_SERVER_KEY", "")
api_server_cors_origins = getenv("API_SERVER_CORS_ORIGINS", "")
api_server_port = getenv("API_SERVER_PORT")

View file

@ -3633,21 +3633,18 @@ class APIServerAdapter(BasePlatformAdapter):
headers["X-Hermes-Session-Key"] = gateway_session_key
response = web.StreamResponse(status=200, headers=headers)
await response.prepare(request)
last_write = time.monotonic()
try:
while True:
try:
item = await asyncio.wait_for(queue.get(), timeout=CHAT_COMPLETIONS_SSE_KEEPALIVE_SECONDS)
except asyncio.TimeoutError:
await response.write(b": keepalive\n\n")
last_write = time.monotonic()
continue
if item is None:
break
name, payload = item
data = json.dumps(payload, ensure_ascii=False)
await response.write(f"event: {name}\ndata: {data}\n\n".encode("utf-8"))
last_write = time.monotonic()
except (asyncio.CancelledError, ConnectionResetError):
task.cancel()
raise

View file

@ -4337,7 +4337,6 @@ class BasePlatformAdapter(ABC):
``MEDIA:`/path/to/file.png` ``) to avoid breaking path extraction.
"""
chars = list(content)
n = len(chars)
# Build list of (start, end) spans to mask
spans: list = []

View file

@ -42,7 +42,7 @@ import subprocess
import sys
import time
from collections import deque
from typing import Any, Deque, Dict, List, Optional
from typing import Any, Deque, Dict, Optional
try:
from aiohttp import web

View file

@ -76,7 +76,6 @@ from gateway.platforms.base import (
MessageEvent,
MessageType,
SendResult,
SUPPORTED_DOCUMENT_TYPES,
)
from gateway.platforms.whatsapp_common import WhatsAppBehaviorMixin
from gateway.platforms.media_cache import ext_for_mime

View file

@ -37,23 +37,14 @@ import shlex
import site
import sys
import signal
import tempfile
import threading
import time
import sqlite3
from collections import OrderedDict
from contextvars import copy_context
from pathlib import Path
from datetime import datetime
from typing import Awaitable, Callable, Dict, Optional, Any, List, Union, cast
# account_usage imports the OpenAI SDK chain (~230 ms). Only needed by
# /usage; we still import it at module top in the gateway because test
# patches (tests/gateway/test_usage_command.py) target
# `gateway.run.fetch_account_usage` as a module-level attribute. The
# gateway is a long-running daemon, so its boot cost matters less than
# preserving the established test-patch surface.
from agent.account_usage import fetch_account_usage, render_account_usage_lines
from agent.async_utils import consume_detached_task_result, safe_schedule_threadsafe
from agent.conversation_compression import (
COMPACTION_STATUS,
@ -407,7 +398,6 @@ def _gateway_loop_exception_handler(
"""
exc = context.get("exception")
if exc is not None and _is_transient_network_error(exc):
message = context.get("message") or "transient network error"
task = context.get("future") or context.get("task")
task_name = ""
if task is not None:
@ -1661,7 +1651,7 @@ sys.path.insert(0, str(Path(__file__).parent.parent))
# Resolve Hermes home directory (respects HERMES_HOME override)
from hermes_constants import get_hermes_home, get_hermes_home_override
from utils import atomic_json_write, atomic_yaml_write, base_url_host_matches, is_truthy_value
from utils import atomic_json_write, is_truthy_value
_hermes_home = get_hermes_home()
# Load environment variables from ~/.hermes/.env first.
@ -2179,7 +2169,6 @@ from gateway.config import (
Platform,
_BUILTIN_PLATFORM_VALUES,
GatewayConfig,
HomeChannel,
PlatformConfig,
load_gateway_config,
)
@ -14350,7 +14339,6 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
# under that profile's loaded config — check after scope install.
if not home_env:
try:
from hermes_cli.profiles import get_profile_dir
from gateway.config import load_gateway_config as _lgc
prof = (getattr(source, "profile", None) or "").strip()
if prof and prof != "default":

View file

@ -2956,7 +2956,7 @@ class SessionStore:
# Cap pending messages per session to avoid unbounded memory
# growth when the DB is persistently broken. Drop the oldest.
if len(pending) > self._MAX_PENDING_PER_SESSION:
dropped = pending.pop(0)
pending.pop(0)
logger.warning(
"Session DB transcript pending queue full for %s "
"(cap=%d); dropping oldest message to make room",

View file

@ -19,7 +19,6 @@ import asyncio
import inspect
import logging
import queue
import re
import threading
import time
from dataclasses import dataclass

View file

@ -36,7 +36,7 @@ import webbrowser
from contextlib import contextmanager
from dataclasses import dataclass, field
from datetime import datetime, timezone
from http.server import BaseHTTPRequestHandler, HTTPServer, ThreadingHTTPServer
from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path
from typing import Any, Callable, Dict, FrozenSet, Iterable, List, Optional, Tuple
from urllib.parse import parse_qs, urlencode, urlparse

View file

@ -15,7 +15,6 @@ Import discipline mirrors ``hermes_cli.cli_commands_mixin``:
from __future__ import annotations
import time
class CLIBillingMixin:

View file

@ -16,7 +16,7 @@ import io
import json
import shlex
import sys
from dataclasses import dataclass, replace
from dataclasses import dataclass
from pathlib import Path
from typing import Callable, Iterable, Literal, NoReturn, Sequence

View file

@ -19,7 +19,7 @@ import logging
import threading
import time
from collections import defaultdict, deque
from typing import Any, Deque, Dict, Tuple
from typing import Any, Deque, Dict
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse

View file

@ -15,7 +15,6 @@ browser tool needs agent-browser).
"""
from __future__ import annotations
import os
import platform
import shutil
import subprocess

View file

@ -2358,7 +2358,6 @@ def run_doctor(args):
[f"Install azure-identity: {sys.executable} -m pip install azure-identity"],
)
base_url = str(model_cfg.get("base_url") or "").strip()
entra_cfg = model_cfg.get("entra") or {}
if not isinstance(entra_cfg, dict):
entra_cfg = {}

View file

@ -408,7 +408,6 @@ def _scan_gateway_pids(
_no_window = {"creationflags": windows_hide_flags()}
wmic_path = shutil.which("wmic")
used_fallback = False
result = None
if wmic_path is not None:
try:
@ -455,7 +454,6 @@ def _scan_gateway_pids(
)
except (OSError, subprocess.TimeoutExpired):
return []
used_fallback = True
if result.returncode != 0 or result.stdout is None:
return []
current_cmd = ""

View file

@ -160,7 +160,7 @@ def _post_enroll(
def cmd_gateway_enroll(args) -> None:
"""Enroll this gateway with a relay connector; persist the auth creds to .env."""
from hermes_cli.auth import AuthError, resolve_nous_access_token
from hermes_cli.auth import AuthError
from hermes_cli.config import is_managed, save_env_value
# Managed installs get GATEWAY_RELAY_* stamped in by the orchestrator (NAS

View file

@ -26,7 +26,6 @@ from typing import Any, Optional
from hermes_cli import kanban_db as kb
from hermes_cli import kanban_swarm as ks
from hermes_cli.profiles import get_active_profile_name
# ---------------------------------------------------------------------------

View file

@ -5507,7 +5507,6 @@ def block_task(
raise ValueError(
f"block kind must be one of {sorted(VALID_BLOCK_KINDS)} or None"
)
routed_to = "blocked"
recurrences = 0
with write_txn(conn):
cur_row = conn.execute(
@ -5558,7 +5557,6 @@ def block_task(
conn, task_id, "dependency_wait",
{"reason": reason, "kind": kind}, run_id=run_id,
)
routed_to = "todo"
_blocked_task = get_task(conn, task_id)
_fire_kanban_lifecycle_hook(
"kanban_task_blocked",
@ -5618,7 +5616,6 @@ def block_task(
},
run_id=run_id,
)
routed_to = "triage"
else:
if expected_run_id is None:
cur = conn.execute(
@ -7194,7 +7191,6 @@ def detect_stale_running(
now = int(time.time())
host_prefix = f"{_claimer_id().split(':', 1)[0]}:"
reclaimed: list[str] = []
rows = conn.execute(
@ -7708,7 +7704,6 @@ def _record_task_failure(
if row is None:
return False
failures = int(row["consecutive_failures"]) + 1
cur_status = row["status"]
# Per-task override wins over both caller-supplied and default
# thresholds. None (the common case) falls through.

View file

@ -10,7 +10,7 @@ from __future__ import annotations
import logging
from copy import deepcopy
from dataclasses import dataclass, field
from typing import Any, Callable, Dict, List, Optional
from typing import Any, Callable, Dict, List
logger = logging.getLogger(__name__)

View file

@ -1981,7 +1981,6 @@ def _model_flow_kimi(config, current_model=""):
provider_id = "kimi-coding"
pconfig = PROVIDER_REGISTRY[provider_id]
key_env = pconfig.api_key_env_vars[0] if pconfig.api_key_env_vars else ""
base_url_env = pconfig.base_url_env_var or ""
# Step 1: Check / prompt for API key
@ -2066,7 +2065,6 @@ def _model_flow_stepfun(config, current_model=""):
provider_id = "stepfun"
pconfig = PROVIDER_REGISTRY[provider_id]
key_env = pconfig.api_key_env_vars[0] if pconfig.api_key_env_vars else ""
base_url_env = pconfig.base_url_env_var or ""
existing_key, existing_source = _existing_api_key_for_model_flow(provider_id, pconfig)
@ -2174,7 +2172,6 @@ def _model_flow_bedrock_api_key(config, region, current_model=""):
from hermes_cli.config import (
load_config,
save_config,
get_env_value,
save_env_value,
)
from hermes_cli.models import _PROVIDER_MODELS

View file

@ -1916,7 +1916,6 @@ def list_authenticated_providers(
# --- 1. Check Hermes-mapped providers ---
from hermes_cli.models import _AGGREGATOR_PROVIDERS as _AGG_PROVIDERS
from hermes_cli.models import _PROVIDER_ALIASES as _CANON_ALIASES
from hermes_cli.providers import ALIASES as _PROVIDER_ALIAS_TABLE
for hermes_id, mdev_id in PROVIDER_TO_MODELS_DEV.items():
# Skip vendor names that are merely aliases routing through an

View file

@ -394,7 +394,6 @@ def get_nous_subscription_features(
# Per-capability overrides: if set, they determine which backend is active for
# search/extract independently of web.backend.
web_search_backend = str(web_cfg.get("search_backend") or "").strip().lower()
web_extract_backend = str(web_cfg.get("extract_backend") or "").strip().lower()
tts_provider = str(tts_cfg.get("provider") or "edge").strip().lower()
# STT default is "local" (faster-whisper) per DEFAULT_CONFIG, which
# requires `pip install faster-whisper`. For Nous subscribers we'd

View file

@ -18,7 +18,6 @@ from __future__ import annotations
import argparse
import os
from pathlib import Path
from typing import List
from rich.console import Console

View file

@ -26,7 +26,7 @@ import logging
import os
import re
from pathlib import Path
from typing import Any, Optional
from typing import Optional
logger = logging.getLogger("hermes.security_audit")

View file

@ -6,7 +6,6 @@ No remote dependencies.
Enhanced with UI-UX-PRO-MAX design intelligence.
"""
import json
import datetime
import secrets
from typing import Any, Dict, List

View file

@ -23,7 +23,6 @@ from typing import Optional, Dict, Any
from hermes_cli.nous_subscription import get_nous_subscription_features
from tools.tool_backend_helpers import managed_nous_tools_enabled
from utils import base_url_hostname
from hermes_constants import get_optional_skills_dir
logger = logging.getLogger(__name__)
@ -795,12 +794,6 @@ def setup_model_provider(config: dict, *, quick: bool = False):
config.clear()
config.update(_refreshed)
# Derive the selected provider for downstream steps (vision setup).
selected_provider = None
_m = config.get("model")
if isinstance(_m, dict):
selected_provider = _m.get("provider")
# Credential rotation, vision-backend selection, and TTS provider are no
# longer prompted here. They have safe defaults (rotation off, vision
# auto-detected from the main provider, TTS = Edge) and are configurable
@ -880,8 +873,6 @@ def _install_neutts_deps() -> bool:
def _install_kittentts_deps() -> bool:
"""Install KittenTTS dependencies with user approval. Returns True on success."""
import subprocess
import sys
wheel_url = (
"https://github.com/KittenML/KittenTTS/releases/download/"
@ -3177,7 +3168,6 @@ def _run_blank_slate_setup(config: dict, hermes_home, is_existing: bool):
Either way nothing is enabled that the user did not explicitly choose.
"""
from hermes_cli.config import load_config
print()
print_header("Blank Slate Setup")

View file

@ -12,7 +12,7 @@ significant debugging to find. Surfacing invalid toolset names (and the
zero-tools end state) loudly turns that silent failure into an actionable one.
"""
from typing import Callable, Dict, List
from typing import Callable, List
def validate_platform_toolsets(

View file

@ -11262,7 +11262,6 @@ def _codex_full_login_worker(session_id: str) -> None:
from hermes_cli.auth import (
CODEX_OAUTH_CLIENT_ID,
CODEX_OAUTH_TOKEN_URL,
DEFAULT_CODEX_BASE_URL,
)
issuer = "https://auth.openai.com"
@ -13410,7 +13409,7 @@ async def install_mcp_catalog_entry(body: MCPCatalogInstall, profile: Optional[s
# the first clone is still running.
action = _mcp_install_action_name(name)
try:
proc = _spawn_hermes_action(
_spawn_hermes_action(
_profile_cli_args(effective_profile) + ["mcp", "install", name],
action,
)

View file

@ -2,7 +2,6 @@
from __future__ import annotations
import argparse
import json
import os
import re

View file

@ -16,7 +16,6 @@ Key design decisions:
import asyncio
import atexit
import contextlib
import json
import logging
import os

View file

@ -600,7 +600,7 @@ class AIAgent:
self._session_db = SessionDB()
return self._session_db
except Exception as exc:
except Exception:
logger.debug("SessionDB unavailable for recall", exc_info=True)
return None

View file

@ -259,7 +259,6 @@ def export_blueprint(job: Dict[str, Any], body: str, *, blueprint_name: Optional
name = name.strip("-_") or "shared-blueprint"
schedule = job.get("schedule_display") or _schedule_to_string(job.get("schedule"))
skills = job.get("skills") or ([job["skill"]] if job.get("skill") else [])
blueprint_block: Dict[str, Any] = {"schedule": schedule}
deliver = job.get("deliver")

View file

@ -13,7 +13,6 @@ the GUI.
"""
import json
import os
from utils import env_var_enabled

View file

@ -2251,9 +2251,6 @@ class CuaDriverBackend(ComputerUseBackend):
text = gws_out["data"] if isinstance(gws_out["data"], str) else ""
summary, tree = _split_tree_text(text)
# Parse element count from summary e.g. "✅ AppName — 42 elements, turn 3..."
m = re.search(r'(\d+)\s+elements?', summary)
# Surface 2 of NousResearch/hermes-agent#47072: prefer the
# canonical structuredContent.elements array (trycua/cua#1961).
# Falls back to markdown regex parsing for cua-driver builds

View file

@ -25,7 +25,6 @@ import json
import os
import platform as _platform_mod
import re
import shutil
import subprocess
import sys
from typing import Any, Dict, List, Optional, Sequence, Tuple

View file

@ -27,7 +27,6 @@ import os
import threading
import time
from concurrent.futures import (
ThreadPoolExecutor,
TimeoutError as FuturesTimeoutError,
)
from typing import Any, Dict, List, Optional

View file

@ -172,7 +172,6 @@ _capability_bg_lock = threading.Lock()
def _capability_disk_cache_path() -> "Path":
from pathlib import Path
from hermes_constants import get_hermes_home

View file

@ -33,7 +33,6 @@ import logging
import os
import shutil
import subprocess
import sys
import tempfile
import threading
from typing import Optional

View file

@ -9,7 +9,6 @@ over the platform-injected callback.
"""
import json
import os
from typing import Callable, Optional
from tools.registry import registry, tool_error

View file

@ -10,9 +10,7 @@ import json
import logging
import os
import re
import ssl
import time
from email.utils import formatdate
from agent.redact import redact_sensitive_text
from agent.secret_scope import get_secret

View file

@ -894,7 +894,7 @@ def archive_skill(skill_name: str) -> Tuple[bool, str]:
try:
skill_dir.rename(dest)
except OSError as e:
except OSError:
# Cross-device — fall back to shutil.move
import shutil
try:

View file

@ -4031,7 +4031,7 @@ def parallel_search_sources(
*on_source_done* is an optional callback ``(source_id, count) -> None``
invoked as each source completes useful for progress indicators.
"""
from concurrent.futures import ThreadPoolExecutor, as_completed
from concurrent.futures import as_completed
per_source_limits = per_source_limits or {}

View file

@ -545,7 +545,6 @@ def _truncate_with_footer(
total = len(content)
stored_path = _store_full_text(url, content)
shown = len(head) + len(tail)
footer_lines = [
"",

View file

@ -1905,7 +1905,6 @@ def _start_agent_build(sid: str, session: dict) -> None:
ready.set()
return
worker = None
notify_registered = False
home_token = None
secret_token = None