Access large language models from the command-line
This report presents the forensic synthetic code analysis of simonw/llm, a Python project with 12,421 GitHub stars. SynthScan v2.0 examined 50,965 lines of code across 109 source files, recording 799 pattern matches distributed across 13 syntactic categories. The overall adjusted score of 14.2 places this repository in the Low AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 799 distinct pattern matches across 13 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. 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 diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | llm/hookspecs.py | 18 | def register_embedding_models(register): | CODE |
| LOW⚡ | llm/hookspecs.py | 23 | def register_template_loaders(register): | CODE |
| LOW⚡ | llm/hookspecs.py | 28 | def register_fragment_loaders(register): | CODE |
| LOW | llm/models.py | 260 | def _get_arguments_input_schema(function, name): | CODE |
| LOW | llm/models.py | 289 | def _implementation_arguments(tool: "Tool", tool_call: "ToolCall") -> dict: | CODE |
| LOW | llm/models.py | 2707 | def _append_tool_results_to_chain(chain, tool_results, attachments) -> list[Any]: | CODE |
| LOW | llm/models.py | 2760 | def _trailing_pending_tool_calls(messages) -> list[ToolCall]: | CODE |
| LOW | llm/models.py | 3216 | def supported_server_side_tools(self) -> tuple[type[ServerSideTool], ...]: | CODE |
| LOW | llm/models.py | 3651 | def _remove_titles_recursively(obj): | CODE |
| LOW | llm/__init__.py | 237 | def get_embedding_models_with_aliases() -> list["EmbeddingModelWithAliases"]: | CODE |
| LOW | llm/__init__.py | 279 | def get_embedding_model_aliases() -> dict[str, EmbeddingModel]: | CODE |
| LOW | llm/__init__.py | 501 | def get_default_embedding_model(): | CODE |
| LOW | llm/__init__.py | 505 | def set_default_embedding_model(model): | CODE |
| LOW | llm/embeddings.py | 183 | def embed_multi_with_metadata( | CODE |
| LOW | llm/cli.py | 122 | async def display_async_stream_events(events, *, show_reasoning=True): | CODE |
| LOW | llm/cli.py | 299 | def process_fragments_in_chat( | CODE |
| LOW | llm/cli.py | 388 | def resolve_attachment_with_type(value: str, mimetype: str) -> Attachment: | CODE |
| LOW | llm/cli.py | 404 | def attachment_types_callback(ctx, param, values) -> list[Attachment]: | CODE |
| LOW | llm/cli.py | 439 | def _merge_template_attachments(template, attachments, attachment_types): | CODE |
| LOW | llm/cli.py | 1764 | def logs_json_for_response_ids(db, ids): | STRING |
| LOW | llm/cli.py | 2066 | def _format_tool_call_arguments(arguments): | STRING |
| LOW | llm/cli.py | 2380 | def model_matches_id_or_alias(model_with_aliases, model_ids): | STRING |
| LOW | llm/cli.py | 2387 | def render_model_with_aliases( | STRING |
| LOW | llm/cli.py | 2455 | def render_model_with_options(model_id, *, async_=False): | STRING |
| LOW | llm/utils.py | 181 | def extract_fenced_code_block(text: str, last: bool = False) -> str | None: | CODE |
| LOW | llm/logs.py | 1581 | def _instances_by_tool_call_id( | CODE |
| LOW | llm/default_plugins/openai_models.py | 427 | def register_embedding_models(register): | CODE |
| LOW | llm/default_plugins/openai_models.py | 1833 | def supported_server_side_tools(self): | CODE |
| LOW | llm/default_plugins/openai_models.py | 2116 | def _finalize_responses_kwargs(self, prompt, stream, instructions=None): | CODE |
| LOW | llm/default_plugins/openai_models.py | 2149 | def _reasoning_text_from_item(self, item): | CODE |
| LOW | llm/default_plugins/openai_models.py | 2194 | def _reasoning_refresh_events(self, response_json, done_events): | CODE |
| LOW | llm/default_plugins/openai_models.py | 2325 | def _refresh_server_tool_events(self, output, done_events): | CODE |
| LOW | llm/default_plugins/openai_models.py | 2350 | def _non_streaming_output_events(self, output, response): | CODE |
| LOW | tests/test_cli_openai_models.py | 49 | def test_openai_options_min_max(): | CODE |
| LOW | tests/test_cli_openai_models.py | 108 | def test_deprecated_models_are_not_registered(model_id): | CODE |
| LOW | tests/test_cli_openai_models.py | 217 | def test_code_interpreter_cli_tool_is_resolved_from_model(httpx_mock): | CODE |
| LOW | tests/test_cli_openai_models.py | 274 | def test_code_interpreter_cli_tool_is_reused_on_continue(httpx_mock, user_path): | CODE |
| LOW | tests/test_cli_openai_models.py | 395 | def test_web_search_cli_tool_is_resolved_from_model(httpx_mock): | CODE |
| LOW | tests/test_cli_openai_models.py | 453 | def test_tools_list_for_model_includes_server_side_tools(): | CODE |
| LOW | tests/test_cli_openai_models.py | 485 | def test_tools_list_for_model_with_no_server_side_tools(): | CODE |
| LOW | tests/test_cli_openai_models.py | 496 | def test_tools_list_rejects_unknown_model(): | CODE |
| LOW | tests/test_cli_openai_models.py | 520 | def test_openai_image_detail_option_description(model_id, expected_description): | CODE |
| LOW | tests/test_cli_openai_models.py | 525 | def test_openai_image_detail_option_is_sent_on_image_attachments(httpx_mock): | CODE |
| LOW | tests/test_cli_openai_models.py | 672 | def test_openai_image_detail_original_is_rejected_for_other_models(): | CODE |
| LOW | tests/test_async_parity.py | 17 | def test_echo_registered_for_both(): | CODE |
| LOW | tests/test_async_parity.py | 26 | async def test_async_to_dict_captures_chain_and_output(): | CODE |
| LOW | tests/test_async_parity.py | 40 | async def test_async_to_dict_raises_before_awaited(): | CODE |
| LOW | tests/test_async_parity.py | 48 | async def test_async_from_dict_rehydrates(): | CODE |
| LOW | tests/test_async_parity.py | 66 | async def test_async_from_dict_then_reply_continues(): | CODE |
| LOW | tests/test_async_parity.py | 90 | async def test_async_from_row_response_messages_synthesized(tmp_path): | CODE |
| LOW | tests/test_async_parity.py | 136 | async def test_async_load_conversation_follow_up_preserves_chain(tmp_path): | CODE |
| LOW | tests/test_async_parity.py | 188 | async def test_sync_and_async_produce_identical_chain(): | CODE |
| LOW | tests/test_async_parity.py | 207 | async def test_async_chain_tool_result_turn_has_full_chain(): | CODE |
| LOW | tests/test_async_parity.py | 246 | async def test_astream_events_matches_stream_events_for_text_only(): | CODE |
| LOW | tests/test_async_parity.py | 276 | async def test_async_from_dict_model_override(): | CODE |
| LOW | tests/test_async_parity.py | 288 | def test_sync_from_dict_model_override(): | CODE |
| LOW | tests/test_async_parity.py | 300 | async def test_async_to_dict_preserves_datetime(): | CODE |
| LOW | tests/test_async_parity.py | 310 | async def test_async_to_dict_preserves_usage_when_set(async_mock_model): | CODE |
| LOW | tests/test_async_parity.py | 328 | async def test_async_reply_messages_kwarg_appends(): | CODE |
| LOW | tests/test_async_parity.py | 341 | async def test_async_full_chain_to_dict_round_trip_three_turns(): | CODE |
| 614 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | llm/utils.py | 699 | if re.match(r'\s*(["\[\d\-]|true|false|null)', arg_body, re.IGNORECASE): | CODE |
| HIGH | llm/logs.py | 1082 | where json_extract(je.value, '$.literal') is not null) | CODE |
| HIGH | llm/migrations.py | 676 | and p2.tool_name is not null) as tools | CODE |
| HIGH | tests/test_llm_logs.py | 1387 | """When reasoning is empty/null, no heading appears (existing | STRING |
| HIGH⚡ | tests/test_plugins.py | 479 | '[{"id": ID, "tool_id": 1, "name": "upper", "output": "ONE", "tool_call_id": "tc_TCID", "exception": nul | CODE |
| HIGH⚡ | tests/test_plugins.py | 484 | '[{"id": ID, "tool_id": 1, "name": "upper", "output": "TWO", "tool_call_id": "tc_TCID", "exception": nul | CODE |
| HIGH⚡ | tests/test_plugins.py | 492 | '[{"id": ID, "tool_id": 1, "name": "upper", "output": "THREE", "tool_call_id": "tc_TCID", "exception": n | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/plugins.py | 23 | CODE | |
| LOW | llm/models.py | 604 | CODE | |
| LOW | llm/models.py | 104 | CODE | |
| LOW | llm/models.py | 1311 | CODE | |
| LOW | llm/models.py | 1879 | CODE | |
| LOW | llm/models.py | 2226 | CODE | |
| LOW | llm/models.py | 3009 | CODE | |
| LOW | llm/cli.py | 136 | CODE | |
| LOW | llm/cli.py | 228 | CODE | |
| LOW | llm/cli.py | 685 | CODE | |
| LOW | llm/cli.py | 1412 | CODE | |
| LOW | llm/cli.py | 1683 | CODE | |
| LOW | llm/cli.py | 1878 | CODE | |
| LOW | llm/cli.py | 2802 | CODE | |
| LOW | llm/cli.py | 3358 | CODE | |
| LOW | llm/cli.py | 3501 | CODE | |
| LOW | llm/cli.py | 3699 | CODE | |
| LOW | llm/cli.py | 2087 | CODE | |
| LOW | llm/cli.py | 3595 | CODE | |
| LOW | llm/utils.py | 76 | CODE | |
| LOW | llm/utils.py | 311 | CODE | |
| LOW | llm/utils.py | 585 | CODE | |
| LOW | llm/logs.py | 85 | CODE | |
| LOW | llm/logs.py | 878 | CODE | |
| LOW | llm/parts.py | 253 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 489 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 3037 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 580 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1215 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1385 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1503 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1746 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1927 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2037 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2233 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2350 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2480 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2724 | CODE | |
| LOW | tests/test_templates.py | 510 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/__init__.py | 11 | CODE | |
| LOW | llm/__init__.py | 12 | CODE | |
| LOW | llm/__init__.py | 12 | CODE | |
| LOW | llm/__init__.py | 16 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 17 | CODE | |
| LOW | llm/__init__.py | 42 | CODE | |
| LOW | llm/__init__.py | 42 | CODE | |
| LOW | llm/__init__.py | 42 | CODE | |
| LOW | llm/__init__.py | 42 | CODE | |
| LOW | llm/__init__.py | 42 | CODE | |
| LOW | llm/__init__.py | 51 | CODE | |
| LOW | tests/test_options_parameter.py | 89 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/models.py | 1980 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/models.py | 2300 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/models.py | 2355 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/models.py | 2399 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/models.py | 2423 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/models.py | 2441 | except Exception as ex: # noqa: BLE001 | CODE |
| MEDIUM | llm/cli.py | 381 | def convert(self, value, param, ctx): | CODE |
| LOW | llm/cli.py | 282 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | llm/cli.py | 1142 | except Exception as ex: | CODE |
| LOW | llm/cli.py | 1663 | except Exception as ex: # noqa: BLE001 | STRING |
| LOW | llm/cli.py | 4227 | except Exception as ex: # noqa: BLE001 | STRING |
| LOW | llm/default_plugins/openai_models.py | 829 | except Exception as ex: | CODE |
| LOW | llm/default_plugins/openai_models.py | 2185 | except Exception: # noqa: BLE001 | CODE |
| LOW | docs/plugins/plugin-hooks.md | 221 | except Exception as e: | CODE |
| LOW | docs/plugins/plugin-hooks.md | 271 | except Exception as ex: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | llm/__init__.py | 442 | # Try to resolve it to an embedding model | COMMENT |
| MEDIUM | tests/test_embed_cli.py | 180 | # --key should be passed through to the embedding model | COMMENT |
| MEDIUM | tests/test_embed_cli.py | 201 | # --key should be passed through to the embedding model for embed-multi too | COMMENT |
| MEDIUM | tests/test_openai_responses.py | 1242 | # item, otherwise the model loses its chain of thought. | COMMENT |
| MEDIUM | docs/embeddings/python-api.md | 50 | To work with embeddings in this way you will need an instance of a [sqlite-utils Database](https://sqlite-utils.datasett | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/models.py | 493 | CODE | |
| LOW | llm/models.py | 823 | CODE | |
| LOW | llm/models.py | 877 | CODE | |
| LOW | llm/models.py | 956 | CODE | |
| LOW | llm/models.py | 1010 | CODE | |
| LOW | llm/models.py | 3263 | CODE | |
| LOW | llm/models.py | 3310 | CODE | |
| LOW | llm/models.py | 3389 | CODE | |
| LOW | llm/models.py | 3435 | CODE | |
| LOW | llm/logs.py | 1307 | CODE | |
| LOW | llm/logs.py | 1650 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1148 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 1651 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2422 | CODE | |
| LOW | llm/default_plugins/openai_models.py | 2668 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | README.md | 84 | Add `--key your-api-key` if the endpoint requires authentication. See [Run against an endpoint without configuring it](h | CODE |
| HIGH | docs/index.md | 52 | Add `--key your-api-key` if the endpoint requires authentication. See {ref}`Run against an endpoint without configuring | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | llm/cli.py | 3977 | # Create a test Options object to validate | STRING |
| MEDIUM | tests/test_templates.py | 160 | # Create a file to test attachment | COMMENT |
| MEDIUM | tests/test_chat_templates.py | 38 | # Create a system fragment file | COMMENT |
| MEDIUM | docs/conf.py | 3 | # This file is execfile()d with the current directory set to its | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/cli.py | 3636 | # Read the file twice - first time is to get a count | COMMENT |
| LOW | llm/utils.py | 376 | # Check if the schema is newline-separated or comma-separated | COMMENT |
| LOW | tests/test_utils.py | 434 | # Check if the correct number of backticks is used | COMMENT |
| LOW | .github/workflows/stable-docs.yml | 52 | # Check if the list of files is non-empty | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/__init__.py | 53 | __all__ = [ | CODE |
| LOW | llm/cli.py | 4130 | def set_model_option(model_id: str, key: str, value: Any) -> None: | STRING |
| LOW | llm/logs.py | 45 | __all__ = [ | CODE |
| LOW | llm/serialization.py | 41 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/migrations.py | 721 | # only while sorted by path. | COMMENT |
| LOW | docs/conf.py | 1 | from subprocess import PIPE, Popen | COMMENT |
| LOW | docs/conf.py | 121 | # The paper size ('letterpaper' or 'a4paper'). | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | llm/utils.py | 107 | def handle_request(self, request: httpx2.Request) -> httpx2.Response: | CODE |