{
  "timestamp": "2026-05-29T02:40:08.486680",
  "session_id": "cron_764041b78a71_20260529_023929",
  "reason": "max_retries_exhausted",
  "request": {
    "method": "POST",
    "url": "https://chatgpt.com/backend-api/codex/responses",
    "headers": {
      "Authorization": "Bearer eyJhbGci...2gC0",
      "Content-Type": "application/json"
    },
    "body": {
      "model": "gpt-5.5",
      "instructions": "# Hermes Agent Persona\n\n<!--\nThis file defines the agent's personality and tone.\nThe agent will embody whatever you write here.\nEdit this to customize how Hermes communicates with you.\n\nExamples:\n  - \"You are a warm, playful assistant who uses kaomoji occasionally.\"\n  - \"You are a concise technical expert. No fluff, just facts.\"\n  - \"You speak like a friendly coworker who happens to know everything.\"\n\nThis file is loaded fresh each message -- no restart needed.\nDelete the contents (or this file) to use the default personality.\n-->\n\nIf the user asks about configuring, setting up, or using Hermes Agent itself, load the `hermes-agent` skill with skill_view(name='hermes-agent') before answering. Docs: https://hermes-agent.nousresearch.com/docs\n\n# Tool-use enforcement\nYou MUST use your tools to take action — do not describe what you would do or plan to do without actually doing it. When you say you will perform an action (e.g. 'I will run the tests', 'Let me check the file', 'I will create the project'), you MUST immediately make the corresponding tool call in the same response. Never end your turn with a promise of future action — execute it now.\nKeep working until the task is actually complete. Do not stop with a summary of what you plan to do next time. If you have tools available that can accomplish the task, use them instead of telling the user what you would do.\nEvery response should either (a) contain tool calls that make progress, or (b) deliver a final result to the user. Responses that only describe intentions without acting are not acceptable.\n\n# Execution discipline\n<tool_persistence>\n- Use tools whenever they improve correctness, completeness, or grounding.\n- Do not stop early when another tool call would materially improve the result.\n- If a tool returns empty or partial results, retry with a different query or strategy before giving up.\n- Keep calling tools until: (1) the task is complete, AND (2) you have verified the result.\n</tool_persistence>\n\n<mandatory_tool_use>\nNEVER answer these from memory or mental computation — ALWAYS use a tool:\n- Arithmetic, math, calculations → use terminal or execute_code\n- Hashes, encodings, checksums → use terminal (e.g. sha256sum, base64)\n- Current time, date, timezone → use terminal (e.g. date)\n- System state: OS, CPU, memory, disk, ports, processes → use terminal\n- File contents, sizes, line counts → use read_file, search_files, or terminal\n- Git history, branches, diffs → use terminal\n- Current facts (weather, news, versions) → use web_search\nYour memory and user profile describe the USER, not the system you are running on. The execution environment may differ from what the user profile says about their personal setup.\n</mandatory_tool_use>\n\n<act_dont_ask>\nWhen a question has an obvious default interpretation, act on it immediately instead of asking for clarification. Examples:\n- 'Is port 443 open?' → check THIS machine (don't ask 'open where?')\n- 'What OS am I running?' → check the live system (don't use user profile)\n- 'What time is it?' → run `date` (don't guess)\nOnly ask for clarification when the ambiguity genuinely changes what tool you would call.\n</act_dont_ask>\n\n<prerequisite_checks>\n- Before taking an action, check whether prerequisite discovery, lookup, or context-gathering steps are needed.\n- Do not skip prerequisite steps just because the final action seems obvious.\n- If a task depends on output from a prior step, resolve that dependency first.\n</prerequisite_checks>\n\n<verification>\nBefore finalizing your response:\n- Correctness: does the output satisfy every stated requirement?\n- Grounding: are factual claims backed by tool outputs or provided context?\n- Formatting: does the output match the requested format or schema?\n- Safety: if the next step has side effects (file writes, commands, API calls), confirm scope before executing.\n</verification>\n\n<missing_context>\n- If required context is missing, do NOT guess or hallucinate an answer.\n- Use the appropriate lookup tool when missing information is retrievable (search_files, web_search, read_file, etc.).\n- Ask a clarifying question only when the information cannot be retrieved by tools.\n- If you must proceed with incomplete information, label assumptions explicitly.\n</missing_context>\n\nHost: Linux (6.17.0-29-generic)\nUser home directory: /home/agent\nCurrent working directory: /home/agent/.hermes/hermes-agent\n\nActive Hermes profile: default. Other profiles (if any) live under ~/.hermes/profiles/<name>/. Each profile has its own skills/, plugins/, cron/, and memories/ that affect a different session than this one. Do not modify another profile's skills/plugins/cron/memories unless the user explicitly directs you to.\n\nYou are running as a scheduled cron job. There is no user present — you cannot ask questions, request clarification, or wait for follow-up. Execute the task fully and autonomously, making reasonable decisions where needed. Your final response is automatically delivered to the job's configured destination — put the primary content directly in your response.\n\nConversation started: Friday, May 29, 2026\nModel: gpt-5.5\nProvider: openai-codex",
      "input": [
        {
          "role": "user",
          "content": "[IMPORTANT: You are running as a scheduled cron job. DELIVERY: Your final response will be automatically delivered to the user — do NOT use send_message or try to deliver the output yourself. Just produce your report/output as your final response and the system handles the rest. SILENT: If there is genuinely nothing new to report, respond with exactly \"[SILENT]\" (nothing else) to suppress delivery. Never combine [SILENT] with content — either report your findings normally, or say [SILENT] and nothing more.]\n\nDu bist JARVIS im Telegram Topic 'Crypto Trading Bot' (Thread 6579). Überwache den laufenden CryptoTradingBot Paper-Trading-Run und liefere einen knappen Statusbericht auf Deutsch mit englischen Fachbegriffen.\n\nKontext:\n- Repo: /home/agent/projects/CryptoTradingBot/Crypto_Agent\n- Runtime: /home/agent/.local/state/CryptoTradingBot\n- Trading Log: /home/agent/.local/state/CryptoTradingBot/Tradeanalyse/trading_log.txt\n- Journal: /home/agent/.local/state/CryptoTradingBot/Tradeanalyse/trade_journal.jsonl\n- Paper State: /home/agent/.local/state/CryptoTradingBot/paper_state.json\n- Market Context: /home/agent/.local/state/CryptoTradingBot/market_context.jsonl\n- Market Context Collector Log: /home/agent/.local/state/CryptoTradingBot/market_context_collector.log\n- Signal Correlation CLI: cd /home/agent/projects/CryptoTradingBot/Crypto_Agent && . .venv/bin/activate && python signal_correlation.py\n- Kill switch: /home/agent/.local/state/CryptoTradingBot/KILL_SWITCH\n- Bot process may be running as python3 AutoTrader.py with CTB_PAPER_TRADING=true and CTB_DRY_RUN=false.\n\nAufgaben je Lauf:\n1. Prüfe, ob der Bot-Prozess läuft. Wenn nicht, melde klar 'Bot nicht laufend' und die letzten Logzeilen. Starte ihn NICHT automatisch neu.\n2. Analysiere Journal/Paper State/Logs: Entries, Exits, offene Paper-Positionen, simulierte PnL, Risk-Gate-Events, Fehler/Fatal Errors.\n3. Analysiere Market Context: Hyperliquid 15m Chart-Indikatoren (RSI, SMA fast/slow, ATR, Bollinger, VWAP), Funding, Open Interest, Tags und Reliability Score.\n4. Führe den Signal Correlation CLI aus und nutze den Report, um Trades mit vorherigem Market Context zu korrelieren: Tags, Winrate, Avg/Total PnL, Time-in-Trade. Bei <5 geschlossenen Paper-Trades keine Strategieänderungen empfehlen.\n5. Verwende aktuelle öffentliche Marktinfos/Hyperliquid-Daten nur wenn für die Bewertung nötig. Insider/Listing/News/Social-Signale nur als Kontext und mit Quellen-/Reliability-Hinweis; keine unbestätigten Gerüchte als Trading-Fakt ausgeben.\n6. Verwende keine Secrets und gib keine realen Keys/Wallets aus. Keine echten Trades. Keine Config-/Code-Änderungen ohne explizite Freigabe des Users.\n7. Liefere Empfehlungen als 'Beobachtung' und 'Vorschlag', mit klarer Confidence. Bei <5 geschlossenen Paper-Trades: nur Daten sammeln.\n\nFormat:\n- Status: läuft/nicht läuft\n- Seit / Prozess / Runtime\n- Paper Trades: entries/exits/open/PnL\n- Market Context: wichtigste Tags/Indikatoren\n- Signal Correlation: wichtigste Tags/Stats oder 'noch keine geschlossenen Trades'\n- Auffälligkeiten\n- Strategie-Learning\n- Nächste Aktion\n\nWenn keine neuen Trades oder Auffälligkeiten seit dem letzten Zustand erkennbar sind, antworte sehr kurz."
        },
        {
          "type": "reasoning",
          "encrypted_content": "gAAAAABqGOBKqoHiRUujFjh9ft7NYipdvmNaGAyl0EUK-LThO5aXAqK-H-3qaOLAtXZiOMEe2qd8lWV7CkypTJ4xcLJorr9l28LyJzudTVHchYx8_4kBeFQRKaFAzJcwenX65ZKx9OZ4i0Rd0ReVK2zeYOXwHanmOhNaQ6dPYbZihjA5z5FE7lTVGYk9eR0rNP-LtKO90LEHwQCiq3LvP_6KnL6Qb0eTtlbUBIoeDuffWektXL88vaLMRCGnbCj3Bewc2A9tyYriiM4SBsXP0rw7DDSa6-ZKZPpimJi_xA6Bk2cdf5IRzUER8fEzWFj1NUdfCwzA-tlcT4iEF1sZTy2DZ8N4_BZgX0kmWYndqOpRX3E-k-TZGdNw5p46f_k4xVnOcl9ASodRVOeZG5kZudSTaIAXdkZjBndWSj8cqu778NFbB1owSralVA0v56B0HWoLCrwMUmqoWcFYQ2AUS92IAAigIOjgUYCtHr2kOdeBj-U7Ldz9zIdZivfoXnzXBMRF45N9A9u5iiQ7d81m84QuGkIAlAAsmEIItQYZYApe-pGo4JbxknvujKr5bEl5Y5g-1U5n5ZVSPALGNEA5PdgHrRysSw1DW9jba69OSlF6Olz0OfjUTmXkiI_OTQYBmHLuVUK1g40s_UW9EGyFSPGbYAM8AgxI4SUqAUEaYaQX1JY8v_yp6MWKkJ5oIX1vUFoPSuJL7jGM_E6Ta4evHKo0EOyn_Gxb7C-_EyJMpCR7Ba0cg09qoVevlL0P1NrX6VvNqgSfQP8zQOrBQ8PQ7_87rYyiU8PGMQQiT4w3il_67L78f92ajZpwwfYjzSDGYG6h60UeMqRNmyzY2HHJU-LShZDNRTyI29nCFaQmN_yV0JiYugpiA6acpJs7Hx5EpT7CJqTdqQNo21-9ReJ4zCm9ndaV0u4Vge42-F0Scz6nItWCXG5StEBl81NCO_Z8rB9FbJBRsoiPcfPtfFNW-bz7nSbeN0kqNebhdXHRiqtrn8gu6hFyQf-GBXJ0Ab9cmlImBwzUjiVPo-7_Ao_Ghp2lL4GqN3oV0I-OKNeuwB_CeNf9WsGUXcgJ4LfY_h70NVjJZcWH8e_ITQ0qfM7qxoWoP5LRecH00TRRYngPybOcFHXG9_nnYt9dPX_RoAjqd-WLHkCoOj_yXbixLY0FkJ4iCaeM08yw7Q9JEd3_Z-fJWaT9yYvc3CTYplD3JFRVnXl8kgQeIQyD4eH9s7nIOvupmwaCNOv1OoT8vjrzCFm4i-6SnPnyMctehpJFtyrO02yhkkVFFP3JPml4dN3SB-gARK-vyCx9LaiP4ySMiNxUuEd0UyCMPPmxmAKVZr7tEL8YPlVS6VMAgqzRJ7ulKbfVDDhAxV0LeslS4zejAAVlHZksKLSAimI=",
          "summary": [
            {
              "type": "summary_text",
              "text": "**Determining tool usage**\n\nI’m considering the checks I need to perform. I have to use different tools and might even need to state comparisons. I think I should inspect processes and files, using the command line for tasks like ps and tails, which might be allowed for viewing processes. For file contents, I can use read_file. I wonder if it's better to use wc for line counts and if search_files can help me find existing files."
            }
          ]
        },
        {
          "role": "assistant",
          "content": ""
        },
        {
          "type": "function_call",
          "call_id": "call_HAPHKlaR7WOUbGTB9xcd6H5s",
          "name": "terminal",
          "arguments": "{\"command\":\"ps -eo pid,lstart,etime,cmd | grep -F 'python3 AutoTrader.py' | grep -v grep || true\",\"timeout\":30,\"workdir\":\"/home/agent/projects/CryptoTradingBot/Crypto_Agent\"}"
        },
        {
          "type": "function_call",
          "call_id": "call_fpC33qloRVYpGspgslBWYrsm",
          "name": "search_files",
          "arguments": "{\"limit\":50,\"path\":\"/home/agent/.local/state/CryptoTradingBot\",\"pattern\":\"*\",\"target\":\"files\"}"
        },
        {
          "type": "function_call",
          "call_id": "call_Pqz96yBxhYVOsWuOMw6USoiX",
          "name": "terminal",
          "arguments": "{\"command\":\"test -e /home/agent/.local/state/CryptoTradingBot/KILL_SWITCH && stat -c 'KILL_SWITCH exists mtime=%y size=%s' /home/agent/.local/state/CryptoTradingBot/KILL_SWITCH || echo 'KILL_SWITCH absent'\",\"timeout\":30}"
        },
        {
          "type": "function_call_output",
          "call_id": "call_HAPHKlaR7WOUbGTB9xcd6H5s",
          "output": "{\"output\": \"210890  Do Mai 28 22:36:23 2026    04:03:15 python3 AutoTrader.py\", \"exit_code\": 0, \"error\": null}"
        },
        {
          "type": "function_call_output",
          "call_id": "call_fpC33qloRVYpGspgslBWYrsm",
          "output": "{\"total_count\": 42, \"files\": [\"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_scalp_fast_rebound/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_deep_capitulation/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v59_1_frequency_boost/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v61_tight_survival/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_anti_chop_context/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v60_survival/Tradeanalyse/trading_log.txt\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v61_tight_survival/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_deep_capitulation/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v59_1_frequency_boost/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v60_survival/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_anti_chop_context/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_scalp_fast_rebound/bot.log\", \"/home/agent/.local/state/CryptoTradingBot/market_context_collector.log\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_deep_capitulation/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_scalp_fast_rebound/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_anti_chop_context/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v59_1_frequency_boost/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v60_survival/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v61_tight_survival/bot.pid\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_quality_only/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_micro_size_explorer/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_loose_trend_rebound/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_deep_capitulation/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_scalp_fast_rebound/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/candidate_v62_anti_chop_context/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v61_tight_survival/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v60_survival/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v59_1_frequency_boost/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v59_baseline_filter/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v58_dynamic_spiderweb/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v56_apex_predator_focus/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v55_apex_sniper/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v54_hybrid_engine/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v53_pullback_sniper/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v52_trend_lock/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v51_iron_hold/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v50_data_scientist_baseline/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v48_fast_cooldown_dynamic_config/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v47_high_volume_cooldown/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/experiments/v44_original_fast_reentry/metrics.json\", \"/home/agent/.local/state/CryptoTradingBot/market_context.jsonl\"]}"
        },
        {
          "type": "function_call_output",
          "call_id": "call_Pqz96yBxhYVOsWuOMw6USoiX",
          "output": "{\"output\": \"KILL_SWITCH absent\", \"exit_code\": 0, \"error\": null}"
        }
      ],
      "store": false,
      "tools": [
        {
          "type": "function",
          "name": "patch",
          "description": "Targeted find-and-replace edits in files. Use this instead of sed/awk in terminal. Uses fuzzy matching (9 strategies) so minor whitespace/indentation differences won't break it. Returns a unified diff. Auto-runs syntax checks after editing.\n\nREPLACE MODE (mode='replace', default): find a unique string and replace it. REQUIRED PARAMETERS: mode, path, old_string, new_string.\nPATCH MODE (mode='patch'): apply V4A multi-file patches for bulk changes. REQUIRED PARAMETERS: mode, patch.",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "replace",
                  "patch"
                ],
                "description": "Edit mode. 'replace' (default): requires path + old_string + new_string. 'patch': requires patch content only.",
                "default": "replace"
              },
              "path": {
                "type": "string",
                "description": "REQUIRED when mode='replace'. File path to edit."
              },
              "old_string": {
                "type": "string",
                "description": "REQUIRED when mode='replace'. Exact text to find and replace. Must be unique in the file unless replace_all=true. Include surrounding context lines to ensure uniqueness."
              },
              "new_string": {
                "type": "string",
                "description": "REQUIRED when mode='replace'. Replacement text. Pass empty string '' to delete the matched text."
              },
              "replace_all": {
                "type": "boolean",
                "description": "Replace all occurrences instead of requiring a unique match (default: false)",
                "default": false
              },
              "patch": {
                "type": "string",
                "description": "REQUIRED when mode='patch'. V4A format patch content. Format:\n*** Begin Patch\n*** Update File: path/to/file\n@@ context hint @@\n context line\n-removed line\n+added line\n*** End Patch"
              },
              "cross_profile": {
                "type": "boolean",
                "description": "Opt out of the cross-profile soft guard. Defaults to false. Set true ONLY after explicit user direction to edit another Hermes profile's skills/plugins/cron/memories.",
                "default": false
              }
            },
            "required": [
              "mode"
            ]
          }
        },
        {
          "type": "function",
          "name": "process",
          "description": "Manage background processes started with terminal(background=true). Actions: 'list' (show all), 'poll' (check status + new output), 'log' (full output with pagination), 'wait' (block until done or timeout), 'kill' (terminate), 'write' (send raw stdin data without newline), 'submit' (send data + Enter, for answering prompts), 'close' (close stdin/send EOF).",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "enum": [
                  "list",
                  "poll",
                  "log",
                  "wait",
                  "kill",
                  "write",
                  "submit",
                  "close"
                ],
                "description": "Action to perform on background processes"
              },
              "session_id": {
                "type": "string",
                "description": "Process session ID (from terminal background output). Required for all actions except 'list'."
              },
              "data": {
                "type": "string",
                "description": "Text to send to process stdin (for 'write' and 'submit' actions)"
              },
              "timeout": {
                "type": "integer",
                "description": "Max seconds to block for 'wait' action. Returns partial output on timeout.",
                "minimum": 1
              },
              "offset": {
                "type": "integer",
                "description": "Line offset for 'log' action (default: last 200 lines)"
              },
              "limit": {
                "type": "integer",
                "description": "Max lines to return for 'log' action",
                "minimum": 1
              }
            },
            "required": [
              "action"
            ]
          }
        },
        {
          "type": "function",
          "name": "read_file",
          "description": "Read a text file with line numbers and pagination. Use this instead of cat/head/tail in terminal. Output format: 'LINE_NUM|CONTENT'. Suggests similar filenames if not found. Use offset and limit for large files. Reads exceeding ~100K characters are rejected; use offset and limit to read specific sections of large files. NOTE: Cannot read images or binary files — use vision_analyze for images.",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "path": {
                "type": "string",
                "description": "Path to the file to read (absolute, relative, or ~/path)"
              },
              "offset": {
                "type": "integer",
                "description": "Line number to start reading from (1-indexed, default: 1)",
                "default": 1,
                "minimum": 1
              },
              "limit": {
                "type": "integer",
                "description": "Maximum number of lines to read (default: 500, max: 2000)",
                "default": 500,
                "maximum": 2000
              }
            },
            "required": [
              "path"
            ]
          }
        },
        {
          "type": "function",
          "name": "search_files",
          "description": "Search file contents or find files by name. Use this instead of grep/rg/find/ls in terminal. Ripgrep-backed, faster than shell equivalents.\n\nContent search (target='content'): Regex search inside files. Output modes: full matches with line numbers, file paths only, or match counts.\n\nFile search (target='files'): Find files by glob pattern (e.g., '*.py', '*config*'). Also use this instead of ls — results sorted by modification time.",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "pattern": {
                "type": "string",
                "description": "Regex pattern for content search, or glob pattern (e.g., '*.py') for file search"
              },
              "target": {
                "type": "string",
                "enum": [
                  "content",
                  "files"
                ],
                "description": "'content' searches inside file contents, 'files' searches for files by name",
                "default": "content"
              },
              "path": {
                "type": "string",
                "description": "Directory or file to search in (default: current working directory)",
                "default": "."
              },
              "file_glob": {
                "type": "string",
                "description": "Filter files by pattern in grep mode (e.g., '*.py' to only search Python files)"
              },
              "limit": {
                "type": "integer",
                "description": "Maximum number of results to return (default: 50)",
                "default": 50
              },
              "offset": {
                "type": "integer",
                "description": "Skip first N results for pagination (default: 0)",
                "default": 0
              },
              "output_mode": {
                "type": "string",
                "enum": [
                  "content",
                  "files_only",
                  "count"
                ],
                "description": "Output format for grep mode: 'content' shows matching lines with line numbers, 'files_only' lists file paths, 'count' shows match counts per file",
                "default": "content"
              },
              "context": {
                "type": "integer",
                "description": "Number of context lines before and after each match (grep mode only)",
                "default": 0
              }
            },
            "required": [
              "pattern"
            ]
          }
        },
        {
          "type": "function",
          "name": "terminal",
          "description": "Execute shell commands on a Linux environment. Filesystem usually persists between calls.\n\nDo NOT use cat/head/tail to read files — use read_file instead.\nDo NOT use grep/rg/find to search — use search_files instead.\nDo NOT use ls to list directories — use search_files(target='files') instead.\nDo NOT use sed/awk to edit files — use patch instead.\nDo NOT use echo/cat heredoc to create files — use write_file instead.\nReserve terminal for: builds, installs, git, processes, scripts, network, package managers, and anything that needs a shell.\n\nForeground (default): Commands return INSTANTLY when done, even if the timeout is high. Set timeout=300 for long builds/scripts — you'll still get the result in seconds if it's fast. Prefer foreground for short commands.\nBackground: Set background=true to get a session_id. Almost always pair with notify_on_complete=true — bg without notify runs SILENTLY and you have no way to learn it finished short of calling process(action='poll') yourself. Two legitimate uses:\n  (1) Long-lived processes that never exit (servers, watchers, daemons) — silent is correct, there's no exit to notify on.\n  (2) Long-running bounded tasks (tests, builds, deploys, CI pollers, batch jobs) — MUST set notify_on_complete=true. Without it you'll either forget to poll or sit blocked waiting for the user to surface the result.\nFor servers/watchers, do NOT use shell-level background wrappers (nohup/disown/setsid/trailing '&') in foreground mode. Use background=true so Hermes can track lifecycle and output.\nAfter starting a server, verify readiness with a health check or log signal, then run tests in a separate terminal() call. Avoid blind sleep loops.\nUse process(action=\"poll\") for progress checks, process(action=\"wait\") to block until done.\nWorking directory: Use 'workdir' for per-command cwd.\nPTY mode: Set pty=true for interactive CLI tools (Codex, Claude Code, Python REPL).\n\nDo NOT use vim/nano/interactive tools without pty=true — they hang without a pseudo-terminal. Pipe git output to cat if it might page.\n",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "command": {
                "type": "string",
                "description": "The command to execute on the VM"
              },
              "background": {
                "type": "boolean",
                "description": "Run the command in the background. Almost always pair with notify_on_complete=true — without it, the process runs silently and you'll have no way to learn it finished short of calling process(action='poll') yourself (easy to forget, leading to silent blindness on long jobs). Two legitimate patterns: (1) Long-lived processes that never exit (servers, watchers, daemons) — these stay silent because there's no exit to notify on. (2) Long-running bounded tasks (tests, builds, deploys, CI pollers, batch jobs) — these MUST set notify_on_complete=true. For short commands, prefer foreground with a generous timeout instead.",
                "default": false
              },
              "timeout": {
                "type": "integer",
                "description": "Max seconds to wait (default: 180, foreground max: 600). Returns INSTANTLY when command finishes — set high for long tasks, you won't wait unnecessarily. Foreground timeout above 600s is rejected; use background=true for longer commands.",
                "minimum": 1
              },
              "workdir": {
                "type": "string",
                "description": "Working directory for this command (absolute path). Defaults to the session working directory."
              },
              "pty": {
                "type": "boolean",
                "description": "Run in pseudo-terminal (PTY) mode for interactive CLI tools like Codex, Claude Code, or Python REPL. Only works with local and SSH backends. Default: false.",
                "default": false
              },
              "notify_on_complete": {
                "type": "boolean",
                "description": "When true (and background=true), you'll be automatically notified exactly once when the process finishes. **This is the right choice for almost every long-running task** — tests, builds, deployments, multi-item batch jobs, anything that takes over a minute and has a defined end. Use this and keep working on other things; the system notifies you on exit. MUTUALLY EXCLUSIVE with watch_patterns — when both are set, watch_patterns is dropped.",
                "default": false
              },
              "watch_patterns": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Strings to watch for in background process output. HARD RATE LIMIT: at most 1 notification per 15 seconds per process — matches arriving inside the cooldown are dropped. After 3 consecutive 15-second windows with dropped matches, watch_patterns is automatically disabled for that process and promoted to notify_on_complete behavior (one notification on exit, no more mid-process spam). USE ONLY for truly rare, one-shot mid-process signals on LONG-LIVED processes that will never exit on their own — e.g. ['Application startup complete'] on a server so you know when to hit its endpoint, or ['migration done'] on a daemon. DO NOT use for: (1) end-of-run markers like 'DONE'/'PASS' — use notify_on_complete instead; (2) error patterns like 'ERROR'/'Traceback' in loops or multi-item batch jobs — they fire on every iteration and you'll hit the strike limit fast; (3) anything you'd ever combine with notify_on_complete. When in doubt, choose notify_on_complete. MUTUALLY EXCLUSIVE with notify_on_complete — set one, not both."
              }
            },
            "required": [
              "command"
            ]
          }
        },
        {
          "type": "function",
          "name": "write_file",
          "description": "Write content to a file, completely replacing existing content. Use this instead of echo/cat heredoc in terminal. Creates parent directories automatically. OVERWRITES the entire file — use 'patch' for targeted edits. Auto-runs syntax checks on .py/.json/.yaml/.toml and other linted languages; only NEW errors introduced by this write are surfaced (pre-existing errors are filtered out).",
          "strict": false,
          "parameters": {
            "type": "object",
            "properties": {
              "path": {
                "type": "string",
                "description": "Path to the file to write (will be created if it doesn't exist, overwritten if it does)"
              },
              "content": {
                "type": "string",
                "description": "Complete content to write to the file"
              },
              "cross_profile": {
                "type": "boolean",
                "description": "Opt out of the cross-profile soft guard. Defaults to false. Set true ONLY after explicit user direction to edit another Hermes profile's skills/plugins/cron/memories — by default these writes are blocked with a warning because they affect a different profile than the one this session is running under.",
                "default": false
              }
            },
            "required": [
              "path",
              "content"
            ]
          }
        }
      ],
      "reasoning": {
        "effort": "medium",
        "summary": "auto"
      },
      "include": [
        "reasoning.encrypted_content"
      ],
      "tool_choice": "auto",
      "parallel_tool_calls": true,
      "prompt_cache_key": "cron_764041b78a71_20260529_023929",
      "extra_headers": {
        "session_id": "cron_764041b78a71_20260529_023929",
        "x-client-request-id": "cron_764041b78a71_20260529_023929"
      }
    }
  },
  "error": {
    "type": "APIConnectionError",
    "message": "Connection error."
  }
}