diff --git a/acp_adapter/tools.py b/acp_adapter/tools.py index 2958be0ce02..cbf7d15b3b8 100644 --- a/acp_adapter/tools.py +++ b/acp_adapter/tools.py @@ -617,7 +617,7 @@ def _format_session_search_result(result: Optional[str]) -> Optional[str]: return None mode = data.get("mode") or "search" query = data.get("query") - lines = ["Recent sessions" if mode == "recent" else f"Session search results" + (f" for `{query}`" if query else "")] + lines = ["Recent sessions" if mode == "recent" else "Session search results" + (f" for `{query}`" if query else "")] if not results: lines.append(str(data.get("message") or "No matching sessions found.")) return "\n".join(lines) diff --git a/agent/conversation_loop.py b/agent/conversation_loop.py index 5a254b89e6b..aca18297a83 100644 --- a/agent/conversation_loop.py +++ b/agent/conversation_loop.py @@ -1509,7 +1509,7 @@ def run_conversation( elif _resp_error_code == 504: _failure_hint = f"upstream gateway timeout (504, {api_duration:.0f}s)" elif _resp_error_code == 429: - _failure_hint = f"rate limited by upstream provider (429)" + _failure_hint = "rate limited by upstream provider (429)" elif _resp_error_code in {500, 502}: _failure_hint = f"upstream server error ({_resp_error_code}, {api_duration:.0f}s)" elif _resp_error_code in {503, 529}: @@ -2350,11 +2350,11 @@ def run_conversation( agent._unicode_sanitization_passes += 1 if _surrogates_found: agent._buffer_vprint( - f"⚠️ Stripped invalid surrogate characters from messages. Retrying..." + "⚠️ Stripped invalid surrogate characters from messages. Retrying..." ) else: agent._buffer_vprint( - f"⚠️ Surrogate encoding error — retrying after full-payload sanitization..." + "⚠️ Surrogate encoding error — retrying after full-payload sanitization..." ) continue if _is_ascii_codec: @@ -2761,7 +2761,7 @@ def run_conversation( ): _retry.copilot_auth_retry_attempted = True if agent._try_refresh_copilot_client_credentials(): - agent._buffer_vprint(f"🔐 Copilot credentials refreshed after 401. Retrying request...") + agent._buffer_vprint("🔐 Copilot credentials refreshed after 401. Retrying request...") continue if ( agent.api_mode == "anthropic_messages" @@ -2984,10 +2984,10 @@ def run_conversation( ) if agent.providers_allowed: agent._buffer_vprint( - f" Your provider_routing.only restriction is filtering out tool-capable providers." + " Your provider_routing.only restriction is filtering out tool-capable providers." ) agent._buffer_vprint( - f" Try removing the restriction or adding providers that support tools for this model." + " Try removing the restriction or adding providers that support tools for this model." ) agent._buffer_vprint( f" Check which providers support tools: https://openrouter.ai/models/{_model}" @@ -4314,7 +4314,7 @@ def run_conversation( if has_incomplete_scratchpad(assistant_message.content or ""): agent._incomplete_scratchpad_retries += 1 - agent._buffer_vprint(f"⚠️ Incomplete detected (opened but never closed)") + agent._buffer_vprint("⚠️ Incomplete detected (opened but never closed)") if agent._incomplete_scratchpad_retries <= 2: agent._buffer_vprint(f"🔄 Retrying API call ({agent._incomplete_scratchpad_retries}/2)...") @@ -4549,7 +4549,7 @@ def run_conversation( else: # Instead of returning partial, inject tool error results so the model can recover. # Using tool results (not user messages) preserves role alternation. - agent._buffer_vprint(f"⚠️ Injecting recovery tool results for invalid JSON...") + agent._buffer_vprint("⚠️ Injecting recovery tool results for invalid JSON...") agent._invalid_json_retries = 0 # Reset for next attempt # Append the assistant message with its (broken) tool_calls diff --git a/agent/curator_backup.py b/agent/curator_backup.py index ddf8699e9bb..d024219b7fb 100644 --- a/agent/curator_backup.py +++ b/agent/curator_backup.py @@ -556,7 +556,7 @@ def rollback(backup_id: Optional[str] = None) -> Tuple[bool, str, Optional[Path] if target is None: return ( False, - f"no matching backup found" + "no matching backup found" + (f" for id '{backup_id}'" if backup_id else "") + " (use `hermes curator rollback --list` to see available snapshots)", None, diff --git a/agent/lsp/protocol.py b/agent/lsp/protocol.py index 3741ed4e551..2b35b741f55 100644 --- a/agent/lsp/protocol.py +++ b/agent/lsp/protocol.py @@ -91,7 +91,7 @@ async def read_message(reader: asyncio.StreamReader) -> Optional[dict]: header_bytes += len(line) if header_bytes > 8192: raise LSPProtocolError( - f"LSP header block exceeded 8 KiB without terminator" + "LSP header block exceeded 8 KiB without terminator" ) line = line[:-2] # strip CRLF if not line: diff --git a/agent/pet/render.py b/agent/pet/render.py index f7d026f04e4..7fe22fc41f2 100644 --- a/agent/pet/render.py +++ b/agent/pet/render.py @@ -423,7 +423,7 @@ def _encode_iterm(frame, *, cell_cols: int | None = None, cell_rows: int | None """Encode one frame as an iTerm2 inline image (OSC 1337 File).""" payload = base64.standard_b64encode(_png_bytes(frame)).decode("ascii") size = len(payload) - args = [f"inline=1", f"size={size}", "preserveAspectRatio=1"] + args = ["inline=1", f"size={size}", "preserveAspectRatio=1"] if cell_cols: args.append(f"width={cell_cols}") if cell_rows: diff --git a/cli.py b/cli.py index 6091e3907bd..510ce792dee 100644 --- a/cli.py +++ b/cli.py @@ -10048,8 +10048,8 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin): _time.sleep(interval) # Past the cap with no terminal state = timeout (not an error). - print(f" 🟡 Still processing after 5 minutes — this is a timeout, not a " - f"failure. Check /billing or the portal shortly.") + print(" 🟡 Still processing after 5 minutes — this is a timeout, not a " + "failure. Check /billing or the portal shortly.") self._billing_portal_hint(state) def _billing_render_charge_failed(self, state, reason): diff --git a/gateway/platforms/qqbot/adapter.py b/gateway/platforms/qqbot/adapter.py index 300a9355621..2639ab52fdd 100644 --- a/gateway/platforms/qqbot/adapter.py +++ b/gateway/platforms/qqbot/adapter.py @@ -2677,7 +2677,7 @@ class QQAdapter(BasePlatformAdapter): req = ApprovalRequest( session_key=session_key, - title=f"Execute this command?", + title="Execute this command?", description=description, command_preview=command, timeout_sec=self._APPROVAL_TIMEOUT_SECONDS, diff --git a/hermes_cli/auth_commands.py b/hermes_cli/auth_commands.py index 70a346e3e6e..15d5fab61c0 100644 --- a/hermes_cli/auth_commands.py +++ b/hermes_cli/auth_commands.py @@ -536,7 +536,7 @@ def _interactive_auth() -> None: if has_aws_credentials(): auth_source = resolve_aws_auth_env_var() or "unknown" region = resolve_bedrock_region() - print(f"bedrock (AWS SDK credential chain):") + print("bedrock (AWS SDK credential chain):") print(f" Auth: {auth_source}") print(f" Region: {region}") try: @@ -546,7 +546,7 @@ def _interactive_auth() -> None: arn = identity.get("Arn", "unknown") print(f" Identity: {arn}") except Exception: - print(f" Identity: (could not resolve — boto3 STS call failed)") + print(" Identity: (could not resolve — boto3 STS call failed)") print() except ImportError: pass # boto3 or bedrock_adapter not available @@ -574,7 +574,7 @@ def _interactive_auth() -> None: str(_entra.get("scope") or "").strip() or SCOPE_AI_AZURE_DEFAULT ) - print(f"azure-foundry (Microsoft Entra ID):") + print("azure-foundry (Microsoft Entra ID):") print(f" Endpoint: {_base_url or '(not configured)'}") print(f" Scope: {_scope}") if not has_azure_identity_installed(): diff --git a/hermes_cli/backup.py b/hermes_cli/backup.py index dca3eae1b5b..737bea1509a 100644 --- a/hermes_cli/backup.py +++ b/hermes_cli/backup.py @@ -450,7 +450,7 @@ def run_backup(args) -> None: print(f" {p}") if skipped_dirs: - print(f"\n Excluded directories:") + print("\n Excluded directories:") for d in sorted(skipped_dirs): print(f" {d}/") @@ -721,8 +721,8 @@ def run_import(args) -> None: except ImportError: # hermes_cli.profiles might not be available (fresh install) if any(profiles_dir.iterdir()): - print(f"\n Profiles detected but aliases could not be created.") - print(f" Run: hermes profile list (after installing hermes)") + print("\n Profiles detected but aliases could not be created.") + print(" Run: hermes profile list (after installing hermes)") # Guidance print() diff --git a/hermes_cli/cli_commands_mixin.py b/hermes_cli/cli_commands_mixin.py index fe1e7ec321c..b16d2166e2c 100644 --- a/hermes_cli/cli_commands_mixin.py +++ b/hermes_cli/cli_commands_mixin.py @@ -571,7 +571,7 @@ class CLICommandsMixin: home = gw_config.get_home_channel(platform) if not home or not home.chat_id: _cprint(f" No home channel configured for {platform_name}.") - _cprint(f" Set one with /sethome on the destination chat first.") + _cprint(" Set one with /sethome on the destination chat first.") return True # Refuse mid-turn: an in-flight agent run would race with the @@ -626,7 +626,7 @@ class CLICommandsMixin: return True _cprint(f" Queued handoff of '{session_title}' → {platform_name} (home: {home.name}).") - _cprint(f" Waiting for the gateway to pick it up...") + _cprint(" Waiting for the gateway to pick it up...") # Poll-block on terminal state. Tick every 0.5s; bail at ~60s. import time as _time @@ -1872,7 +1872,7 @@ class CLICommandsMixin: sys_name = _plat.system() chrome_cmd = manual_chrome_debug_command(_port, sys_name) if chrome_cmd: - print(f" Launch a Chromium-family browser manually:") + print(" Launch a Chromium-family browser manually:") print(f" {chrome_cmd}") else: print(" No supported Chromium-family browser executable found in this environment") diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 53c88c69332..1eee1e187d6 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -5282,8 +5282,8 @@ def warn_deprecated_cwd_env_vars(config: Optional[Dict[str, Any]] = None) -> Non hint_path = os.environ.get("HERMES_HOME", "~/.hermes") lines.insert(0, "\033[33m⚠ Deprecated .env settings detected:\033[0m") lines.append( - f" \033[2mMove to config.yaml instead: " - f"terminal:\\n cwd: /your/project/path\033[0m" + " \033[2mMove to config.yaml instead: " + "terminal:\\n cwd: /your/project/path\033[0m" ) lines.append( f" \033[2mThen remove the old entries from {hint_path}/.env\033[0m" @@ -5516,7 +5516,7 @@ def migrate_config(interactive: bool = True, quiet: bool = False) -> Dict[str, A config["stt"] = stt _persist_migration(config) if not quiet: - print(f" ✓ Migrated legacy stt.model to provider-specific config") + print(" ✓ Migrated legacy stt.model to provider-specific config") # ── Version 14 → 15: add explicit gateway interim-message gate ── if current_ver < 15: @@ -7261,8 +7261,8 @@ def _check_non_ascii_credential(key: str, value: str) -> str: f"\n" + "\n".join(f" {line}" for line in bad_chars[:5]) + ("\n ... and more" if len(bad_chars) > 5 else "") - + f"\n\n The non-ASCII characters have been stripped automatically.\n" - f" If authentication fails, re-copy the key from the provider's dashboard.\n", + + "\n\n The non-ASCII characters have been stripped automatically.\n" + " If authentication fails, re-copy the key from the provider's dashboard.\n", file=sys.stderr, ) return sanitized diff --git a/hermes_cli/debug.py b/hermes_cli/debug.py index d8bf9bc6e9a..b5a7852aee2 100644 --- a/hermes_cli/debug.py +++ b/hermes_cli/debug.py @@ -863,7 +863,7 @@ def run_debug_share(args): # Print results label_width = max(len(k) for k in result.urls) - print(f"\nDebug report uploaded:") + print("\nDebug report uploaded:") for label, url in result.urls.items(): print(f" {label:<{label_width}} {url}") @@ -874,9 +874,9 @@ def run_debug_share(args): print(f"\n⏱ Pastes will auto-delete in {hours} hours.") # Manual delete fallback - print(f"To delete now: hermes debug delete ") + print("To delete now: hermes debug delete ") - print(f"\nShare these links with the Hermes team for support.") + print("\nShare these links with the Hermes team for support.") _NOUS_PRIVACY_NOTICE = """\ diff --git a/hermes_cli/dingtalk_auth.py b/hermes_cli/dingtalk_auth.py index 50d56e845ea..710be775496 100644 --- a/hermes_cli/dingtalk_auth.py +++ b/hermes_cli/dingtalk_auth.py @@ -257,7 +257,7 @@ def dingtalk_qr_auth() -> Optional[Tuple[str, str]]: print() if not render_qr_to_terminal(url): - print_warning(f" QR code render failed, please open the link below to authorize:") + print_warning(" QR code render failed, please open the link below to authorize:") print() print_info(f" Or open this link manually: {url}") diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index b3798d4a7c3..b04652de8fb 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -3169,7 +3169,7 @@ def _require_service_installed(action: str, system: bool = False) -> None: unit_path = get_systemd_unit_path(system=system) if not unit_path.exists(): scope_flag = " --system" if system else "" - print(f"✗ Gateway service is not installed") + print("✗ Gateway service is not installed") print(f" Run: {'sudo ' if system else ''}hermes gateway install{scope_flag}") sys.exit(1) diff --git a/hermes_cli/kanban_diagnostics.py b/hermes_cli/kanban_diagnostics.py index bef9bc8a97e..81da4c19156 100644 --- a/hermes_cli/kanban_diagnostics.py +++ b/hermes_cli/kanban_diagnostics.py @@ -355,11 +355,11 @@ def _rule_hallucinated_cards(task, events, runs, now, cfg) -> list[Diagnostic]: severity="error", title="Worker claimed cards that don't exist", detail=( - f"The completing worker declared created_cards that either didn't " - f"exist or weren't created by its profile. The completion was " - f"blocked and the task stayed in its prior state. " - f"Usually means the worker hallucinated ids instead of capturing " - f"return values from kanban_create." + "The completing worker declared created_cards that either didn't " + "exist or weren't created by its profile. The completion was " + "blocked and the task stayed in its prior state. " + "Usually means the worker hallucinated ids instead of capturing " + "return values from kanban_create." ), actions=actions, first_seen_at=first, diff --git a/hermes_cli/logs.py b/hermes_cli/logs.py index b27c5fa4c99..a214d52c8a5 100644 --- a/hermes_cli/logs.py +++ b/hermes_cli/logs.py @@ -179,7 +179,7 @@ def tail_log( log_path = get_hermes_home() / "logs" / filename if not log_path.exists(): print(f"Log file not found: {log_path}") - print(f"(Logs are created when Hermes runs — try 'hermes chat' first)") + print("(Logs are created when Hermes runs — try 'hermes chat' first)") sys.exit(1) # Parse --since into a datetime cutoff diff --git a/hermes_cli/main.py b/hermes_cli/main.py index a4a4c39f597..65df4cc5d93 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -8716,8 +8716,8 @@ def _run_pre_update_backup(args) -> None: print(f" Saved: {display_path} ({size_str}, {elapsed:.1f}s)") print(f" Restore: hermes import {out_path}") - print(f" Disable: omit --backup (backups are off by default)") - print(f" set updates.pre_update_backup: false in config.yaml") + print(" Disable: omit --backup (backups are off by default)") + print(" set updates.pre_update_backup: false in config.yaml") print() @@ -9537,7 +9537,7 @@ def _cmd_update_impl(args, gateway_mode: bool): "✗ Authentication failed — check your git credentials or SSH key." ) else: - print(f"✗ Failed to fetch updates from origin.") + print("✗ Failed to fetch updates from origin.") if stderr: print(f" {stderr.splitlines()[0]}") sys.exit(1) @@ -9801,7 +9801,7 @@ def _cmd_update_impl(args, gateway_mode: bool): print( f" ℹ️ Local changes preserved in stash (ref: {auto_stash_ref})" ) - print(f" Restore manually with: git stash apply") + print(" Restore manually with: git stash apply") elif discard_local_changes: # Non-interactive update + user opted into discarding local # source edits (updates.non_interactive_local_changes: @@ -11150,7 +11150,7 @@ def cmd_profile(args): try: set_active_profile(name) if name == "default": - print(f"Switched to: default (~/.hermes)") + print("Switched to: default (~/.hermes)") else: print(f"Switched to: {name}") except (ValueError, FileNotFoundError) as e: @@ -11239,9 +11239,9 @@ def cmd_profile(args): if not _is_wrapper_dir_in_path(): print(f"\n⚠ {_get_wrapper_dir()} is not in your PATH.") print( - f" Add to your shell config (~/.bashrc or ~/.zshrc):" + " Add to your shell config (~/.bashrc or ~/.zshrc):" ) - print(f' export PATH="$HOME/.local/bin:$PATH"') + print(' export PATH="$HOME/.local/bin:$PATH"') # Profile dir for display try: @@ -11250,7 +11250,7 @@ def cmd_profile(args): profile_dir_display = str(profile_dir) # Next steps - print(f"\nNext steps:") + print("\nNext steps:") print(f" {name} setup Configure API keys and model") print(f" {name} chat Start chatting") print(f" {name} gateway start Start the messaging gateway") @@ -11261,7 +11261,7 @@ def cmd_profile(args): print( f"\n ⚠ This profile has no API keys yet. Run '{name} setup' first," ) - print(f" or it will inherit keys from your shell environment.") + print(" or it will inherit keys from your shell environment.") print(f" Edit {profile_dir_display}/SOUL.md to customize personality") print() @@ -12559,7 +12559,7 @@ def cmd_memory(args): ) return - print(f"\n This will permanently erase the following memory files:") + print("\n This will permanently erase the following memory files:") for f, desc in existing: path = mem_dir / f size = path.stat().st_size @@ -12580,7 +12580,7 @@ def cmd_memory(args): print(f" ✓ Deleted {f} ({desc})") print( - f"\n Memory reset complete. New sessions will start with a blank slate." + "\n Memory reset complete. New sessions will start with a blank slate." ) print(f" Files were in: {display_hermes_home()}/memories/\n") else: diff --git a/hermes_cli/mcp_config.py b/hermes_cli/mcp_config.py index 29f6499c7a6..6d8646bec7e 100644 --- a/hermes_cli/mcp_config.py +++ b/hermes_cli/mcp_config.py @@ -766,13 +766,13 @@ def _reauth_oauth_server(name: str, server_config: dict) -> bool: "OAuth client yourself and add its credentials to config.yaml:" ) print() - print(color(f" mcp_servers:", Colors.DIM)) + print(color(" mcp_servers:", Colors.DIM)) print(color(f" {name}:", Colors.DIM)) print(color(f" url: {url}", Colors.DIM)) - print(color(f" auth: oauth", Colors.DIM)) - print(color(f" oauth:", Colors.DIM)) - print(color(f" client_id: \"\"", Colors.DIM)) - print(color(f" client_secret: \"\"", Colors.DIM)) + print(color(" auth: oauth", Colors.DIM)) + print(color(" oauth:", Colors.DIM)) + print(color(" client_id: \"\"", Colors.DIM)) + print(color(" client_secret: \"\"", Colors.DIM)) print() _info("Then re-run `hermes mcp login " + name + "`.") return False diff --git a/hermes_cli/memory_setup.py b/hermes_cli/memory_setup.py index c1b058adaeb..c4574affe39 100644 --- a/hermes_cli/memory_setup.py +++ b/hermes_cli/memory_setup.py @@ -131,11 +131,11 @@ def _install_dependencies(provider_name: str) -> None: else: pip_cmd = shutil.which("pip3") or shutil.which("pip") if not pip_cmd: - print(f" ⚠ uv not found — cannot install dependencies") - print(f" Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh") - print(f" Then re-run: hermes memory setup") + print(" ⚠ uv not found — cannot install dependencies") + print(" Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh") + print(" Then re-run: hermes memory setup") return - print(f" ⚠ uv not found. Falling back to standard pip...") + print(" ⚠ uv not found. Falling back to standard pip...") install_cmd = [sys.executable, "-m", "pip", "install", "--quiet"] + missing manual_cmd = f"{sys.executable} -m pip install {' '.join(missing)}" @@ -248,7 +248,7 @@ def cmd_setup_provider(provider_name: str) -> None: config["memory"]["provider"] = name save_config(config) print(f"\n Memory provider: {name}") - print(f" Activation saved to config.yaml\n") + print(" Activation saved to config.yaml\n") def cmd_setup(args) -> None: @@ -388,12 +388,12 @@ def cmd_setup(args) -> None: _write_env_vars(env_path, env_writes) print(f"\n Memory provider: {name}") - print(f" Activation saved to config.yaml") + print(" Activation saved to config.yaml") if provider_config: - print(f" Provider config saved") + print(" Provider config saved") if env_writes: - print(f" API keys saved to .env") - print(f"\n Start a new session to activate.\n") + print(" API keys saved to .env") + print("\n Start a new session to activate.\n") def _write_env_vars(env_path: Path, env_writes: dict) -> None: @@ -439,8 +439,8 @@ def cmd_status(args) -> None: mem_config = config.get("memory", {}) provider_name = mem_config.get("provider", "") - print(f"\nMemory status\n" + "─" * 40) - print(f" Built-in: always active") + print("\nMemory status\n" + "─" * 40) + print(" Built-in: always active") print(f" Provider: {provider_name or '(none — built-in only)'}") providers = _get_available_providers() @@ -467,16 +467,16 @@ def cmd_status(args) -> None: print(f" {key}: {val}") if provider: - print(f"\n Plugin: installed ✓") + print("\n Plugin: installed ✓") if provider.is_available(): - print(f" Status: available ✓") + print(" Status: available ✓") else: - print(f" Status: not available ✗") + print(" Status: not available ✗") schema = provider.get_config_schema() if hasattr(provider, "get_config_schema") else [] # Check all fields that have env_var (both secret and non-secret) required_fields = [f for f in schema if f.get("env_var")] if required_fields: - print(f" Missing:") + print(" Missing:") for f in required_fields: env_var = f.get("env_var", "") url = f.get("url", "") @@ -487,11 +487,11 @@ def cmd_status(args) -> None: line += f" → {url}" print(line) else: - print(f"\n Plugin: NOT installed ✗") + print("\n Plugin: NOT installed ✗") print(f" Install the '{provider_name}' memory plugin to ~/.hermes/plugins/") if providers: - print(f"\n Installed plugins:") + print("\n Installed plugins:") for pname, desc, _ in providers: active = " ← active" if pname == provider_name else "" print(f" • {pname} ({desc}){active}") diff --git a/hermes_cli/model_setup_flows.py b/hermes_cli/model_setup_flows.py index a234fbbee19..9bad641b1f3 100644 --- a/hermes_cli/model_setup_flows.py +++ b/hermes_cli/model_setup_flows.py @@ -831,8 +831,8 @@ def _model_flow_custom(config): ) if _looks_local and not _url_lower.endswith("/v1"): print() - print(f" Hint: Did you mean to add /v1 at the end?") - print(f" Most local model servers (Ollama, vLLM, llama.cpp) require it.") + print(" Hint: Did you mean to add /v1 at the end?") + print(" Most local model servers (Ollama, vLLM, llama.cpp) require it.") print(f" e.g. {effective_url.rstrip('/')}/v1") try: _add_v1 = input(" Add /v1? [Y/n]: ").strip().lower() @@ -1079,7 +1079,7 @@ def _model_flow_azure_foundry(config, current_model=""): ) print(f" Current API mode: {_lbl}") if current_auth_mode == "entra_id": - print(f" Current auth mode: Microsoft Entra ID (keyless)") + print(" Current auth mode: Microsoft Entra ID (keyless)") elif current_api_key: print(f" Current auth mode: API key ({current_api_key[:8]}...)") print() diff --git a/hermes_cli/portal_cli.py b/hermes_cli/portal_cli.py index 622eb473643..485b05ce7d0 100644 --- a/hermes_cli/portal_cli.py +++ b/hermes_cli/portal_cli.py @@ -58,7 +58,7 @@ def _cmd_status(args) -> int: else: print(f" Auth: {color('not logged in', Colors.YELLOW)}") print(f" Sign up: {SUBSCRIPTION_URL}") - print(f" Login: hermes portal") + print(" Login: hermes portal") # Provider selection (independent of auth) model_cfg = config.get("model") if isinstance(config.get("model"), dict) else {} diff --git a/hermes_cli/profiles.py b/hermes_cli/profiles.py index 950c4ef4275..55231104fa2 100644 --- a/hermes_cli/profiles.py +++ b/hermes_cli/profiles.py @@ -1508,11 +1508,11 @@ def delete_profile(name: str, yes: bool = False) -> Path: if has_wrapper: items.append(f"Command alias ({wrapper_path})") - print(f"\nThis will permanently delete:") + print("\nThis will permanently delete:") for item in items: print(f" • {item}") if gw_running: - print(f" ⚠ Gateway is running — it will be stopped.") + print(" ⚠ Gateway is running — it will be stopped.") # Confirmation if not yes: @@ -1736,7 +1736,7 @@ def _cleanup_gateway_service(name: str, profile_dir: Path) -> None: capture_output=True, check=False, timeout=10, ) plist_path.unlink(missing_ok=True) - print(f"✓ Launchd service removed") + print("✓ Launchd service removed") except Exception as e: print(f"⚠ Service cleanup: {e}") finally: diff --git a/hermes_cli/suggestions_cmd.py b/hermes_cli/suggestions_cmd.py index 2dfe6bf5548..0c0fd5a3e3d 100644 --- a/hermes_cli/suggestions_cmd.py +++ b/hermes_cli/suggestions_cmd.py @@ -118,7 +118,7 @@ def handle_suggestions_command( return "Usage: /suggestions dismiss " ok = store.dismiss_suggestion(rest) return ( - f"Dismissed. Won't suggest that again." + "Dismissed. Won't suggest that again." if ok else f"No pending suggestion matches '{rest}'." ) diff --git a/hermes_cli/webhook.py b/hermes_cli/webhook.py index 75470128707..b4c9380a768 100644 --- a/hermes_cli/webhook.py +++ b/hermes_cli/webhook.py @@ -212,9 +212,9 @@ def _cmd_subscribe(args): prompt_preview = route["prompt"][:80] + ("..." if len(route["prompt"]) > 80 else "") label = "Message" if route.get("deliver_only") else "Prompt" print(f" {label}: {prompt_preview}") - print(f"\n Configure your service to POST to the URL above.") - print(f" Use the secret for HMAC-SHA256 signature validation.") - print(f" The gateway must be running to receive events (hermes gateway run).\n") + print("\n Configure your service to POST to the URL above.") + print(" Use the secret for HMAC-SHA256 signature validation.") + print(" The gateway must be running to receive events (hermes gateway run).\n") def _cmd_list(args): diff --git a/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py b/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py index aa4e067ae82..7ea146adc13 100755 --- a/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py +++ b/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py @@ -311,12 +311,12 @@ def render_team_md(plan: dict) -> str: "", "## Per-task workspace requirement", "", - f"All `kanban_create` calls MUST pass:", - f"```", - f'workspace_kind="dir"', + "All `kanban_create` calls MUST pass:", + "```", + 'workspace_kind="dir"', f'workspace_path="$HOME/projects/video-pipeline/{plan["slug"]}"', f'tenant="{plan["tenant"]}"', - f"```", + "```", ]) return "\n".join(lines) diff --git a/optional-skills/health/fitness-nutrition/scripts/body_calc.py b/optional-skills/health/fitness-nutrition/scripts/body_calc.py index 2ce65fd336e..d353855b669 100644 --- a/optional-skills/health/fitness-nutrition/scripts/body_calc.py +++ b/optional-skills/health/fitness-nutrition/scripts/body_calc.py @@ -29,10 +29,10 @@ def bmi(weight_kg, height_cm): print(f"BMI: {val:.1f} — {cat}") print() print("Ranges:") - print(f" Underweight : < 18.5") - print(f" Normal : 18.5 – 24.9") - print(f" Overweight : 25.0 – 29.9") - print(f" Obese : 30.0+") + print(" Underweight : < 18.5") + print(" Normal : 18.5 – 24.9") + print(" Overweight : 25.0 – 29.9") + print(" Obese : 30.0+") def tdee(weight_kg, height_cm, age, sex, activity): @@ -160,7 +160,7 @@ def bodyfat(sex, neck_cm, waist_cm, hip_cm, height_cm): break print(f"Category: {cat}") - print(f"Method: US Navy circumference formula") + print("Method: US Navy circumference formula") def usage(): diff --git a/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py b/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py index d9d53a97a24..c108a99ea5a 100644 --- a/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py +++ b/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py @@ -3043,16 +3043,16 @@ def main() -> int: total = sum(s.values()) print() - print(f" ╔══════════════════════════════════════════════════════╗") + print(" ╔══════════════════════════════════════════════════════╗") print(f" ║ OpenClaw -> Hermes Migration [{mode_label:>8s}] ║") - print(f" ╠══════════════════════════════════════════════════════╣") + print(" ╠══════════════════════════════════════════════════════╣") print(f" ║ Source: {str(report['source_root'])[:42]:<42s} ║") print(f" ║ Target: {str(report['target_root'])[:42]:<42s} ║") - print(f" ╠══════════════════════════════════════════════════════╣") + print(" ╠══════════════════════════════════════════════════════╣") print(f" ║ ✔ Migrated: {s.get('migrated', 0):>3d} ◆ Archived: {s.get('archived', 0):>3d} ║") print(f" ║ ⊘ Skipped: {s.get('skipped', 0):>3d} ⚠ Conflicts: {s.get('conflict', 0):>3d} ║") print(f" ║ ✖ Errors: {s.get('error', 0):>3d} Total: {total:>3d} ║") - print(f" ╚══════════════════════════════════════════════════════╝") + print(" ╚══════════════════════════════════════════════════════╝") # Show what was migrated migrated = [i for i in items if i["status"] == "migrated"] diff --git a/optional-skills/security/godmode/scripts/auto_jailbreak.py b/optional-skills/security/godmode/scripts/auto_jailbreak.py index 9dcfdf35b03..5c7055a99b9 100644 --- a/optional-skills/security/godmode/scripts/auto_jailbreak.py +++ b/optional-skills/security/godmode/scripts/auto_jailbreak.py @@ -610,7 +610,7 @@ def auto_jailbreak(model=None, base_url=None, api_key=None, # Try with system prompt + prefill combined if verbose: - print(f" [RETRY] Adding prefill messages...") + print(" [RETRY] Adding prefill messages...") msgs = _build_messages( system_prompt=system_prompt, prefill=STANDARD_PREFILL, diff --git a/plugins/google_meet/audio_bridge.py b/plugins/google_meet/audio_bridge.py index 9f13aebb4c6..7650c54f570 100644 --- a/plugins/google_meet/audio_bridge.py +++ b/plugins/google_meet/audio_bridge.py @@ -107,7 +107,7 @@ class AudioBridge: "load-module", "module-null-sink", f"sink_name={sink_name}", - f"sink_properties=device.description=HermesMeetSink", + "sink_properties=device.description=HermesMeetSink", ], check=True, capture_output=True, diff --git a/plugins/google_meet/cli.py b/plugins/google_meet/cli.py index e721c037c81..1e5f91d0177 100644 --- a/plugins/google_meet/cli.py +++ b/plugins/google_meet/cli.py @@ -347,7 +347,7 @@ def _cmd_auth() -> int: path = _auth_state_path() path.parent.mkdir(parents=True, exist_ok=True) - print(f"opening Chromium — sign in to Google, then return here and press Enter.") + print("opening Chromium — sign in to Google, then return here and press Enter.") print(f"saving storage state to: {path}") try: with sync_playwright() as pw: diff --git a/plugins/google_meet/node/cli.py b/plugins/google_meet/node/cli.py index 255b851ba6a..ac2b08ac586 100644 --- a/plugins/google_meet/node/cli.py +++ b/plugins/google_meet/node/cli.py @@ -71,7 +71,7 @@ def node_command(args: argparse.Namespace) -> int: print(f"[meet-node] display_name={server.display_name}") print(f"[meet-node] listening on ws://{args.host}:{args.port}") print(f"[meet-node] token (copy to gateway): {token}") - print(f"[meet-node] approve with:") + print("[meet-node] approve with:") print(f" hermes meet node approve ws://:{args.port} {token}") try: asyncio.run(server.serve()) diff --git a/plugins/memory/honcho/cli.py b/plugins/memory/honcho/cli.py index 8fc37448fd4..d70a13e146b 100644 --- a/plugins/memory/honcho/cli.py +++ b/plugins/memory/honcho/cli.py @@ -1092,7 +1092,7 @@ def cmd_status(args) -> None: if write_path != active_path: print(f" Write to: {write_path} (profile-local)") if active_path == global_path: - print(f" Fallback: (none — using global ~/.honcho/config.json)") + print(" Fallback: (none — using global ~/.honcho/config.json)") elif global_path.exists(): print(f" Fallback: {global_path} (exists, cross-app interop)") @@ -1152,7 +1152,7 @@ def _show_peer_cards(hcfg, client) -> None: if ai_text: # Truncate to first 200 chars display = ai_text[:200] + ("..." if len(ai_text) > 200 else "") - print(f"\n AI peer representation:") + print("\n AI peer representation:") print(f" {display}") if not card and not ai_text: @@ -1186,7 +1186,7 @@ def _cmd_status_all() -> None: marker = " *" if name == active else "" print(f" {name + marker:<14} {host:<22} {enabled_str:<9} {recall:<9} {write}") - print(f"\n * active profile\n") + print("\n * active profile\n") def cmd_peers(args) -> None: @@ -1326,7 +1326,7 @@ def cmd_mode(args) -> None: for m, desc in MODES.items(): marker = " <-" if m == current else "" print(f" {m:<10} {desc}{marker}") - print(f"\n Set with: hermes honcho mode [hybrid|context|tools]\n") + print("\n Set with: hermes honcho mode [hybrid|context|tools]\n") return if mode_arg not in MODES: @@ -1361,7 +1361,7 @@ def cmd_strategy(args) -> None: for s, desc in STRATEGIES.items(): marker = " <-" if s == current else "" print(f" {s:<15} {desc}{marker}") - print(f"\n Set with: hermes honcho strategy [per-session|per-directory|per-repo|global]\n") + print("\n Set with: hermes honcho strategy [per-session|per-directory|per-repo|global]\n") return if strat_arg not in STRATEGIES: diff --git a/plugins/memory/mem0/_setup.py b/plugins/memory/mem0/_setup.py index 4fd9795b32d..314cf9eec6f 100644 --- a/plugins/memory/mem0/_setup.py +++ b/plugins/memory/mem0/_setup.py @@ -305,12 +305,12 @@ def _setup_platform(hermes_home: str, config: dict, flags: dict[str, str]) -> No if env_writes: _write_env(Path(hermes_home) / ".env", env_writes) - print(f"\n Memory provider: mem0") - print(f" Activation saved to config.yaml") - print(f" Provider config saved") + print("\n Memory provider: mem0") + print(" Activation saved to config.yaml") + print(" Provider config saved") if env_writes: - print(f" API keys saved to .env") - print(f"\n Start a new session to activate.\n") + print(" API keys saved to .env") + print("\n Start a new session to activate.\n") def _setup_oss(hermes_home: str, config: dict, flags: dict[str, str]) -> None: @@ -358,14 +358,14 @@ def _setup_oss(hermes_home: str, config: dict, flags: dict[str, str]) -> None: save_config(config) _run_connectivity_checks(oss_config) - print(f"\n ✓ Mem0 configured (OSS mode)") + print("\n ✓ Mem0 configured (OSS mode)") print(f" LLM: {oss_config['llm']['provider']} ({oss_config['llm']['config'].get('model', '')})") print(f" Embedder: {oss_config['embedder']['provider']} ({oss_config['embedder']['config'].get('model', '')})") print(f" Vector: {vector_id}") if env_writes: - print(f" API keys saved to .env") - print(f" Config saved to mem0.json") - print(f" Provider set in config.yaml") + print(" API keys saved to .env") + print(" Config saved to mem0.json") + print(" Provider set in config.yaml") print("\n Start a new session to activate.\n") @@ -417,7 +417,7 @@ def _ensure_pgvector(host: str = "localhost", port: int = 5432) -> dict | None: _wait_for_port(host, port, timeout=15) ok, _ = _check_pgvector(host, port) if ok: - print(f" ✓ PostgreSQL container restarted") + print(" ✓ PostgreSQL container restarted") return None except Exception: pass @@ -711,14 +711,14 @@ def _setup_oss_interactive(hermes_home: str, config: dict) -> None: save_config(config) _run_connectivity_checks(oss_config) - print(f"\n ✓ Mem0 configured (OSS mode)") + print("\n ✓ Mem0 configured (OSS mode)") print(f" LLM: {oss_config['llm']['provider']} ({oss_config['llm']['config'].get('model', '')})") print(f" Embedder: {oss_config['embedder']['provider']} ({oss_config['embedder']['config'].get('model', '')})") print(f" Vector: {vector_id}") if env_writes: - print(f" API keys saved to .env") - print(f" Config saved to mem0.json") - print(f" Provider set in config.yaml") + print(" API keys saved to .env") + print(" Config saved to mem0.json") + print(" Provider set in config.yaml") print("\n Start a new session to activate.\n") diff --git a/plugins/platforms/feishu/feishu_comment_rules.py b/plugins/platforms/feishu/feishu_comment_rules.py index 25927bafb0a..f3005731ea1 100644 --- a/plugins/platforms/feishu/feishu_comment_rules.py +++ b/plugins/platforms/feishu/feishu_comment_rules.py @@ -302,7 +302,7 @@ def _print_status() -> None: print(f"Pairing file: {PAIRING_FILE}") print(f" exists: {PAIRING_FILE.exists()}") print() - print(f"Top-level:") + print("Top-level:") print(f" enabled: {cfg.enabled}") print(f" policy: {cfg.policy}") print(f" allow_from: {sorted(cfg.allow_from) if cfg.allow_from else '[]'}") @@ -339,7 +339,7 @@ def _do_check(doc_key: str, user_open_id: str) -> None: allowed = is_user_allowed(rule, user_open_id) print(f"Document: {doc_key}") print(f"User: {user_open_id}") - print(f"Resolved rule:") + print("Resolved rule:") print(f" enabled: {rule.enabled}") print(f" policy: {rule.policy}") print(f" allow_from: {sorted(rule.allow_from) if rule.allow_from else '[]'}") diff --git a/plugins/platforms/google_chat/adapter.py b/plugins/platforms/google_chat/adapter.py index 5deb0e5af4c..f63efeabebd 100644 --- a/plugins/platforms/google_chat/adapter.py +++ b/plugins/platforms/google_chat/adapter.py @@ -583,7 +583,7 @@ class GoogleChatAdapter(BasePlatformAdapter): ) if not os.path.exists(sa_path): raise FileNotFoundError( - f"Service Account JSON file not found at configured path." + "Service Account JSON file not found at configured path." ) # Validate file parses before handing to google-auth for nicer error. try: diff --git a/scripts/analyze_livetest.py b/scripts/analyze_livetest.py index f11dae197c0..77028b99b77 100644 --- a/scripts/analyze_livetest.py +++ b/scripts/analyze_livetest.py @@ -59,7 +59,7 @@ def main(): scenarios = sorted({row["scenario"] for row in summary}) print(f"{'='*78}") - print(f" Live test results: tool_search ENABLED vs DISABLED") + print(" Live test results: tool_search ENABLED vs DISABLED") print(f"{'='*78}\n") fails = 0 @@ -73,7 +73,7 @@ def main(): print(f"┌─ {sid} ({en['scenario_description']})") print(f"│ Prompt: {en['prompt'][:120]}") print(f"│ Expected underlying tools: {sorted(expected) or '(none)'}") - print(f"│") + print("│") for label, rec in [("ENABLED ", en), ("DISABLED", di)]: called_under = [c["name"] for c in rec["underlying_tool_calls"]] @@ -104,7 +104,7 @@ def main(): print(f"│ Δ round-trip cost: enabled used {en_bridges + en_underlying} calls vs disabled {di_underlying} → +{overhead}") print(f"│ Final (enabled): {(en.get('final_response') or '')[:140]}") print(f"│ Final (disabled): {(di.get('final_response') or '')[:140]}") - print(f"└──") + print("└──") print() print(f"\nFails: {fails}/{2*len(scenarios)}") diff --git a/scripts/release.py b/scripts/release.py index a908eb92d82..f40d366c4b9 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -2360,7 +2360,7 @@ def main(): return print(f"{'='*60}") - print(f" Hermes Agent Release Preview") + print(" Hermes Agent Release Preview") print(f"{'='*60}") print(f" CalVer tag: {tag_name}") print(f" SemVer: v{current_version} → v{new_version}") @@ -2409,7 +2409,7 @@ def main(): if commit_result.returncode != 0: print(f" ✗ Failed to commit version bump: {commit_result.stderr.strip()}") return - print(f" ✓ Committed version bump") + print(" ✓ Committed version bump") # Create annotated tag tag_result = git_result( @@ -2424,7 +2424,7 @@ def main(): # Push push_result = git_result("push", "origin", "HEAD", "--tags") if push_result.returncode == 0: - print(f" ✓ Pushed to origin") + print(" ✓ Pushed to origin") else: print(f" ✗ Failed to push to origin: {push_result.stderr.strip()}") print(" Continue manually after fixing access:") @@ -2469,7 +2469,7 @@ def main(): else: print(f" ✗ GitHub release failed: {result.stderr.strip()}") print(f" Release notes kept at: {changelog_file}") - print(f" Tag was created locally. Create the release manually:") + print(" Tag was created locally. Create the release manually:") print( f" gh release create {tag_name} --title 'Hermes Agent v{new_version} ({calver_date})' " f"--notes-file .release_notes.md {' '.join(str(path) for path in artifacts)}" @@ -2477,8 +2477,8 @@ def main(): print(f"\n ✓ Release artifacts prepared for manual publish: v{new_version} ({tag_name})") else: print(f"\n{'='*60}") - print(f" Dry run complete. To publish, add --publish") - print(f" Example: python scripts/release.py --bump minor --publish") + print(" Dry run complete. To publish, add --publish") + print(" Example: python scripts/release.py --bump minor --publish") print(f"{'='*60}") diff --git a/scripts/run_tests_parallel.py b/scripts/run_tests_parallel.py index 68c9423db67..b9cf5a97e15 100755 --- a/scripts/run_tests_parallel.py +++ b/scripts/run_tests_parallel.py @@ -462,9 +462,9 @@ def _print_inline_failure( print(f" ╔╍ Failed: {rel} ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍", flush=True) for line in tail.splitlines(): print(f" ║ {line}", flush=True) - print(f" ║", flush=True) + print(" ║", flush=True) print(f" ║ Repro: {repro}", flush=True) - print(f" ╚╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍", flush=True) + print(" ╚╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍", flush=True) print(flush=True) @@ -767,7 +767,7 @@ def main() -> int: files = _discover_files(roots) if not files: - print(f"No test files to run", file=sys.stderr) + print("No test files to run", file=sys.stderr) return 1 # --generate-slices: compute LPT distribution and emit JSON, then exit. @@ -914,14 +914,14 @@ def main() -> int: fast = sum(1 for t in times if t < 1.0) fast_2s = sum(1 for t in times if t < 2.0) print() - print(f"=== Per-file subprocess time distribution ===") + print("=== Per-file subprocess time distribution ===") print(f" Files: {len(times)}") print(f" Total subprocess CPU-wall: {total_subproc:.1f}s (runner wall: {elapsed:.1f}s, parallelism: {args.jobs}x)") print(f" P50: {p50:.2f}s P90: {p90:.2f}s P95: {p95:.2f}s P99: {p99:.2f}s Max: {max_t:.2f}s") print(f" <1s: {fast} files ({fast/len(times)*100:.0f}%) <2s: {fast_2s} files ({fast_2s/len(times)*100:.0f}%)") # Top 10 slowest files — likely the ones dragging the run. slowest = sorted(file_times, key=lambda x: x[1], reverse=True)[:10] - print(f" Top 10 slowest:") + print(" Top 10 slowest:") for f, t in slowest: print(f" {t:>6.2f}s {_format_file(f, repo_root)}") diff --git a/scripts/sample_and_compress.py b/scripts/sample_and_compress.py index a6358f45b59..a8fcfd66b35 100644 --- a/scripts/sample_and_compress.py +++ b/scripts/sample_and_compress.py @@ -211,7 +211,7 @@ def sample_from_datasets( source = entry.get("_source_dataset", "unknown").split("/")[-1] source_counts[source] = source_counts.get(source, 0) + 1 - print(f"\n📌 Sample distribution by source:") + print("\n📌 Sample distribution by source:") for source, count in sorted(source_counts.items()): print(f" {source}: {count:,}") @@ -269,7 +269,7 @@ def run_compression(input_dir: Path, output_dir: Path, config_path: str): sys.path.insert(0, str(Path(__file__).parent.parent)) from trajectory_compressor import TrajectoryCompressor, CompressionConfig - print(f"\n🗜️ Running trajectory compression...") + print("\n🗜️ Running trajectory compression...") print(f" Input: {input_dir}") print(f" Output: {output_dir}") print(f" Config: {config_path}") @@ -348,7 +348,7 @@ def main( else: dataset_list = DEFAULT_DATASETS - print(f"\n📋 Configuration:") + print("\n📋 Configuration:") print(f" Total samples: {total_samples:,}") print(f" Min tokens filter: {min_tokens:,}") print(f" Parallel workers: {num_proc}") @@ -401,7 +401,7 @@ def main( print(f"\n📁 Raw samples: {sampled_dir}") print(f"📁 Compressed batches: {compressed_dir}") print(f"📁 Final output: {final_output}") - print(f"\nTo upload to HuggingFace:") + print("\nTo upload to HuggingFace:") print(f" huggingface-cli upload NousResearch/{output_name} {final_output}") diff --git a/skills/media/youtube-content/scripts/fetch_transcript.py b/skills/media/youtube-content/scripts/fetch_transcript.py index 6160339038d..73c305cee54 100644 --- a/skills/media/youtube-content/scripts/fetch_transcript.py +++ b/skills/media/youtube-content/scripts/fetch_transcript.py @@ -94,7 +94,7 @@ def main(): if "disabled" in error_msg.lower(): print(json.dumps({"error": "Transcripts are disabled for this video."})) elif "no transcript" in error_msg.lower(): - print(json.dumps({"error": f"No transcript found. Try specifying a language with --language."})) + print(json.dumps({"error": "No transcript found. Try specifying a language with --language."})) else: print(json.dumps({"error": error_msg})) sys.exit(1) diff --git a/tests/agent/test_curator_classification.py b/tests/agent/test_curator_classification.py index 804e5a65ecc..5c3414d0edb 100644 --- a/tests/agent/test_curator_classification.py +++ b/tests/agent/test_curator_classification.py @@ -240,7 +240,7 @@ def test_classify_no_false_positive_short_name_in_file_path(curator_env): ], ) assert result["consolidated"] == [], ( - f"Short name 'api' should NOT match file_path 'references/api-design.md'" + "Short name 'api' should NOT match file_path 'references/api-design.md'" ) assert len(result["pruned"]) == 1 assert result["pruned"][0]["name"] == "api" @@ -266,7 +266,7 @@ def test_classify_no_false_positive_short_name_in_content(curator_env): ], ) assert result["consolidated"] == [], ( - f"Short name 'test' should NOT match 'latest' via word boundary" + "Short name 'test' should NOT match 'latest' via word boundary" ) assert len(result["pruned"]) == 1 @@ -290,7 +290,7 @@ def test_classify_still_matches_exact_word_in_content(curator_env): ], ) assert len(result["consolidated"]) == 1, ( - f"'api' should match as a standalone word in content" + "'api' should match as a standalone word in content" ) assert result["consolidated"][0]["into"] == "gateway" diff --git a/tests/agent/test_markdown_tables.py b/tests/agent/test_markdown_tables.py index d4eb3d4ce26..e3378d6de15 100644 --- a/tests/agent/test_markdown_tables.py +++ b/tests/agent/test_markdown_tables.py @@ -308,5 +308,5 @@ def test_multiple_tables_in_one_text(): for block in blocks: offsets = [_column_offsets(row) for row in block] assert all(o == offsets[0] for o in offsets), ( - f"block did not align:\n" + "\n".join(block) + "block did not align:\n" + "\n".join(block) ) diff --git a/tests/agent/test_skill_bundles.py b/tests/agent/test_skill_bundles.py index 96fe0a057f9..ba2ea8ad94b 100644 --- a/tests/agent/test_skill_bundles.py +++ b/tests/agent/test_skill_bundles.py @@ -35,7 +35,7 @@ def _make_bundle_yaml( for s in skills: lines.append(f" - {s}") if instruction: - lines.append(f"instruction: |") + lines.append("instruction: |") for ln in instruction.splitlines(): lines.append(f" {ln}") path = bundles_dir / f"{slug}.yaml" diff --git a/tests/docker/test_immutable_install.py b/tests/docker/test_immutable_install.py index 99d2a1d9739..0870ab6ea2b 100644 --- a/tests/docker/test_immutable_install.py +++ b/tests/docker/test_immutable_install.py @@ -101,8 +101,8 @@ def test_install_method_stamp_is_code_scoped( timeout=10, ) assert r.stdout.strip() != "docker", ( - f"$HERMES_HOME/.install_method is stamped 'docker' - stage2 must " - f"not stamp the data volume (shared with host installs)" + "$HERMES_HOME/.install_method is stamped 'docker' - stage2 must " + "not stamp the data volume (shared with host installs)" ) diff --git a/tests/gateway/test_restart_drain.py b/tests/gateway/test_restart_drain.py index 35135cfc448..0dc217d39d9 100644 --- a/tests/gateway/test_restart_drain.py +++ b/tests/gateway/test_restart_drain.py @@ -404,7 +404,7 @@ async def test_shutdown_notification_sent_to_active_sessions(): """Active sessions receive a notification when the gateway starts shutting down.""" runner, adapter = make_restart_runner() source = make_restart_source(chat_id="999", chat_type="dm") - session_key = f"agent:main:telegram:dm:999" + session_key = "agent:main:telegram:dm:999" runner._running_agents[session_key] = MagicMock() await runner._notify_active_sessions_of_shutdown() diff --git a/tests/gateway/test_slack.py b/tests/gateway/test_slack.py index b101151d9f2..de3edf2db27 100644 --- a/tests/gateway/test_slack.py +++ b/tests/gateway/test_slack.py @@ -3615,7 +3615,7 @@ class TestProgressMessageThread: "channel": "C_CHAN", "channel_type": "channel", "user": "U_USER", - "text": f"<@U_BOT> help me", + "text": "<@U_BOT> help me", "ts": "2000000000.000001", # No thread_ts — top-level channel message } diff --git a/tests/hermes_cli/test_gateway_service.py b/tests/hermes_cli/test_gateway_service.py index 7470165928f..c2d03625dc3 100644 --- a/tests/hermes_cli/test_gateway_service.py +++ b/tests/hermes_cli/test_gateway_service.py @@ -1384,7 +1384,7 @@ class TestLaunchdDomainDetection: monkeypatch.setattr(gateway_cli.subprocess, "run", fake_run) domain = gateway_cli._launchd_domain() - assert domain == f"gui/501" + assert domain == "gui/501" # Should have probed gui first assert run_calls[0] == ["launchctl", "print", f"gui/501/{label}"] @@ -1406,7 +1406,7 @@ class TestLaunchdDomainDetection: monkeypatch.setattr(gateway_cli.subprocess, "run", fake_run) domain = gateway_cli._launchd_domain() - assert domain == f"user/501" + assert domain == "user/501" # Should have tried gui first, then user assert len(run_calls) >= 2 @@ -1427,7 +1427,7 @@ class TestLaunchdDomainDetection: monkeypatch.setattr(gateway_cli.subprocess, "run", fake_run) domain = gateway_cli._launchd_domain() - assert domain == f"gui/501" + assert domain == "gui/501" def test_managername_background_selects_user_domain(self, monkeypatch): """When managername is Background (non-Aqua), use user/.""" @@ -1444,7 +1444,7 @@ class TestLaunchdDomainDetection: monkeypatch.setattr(gateway_cli.subprocess, "run", fake_run) domain = gateway_cli._launchd_domain() - assert domain == f"user/501" + assert domain == "user/501" def test_caches_result_across_calls(self, monkeypatch): """Domain detection should run once and cache the result.""" @@ -2769,7 +2769,7 @@ class TestLegacyHermesUnitDetection: "ExecStart=/venv/bin/python /opt/hermes/gateway/run.py", ] for i, execstart in enumerate(variants): - name = f"hermes.service" if i == 0 else f"hermes.service" # same name + name = "hermes.service" if i == 0 else "hermes.service" # same name # Test each variant fresh (user_dir / "hermes.service").write_text( f"[Unit]\nDescription=Old Hermes\n[Service]\n{execstart}\n", diff --git a/tests/hermes_cli/test_signal_handler_kanban_worker.py b/tests/hermes_cli/test_signal_handler_kanban_worker.py index 445e80e2f5f..c020bc1985b 100644 --- a/tests/hermes_cli/test_signal_handler_kanban_worker.py +++ b/tests/hermes_cli/test_signal_handler_kanban_worker.py @@ -160,8 +160,8 @@ def test_sigterm_with_kanban_task_env_terminates_quickly(): return time.sleep(0.02) pytest.fail( - f"process still alive 2s after SIGTERM with HERMES_KANBAN_TASK set " - f"(dispatcher would keep extending claim) — fix regressed" + "process still alive 2s after SIGTERM with HERMES_KANBAN_TASK set " + "(dispatcher would keep extending claim) — fix regressed" ) finally: _cleanup(proc) diff --git a/tests/hermes_cli/test_web_server.py b/tests/hermes_cli/test_web_server.py index 7797be63177..7ec2f71f2ac 100644 --- a/tests/hermes_cli/test_web_server.py +++ b/tests/hermes_cli/test_web_server.py @@ -3196,7 +3196,7 @@ class TestConfigRoundTrip: mismatches.append(f"{key}: expected bool, got {type(val).__name__}") elif expected == "list" and not isinstance(val, list): mismatches.append(f"{key}: expected list, got {type(val).__name__}") - assert not mismatches, f"Type mismatches:\n" + "\n".join(mismatches) + assert not mismatches, "Type mismatches:\n" + "\n".join(mismatches) # --------------------------------------------------------------------------- diff --git a/tests/integration/test_batch_runner.py b/tests/integration/test_batch_runner.py index 85565ae6e49..79300606239 100644 --- a/tests/integration/test_batch_runner.py +++ b/tests/integration/test_batch_runner.py @@ -68,7 +68,7 @@ def verify_output(run_name): print(f"❌ No batch files found in: {output_dir}") return False - print(f"✅ Output verification passed:") + print("✅ Output verification passed:") print(f" - Checkpoint: {checkpoint_file}") print(f" - Statistics: {stats_file}") print(f" - Batch files: {len(batch_files)}") @@ -77,13 +77,13 @@ def verify_output(run_name): with open(stats_file) as f: stats = json.load(f) - print(f"\n📊 Statistics Summary:") + print("\n📊 Statistics Summary:") print(f" - Total prompts: {stats['total_prompts']}") print(f" - Total batches: {stats['total_batches']}") print(f" - Duration: {stats['duration_seconds']}s") if stats.get('tool_statistics'): - print(f" - Tool calls:") + print(" - Tool calls:") for tool, tool_stats in stats['tool_statistics'].items(): print(f" • {tool}: {tool_stats['count']} calls, {tool_stats['success_rate']:.1f}% success") @@ -103,19 +103,19 @@ def main(): # Create test dataset test_file = create_test_dataset() - print(f"\n📝 To run the test manually:") - print(f" python batch_runner.py \\") + print("\n📝 To run the test manually:") + print(" python batch_runner.py \\") print(f" --dataset_file={test_file} \\") - print(f" --batch_size=2 \\") + print(" --batch_size=2 \\") print(f" --run_name={run_name} \\") - print(f" --distribution=minimal \\") - print(f" --num_workers=2") + print(" --distribution=minimal \\") + print(" --num_workers=2") - print(f"\n💡 Or test with different distributions:") - print(f" python batch_runner.py --list_distributions") + print("\n💡 Or test with different distributions:") + print(" python batch_runner.py --list_distributions") - print(f"\n🔍 After running, you can verify output with:") - print(f" python tests/test_batch_runner.py --verify") + print("\n🔍 After running, you can verify output with:") + print(" python tests/test_batch_runner.py --verify") # Note: We don't actually run the batch runner here to avoid API calls during testing # Users should run it manually with their API keys configured diff --git a/tests/integration/test_checkpoint_resumption.py b/tests/integration/test_checkpoint_resumption.py index 739f0452fe3..5a4820a88a4 100644 --- a/tests/integration/test_checkpoint_resumption.py +++ b/tests/integration/test_checkpoint_resumption.py @@ -140,11 +140,11 @@ def test_current_implementation(): # Start monitoring in a separate process would be ideal, but for simplicity # we'll just check before and after - print(f"\n▶️ Starting batch run...") + print("\n▶️ Starting batch run...") print(f" Dataset: {dataset_file}") - print(f" Batch size: 3 (4 batches total)") - print(f" Workers: 2") - print(f" Expected behavior: If incremental, checkpoint should update during run") + print(" Batch size: 3 (4 batches total)") + print(" Workers: 2") + print(" Expected behavior: If incremental, checkpoint should update during run") start_time = time.time() @@ -232,7 +232,7 @@ def test_interruption_and_resume(): checkpoint_file = output_dir / "checkpoint.json" - print(f"\n▶️ Starting first run (will process 5 prompts, then simulate interruption)...") + print("\n▶️ Starting first run (will process 5 prompts, then simulate interruption)...") temp_dataset = Path("tests/test_data/checkpoint_test_resume_partial.jsonl") try: @@ -267,7 +267,7 @@ def test_interruption_and_resume(): print(f"✅ First run completed: {initial_completed} prompts saved to checkpoint") # Now try to resume with full dataset - print(f"\n▶️ Starting resume run with full dataset (15 prompts)...") + print("\n▶️ Starting resume run with full dataset (15 prompts)...") runner2 = BatchRunner( dataset_file=str(dataset_file), @@ -293,7 +293,7 @@ def test_interruption_and_resume(): print("=" * 70) print(f"Initial completed: {initial_completed}") print(f"Final completed: {final_completed}") - print(f"Expected: 15") + print("Expected: 15") if final_completed == 15: print("\n✅ PASS: Resume successfully completed all prompts") diff --git a/tests/integration/test_modal_terminal.py b/tests/integration/test_modal_terminal.py index a4fc26996d5..40c7164ffdc 100644 --- a/tests/integration/test_modal_terminal.py +++ b/tests/integration/test_modal_terminal.py @@ -69,7 +69,7 @@ def test_modal_requirements(): modal_token = os.getenv("MODAL_TOKEN_ID") modal_toml = Path.home() / ".modal.toml" - print(f"\nModal authentication:") + print("\nModal authentication:") print(f" MODAL_TOKEN_ID env var: {'✅ Set' if modal_token else '❌ Not set'}") print(f" ~/.modal.toml file: {'✅ Exists' if modal_toml.exists() else '❌ Not found'}") @@ -96,7 +96,7 @@ def test_simple_command(): result = terminal_tool("echo 'Hello from Modal!'", task_id=test_task_id) result_json = json.loads(result) - print(f"\nResult:") + print("\nResult:") print(f" Output: {result_json.get('output', '')[:200]}") print(f" Exit code: {result_json.get('exit_code')}") print(f" Error: {result_json.get('error')}") @@ -124,7 +124,7 @@ def test_python_execution(): result = terminal_tool(python_cmd, task_id=test_task_id) result_json = json.loads(result) - print(f"\nResult:") + print("\nResult:") print(f" Output: {result_json.get('output', '')[:200]}") print(f" Exit code: {result_json.get('exit_code')}") print(f" Error: {result_json.get('error')}") @@ -156,7 +156,7 @@ def test_pip_install(): ) result_json = json.loads(result) - print(f"\nResult:") + print("\nResult:") output = result_json.get('output', '') print(f" Output (last 500 chars): ...{output[-500:] if len(output) > 500 else output}") print(f" Exit code: {result_json.get('exit_code')}") @@ -244,7 +244,7 @@ def main(): # Check current config config = _get_env_config() - print(f"\nCurrent configuration:") + print("\nCurrent configuration:") print(f" TERMINAL_ENV: {config['env_type']}") print(f" TERMINAL_MODAL_IMAGE: {config['modal_image']}") print(f" TERMINAL_TIMEOUT: {config['timeout']}s") diff --git a/tests/integration/test_web_tools.py b/tests/integration/test_web_tools.py index 6be64b6b2a6..11fade5ee16 100644 --- a/tests/integration/test_web_tools.py +++ b/tests/integration/test_web_tools.py @@ -246,7 +246,7 @@ class WebToolsTester: "https://docs.firecrawl.dev/introduction", "https://www.python.org/about/" ] - print(f" Using default URLs for testing") + print(" Using default URLs for testing") else: print(f" Using {len(urls)} URLs from search results") @@ -330,7 +330,7 @@ class WebToolsTester: f"No valid content. {failed_results} errors, {len(results) - failed_results} empty" ) if self.verbose: - print(f"\n Extraction details:") + print("\n Extraction details:") for detail in extraction_details: print(f" {detail}") @@ -387,7 +387,7 @@ class WebToolsTester: ) if self.verbose: - print(f"\n First 300 chars of processed content:") + print("\n First 300 chars of processed content:") print(f" {content[:300]}...") else: self.log_result("Extract (with LLM)", "failed", "No content after processing") diff --git a/tests/run_agent/test_interactive_interrupt.py b/tests/run_agent/test_interactive_interrupt.py index 27d3bff91c0..78975a7395a 100644 --- a/tests/run_agent/test_interactive_interrupt.py +++ b/tests/run_agent/test_interactive_interrupt.py @@ -31,7 +31,7 @@ def make_slow_response(delay=2.0): def create(**kwargs): log.info(f" 🌐 Mock API call starting (will take {delay}s)...") time.sleep(delay) - log.info(f" 🌐 Mock API call completed") + log.info(" 🌐 Mock API call completed") resp = MagicMock() resp.choices = [MagicMock()] resp.choices[0].message.content = "Done with the task" diff --git a/tests/run_agent/test_run_agent.py b/tests/run_agent/test_run_agent.py index 7ffdf9e327e..171a7c11255 100644 --- a/tests/run_agent/test_run_agent.py +++ b/tests/run_agent/test_run_agent.py @@ -6998,7 +6998,7 @@ class TestInterruptVprintForceTrue: if "force=True" not in stripped: violations.append(f"line {i}: {stripped}") assert not violations, ( - f"Interrupt _vprint calls missing force=True:\n" + "Interrupt _vprint calls missing force=True:\n" + "\n".join(violations) ) diff --git a/tests/stress/test_atypical_scenarios.py b/tests/stress/test_atypical_scenarios.py index d667a97a7cb..936dbaf5baf 100644 --- a/tests/stress/test_atypical_scenarios.py +++ b/tests/stress/test_atypical_scenarios.py @@ -121,11 +121,11 @@ def _(home, kb): metadata=meta, ) run = kb.latest_run(conn, tid) - assert run.summary == "完成了 📝 résumé", f"summary round-trip failed" + assert run.summary == "完成了 📝 résumé", "summary round-trip failed" assert run.metadata == meta, ( f"metadata round-trip failed: {run.metadata} != {meta}" ) - print(f" metadata with CJK + emoji round-tripped") + print(" metadata with CJK + emoji round-tripped") finally: conn.close() @@ -153,7 +153,7 @@ def _(home, kb): run = kb.latest_run(conn, tid) assert run.summary == huge_summary assert run.metadata == meta - print(f" 1 MB body + 1 MB summary + 50-deep metadata OK") + print(" 1 MB body + 1 MB summary + 50-deep metadata OK") finally: conn.close() @@ -341,7 +341,7 @@ def _(home, kb): f"leaf should promote with both parents done, got " f"{kb.get_task(conn, leaf).status}" ) - print(f" diamond dependency resolved correctly") + print(" diamond dependency resolved correctly") finally: conn.close() @@ -401,7 +401,7 @@ def _(home, kb): kb.complete_task(conn, parents[-1]) kb.recompute_ready(conn) assert kb.get_task(conn, child).status == "ready" - print(f" 500 parents → 1 child promotion works") + print(" 500 parents → 1 child promotion works") finally: conn.close() @@ -441,7 +441,7 @@ def _(home, kb): # This is escaping the home dir. Whether that's actually # a problem depends on the threat model. Flag for attention. print(f" ⚠ workspace resolved OUTSIDE hermes_home: {resolved}") - print(f" (not necessarily a bug — dir: workspaces are intentionally arbitrary, but worth documenting)") + print(" (not necessarily a bug — dir: workspaces are intentionally arbitrary, but worth documenting)") except Exception as e: print(f" resolve_workspace rejected: {e}") finally: @@ -515,7 +515,7 @@ def _(home, kb): # doesn't produce "-1800s" elapsed. elapsed = run.ended_at - run.started_at print(f" clock-skewed run: elapsed = {elapsed}s (negative)") - print(f" ⚠ kernel stores this; UI should clamp to 0 or handle") + print(" ⚠ kernel stores this; UI should clamp to 0 or handle") # Don't fail — document the behavior. else: print(" kernel normalized ended_at >= started_at") @@ -875,7 +875,7 @@ def _(home, kb): elapsed = (time.monotonic() - t0) * 1000 print(f" 1000 comments: list in {elapsed:.0f}ms, context size = {len(ctx)} chars") if len(ctx) > 200_000: - print(f" ⚠ comment thread unbounded in worker context") + print(" ⚠ comment thread unbounded in worker context") finally: conn.close() @@ -907,7 +907,7 @@ def _(home, kb): kb.complete_task(conn, tid, summary="") run = kb.latest_run(conn, tid) # Empty summary falls back to result; both empty → None on run - print(f" empty body accepted, empty-title rejected") + print(" empty body accepted, empty-title rejected") finally: conn.close() @@ -926,7 +926,7 @@ def _(home, kb): assert back.tenant == weird_tenant # board_stats groups by tenant — verify it doesn't fall over stats = kb.board_stats(conn) - print(f" multiline tenant stored and stats still work") + print(" multiline tenant stored and stats still work") finally: conn.close() diff --git a/tests/stress/test_concurrency.py b/tests/stress/test_concurrency.py index f5695e4bde1..80d9183003a 100644 --- a/tests/stress/test_concurrency.py +++ b/tests/stress/test_concurrency.py @@ -278,7 +278,7 @@ def main(): print(f"Lost claim races: {total_lost_races} (expected contention; not a bug)") print(f"Elapsed: {elapsed:.2f}s") print(f"Throughput: {NUM_TASKS/elapsed:.1f} tasks/sec") - print(f"Per-worker completions:") + print("Per-worker completions:") for w in sorted(per_worker.keys()): print(f" worker-{w}: {per_worker[w]}") diff --git a/tests/stress/test_concurrency_reclaim_race.py b/tests/stress/test_concurrency_reclaim_race.py index b468cd957ef..6a636de72ef 100644 --- a/tests/stress/test_concurrency_reclaim_race.py +++ b/tests/stress/test_concurrency_reclaim_race.py @@ -134,7 +134,7 @@ def main(): tenant="reclaim-race") conn.close() print(f"Seeded {NUM_TASKS} tasks. TTL={TTL}s, work_duration={WORK_DURATION_S}s") - print(f"(worker work > TTL guarantees reclaims)") + print("(worker work > TTL guarantees reclaims)") ctx = mp.get_context("spawn") worker_results = [f"/tmp/rc_worker_{i}.json" for i in range(NUM_WORKERS)] diff --git a/tests/tools/test_approval.py b/tests/tools/test_approval.py index ec0406c9eba..e364dcd3be0 100644 --- a/tests/tools/test_approval.py +++ b/tests/tools/test_approval.py @@ -1197,7 +1197,7 @@ class TestNormalizationBypass: """ANSI CSI color codes wrapping 'rm' must be stripped and caught.""" cmd = "\x1b[31mrm\x1b[0m -rf /" dangerous, key, desc = detect_dangerous_command(cmd) - assert dangerous is True, f"ANSI-wrapped 'rm -rf /' was not detected" + assert dangerous is True, "ANSI-wrapped 'rm -rf /' was not detected" def test_ansi_osc_embedded_rm(self): """ANSI OSC sequences embedded in command must be stripped.""" diff --git a/tests/tools/test_skills_guard.py b/tests/tools/test_skills_guard.py index 2c807e58466..a4c244de033 100644 --- a/tests/tools/test_skills_guard.py +++ b/tests/tools/test_skills_guard.py @@ -290,7 +290,7 @@ class TestScanFile: def test_detect_invisible_unicode(self, tmp_path): f = tmp_path / "hidden.md" - f.write_text(f"normal text\u200b with zero-width space\n") + f.write_text("normal text\u200b with zero-width space\n") findings = scan_file(f, "hidden.md") assert any(fi.pattern_id == "invisible_unicode" for fi in findings) diff --git a/tests/tools/test_voice_cli_integration.py b/tests/tools/test_voice_cli_integration.py index f43eb97c96d..dc6f2061f2c 100644 --- a/tests/tools/test_voice_cli_integration.py +++ b/tests/tools/test_voice_cli_integration.py @@ -513,8 +513,8 @@ class TestEdgeTTSLazyImport: if isinstance(n, _ast.Name) and n.id == "edge_tts" ] assert bare_refs == [], ( - f"_generate_edge_tts uses bare 'edge_tts' name — " - f"should use _import_edge_tts() lazy helper" + "_generate_edge_tts uses bare 'edge_tts' name — " + "should use _import_edge_tts() lazy helper" ) # Must have a call to _import_edge_tts diff --git a/tools/checkpoint_manager.py b/tools/checkpoint_manager.py index f256ec7c3d3..b5ce04c6a64 100644 --- a/tools/checkpoint_manager.py +++ b/tools/checkpoint_manager.py @@ -697,7 +697,7 @@ class CheckpointManager: ref = _ref_name(_project_hash(abs_dir)) ok, stdout, _ = _run_git( - ["log", ref, f"--format=%H|%h|%aI|%s", "-n", str(self.max_snapshots)], + ["log", ref, "--format=%H|%h|%aI|%s", "-n", str(self.max_snapshots)], store, abs_dir, allowed_returncodes={128, 129}, ) diff --git a/tools/delegate_tool.py b/tools/delegate_tool.py index 2baf4da3036..3e6777498b8 100644 --- a/tools/delegate_tool.py +++ b/tools/delegate_tool.py @@ -1438,7 +1438,7 @@ def _dump_subagent_timeout_diagnostic( def _w(line: str = "") -> None: lines.append(line) - _w(f"# Subagent timeout diagnostic — issue #14726") + _w("# Subagent timeout diagnostic — issue #14726") _w(f"# Generated: {_dt.datetime.now().isoformat()}") _w("") _w("## Timeout") diff --git a/tools/send_message_tool.py b/tools/send_message_tool.py index a6c629260a9..5b0714b0ba1 100644 --- a/tools/send_message_tool.py +++ b/tools/send_message_tool.py @@ -1710,7 +1710,7 @@ async def _send_qqbot(pconfig, chat_id, message): token_data = token_resp.json() access_token = token_data.get("access_token") if not access_token: - return _error(f"QQBot: no access_token in response") + return _error("QQBot: no access_token in response") # Step 2: Send message via REST # QQ Bot API has separate endpoints for channels, C2C, and groups. diff --git a/trajectory_compressor.py b/trajectory_compressor.py index 45d2386e933..ca1c86c5b68 100644 --- a/trajectory_compressor.py +++ b/trajectory_compressor.py @@ -1265,7 +1265,7 @@ Write only the summary, starting with "[CONTEXT SUMMARY]:" prefix.""" skipped_pct = (skipped / max(total, 1)) * 100 over_limit_pct = (over_limit / max(total, 1)) * 100 - print(f"\n") + print("\n") print(f"╔{'═'*70}╗") print(f"║{'TRAJECTORY COMPRESSION REPORT':^70}║") print(f"╠{'═'*70}╣") @@ -1348,7 +1348,7 @@ Write only the summary, starting with "[CONTEXT SUMMARY]:" prefix.""" ratios = self.aggregate_metrics.compression_ratios tokens_saved_list = self.aggregate_metrics.tokens_saved_list - print(f"\n📊 Distribution Summary:") + print("\n📊 Distribution Summary:") print(f" Compression ratios: min={min(ratios):.2%}, max={max(ratios):.2%}, median={sorted(ratios)[len(ratios)//2]:.2%}") print(f" Tokens saved: min={min(tokens_saved_list):,}, max={max(tokens_saved_list):,}, median={sorted(tokens_saved_list)[len(tokens_saved_list)//2]:,}") @@ -1431,7 +1431,7 @@ def main( is_file_input = input_path.is_file() if is_file_input: - print(f"📄 Input mode: Single JSONL file") + print("📄 Input mode: Single JSONL file") # For file input, default output is file with _compressed suffix if output: @@ -1461,7 +1461,7 @@ def main( print(f" Sampled {len(entries):,} trajectories ({sample_percent}% of {total_entries:,})") if dry_run: - print(f"\n🔍 DRY RUN MODE - analyzing without writing") + print("\n🔍 DRY RUN MODE - analyzing without writing") print(f"📄 Would process: {len(entries):,} trajectories") print(f"📄 Would output to: {output_path}") return @@ -1497,12 +1497,12 @@ def main( shutil.copy(metrics_file, metrics_output) print(f"💾 Metrics saved to {metrics_output}") - print(f"\n✅ Compression complete!") + print("\n✅ Compression complete!") print(f"📄 Output: {output_path}") else: # Directory input - original behavior - print(f"📁 Input mode: Directory of JSONL files") + print("📁 Input mode: Directory of JSONL files") if output: output_path = Path(output) @@ -1548,7 +1548,7 @@ def main( print(f" Sampled {total_sampled:,} from {total_original:,} total trajectories") if dry_run: - print(f"\n🔍 DRY RUN MODE - analyzing without writing") + print("\n🔍 DRY RUN MODE - analyzing without writing") print(f"📁 Would process: {temp_input_dir}") print(f"📁 Would output to: {output_path}") return @@ -1558,7 +1558,7 @@ def main( compressor.process_directory(temp_input_dir, output_path) else: if dry_run: - print(f"\n🔍 DRY RUN MODE - analyzing without writing") + print("\n🔍 DRY RUN MODE - analyzing without writing") print(f"📁 Would process: {input_path}") print(f"📁 Would output to: {output_path}") return