chore: ruff lint

This commit is contained in:
Richard Tang
2026-04-03 20:31:14 -07:00
parent 294df7f066
commit ed8d417bef
106 changed files with 1149 additions and 828 deletions
+5 -16
View File
@@ -65,9 +65,7 @@ def _extract_error_message(response: httpx.Response) -> str:
def _sanitize_openrouter_model_id(value: str) -> str:
"""Sanitize pasted OpenRouter model IDs into a comparable slug."""
normalized = unicodedata.normalize("NFKC", value or "")
normalized = "".join(
ch for ch in normalized if unicodedata.category(ch) not in {"Cc", "Cf"}
)
normalized = "".join(ch for ch in normalized if unicodedata.category(ch) not in {"Cc", "Cf"})
normalized = normalized.translate(OPENROUTER_SEPARATOR_TRANSLATION)
normalized = re.sub(r"\s+", "", normalized)
if normalized.casefold().startswith("openrouter/"):
@@ -203,9 +201,7 @@ def check_openrouter_model(
)
if r.status_code == 200:
available_model_lookup = _extract_openrouter_model_lookup(r.json())
matched_model = available_model_lookup.get(
_normalize_openrouter_model_id(requested_model)
)
matched_model = available_model_lookup.get(_normalize_openrouter_model_id(requested_model))
if matched_model:
return {
"valid": True,
@@ -231,10 +227,7 @@ def check_openrouter_model(
detail = _extract_error_message(r)
if r.status_code in (400, 404, 422):
base = (
"OpenRouter model is not available for this key/settings: "
f"{requested_model}"
)
base = f"OpenRouter model is not available for this key/settings: {requested_model}"
return {"valid": False, "message": f"{base}. {detail}" if detail else base}
suffix = f": {detail}" if detail else ""
@@ -244,9 +237,7 @@ def check_openrouter_model(
}
def check_minimax(
api_key: str, api_base: str = "https://api.minimax.io/v1", **_: str
) -> dict:
def check_minimax(api_key: str, api_base: str = "https://api.minimax.io/v1", **_: str) -> dict:
"""Validate via chatcompletion_v2 endpoint with empty messages.
MiniMax doesn't support GET /models; their native endpoint is
@@ -327,9 +318,7 @@ PROVIDERS = {
"mistral": lambda key, **_: check_openai_compatible(
key, "https://api.mistral.ai/v1/models", "Mistral"
),
"xai": lambda key, **_: check_openai_compatible(
key, "https://api.x.ai/v1/models", "xAI"
),
"xai": lambda key, **_: check_openai_compatible(key, "https://api.x.ai/v1/models", "xAI"),
"perplexity": lambda key, **_: check_openai_compatible(
key, "https://api.perplexity.ai/v1/models", "Perplexity"
),
+15 -8
View File
@@ -3,8 +3,12 @@
Examples:
uv run scripts/debug_agent_node.py exports/reddit_star_growth_agent --list-nodes
uv run scripts/debug_agent_node.py exports/reddit_star_growth_agent --node load_contacted_users --task '{"repo_url":"https://github.com/acme/repo"}'
uv run scripts/debug_agent_node.py exports/reddit_star_growth_agent/nodes/__init__.py --node load_contacted_users --input-file /tmp/payload.json
uv run scripts/debug_agent_node.py exports/reddit_star_growth_agent \
--node load_contacted_users \
--task '{"repo_url":"https://github.com/acme/repo"}'
uv run scripts/debug_agent_node.py \
exports/reddit_star_growth_agent/nodes/__init__.py \
--node load_contacted_users --input-file /tmp/payload.json
"""
from __future__ import annotations
@@ -23,11 +27,11 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
from framework.graph.checkpoint_config import CheckpointConfig
from framework.graph.edge import GraphSpec
from framework.runtime.agent_runtime import create_agent_runtime
from framework.runtime.execution_stream import EntryPointSpec
from framework.runner.runner import AgentRunner
from framework.graph.checkpoint_config import CheckpointConfig # noqa: E402
from framework.graph.edge import GraphSpec # noqa: E402
from framework.runtime.agent_runtime import create_agent_runtime # noqa: E402
from framework.runtime.execution_stream import EntryPointSpec # noqa: E402
from framework.runner.runner import AgentRunner # noqa: E402
def _configure_event_debug_logging(storage_path: Path) -> None:
@@ -122,7 +126,10 @@ def _parse_args() -> argparse.Namespace:
)
parser.add_argument(
"agent_path",
help="Export directory or file path (for example exports/my_agent or exports/my_agent/nodes/__init__.py).",
help=(
"Export directory or file path (for example"
" exports/my_agent or exports/my_agent/nodes/__init__.py)."
),
)
parser.add_argument(
"--node",
+1 -4
View File
@@ -162,8 +162,5 @@ if __name__ == "__main__":
print_running_prompt()
else:
print(f"Unknown phase: {phase}")
print(
"Usage: uv run scripts/debug_queen_prompt.py "
"[planning|building|staging|running|all]"
)
print("Usage: uv run scripts/debug_queen_prompt.py [planning|building|staging|running|all]")
sys.exit(1)
+49 -38
View File
@@ -108,11 +108,7 @@ def _discover_records(logs_dir: Path, limit_files: int) -> list[dict[str, Any]]:
raise FileNotFoundError(f"log directory not found: {logs_dir}")
files = sorted(
[
path
for path in logs_dir.iterdir()
if path.is_file() and path.suffix == ".jsonl"
],
[path for path in logs_dir.iterdir() if path.is_file() and path.suffix == ".jsonl"],
key=lambda path: path.stat().st_mtime,
reverse=True,
)[:limit_files]
@@ -164,9 +160,7 @@ def _group_sessions(
if not include_tests:
by_session = {
eid: recs
for eid, recs in by_session.items()
if not _is_test_session(eid, recs)
eid: recs for eid, recs in by_session.items() if not _is_test_session(eid, recs)
}
summaries: list[SessionSummary] = []
@@ -187,18 +181,10 @@ def _group_sessions(
end_timestamp=str(last.get("timestamp", "")),
turn_count=len(session_records),
streams=sorted(
{
str(r.get("stream_id", ""))
for r in session_records
if r.get("stream_id")
}
{str(r.get("stream_id", "")) for r in session_records if r.get("stream_id")}
),
nodes=sorted(
{
str(r.get("node_id", ""))
for r in session_records
if r.get("node_id")
}
{str(r.get("node_id", "")) for r in session_records if r.get("node_id")}
),
models=sorted(
{
@@ -585,12 +571,14 @@ def _render_html(
<aside class="sidebar">
<div class="brand">
<h1>Hive Debug</h1>
<p>Pick a session in the browser and inspect prompts, inputs, outputs, and tool activity turn by turn.</p>
<p>Pick a session in the browser and inspect prompts,
inputs, outputs, and tool activity turn by turn.</p>
</div>
<input id="sessionSearch" type="search" placeholder="Filter sessions">
<div class="setup-note">
<h3>Logging status</h3>
<p>LLM turn logging is always on. If this list is empty, run Hive once and refresh after the session produces turns.</p>
<p>LLM turn logging is always on. If this list is empty,
run Hive once and refresh after the session produces turns.</p>
<pre>~/.hive/llm_logs</pre>
</div>
<div class="session-list" id="sessionList"></div>
@@ -602,7 +590,8 @@ def _render_html(
<div class="meta-grid" id="metaGrid"></div>
</section>
<div class="toolbar">
<input id="turnFilter" type="search" placeholder="Filter selected session by text, tool name, role, model, or prompt content">
<input id="turnFilter" type="search"
placeholder="Filter by text, tool, role, model, or prompt">
<button type="button" id="expandAll">Expand all</button>
<button type="button" id="collapseAll">Collapse all</button>
</div>
@@ -610,7 +599,9 @@ def _render_html(
</main>
</div>
<script id="session-summaries" type="application/json">{json.dumps(summaries_data, ensure_ascii=False)}</script>
<script id="session-summaries" type="application/json">{
json.dumps(summaries_data, ensure_ascii=False)
}</script>
<script>
const summaries = JSON.parse(document.getElementById("session-summaries").textContent);
const recordCache = {{}};
@@ -669,9 +660,15 @@ def _render_html(
...(summary.models || []).slice(0, 2),
];
return `
<button type="button" class="session-card${{active}}" data-session-id="${{escapeHtml(summary.execution_id)}}">
<div class="sid">${{escapeHtml(summary.execution_id)}}</div>
<div class="meta">${{chips.map((chip) => `<span>${{escapeHtml(chip)}}</span>`).join("")}}</div>
<button type="button"
class="session-card${{active}}"
data-session-id="${{escapeHtml(summary.execution_id)}}">
<div class="sid">${{escapeHtml(
summary.execution_id
)}}</div>
<div class="meta">${{chips.map(
(chip) => `<span>${{escapeHtml(chip)}}</span>`
).join("")}}</div>
</button>
`;
}})
@@ -679,7 +676,9 @@ def _render_html(
}}
function renderMetaCard(label, value) {{
return `<div class="meta-card"><span class="label">${{escapeHtml(label)}}</span>${{escapeHtml(value || "-")}}</div>`;
return `<div class="meta-card"><span class="label">${{
escapeHtml(label)
}}</span>${{escapeHtml(value || "-")}}</div>`;
}}
function renderMessage(message, index) {{
@@ -699,7 +698,8 @@ def _render_html(
}}
${{
toolCalls
? `<details class="block"><summary>tool_calls</summary><pre>${{prettyJson(toolCalls)}}</pre></details>`
? `<details class="block"><summary>tool_calls</summary>` +
`<pre>${{prettyJson(toolCalls)}}</pre></details>`
: ""
}}
</div>
@@ -746,12 +746,18 @@ def _render_html(
</div>
${{
systemPrompt
? `<details class="block" open><summary>System prompt</summary><pre>${{escapeHtml(systemPrompt)}}</pre></details>`
? `<details class="block" open>` +
`<summary>System prompt</summary>` +
`<pre>${{escapeHtml(systemPrompt)}}</pre></details>`
: ""
}}
${{
messages.length
? `<details class="block" open><summary>Input messages (${{messages.length}})</summary>${{messages.map((message, index) => renderMessage(message, index + 1)).join("")}}</details>`
? `<details class="block" open>` +
`<summary>Input messages (${{messages.length}})` +
`</summary>${{messages.map((message, index) =>
renderMessage(message, index + 1)
).join("")}}</details>`
: ""
}}
<details class="block" open>
@@ -760,17 +766,26 @@ def _render_html(
</details>
${{
toolCalls.length
? `<details class="block" open><summary>Tool calls (${{toolCalls.length}})</summary>${{toolCalls.map((toolCall, index) => renderToolCall(toolCall, index + 1)).join("")}}</details>`
? `<details class="block" open>` +
`<summary>Tool calls (${{toolCalls.length}})` +
`</summary>${{toolCalls.map((toolCall, index) =>
renderToolCall(toolCall, index + 1)
).join("")}}</details>`
: ""
}}
${{
toolResults.length
? `<details class="block"><summary>Tool results (${{toolResults.length}})</summary><pre>${{prettyJson(toolResults)}}</pre></details>`
? `<details class="block">` +
`<summary>Tool results (${{toolResults.length}})` +
`</summary><pre>${{prettyJson(toolResults)}}` +
`</pre></details>`
: ""
}}
${{
parseError
? `<details class="block"><summary>Parse error</summary><pre>${{prettyJson(record)}}</pre></details>`
? `<details class="block">` +
`<summary>Parse error</summary>` +
`<pre>${{prettyJson(record)}}</pre></details>`
: ""
}}
</section>
@@ -881,9 +896,7 @@ def _run_server(
if records is None:
self._respond(404, "application/json", b"[]")
else:
body = json.dumps(
_sort_records(records), ensure_ascii=False
).encode("utf-8")
body = json.dumps(_sort_records(records), ensure_ascii=False).encode("utf-8")
self._respond(200, "application/json", body)
else:
self.send_error(404)
@@ -919,9 +932,7 @@ def main() -> int:
records = _discover_records(args.logs_dir.expanduser(), args.limit_files)
summaries, sessions = _group_sessions(records, include_tests=args.include_tests)
initial_session_id = args.session or (
summaries[0].execution_id if summaries else ""
)
initial_session_id = args.session or (summaries[0].execution_id if summaries else "")
if initial_session_id and initial_session_id not in sessions:
print(f"session not found: {initial_session_id}")
return 1
+1 -3
View File
@@ -48,9 +48,7 @@ def test_check_requirements():
try:
data = json.loads(result.stdout)
assert data["json"] == "ok", "json should be ok"
assert "error" in data["nonexistent_module"], (
"nonexistent_module should have error"
)
assert "error" in data["nonexistent_module"], "nonexistent_module should have error"
assert result.returncode == 1, "Exit code should be 1 when errors exist"
print("✓ Test 2 passed")
except Exception as e: