🔬 Harness Vibe Research with Self-evolving AI Scientists
This report summarizes scanner evidence for EvoScientist/EvoScientist, a Python project with 4,976 GitHub stars. SynthScan examined 196,369 lines of code across 514 source files, recording 7290 pattern matches distributed across 21 syntactic categories. The legacy adjusted pattern signal is 52.5 (High pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 4726 finding(s).
Are imports declared and package/API names verified? 572 finding(s).
Are wrappers, guards, and repeated structures necessary? 6372 finding(s).
Which changes need focused human review? 7290 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 7290 distinct pattern matches across 21 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_hitl.py | 23 | def test_interrupt_event_structure(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 37 | def test_interrupt_defaults_review_configs(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 41 | def test_interrupt_multiple_action_requests(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 56 | def test_handle_interrupt_sets_pending(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 108 | def test_empty_requests_auto_approves(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 115 | def test_session_auto_approve(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 389 | def test_auto_approve_default(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 419 | def test_shell_allow_list_set(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 432 | async def test_interrupt_from_updates_mode(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 490 | def test_parse_approval_approve(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 496 | def test_parse_approval_reject(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 541 | def test_should_auto_approve_non_execute(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 548 | def test_should_auto_approve_empty(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 553 | def test_should_auto_approve_execute_no_allowlist(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 667 | async def test_register_and_resolve_reply(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 708 | def test_prompt_fn_called_for_execute(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 800 | def test_hitl_interrupt_on_helper_arms_every_shell_tool(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 1038 | def test_dangerous_is_approved_under_session_grant(self): | CODE |
| LOW⚡ | tests/test_hitl.py | 1139 | def test_async_factory_guards_research_agents(self, workspace): | CODE |
| LOW⚡ | tests/test_hitl.py | 1147 | def test_async_factory_does_not_guard_internal_agents(self, workspace): | CODE |
| LOW⚡ | tests/test_hitl.py | 1157 | def test_delegation_prompt_explains_blocked_command_relay(self): | CODE |
| LOW | tests/test_hitl.py | 69 | def test_pending_interrupt_starts_none(self): | CODE |
| LOW | tests/test_hitl.py | 73 | def test_interrupt_does_not_affect_other_state(self): | CODE |
| LOW | tests/test_hitl.py | 87 | def test_done_after_interrupt_preserves_pending(self): | CODE |
| LOW | tests/test_hitl.py | 133 | def test_display_auto_approve_config_true(self): | CODE |
| LOW | tests/test_hitl.py | 159 | def test_non_execute_tool_auto_approves(self): | CODE |
| LOW | tests/test_hitl.py | 185 | def test_execute_with_matching_allow_list(self): | CODE |
| LOW | tests/test_hitl.py | 211 | def test_execute_not_in_allow_list_prompts(self): | CODE |
| LOW | tests/test_hitl.py | 242 | def test_run_in_background_not_in_allow_list_prompts(self): | CODE |
| LOW | tests/test_hitl.py | 277 | def test_run_in_background_in_allow_list_auto_approves(self): | CODE |
| LOW | tests/test_hitl.py | 307 | def test_delete_only_request_prompts_not_auto_approved(self): | CODE |
| LOW | tests/test_hitl.py | 340 | def test_rich_cli_approve_all_keeps_policy_reject(self): | CODE |
| LOW | tests/test_hitl.py | 401 | def test_shell_allow_list_default(self): | CODE |
| LOW | tests/test_hitl.py | 469 | async def test_updates_without_interrupt_skipped(self): | CODE |
| LOW | tests/test_hitl.py | 508 | def test_parse_approval_unrecognized(self): | CODE |
| LOW | tests/test_hitl.py | 515 | def test_format_approval_prompt(self): | CODE |
| LOW | tests/test_hitl.py | 529 | def test_format_approval_prompt_multiple(self): | CODE |
| LOW | tests/test_hitl.py | 571 | def test_should_auto_approve_run_in_background_no_allowlist(self): | CODE |
| LOW | tests/test_hitl.py | 588 | def test_should_auto_approve_config_true(self): | CODE |
| LOW | tests/test_hitl.py | 603 | def test_should_auto_approve_allowlist_match(self): | CODE |
| LOW | tests/test_hitl.py | 619 | def test_should_auto_approve_delete_not_cleared(self): | CODE |
| LOW | tests/test_hitl.py | 637 | def test_dangerous_mode_approves_always_prompt_tools(self): | CODE |
| LOW | tests/test_hitl.py | 683 | def test_try_resolve_no_pending(self): | CODE |
| LOW | tests/test_hitl.py | 691 | async def test_reply_timeout_returns_none(self): | CODE |
| LOW | tests/test_hitl.py | 738 | def test_prompt_fn_not_called_for_auto_approve(self): | CODE |
| LOW | tests/test_hitl.py | 766 | def test_prompt_fn_not_called_for_non_execute(self): | CODE |
| LOW | tests/test_hitl.py | 811 | def test_hitl_when_arms_by_default_outside_a_run(self): | CODE |
| LOW | tests/test_hitl.py | 818 | def test_hitl_when_disarms_when_run_is_suppressed(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 835 | def test_hitl_when_reads_the_requests_own_runtime_config(self): | CODE |
| LOW | tests/test_hitl.py | 852 | def test_hitl_interrupt_on_reaches_create_deep_agent(self, workspace): | CODE |
| LOW | tests/test_hitl.py | 916 | def test_dangerous_command_rejected_under_auto_approve(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 937 | def test_everyday_command_approved_under_auto_approve(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 950 | def test_session_grant_blanket_approves_dangerous(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 965 | def test_interactive_dangerous_calls_prompt(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 985 | def test_schedule_task_always_prompts_not_auto_cleared(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 1008 | def test_malformed_request_is_not_auto_approved(self, monkeypatch): | CODE |
| LOW | tests/test_hitl.py | 1054 | def test_length_matches_all_approved(self): | CODE |
| LOW | tests/test_hitl.py | 1065 | def test_empty_batch_returns_empty(self): | CODE |
| LOW | tests/test_hitl.py | 1076 | def test_get_default_backend_applies_forced_guard(self, workspace): | CODE |
| LOW | tests/test_hitl.py | 1092 | def test_get_default_backend_guard_defaults_false(self, workspace): | CODE |
| 4294 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_hitl.py | 17 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 19 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 50 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 52 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 102 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 104 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 383 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 385 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 426 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 428 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 484 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 486 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 657 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 659 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 702 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 704 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 792 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 794 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 1027 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_hitl.py | 1029 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_hitl.py | 898 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_hitl.py | 900 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 14 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 16 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 26 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 28 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 74 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 76 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 143 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 145 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 204 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_tool_error_handler.py | 206 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_ccproxy_manager.py | 86 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_ccproxy_manager.py | 88 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 22 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 24 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 40 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 42 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 124 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 126 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 199 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 201 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 220 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 222 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 246 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 248 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 272 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 274 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 288 | # ============================================================================= | COMMENT |
| MEDIUM | tests/test_ccproxy_manager.py | 290 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 32 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 34 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 139 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 141 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 206 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_serde_default_rich_exception.py | 209 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_stream_state.py | 10 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_stream_state.py | 12 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_stream_state.py | 63 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_stream_state.py | 65 | # ============================================================================= | COMMENT |
| 990 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_wechat_channel.py | 249 | except ImportError: | CODE |
| HIGH | tests/test_background_middleware.py | 90 | except Exception: | CODE |
| HIGH | tests/test_agent_loader.py | 161 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_cli_channel_bridge.py | 88 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_cli_channel_bridge.py | 123 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_sessions.py | 223 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 744 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 748 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 1176 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 1439 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 1443 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 1774 | except OSError: | CODE |
| HIGH | tests/test_sessions.py | 1778 | except OSError: | CODE |
| HIGH | tests/test_mcp_client.py | 818 | except psutil.NoSuchProcess: | CODE |
| HIGH | tests/test_mcp_client.py | 852 | except psutil.NoSuchProcess: | CODE |
| HIGH | tests/test_langgraph_manager.py | 189 | except OSError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 870 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 885 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 912 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 933 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 1019 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 1032 | except FileNotFoundError: | CODE |
| HIGH | tests/test_langgraph_manager.py | 794 | except FileNotFoundError: | CODE |
| HIGH | tests/test_bus_integration.py | 110 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 157 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 204 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 266 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 463 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 627 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_bus_integration.py | 681 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_debug.py | 331 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_debug.py | 305 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_debug.py | 379 | except RuntimeError: | CODE |
| HIGH | tests/test_background.py | 44 | except Exception: | CODE |
| HIGH | tests/test_agent_shell.py | 704 | except (psutil.Error, TypeError): | CODE |
| HIGH | tests/test_agent_shell.py | 836 | except (psutil.Error, TypeError): | CODE |
| HIGH | tests/test_stream_recovery.py | 91 | except Exception: | CODE |
| HIGH | tests/test_stream_recovery.py | 303 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_async_notifier.py | 458 | except RuntimeError: | CODE |
| HIGH | tests/test_tui_banner_position.py | 108 | except SystemExit: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 70 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1556 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1583 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1614 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1651 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1726 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 1763 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_channel_comprehensive.py | 2242 | except asyncio.CancelledError: | CODE |
| HIGH | tests/test_workspace_injection.py | 207 | except RuntimeError: | CODE |
| HIGH | EvoScientist/sessions.py | 1247 | except aiosqlite.Error: | CODE |
| HIGH | EvoScientist/sessions.py | 1519 | except Exception: | CODE |
| HIGH | EvoScientist/sessions.py | 1332 | except Exception: # pragma: no cover - never let UI break sweep | CODE |
| HIGH | EvoScientist/sessions.py | 1869 | except (ValueError, TypeError): | CODE |
| HIGH | EvoScientist/background.py | 226 | except Exception: | CODE |
| HIGH | EvoScientist/background.py | 390 | except ProcessLookupError: | CODE |
| HIGH | EvoScientist/background.py | 384 | except (psutil.NoSuchProcess, psutil.AccessDenied): | CODE |
| HIGH | EvoScientist/runtime.py | 317 | except concurrent.futures.InvalidStateError: | CODE |
| HIGH | EvoScientist/runtime.py | 324 | except concurrent.futures.InvalidStateError: | CODE |
| HIGH | EvoScientist/runtime.py | 343 | except RuntimeError: | CODE |
| HIGH | EvoScientist/runtime.py | 550 | except RuntimeError: | CODE |
| 170 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_tool_error_handler.py | 68 | except Exception: | CODE |
| LOW | tests/test_background_middleware.py | 90 | except Exception: | CODE |
| LOW | tests/test_observation_memory.py | 480 | except Exception as exc: | CODE |
| MEDIUM | tests/test_stream_utils.py | 41 | content = '#!/usr/bin/env python3\n"""\nSkill Packager\n"""\n\nprint(f"Error: not found")' | CODE |
| LOW | tests/test_bus_integration.py | 23 | except Exception: | CODE |
| LOW⚡ | tests/test_background.py | 44 | except Exception: | CODE |
| MEDIUM | tests/test_agent_shell.py | 420 | def churn(group): | CODE |
| LOW | tests/test_agent_shell.py | 425 | except Exception as exc: | CODE |
| LOW | tests/test_stream_recovery.py | 91 | except Exception: | CODE |
| LOW⚡ | EvoScientist/sessions.py | 463 | except Exception: # pragma: no cover - defensive (config import errors) | CODE |
| LOW⚡ | EvoScientist/sessions.py | 534 | except Exception as exc: | CODE |
| LOW⚡ | EvoScientist/sessions.py | 1519 | except Exception: | CODE |
| LOW | EvoScientist/sessions.py | 241 | except Exception as exc: # pragma: no cover - defensive | CODE |
| LOW | EvoScientist/sessions.py | 346 | except Exception as exc: | CODE |
| LOW | EvoScientist/sessions.py | 762 | except Exception as exc: | CODE |
| LOW | EvoScientist/sessions.py | 1416 | except Exception as exc: | CODE |
| LOW | EvoScientist/sessions.py | 1703 | except Exception: | CODE |
| LOW | EvoScientist/sessions.py | 1979 | except Exception: | CODE |
| LOW | EvoScientist/sessions.py | 2041 | except Exception: | CODE |
| LOW | EvoScientist/sessions.py | 1332 | except Exception: # pragma: no cover - never let UI break sweep | STRING |
| LOW | EvoScientist/sessions.py | 1861 | except Exception: | STRING |
| LOW | EvoScientist/paths.py | 333 | except Exception: | CODE |
| LOW | EvoScientist/update_check.py | 44 | except Exception: | CODE |
| LOW | EvoScientist/update_check.py | 57 | except Exception: | CODE |
| LOW | EvoScientist/update_check.py | 68 | except Exception: | CODE |
| LOW | EvoScientist/background.py | 226 | except Exception: | CODE |
| LOW | EvoScientist/backends.py | 405 | except Exception: | CODE |
| LOW | EvoScientist/backends.py | 516 | except Exception: | CODE |
| LOW | EvoScientist/backends.py | 1546 | except Exception: | CODE |
| LOW | EvoScientist/backends.py | 1559 | except Exception: | CODE |
| LOW | EvoScientist/backends.py | 2169 | except Exception as exc: | CODE |
| LOW | EvoScientist/ccproxy_manager.py | 74 | except Exception: | CODE |
| LOW⚡ | EvoScientist/ccproxy_manager.py | 166 | except Exception as exc: | CODE |
| LOW | EvoScientist/ccproxy_manager.py | 266 | except Exception: | CODE |
| LOW | EvoScientist/stt.py | 133 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/expert_async_subagent.py | 401 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/expert_async_subagent.py | 449 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/context_overflow.py | 36 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/context_overflow.py | 54 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/memory.py | 324 | except Exception: | CODE |
| LOW | EvoScientist/middleware/memory.py | 774 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/memory.py | 785 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/memory.py | 836 | except Exception as e: | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 323 | except Exception as fb_exc: | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 393 | except Exception as fb_exc: | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 525 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 543 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/events.py | 378 | except Exception: | CODE |
| LOW | EvoScientist/middleware/tool_selector.py | 96 | except Exception: | CODE |
| LOW | EvoScientist/middleware/tool_selector.py | 299 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/tool_selector.py | 307 | except Exception as exc: | CODE |
| LOW⚡ | EvoScientist/middleware/tool_selector.py | 361 | except Exception as exc: | CODE |
| LOW⚡ | EvoScientist/middleware/tool_selector.py | 369 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/configurable_model.py | 60 | except Exception: | CODE |
| LOW | EvoScientist/middleware/configurable_model.py | 158 | except Exception: | CODE |
| LOW | EvoScientist/middleware/configurable_model.py | 186 | except Exception: | CODE |
| LOW | EvoScientist/middleware/error_normalization.py | 318 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/error_normalization.py | 331 | except Exception as exc: | CODE |
| LOW | EvoScientist/middleware/background.py | 75 | except Exception: | CODE |
| LOW | EvoScientist/middleware/active_team.py | 78 | except Exception: | CODE |
| 495 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_setup_install.py | 3 | CODE | |
| LOW | tests/test_serde_default_rich_exception.py | 17 | CODE | |
| LOW | tests/test_serve_agent_holder.py | 9 | CODE | |
| LOW | tests/test_middleware_utils.py | 8 | CODE | |
| LOW | tests/test_channel_notification_origin.py | 4 | CODE | |
| LOW | tests/test_message_meta.py | 3 | CODE | |
| LOW | tests/stream_v3_fakes.py | 3 | CODE | |
| LOW | tests/test_thread_selector.py | 3 | CODE | |
| LOW | tests/test_cli_resume_flag.py | 3 | CODE | |
| LOW | tests/test_configurable_model_middleware.py | 9 | CODE | |
| LOW | tests/test_cron_scoping.py | 3 | CODE | |
| LOW | tests/test_agent_shell_env.py | 3 | CODE | |
| LOW | tests/test_wechat_channel.py | 241 | CODE | |
| LOW | tests/test_wechat_channel.py | 246 | CODE | |
| LOW | tests/test_async_subagent_swap.py | 8 | CODE | |
| LOW | tests/test_autoskills.py | 1 | CODE | |
| LOW | tests/test_async_subagent_factory.py | 10 | CODE | |
| LOW | tests/test_async_subagent_factory.py | 16 | CODE | |
| LOW | tests/test_setup_webui.py | 3 | CODE | |
| LOW | tests/test_route_async_specs.py | 13 | CODE | |
| LOW | tests/test_observation_memory.py | 1 | CODE | |
| LOW | tests/test_active_team_middleware.py | 3 | CODE | |
| LOW | tests/test_cli_async_runtime.py | 9 | CODE | |
| LOW | tests/test_langgraph_dev_server_env.py | 7 | CODE | |
| LOW | tests/test_llm.py | 11 | CODE | |
| LOW | tests/test_file_mentions.py | 3 | CODE | |
| LOW | tests/test_langgraph_schema_generator_silenced.py | 11 | CODE | |
| LOW | tests/test_picker_widgets.py | 11 | CODE | |
| LOW | tests/test_error_normalization_middleware.py | 10 | CODE | |
| LOW | tests/test_agent_loader.py | 3 | CODE | |
| LOW | tests/test_command_goto_none_crash.py | 35 | CODE | |
| LOW | tests/test_command_goto_none_crash.py | 48 | CODE | |
| LOW | tests/test_expert_container.py | 3 | CODE | |
| LOW | tests/test_langgraph_dev_stream_transformers.py | 15 | CODE | |
| LOW | tests/test_tui_completion_window.py | 11 | CODE | |
| LOW | tests/test_load_subagents.py | 8 | CODE | |
| LOW | tests/test_langgraph_dev_http.py | 6 | CODE | |
| LOW | tests/test_langgraph_dev_workspace_sidecar.py | 17 | CODE | |
| LOW | tests/test_cli_serve.py | 3 | CODE | |
| LOW | tests/test_runtime.py | 3 | CODE | |
| LOW | tests/test_mcp_client.py | 392 | CODE | |
| LOW | tests/test_mcp_client.py | 615 | CODE | |
| LOW | tests/test_graph_gateway.py | 3 | CODE | |
| LOW | tests/test_experts_command.py | 3 | CODE | |
| LOW | tests/test_skills_reload_middleware.py | 3 | CODE | |
| LOW | tests/test_middleware_event_sink.py | 11 | CODE | |
| LOW | tests/test_cli_workspace_resolution.py | 3 | CODE | |
| LOW | tests/test_langgraph_dev_sdk.py | 3 | CODE | |
| LOW | tests/test_subagent_summarize.py | 10 | CODE | |
| LOW | tests/test_tui_stream_lifecycle.py | 3 | CODE | |
| LOW | tests/test_ollama_discovery.py | 9 | CODE | |
| LOW | tests/test_langgraph_manager.py | 8 | CODE | |
| LOW | tests/test_cli_channel_bus_mode.py | 3 | CODE | |
| LOW | tests/test_gateway_composite.py | 3 | CODE | |
| LOW | tests/test_stream_cancel.py | 3 | CODE | |
| LOW | tests/test_panel_widget.py | 10 | CODE | |
| LOW | tests/test_agent_mcp_cache.py | 3 | CODE | |
| LOW | tests/test_profile_memory_middleware.py | 1 | CODE | |
| LOW | tests/test_gateway_background_runs.py | 1 | CODE | |
| LOW | tests/test_tui_widgets.py | 7 | CODE | |
| 471 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | tests/test_background_middleware.py | 208 | {"command": "cat /etc/hosts && cat ../x"} | CODE |
| HIGH⚡ | tests/test_background_middleware.py | 211 | assert captured["command"] == "cat /etc/hosts && cat ../x" # no ./ rewrite | CODE |
| HIGH | tests/test_langgraph_dev_workspace_sidecar.py | 83 | '{"workspace": null}', # workspace present but null → Path(None) TypeError | CODE |
| HIGH⚡ | tests/test_backends.py | 113 | result = validate_command("cd /etc && cat passwd") | CODE |
| HIGH⚡ | tests/test_backends.py | 141 | assert validate_command("cd /etc && ls", dangerous=True) is None | CODE |
| HIGH⚡ | tests/test_backends.py | 1423 | "cat /data/file.txt && ssh host 'ls /home/username/project'", | CODE |
| HIGH⚡ | tests/test_backends.py | 1430 | == "cat ./data/file.txt && ssh host 'ls /home/username/project'" | CODE |
| HIGH⚡ | tests/test_backends.py | 1564 | command = "cat /data/file.txt && ssh host 'ls /home/username/project'" | CODE |
| HIGH⚡ | tests/test_backends.py | 1571 | == "cat ./data/file.txt && ssh host 'ls /home/username/project'" | CODE |
| HIGH⚡ | tests/test_backends.py | 1777 | result = validate_command("echo ok && chmod 777 file") | CODE |
| HIGH⚡ | tests/test_backends.py | 1793 | assert validate_command("mkdir build && cd build") is None | CODE |
| HIGH⚡ | tests/test_backends.py | 2149 | assert check_dangerous_command("a || bash") is None | CODE |
| HIGH⚡ | tests/test_backends.py | 2150 | assert check_dangerous_command("a && bash") is None | CODE |
| HIGH⚡ | tests/test_backends.py | 2398 | "ls -la && curl http://x -o y", | CODE |
| HIGH⚡ | tests/test_backends.py | 2399 | "ls -la || rm x", | CODE |
| HIGH | tests/test_backends.py | 1277 | command = f"mkdir -p {tmp_workspace}/test-sanitized && echo ok" | CODE |
| HIGH | tests/test_backends.py | 1465 | command = "echo __EVOSCI_SSH_REMOTE_0__ && ssh host 'ls /home'" | CODE |
| HIGH⚡ | tests/test_backends.py | 1776 | """chmod after && should be caught.""" | STRING |
| HIGH⚡ | tests/test_backends.py | 1792 | """Normal && chains should be fine.""" | STRING |
| HIGH⚡ | EvoScientist/backends.py | 804 | "for example: ssh host 'cd /home/user/project && python train.py'." | CODE |
| HIGH | EvoScientist/backends.py | 457 | a chain (``a; b``, ``a && b``, ``a | b``) must match, so an allow-listed | STRING |
| HIGH | EvoScientist/backends.py | 685 | >>> [(i, h, r, e) for _, i, h, r, e in _ssh_invocations("cat x && ssh -p 22 host 'pwd'")] | STRING |
| HIGH | EvoScientist/backends.py | 732 | >>> _ssh_remote_command_spans("cat /tmp/x && ssh host 'pwd'") | STRING |
| HIGH | EvoScientist/middleware/error_normalization.py | 10 | ``{"message": …, "status_code": …, "body": …, "headers": null, | STRING |
| HIGH | EvoScientist/middleware/error_normalization.py | 11 | "raw_response": null, "data": {…}}`` with no ``error`` / ``class`` / | STRING |
| HIGH | EvoScientist/subagents/_factory.py | 54 | # criteria ``oneOf`` (every entry comes back null), Anthropic JSON mode returns | COMMENT |
| HIGH | EvoScientist/langgraph_dev/http.py | 189 | the interrupt delivers). Response: ``{"decisions": list[dict] | null}`` — | STRING |
| HIGH | EvoScientist/langgraph_dev/manager.py | 337 | ``{"workspace": null}`` or ``{"workspace": []}`` would parse fine, pass | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/fakes.py | 122 | def update_status_after_compact(self, tokens_after: int) -> None: | CODE |
| LOW | EvoScientist/sessions.py | 1176 | async def _set_user_version(conn: aiosqlite.Connection, version: int) -> None: | STRING |
| LOW⚡ | EvoScientist/EvoScientist.py | 110 | def set_active_config(cfg) -> None: | CODE |
| LOW | EvoScientist/EvoScientist.py | 238 | def set_chat_model_instance(instance, key: tuple[str | None, str | None]) -> None: | CODE |
| LOW | EvoScientist/git_cli.py | 16 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/paths.py | 14 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/update_check.py | 16 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/background.py | 34 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/runtime.py | 28 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/runtime.py | 217 | def _settle_abandoned_tasks(self) -> None: | CODE |
| LOW | EvoScientist/runtime.py | 314 | def _set_handle_result(handle: RuntimeHandle[Any], result: Any) -> None: | CODE |
| LOW | EvoScientist/runtime.py | 321 | def _set_handle_exception(handle: RuntimeHandle[Any], exc: BaseException) -> None: | CODE |
| LOW | EvoScientist/runtime.py | 562 | __all__ = [ | CODE |
| LOW | EvoScientist/utils.py | 17 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | EvoScientist/ccproxy_manager.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/stt.py | 23 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/agent_shell.py | 39 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/context_overflow.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/code_interpreter.py | 47 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/memory.py | 44 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 31 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/model_fallback.py | 153 | def set_fallback_chain(chain: list[tuple[str, str]]) -> None: | CODE |
| LOW | EvoScientist/middleware/tool_selector.py | 43 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/configurable_model.py | 44 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/__init__.py | 46 | __all__ = [ | CODE |
| LOW⚡ | EvoScientist/middleware/ask_user.py | 37 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/tool_history_repair.py | 45 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/summarization.py | 50 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/memory_lifecycle.py | 23 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/middleware/tool_error_handler.py | 33 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/tools/__init__.py | 11 | __all__ = [ | CODE |
| LOW⚡ | EvoScientist/llm/deepseek.py | 15 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/subagents/_factory.py | 40 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/memory/__init__.py | 34 | __all__ = [ | CODE |
| LOW | EvoScientist/memory/scheduler.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | EvoScientist/memory/agents/memory_worker.py | 35 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/memory/agents/__init__.py | 9 | __all__ = [ | CODE |
| LOW | EvoScientist/memory/agents/observation_linker.py | 24 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/memory/observations/tools.py | 31 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/memory/observations/__init__.py | 40 | __all__ = [ | CODE |
| LOW | EvoScientist/config/__init__.py | 32 | __all__ = [ | CODE |
| LOW | EvoScientist/config/onboard/prompter.py | 115 | __all__ = [ | CODE |
| LOW | EvoScientist/config/onboard/constants.py | 50 | __all__ = [ | CODE |
| LOW | EvoScientist/config/onboard/__init__.py | 34 | __all__ = ["run_onboard"] | CODE |
| LOW | EvoScientist/deploy/__init__.py | 22 | __all__ = ["server"] | CODE |
| LOW | EvoScientist/deploy/launcher.py | 42 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/deploy/busy.py | 16 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/stream/sink.py | 24 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/git.py | 58 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/webui.py | 40 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/webui.py | 849 | __all__ = [ | CODE |
| LOW | EvoScientist/setup/__init__.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/__init__.py | 121 | __all__ = [ | CODE |
| LOW | EvoScientist/setup/node.py | 49 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/_install.py | 13 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/setup/research_env.py | 39 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | EvoScientist/mcp/registry.py | 29 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | EvoScientist/mcp/client.py | 26 | logger = logging.getLogger(__name__) | CODE |
| LOW | EvoScientist/mcp/__init__.py | 29 | __all__ = [ | CODE |
| LOW⚡ | EvoScientist/cli/rich_command_ui.py | 229 | def update_status_after_compact(self, input_tokens: int) -> None: | CODE |
| 92 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_hitl.py | 852 | CODE | |
| LOW | tests/test_graph_gateway.py | 2264 | CODE | |
| LOW | tests/test_model_fallback.py | 856 | CODE | |
| LOW | tests/test_setup_node.py | 28 | CODE | |
| LOW | tests/test_setup_research_env.py | 131 | CODE | |
| LOW | EvoScientist/sessions.py | 468 | CODE | |
| LOW | EvoScientist/sessions.py | 595 | CODE | |
| LOW | EvoScientist/sessions.py | 1726 | CODE | |
| LOW | EvoScientist/background.py | 355 | CODE | |
| LOW | EvoScientist/runtime.py | 456 | CODE | |
| LOW | EvoScientist/backends.py | 177 | CODE | |
| LOW | EvoScientist/backends.py | 317 | CODE | |
| LOW | EvoScientist/backends.py | 887 | CODE | |
| LOW | EvoScientist/backends.py | 1184 | CODE | |
| LOW | EvoScientist/backends.py | 1221 | CODE | |
| LOW | EvoScientist/backends.py | 1256 | CODE | |
| LOW | EvoScientist/backends.py | 1513 | CODE | |
| LOW | EvoScientist/backends.py | 1811 | CODE | |
| LOW | EvoScientist/backends.py | 2030 | CODE | |
| LOW | EvoScientist/utils.py | 43 | CODE | |
| LOW | EvoScientist/utils.py | 85 | CODE | |
| LOW | EvoScientist/ccproxy_manager.py | 55 | CODE | |
| LOW | EvoScientist/middleware/tool_selector.py | 75 | CODE | |
| LOW | EvoScientist/middleware/error_normalization.py | 64 | CODE | |
| LOW | EvoScientist/middleware/ask_user.py | 245 | CODE | |
| LOW | EvoScientist/middleware/tool_history_repair.py | 68 | CODE | |
| LOW | EvoScientist/middleware/tool_history_repair.py | 164 | CODE | |
| LOW | EvoScientist/tools/skills_manager.py | 818 | CODE | |
| LOW | EvoScientist/tools/skills_manager.py | 990 | CODE | |
| LOW | EvoScientist/tools/skills_manager.py | 1117 | CODE | |
| LOW | EvoScientist/tools/skills_manager.py | 1301 | CODE | |
| LOW | EvoScientist/tools/skill_manager.py | 11 | CODE | |
| LOW | EvoScientist/tools/skill_manager.py | 21 | CODE | |
| LOW | EvoScientist/llm/models.py | 391 | CODE | |
| LOW | EvoScientist/llm/patches.py | 51 | CODE | |
| LOW | EvoScientist/llm/patches.py | 95 | CODE | |
| LOW | EvoScientist/llm/patches.py | 356 | CODE | |
| LOW | EvoScientist/llm/patches.py | 393 | CODE | |
| LOW | EvoScientist/llm/patches.py | 874 | CODE | |
| LOW | EvoScientist/llm/patches.py | 1377 | CODE | |
| LOW | EvoScientist/memory/search.py | 92 | CODE | |
| LOW | EvoScientist/memory/autoskills/candidates.py | 124 | CODE | |
| LOW | EvoScientist/config/onboard/steps.py | 1160 | CODE | |
| LOW | EvoScientist/config/onboard/wizard.py | 69 | CODE | |
| LOW | EvoScientist/config/onboard/wizard.py | 171 | CODE | |
| LOW | EvoScientist/config/onboard/wizard.py | 509 | CODE | |
| LOW | EvoScientist/config/onboard/channels.py | 25 | CODE | |
| LOW | EvoScientist/config/onboard/channels.py | 828 | CODE | |
| LOW | EvoScientist/config/onboard/channels.py | 848 | CODE | |
| LOW | EvoScientist/config/onboard/helpers.py | 631 | CODE | |
| LOW | EvoScientist/deploy/launcher.py | 749 | CODE | |
| LOW | EvoScientist/deploy/launcher.py | 491 | CODE | |
| LOW | EvoScientist/stream/events.py | 971 | CODE | |
| LOW | EvoScientist/stream/events.py | 1025 | CODE | |
| LOW | EvoScientist/stream/events.py | 736 | CODE | |
| LOW | EvoScientist/stream/display.py | 282 | CODE | |
| LOW | EvoScientist/stream/display.py | 656 | CODE | |
| LOW | EvoScientist/stream/display.py | 1040 | CODE | |
| LOW | EvoScientist/stream/display.py | 1320 | CODE | |
| LOW | EvoScientist/stream/display.py | 1438 | CODE | |
| 127 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | EvoScientist/prompts.py | 183 | ## Step 5: Write Report | COMMENT |
| LOW⚡ | EvoScientist/prompts.py | 189 | ## Step 6: Verify | COMMENT |
| LOW | EvoScientist/prompts.py | 105 | ## Step 3: Execute & Debug | COMMENT |
| LOW | EvoScientist/prompts.py | 130 | ## Step 4: Evaluate & Iterate | COMMENT |
| LOW⚡ | EvoScientist/prompts.py | 88 | return "\n".join(["## Step 1: Intake & Scope", *bullets]) | STRING |
| LOW⚡ | EvoScientist/prompts.py | 91 | _EXPERIMENT_WORKFLOW_EXECUTION = """## Step 2: Plan (Recommended Structure) | STRING |
| LOW | EvoScientist/config/onboard/helpers.py | 637 | # Step 1: Validate | COMMENT |
| LOW | EvoScientist/config/onboard/helpers.py | 653 | # Step 2: Offer to install | COMMENT |
| LOW | EvoScientist/skills/find-skills/SKILL.md | 20 | ## Step 1: Search for Skills | COMMENT |
| LOW | EvoScientist/skills/find-skills/SKILL.md | 42 | ## Step 2: Present Options | COMMENT |
| LOW | EvoScientist/skills/find-skills/SKILL.md | 50 | ## Step 3: Install | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 206 | ### Step 1: Spawn all runs (with-skill AND baseline) using `task` tool | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 236 | ### Step 2: While runs are in progress, draft assertions | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 242 | ### Step 3: As runs complete, capture timing data | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 254 | ### Step 4: Grade, aggregate, and launch the viewer | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 287 | ### Step 5: Read the feedback | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 330 | ### Step 1: Generate trigger eval queries | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 347 | ### Step 2: Review with user | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 356 | ### Step 3: Run the optimization loop | COMMENT |
| LOW | EvoScientist/skills/skill-creator/SKILL.md | 377 | ### Step 4: Apply the result | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/grader.md | 21 | ### Step 1: Read the Transcript | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/grader.md | 27 | ### Step 2: Examine Output Files | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/grader.md | 33 | ### Step 3: Evaluate Each Assertion | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/grader.md | 43 | ### Step 4: Extract and Verify Claims | COMMENT |
| LOW | EvoScientist/skills/skill-creator/agents/grader.md | 61 | ### Step 5: Read User Notes | COMMENT |
| LOW | EvoScientist/skills/skill-creator/agents/grader.md | 68 | ### Step 6: Critique the Evals | COMMENT |
| LOW | EvoScientist/skills/skill-creator/agents/grader.md | 81 | ### Step 7: Write Grading Results | COMMENT |
| LOW | EvoScientist/skills/skill-creator/agents/grader.md | 101 | ### Step 8: Read Executor Metrics and Timing | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 22 | ### Step 1: Read Both Outputs | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 29 | ### Step 2: Understand the Task | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 37 | ### Step 3: Generate Evaluation Rubric | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 60 | ### Step 4: Evaluate Each Output Against the Rubric | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 68 | ### Step 5: Check Assertions (if provided) | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 77 | ### Step 6: Determine the Winner | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/comparator.md | 87 | ### Step 7: Write Comparison Results | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 23 | ### Step 1: Read Comparison Result | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 29 | ### Step 2: Read Both Skills | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 39 | ### Step 3: Read Both Transcripts | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 49 | ### Step 4: Analyze Instruction Following | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 59 | ### Step 5: Identify Winner Strengths | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 69 | ### Step 6: Identify Loser Weaknesses | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 77 | ### Step 7: Generate Improvement Suggestions | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 87 | ### Step 8: Write Analysis Results | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 205 | ### Step 1: Read Benchmark Data | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 211 | ### Step 2: Analyze Per-Assertion Patterns | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 220 | ### Step 3: Analyze Cross-Eval Patterns | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 227 | ### Step 4: Analyze Metrics Patterns | COMMENT |
| LOW⚡ | EvoScientist/skills/skill-creator/agents/analyzer.md | 234 | ### Step 5: Generate Notes | COMMENT |
| LOW | EvoScientist/skills/skill-creator/agents/analyzer.md | 249 | ### Step 6: Write Notes | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | EvoScientist/__init__.py | 45 | Lazily import and cache package-level attributes. Args: name: The attribute name to look up. Returns: | STRING |
| HIGH | EvoScientist/ccproxy_manager.py | 203 | Start ccproxy serve as a background process. Args: port: Port number for the proxy server. Returns: | STRING |
| HIGH | EvoScientist/middleware/model_fallback.py | 269 | Walk the fallback chain, trying each model until one succeeds. Shared implementation for both sync and async middle | STRING |
| HIGH | EvoScientist/middleware/model_fallback.py | 445 | Check non-fallbackable conditions, then delegate to ``_try_fallbacks``. Args: primary_exc: The exception ra | STRING |
| HIGH | EvoScientist/tools/skill_manager.py | 29 | Manage user-installable skills: install from GitHub or local path, list available skills, browse remote skills, get deta | STRING |
| HIGH | EvoScientist/llm/models.py | 396 | Get a chat model instance. Args: model: Model name (short name like 'claude-sonnet-4-6' or full ID | STRING |
| HIGH | EvoScientist/subagents/_factory.py | 237 | Build a deployable graph for the ``name`` sub-agent defined in yaml. Args: name: The sub-agent's key in one | STRING |
| HIGH | EvoScientist/config/settings.py | 754 | Coerce a value to the expected field type. Args: value: The value to coerce. field_type: The target | STRING |
| HIGH | EvoScientist/langgraph_dev/manager.py | 906 | Start langgraph dev as a background subprocess. Args: workspace_dir: Working directory for the subprocess ( | STRING |
| HIGH | EvoScientist/commands/implementation/model.py | 12 | Parse model name and provider from argument list. Args: args: Non-empty argument list (model_name [provider | STRING |
| HIGH | EvoScientist/channels/imessage/targets.py | 150 | Parse an iMessage target string. Supports formats: - chat_id:123 - chat_guid:abc-def - chat_identifier: | STRING |
| HIGH | EvoScientist/channels/imessage/rpc_client.py | 127 | Send a JSON-RPC request and wait for response. Args: method: RPC method name params: Me | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_stt.py | 261 | # EvoSci config set stt_enabled true | COMMENT |
| LOW | EvoScientist/EvoScientist.py | 81 | # when config.model/provider change (e.g. via /model). Without this, | COMMENT |
| LOW | EvoScientist/EvoScientist.py | 381 | ) | COMMENT |
| LOW | EvoScientist/git_cli.py | 21 | # then open a credential helper window or wait for a username on the terminal. | COMMENT |
| LOW | EvoScientist/middleware/expert_async_subagent.py | 501 | # all five tools using our config-injecting client cache below. | COMMENT |
| LOW | EvoScientist/middleware/summarization.py | 221 | # Captured before any shim wraps it, so racing installers never nest shims. | COMMENT |
| LOW | EvoScientist/tools/skills_manager.py | 141 | # "" — not an expert | COMMENT |
| LOW | EvoScientist/tools/skills_manager.py | 181 | # is a package, a contract file is a capability, presence is the declaration, | COMMENT |
| LOW | EvoScientist/llm/context_window.py | 61 | # Moonshot Kimi K3 — 1M context; covers bare ``kimi-k3`` (native Moonshot), | COMMENT |
| LOW | EvoScientist/llm/models.py | 461 | base_url = os.environ.get("OPENAI_BASE_URL", "") | COMMENT |
| LOW | EvoScientist/llm/models.py | 541 | # summary is returned for display. OpenAI-Responses also emits encrypted | COMMENT |
| LOW | EvoScientist/llm/patches.py | 81 | COMMENT | |
| LOW | EvoScientist/llm/patches.py | 781 | except Exception: | COMMENT |
| LOW | EvoScientist/llm/patches.py | 801 | # The fallback path is fine; the warning + traceback is just noise. And | COMMENT |
| LOW | EvoScientist/llm/patches.py | 841 | # which is a benign fallback. | COMMENT |
| LOW | EvoScientist/llm/patches.py | 921 | except Exception: | COMMENT |
| LOW | EvoScientist/llm/patches.py | 981 | # Moonshot's always-thinking models (kimi-k3). | COMMENT |
| LOW | EvoScientist/llm/patches.py | 1021 | except Exception: | COMMENT |
| LOW | EvoScientist/llm/errors.py | 101 | for. | COMMENT |
| LOW | EvoScientist/llm/errors.py | 161 | # Kept here rather than imported from ``models.py`` to keep the | COMMENT |
| LOW | EvoScientist/subagents/_factory.py | 41 | COMMENT | |
| LOW | EvoScientist/subagents/_factory.py | 301 | COMMENT | |
| LOW | EvoScientist/subagents/expert_container_async.py | 141 | "with status='error' explaining the skill is missing." | COMMENT |
| LOW | EvoScientist/subagents/expert_container_async.py | 281 | # skills that share the same frontmatter ``name`` (workspace listing | COMMENT |
| LOW | EvoScientist/subagents/expert_container_async.py | 361 | # does NOT inherit the main agent's subagent stack. Without at least | COMMENT |
| LOW | EvoScientist/memory/observations/store.py | 361 | ) | COMMENT |
| LOW | EvoScientist/config/settings.py | 221 | # data-analysis-agent. Adds ~10-15s to CLI startup (langgraph dev cold | COMMENT |
| LOW | EvoScientist/config/settings.py | 241 | langgraph_dev_host: str = "127.0.0.1" | COMMENT |
| LOW | EvoScientist/config/settings.py | 261 | # back to UTC if it can't be determined; set e.g. "Europe/London" to pin one. | COMMENT |
| LOW | EvoScientist/config/settings.py | 281 | # exits. The next `EvoSci` start in the same workspace reuses it instantly | COMMENT |
| LOW | EvoScientist/config/settings.py | 321 | # each count as 1) before raising GraphRecursionError. Resets on every | COMMENT |
| LOW | EvoScientist/config/settings.py | 361 | # cache. Each entry holds one parsed document keyed on the file path; at | COMMENT |
| LOW | EvoScientist/config/settings.py | 381 | mirror: Literal["default", "cn"] = "default" | COMMENT |
| LOW | EvoScientist/config/settings.py | 521 | # ``EvoScientist/middleware/code_interpreter.py`` as a load-bearing safety | COMMENT |
| LOW | EvoScientist/config/settings.py | 1081 | COMMENT | |
| LOW | EvoScientist/mcp/client.py | 21 | COMMENT | |
| LOW | EvoScientist/mcp/client.py | 101 | COMMENT | |
| LOW | EvoScientist/mcp/client.py | 381 | COMMENT | |
| LOW | EvoScientist/mcp/client.py | 401 | # ``start_langgraph_dev`` while still leaving room for a first ``npx -y`` | COMMENT |
| LOW | EvoScientist/cli/async_notifier.py | 201 | # below, one completion yields exactly one enqueue. | COMMENT |
| LOW | EvoScientist/cli/channel.py | 501 | # ``run_coroutine_threadsafe`` while the calling (main / TUI) thread blocks | COMMENT |
| LOW | EvoScientist/cli/commands.py | 1961 | # ``_message_queue.get(timeout=...)`` and land in the ``except`` | COMMENT |
| LOW | EvoScientist/langgraph_dev/__init__.py | 21 | # loop that serves runs. Forcing the Proactor loop policy here — at import, | COMMENT |
| LOW | EvoScientist/langgraph_dev/main_graph.py | 41 | # Sanity check on the LangGraph internals ``_strip_private`` scrubs. If any | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 141 | COMMENT | |
| LOW | EvoScientist/langgraph_dev/manager.py | 361 | except OSError: | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 381 | # a thread from a different workspace) and trigger a restart so the deployed | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 621 | except OSError: | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 961 | from ..mcp.client import _ensure_node_for_stdio, load_mcp_config | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 1021 | # ``_rotate_log_if_needed``). See #209. | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 1041 | # is fragile (relative paths in MCP configs etc.); env var is explicit. | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 1061 | # cron job state across CLI restarts — work without further changes. Users | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 1081 | # ``--port`` differs from the persisted ``langgraph_dev_port``, and | COMMENT |
| LOW | EvoScientist/langgraph_dev/manager.py | 1401 | if not needs_langgraph_dev(config, backend=backend): | COMMENT |
| LOW | .github/workflows/publish.yml | 1 | name: Publish to PyPI | COMMENT |
| LOW | .github/scripts/release_guard.sh | 1 | #!/usr/bin/env bash | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_langgraph_manager.py | 490 | # ensure_langgraph_dev — high-level orchestration | COMMENT |
| MEDIUM | …erature/SIGIR2026_public_arxiv_systematic_survey_zh.md | 126 | ## 5. Search Agents、RAG 与推理:从单轮检索到轨迹级策略学习 | COMMENT |
| MEDIUM | …erature/SIGIR2026_public_arxiv_systematic_survey_zh.md | 148 | ### 5.4 长视频与时空 grounding 说明 agentic reasoning 已跨出文本 | COMMENT |
| MEDIUM | …erature/SIGIR2026_public_arxiv_systematic_survey_en.md | 128 | ## 5. Search Agents, RAG, and Reasoning: From Single-Turn Retrieval to Trajectory-Level Policy Learning | COMMENT |
| MEDIUM | EvoScientist/sessions.py | 700 | # a multi-agent DB where a third-party tool shares the same | COMMENT |
| MEDIUM | EvoScientist/backends.py | 45 | # If the agent hallucinates an absolute system path, we block it. | COMMENT |
| MEDIUM⚡ | EvoScientist/ccproxy_manager.py | 315 | # High-level orchestration | COMMENT |
| MEDIUM | EvoScientist/middleware/code_interpreter.py | 122 | # Multi-agent orchestration is the killer use case: ``Promise.all`` over | COMMENT |
| MEDIUM | EvoScientist/middleware/summarization.py | 231 | # Keyed by the resolved context window, not the model object: real | COMMENT |
| MEDIUM | EvoScientist/middleware/context_editing.py | 75 | # Keyed by the resolved context window, not the model object: real | COMMENT |
| MEDIUM⚡ | EvoScientist/langgraph_dev/manager.py | 1304 | # High-level orchestration | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_skills_manager.py | 864 | # Create a fake repo structure | COMMENT |
| MEDIUM | tests/test_sessions.py | 2835 | # Create a valid but empty SQLite DB (no checkpoints table). | COMMENT |
| MEDIUM⚡ | tests/test_mcp_client.py | 1930 | # Create a fake executable in a temp bin dir | COMMENT |
| MEDIUM | tests/test_mcp_client.py | 131 | # Create a fake executable next to sys.executable | COMMENT |
| MEDIUM | tests/test_channel_debug.py | 178 | # Create a minimal concrete channel | COMMENT |
| MEDIUM | EvoScientist/utils.py | 113 | # Create a formatted display of the prompt | COMMENT |
| MEDIUM | EvoScientist/channels/standalone.py | 110 | # Create a lightweight manager for the consumer to use | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_serve_agent_holder.py | 58 | CODE | |
| LOW | tests/test_cli_serve.py | 15 | CODE | |
| LOW | tests/test_cli_serve.py | 50 | CODE | |
| LOW | tests/fakes.py | 213 | CODE | |
| LOW | tests/fakes.py | 302 | CODE | |
| LOW | tests/test_cli_deploy.py | 24 | CODE | |
| LOW | tests/test_cli_deploy.py | 70 | CODE | |
| LOW | EvoScientist/backends.py | 1729 | CODE | |
| LOW | EvoScientist/middleware/memory.py | 994 | CODE | |
| LOW | EvoScientist/middleware/memory.py | 506 | CODE | |
| LOW | EvoScientist/tools/skills_manager.py | 469 | CODE | |
| LOW | EvoScientist/stream/display.py | 656 | CODE | |
| LOW | EvoScientist/stream/display.py | 1438 | CODE | |
| LOW | EvoScientist/cli/tui_runtime.py | 108 | CODE | |
| LOW | EvoScientist/cli/tui_interactive.py | 1641 | CODE | |
| LOW | EvoScientist/cli/tui_backends.py | 22 | CODE | |
| LOW | EvoScientist/cli/tui_backends.py | 54 | CODE | |
| LOW | EvoScientist/cli/interactive.py | 428 | CODE | |
| LOW | EvoScientist/cli/commands.py | 121 | CODE | |
| LOW | EvoScientist/cli/commands.py | 1788 | CODE | |
| LOW | EvoScientist/cli/commands.py | 2527 | CODE | |
| LOW | EvoScientist/cli/commands.py | 552 | CODE | |
| LOW | EvoScientist/langgraph_dev/manager.py | 895 | CODE | |
| LOW | EvoScientist/channels/mixins.py | 141 | CODE | |
| LOW | EvoScientist/channels/consumer.py | 214 | CODE | |
| LOW | EvoScientist/channels/dingtalk/channel.py | 323 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | EvoScientist/tools/skills_manager.py | 840 | # Check if local path exists | COMMENT |
| LOW | EvoScientist/tools/skills_manager.py | 1339 | # Check if it's a built-in skill (read-only, cannot be uninstalled) | COMMENT |
| LOW | EvoScientist/config/settings.py | 224 | # Set False to run fully in-process — saves the startup cost in scenarios | COMMENT |
| LOW | EvoScientist/config/onboard/steps.py | 1382 | # Check if any selected servers require npx | COMMENT |
| LOW | EvoScientist/stream/display.py | 994 | # Check if any sub-agent is active | COMMENT |
| LOW | EvoScientist/mcp/client.py | 1027 | # Check if any pattern contains wildcard characters | COMMENT |
| LOW | EvoScientist/commands/implementation/mcp_install.py | 70 | # Check if it's a tag — fall through to browser | COMMENT |
| LOW | EvoScientist/skills/skill-creator/scripts/run_eval.py | 88 | # Check if the model called load_skill with the right skill name | COMMENT |
| LOW | EvoScientist/skills/skill-creator/scripts/init_skill.py | 207 | # Check if directory already exists | COMMENT |
| LOW | EvoScientist/channels/middleware.py | 276 | # Check if already has pending request | COMMENT |
| LOW | EvoScientist/channels/imessage/targets.py | 185 | # Check if remainder is a chat target | COMMENT |
| LOW | EvoScientist/channels/imessage/rpc_client.py | 214 | # Check if it's a response (has id) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL⚡ | tests/test_agent_shell.py | 499 | assert path.parent == portablegit.git.parent.parent.parent.resolve() | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_background_middleware.py | 0 | cross-platform command that sleeps for *seconds* and exits 0. | STRING |
| HIGH | tests/test_background.py | 0 | cross-platform command that sleeps for *seconds* and exits 0. | STRING |
| HIGH | tests/test_backends.py | 0 | cross-platform command that sleeps for *seconds* and exits 0. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_dingtalk_channel.py | 128 | channel._access_token = "fake-token" | CODE |
| LOW⚡ | tests/test_dingtalk_channel.py | 250 | channel._access_token = "fake-token" | CODE |
| LOW⚡ | tests/test_feishu_channel.py | 554 | channel._access_token = "fake-token" | CODE |
| LOW⚡ | tests/test_feishu_channel.py | 670 | channel._access_token = "fake-token" | CODE |
| LOW⚡ | tests/test_feishu_channel.py | 680 | channel._access_token = "fake-token" | CODE |
| LOW | tests/test_feishu_channel.py | 199 | channel._access_token = "fake-token" | CODE |
| LOW | tests/test_feishu_channel.py | 343 | channel._access_token = "fake-token" | CODE |
| LOW | tests/test_feishu_channel.py | 361 | channel._access_token = "fake-token" | CODE |
| LOW | tests/test_feishu_channel.py | 618 | channel._access_token = "fake-token" | CODE |
| LOW⚡ | tests/test_additional_channel_smoke.py | 27 | chat_id="user@example.com", | CODE |
| LOW⚡ | tests/test_additional_channel_smoke.py | 29 | metadata={"chat_id": "user@example.com"}, | CODE |
| LOW | EvoScientist/config/onboard/helpers.py | 202 | kwargs["placeholder"] = placeholder | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | EvoScientist/prompts.py | 183 | ## Step 5: Write Report | COMMENT |
| LOW⚡ | EvoScientist/prompts.py | 189 | ## Step 6: Verify | COMMENT |
| LOW | EvoScientist/prompts.py | 105 | ## Step 3: Execute & Debug | COMMENT |
| LOW | EvoScientist/prompts.py | 130 | ## Step 4: Evaluate & Iterate | COMMENT |
| LOW⚡ | EvoScientist/prompts.py | 88 | return "\n".join(["## Step 1: Intake & Scope", *bullets]) | STRING |
| LOW⚡ | EvoScientist/prompts.py | 91 | _EXPERIMENT_WORKFLOW_EXECUTION = """## Step 2: Plan (Recommended Structure) | STRING |
| LOW | EvoScientist/config/onboard/helpers.py | 637 | # Step 1: Validate | COMMENT |
| LOW | EvoScientist/config/onboard/helpers.py | 653 | # Step 2: Offer to install | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_langgraph_dev_http.py | 113 | # Ollama suffix — robust to future static Ollama entries in the registry. | COMMENT |
| MEDIUM⚡ | EvoScientist/llm/patches.py | 936 | # azure-ignore is not sufficient). The only robust fix is to drop these items | COMMENT |
| MEDIUM | EvoScientist/mcp/client.py | 237 | # Forward by keyword: robust against future SDK signature changes | COMMENT |
| LOW | EvoScientist/cli/tui_interactive.py | 2792 | # errors; callers just return so the send is dropped. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_llm.py | 2769 | CODE | |
| MEDIUM | tests/test_mcp_client.py | 582 | CODE |