A Python framework for self-hosted LLM tool-calling and multi-step agentic workflows
This report presents the forensic synthetic code analysis of antoinezambelli/forge, a Python project with 2,229 GitHub stars. SynthScan v2.0 examined 78,342 lines of code across 230 source files, recording 1950 pattern matches distributed across 17 syntactic categories. The overall adjusted score of 32.0 places this repository in the Strong 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 1950 distinct pattern matches across 17 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 | tests/conftest.py | 17 | def mock_httpx_client_constructor() -> Iterator[MagicMock]: | CODE |
| LOW | tests/http_mocks.py | 32 | def patch_httpx_client_constructor() -> Iterator[MagicMock]: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 39 | def test_lambda_and_stateful_tools_share_output_contracts() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 180 | def test_lambda_and_stateful_validators_accept_equivalent_formats() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 195 | def test_lambda_and_stateful_validators_reject_benchmark_failure_modes() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 233 | def test_stateful_tools_record_successful_reasoning_path() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 257 | def test_stateful_tools_do_not_record_rejected_paths() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 267 | def _exercise_required_stateful_calls(workflow: Any) -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 278 | def test_validate_state_requires_full_reasoning_path_and_submission() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 297 | def test_validate_state_rejects_skipped_conversion() -> None: | CODE |
| LOW | tests/unit/test_argument_transformation.py | 308 | def test_validate_state_rejects_wrong_submission() -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 90 | async def test_returns_text_response(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 100 | async def test_missing_choices_raises_backend_error(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 110 | async def test_null_content_returns_empty_text(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 120 | async def test_malformed_tool_args_kept_as_raw_args(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 454 | def test_bearer_header_set_when_key_provided(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 460 | def test_no_auth_header_when_no_key(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 464 | def test_base_url_trailing_slash_stripped(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 474 | async def test_yields_text_deltas_and_final(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 827 | def test_recommended_sampling_off_is_silent_for_unknown_model(self) -> None: | CODE |
| LOW⚡ | tests/unit/test_openai_compat_client.py | 837 | def test_recommended_sampling_on_raises_for_unknown_model(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 142 | async def test_malformed_tool_args_kept_even_with_assistant_text(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 163 | async def test_malformed_among_several_kept_per_call(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 185 | async def test_dict_tool_args_accepted(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 204 | async def test_formats_tools_in_request(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 219 | async def test_request_body_structure(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 234 | async def test_posts_to_chat_completions(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 256 | async def test_http_error_raises_backend_error(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 265 | async def test_structured_reasoning_field_captured(self, field) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 286 | async def test_extracts_think_tags_from_content_with_tool_call(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 306 | async def test_reasoning_field_preferred_over_content_tags(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 325 | async def test_content_preamble_not_treated_as_reasoning(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 347 | async def test_think_tags_stripped_from_text_response(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 362 | async def test_plain_preamble_text_response_survives(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 377 | async def test_reasoning_attached_to_first_tool_call_only(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 398 | async def test_empty_string_structured_field_falls_through_to_tags(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 419 | async def test_non_string_reasoning_field_raises(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 496 | async def test_yields_final_with_tool_call(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 525 | async def test_stream_malformed_tool_args_kept_as_raw_args(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 552 | async def test_stream_non_string_arg_fragment_not_dropped(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 574 | async def test_accumulates_reasoning_across_deltas(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 597 | async def test_stream_extracts_think_tags_from_content_with_tool_call(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 620 | async def test_stream_content_preamble_not_treated_as_reasoning(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 643 | async def test_stream_strips_think_tags_from_text_response(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 661 | async def test_stream_other_canonical_fields_accumulate(self, field) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 682 | async def test_stream_structured_preferred_over_content_tags(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 703 | async def test_stream_reasoning_first_tool_call_only(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 725 | async def test_stream_non_string_reasoning_raises(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 741 | async def test_stream_http_error_raises(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 752 | async def test_ignores_non_data_lines(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 777 | def test_extra_headers_merged_alongside_bearer(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 789 | def test_api_key_plus_auth_header_raises(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 802 | def test_extra_headers_alone_set_custom_scheme(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 811 | def test_sampling_kwargs_stored_as_instance_fields(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 859 | async def test_instance_sampling_flows_into_body(self, field, value) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 881 | async def test_passthrough_fields_appear_in_body(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 896 | async def test_forge_owned_fields_override_passthrough(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 917 | async def test_inbound_anthropic_body_accepted_and_ignored(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 933 | async def test_send_stream_accepts_passthrough_and_inbound(self) -> None: | CODE |
| LOW | tests/unit/test_openai_compat_client.py | 954 | async def test_aclose_closes_http_pool(self) -> None: | CODE |
| 1189 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/conftest.py | 23 | # ── Shared LLM client double ───────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_openai_compat_client.py | 450 | # ── auth ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_openai_compat_client.py | 469 | # ── send_stream ────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_openai_compat_client.py | 847 | # ── instance sampling flows into request body ──────────────────── | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 61 | # ── send ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 773 | # ── constructor ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 876 | # ── passthrough + inbound_anthropic_body ───────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 949 | # ── aclose ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_inconsistent_api_recovery.py | 27 | # ── Lambda tool callables ─────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_inconsistent_api_recovery.py | 243 | # ── Stateful backend ──────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_inconsistent_api_recovery.py | 327 | # ── Stateful validate_state ───────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_inconsistent_api_recovery.py | 200 | # ── Validator (lambda) ────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_ollama_client.py | 849 | # ── outbound message normalization (#111 / #115) ───────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_ollama_client.py | 960 | # ── get_context_length + set_num_ctx ───────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_ollama_client.py | 982 | # ── format_tool ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_ollama_client.py | 47 | # ── send ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_ollama_client.py | 476 | # ── send_stream ────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_proxy_auth.py | 86 | # ── relocate_credential ────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_proxy_auth.py | 132 | # ── resolve_inbound_credential ─────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_auth.py | 27 | # ── extract_inbound_credential ─────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_auth.py | 224 | # ── handler threading ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_anthropic_client.py | 137 | # ── _convert_tools ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_anthropic_client.py | 177 | # ── _convert_messages ──────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_anthropic_client.py | 450 | # ── _parse_response ────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_anthropic_client.py | 727 | # ── Prompt caching (static tools+system breakpoint) ────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_llamafile_client.py | 1135 | # ── _merge_consecutive ──────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_llamafile_client.py | 1138 | # ── think flag behavior — sync ──────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 160 | # ── send — native mode ────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 659 | # ── send — prompt mode ────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 749 | # ── get_context_length ─────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 792 | # ── send_stream ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 969 | # ── send_stream — malformed-500 transport boundaries ────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 1049 | # ── mode ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 1059 | # ── _apply_sampling ────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 1391 | # ── think flag behavior — stream ────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 1486 | # ── slot_id ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_llamafile_client.py | 1658 | # ── Issue #121: Path.stem truncates dotted model names ───────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_guardrails.py | 22 | # ── check(): response validation ───────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_guardrails.py | 126 | # ── check(): step enforcement ──────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_guardrails.py | 162 | # ── record() ───────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_guardrails.py | 191 | # ── CheckResult dataclass ──────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_guardrails.py | 220 | # ── Custom retry nudge ─────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_guardrails.py | 9 | # ── Helpers ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_guardrails.py | 206 | # ── Imports ────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_proxy_path1.py | 27 | # ── ProxyServer construction validation ────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_path1.py | 94 | # ── AnthropicClient verbatim path ──────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_path1.py | 182 | # ── AnthropicClient base_url ───────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_path1.py | 198 | # ── End-to-end: cache_control wire preservation ────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_proxy_convert_anthropic.py | 19 | # ── Inbound: Anthropic → forge ───────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_convert_anthropic.py | 237 | # ── Outbound: forge → Anthropic ──────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_proxy_convert_anthropic.py | 293 | # ── SSE event sequence ───────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_context_manager.py | 89 | # ── estimate_tokens ───────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_context_manager.py | 187 | # ── maybe_compact — under threshold ───────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_context_manager.py | 200 | # ── maybe_compact — over threshold ────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_context_manager.py | 14 | # ── Helpers ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/unit/test_context_manager.py | 268 | # ── CompactEvent fields ───────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_vllm_client.py | 89 | # ── constructor / identity derivation ────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_vllm_client.py | 119 | # ── send (non-streaming) ────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_vllm_client.py | 689 | # ── get_served_model_name ────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/unit/test_vllm_client.py | 715 | # ── removed proxy discovery helper ───────────────────────────── | COMMENT |
| 186 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 3 | CODE | |
| LOW | tests/http_mocks.py | 3 | CODE | |
| LOW | tests/unit/test_argument_transformation.py | 3 | CODE | |
| LOW | tests/unit/test_inconsistent_api_recovery.py | 13 | CODE | |
| LOW | tests/unit/test_proxy_installation_docs.py | 3 | CODE | |
| LOW | tests/unit/test_eval_outcomes.py | 3 | CODE | |
| LOW | tests/unit/test_standalone_build.py | 3 | CODE | |
| LOW | tests/unit/test_eval_dataset_builder.py | 3 | CODE | |
| LOW | tests/unit/test_clients_base.py | 3 | CODE | |
| LOW | tests/unit/test_batch_eval_recipes.py | 3 | CODE | |
| LOW | tests/unit/test_server_rpc.py | 3 | CODE | |
| LOW | tests/unit/test_eval_reporting_metrics.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_profiles.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_path1.py | 13 | CODE | |
| LOW | tests/unit/test_data_gap_recovery_extended.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_cli.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_installer.py | 3 | CODE | |
| LOW | tests/unit/test_backend_profiles.py | 3 | CODE | |
| LOW | tests/unit/test_server.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_config.py | 3 | CODE | |
| LOW | tests/unit/test_slot_worker.py | 3 | CODE | |
| LOW | tests/unit/test_slot_worker.py | 6 | CODE | |
| LOW | tests/unit/test_slot_worker.py | 8 | CODE | |
| LOW | tests/unit/test_slot_worker.py | 14 | CODE | |
| LOW | tests/unit/test_slot_worker.py | 389 | CODE | |
| LOW | tests/unit/test_runner.py | 3 | CODE | |
| LOW | tests/unit/test_eval_budget.py | 3 | CODE | |
| LOW | tests/unit/test_eval_budget.py | 15 | CODE | |
| LOW | tests/unit/test_proxy_release.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_proxy.py | 9 | CODE | |
| LOW | tests/unit/test_proxy_release_workflows.py | 3 | CODE | |
| LOW | tests/unit/test_batch_eval_resume.py | 3 | CODE | |
| LOW | tests/unit/test_rpc.py | 3 | CODE | |
| LOW | tests/unit/test_client_auth.py | 15 | CODE | |
| LOW | tests/unit/test_eval_publication.py | 3 | CODE | |
| LOW | tests/unit/test_proxy_lifecycle_smoke.py | 3 | CODE | |
| LOW | tests/unit/test_eval_generation.py | 3 | CODE | |
| LOW | tests/unit/test_grounded_synthesis.py | 12 | CODE | |
| LOW | tests/unit/test_batch_eval_lifecycle.py | 3 | CODE | |
| LOW | tests/integration/_bootstrap_support.py | 3 | CODE | |
| LOW | …egration/bootstrap_contract/test_bootstrap_contract.py | 8 | CODE | |
| LOW | …egration/platform_acceptance/test_windows_installer.py | 3 | CODE | |
| LOW | tests/eval/metrics.py | 3 | CODE | |
| LOW | tests/eval/generation.py | 7 | CODE | |
| LOW | tests/eval/batch_eval.py | 11 | CODE | |
| LOW | tests/eval/batch_eval.py | 19 | CODE | |
| LOW | tests/eval/batch_eval.py | 33 | CODE | |
| LOW | tests/eval/batch_eval.py | 38 | CODE | |
| LOW | tests/eval/ablation.py | 3 | CODE | |
| LOW | tests/eval/dataset_builder.py | 13 | CODE | |
| LOW | tests/eval/outcomes.py | 8 | CODE | |
| LOW | tests/eval/significance.py | 15 | CODE | |
| LOW | tests/eval/publication.py | 15 | CODE | |
| LOW | tests/eval/eval_runner.py | 3 | CODE | |
| LOW | tests/eval/eval_runner.py | 12 | CODE | |
| LOW | tests/eval/eval_runner.py | 18 | CODE | |
| LOW | tests/eval/provenance.py | 3 | CODE | |
| LOW | tests/eval/report.py | 17 | CODE | |
| LOW | tests/eval/scenarios/_base.py | 3 | CODE | |
| LOW | tests/eval/scenarios/_stateful_plumbing.py | 3 | CODE | |
| 187 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | README.md | 3 | [](https://pypi.org/project/forge-guardrails/) | CODE |
| MEDIUM | README.md | 15 | - **Not a coding harness.** Forge is domain-agnostic. If you're building a coding agent (or already using one like openc | CODE |
| MEDIUM | README.md | 174 | Drop-in proxy that sits between any client and a local model server, speaking both the OpenAI chat-completions API and t | CODE |
| MEDIUM | README.md | 325 | runner.py # WorkflowRunner — the agentic loop | CODE |
| MEDIUM | CONTRIBUTING.md | 122 | ### Adding or modifying guardrails | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 421 | # it into replayable chain-of-thought. | COMMENT |
| MEDIUM | tests/unit/test_openai_compat_client.py | 727 | # never repr-coerced into chain-of-thought. | COMMENT |
| MEDIUM | tests/eval/report.py | 1327 | ("## Full Ablation — which guardrails do the work?", lambda rp: rp == "ablation.md"), | CODE |
| MEDIUM | tests/eval/scenarios/_model_reasoning.py | 569 | # guardrails-vs-bare ablation: bare runs hit the first error and | COMMENT |
| MEDIUM | docs/USER_GUIDE.md | 138 | ### Mode 3: Middleware (composable guardrails) | COMMENT |
| MEDIUM | docs/WORKFLOW.md | 474 | └── reasoning: str | None # chain-of-thought (thinking models) | CODE |
| MEDIUM | docs/EVAL_GUIDE.md | 87 | # Ablation — bare (all guardrails off) | COMMENT |
| MEDIUM | docs/decisions/MULTI_MODEL_ROUTING.md | 170 | # Consumer orchestration code | COMMENT |
| MEDIUM | src/forge/clients/sampling_defaults.py | 80 | # documented default reasoning effort for complex coding and agentic work. | COMMENT |
| MEDIUM | src/forge/clients/sampling_defaults.py | 120 | # DeepSeek-V4-Flash-0731 — agentic profile: T=1.0, top_p=0.95. The card | COMMENT |
| MEDIUM | src/forge/clients/sampling_defaults.py | 190 | # explicit chain of thought). Card recommends temperature=0.2, top_k=80, repetition_penalty=1.05 | COMMENT |
| MEDIUM | src/forge/clients/openai_compat.py | 397 | # chain-of-thought. | COMMENT |
| MEDIUM | src/forge/proxy/handler.py | 429 | # in tool-calling mode where guardrails apply. The respond call is | COMMENT |
| MEDIUM | src/forge/proxy/handler.py | 443 | # No tools → plain chat completion, no guardrails needed. | COMMENT |
| MEDIUM | src/forge/proxy/handler.py | 474 | # Set up guardrails | COMMENT |
| MEDIUM | src/forge/proxy/handler.py | 498 | # error. The client's own agentic loop can decide what to do. | COMMENT |
| MEDIUM | src/forge/proxy/proxy.py | 346 | # guardrails wrap its inference loop like any other client. | COMMENT |
| MEDIUM | src/forge/proxy/proxy.py | 348 | # (forge-guardrails[anthropic]). Only Path 1 needs it, so | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/unit/test_eval_dataset_builder.py | 314 | CODE | |
| LOW | tests/unit/test_proxy_release.py | 69 | CODE | |
| LOW | tests/eval/metrics.py | 275 | CODE | |
| LOW | tests/eval/batch_eval.py | 639 | CODE | |
| LOW | tests/eval/batch_eval.py | 1065 | CODE | |
| LOW | tests/eval/dataset_builder.py | 684 | CODE | |
| LOW | tests/eval/dataset_builder.py | 746 | CODE | |
| LOW | tests/eval/significance.py | 106 | CODE | |
| LOW | tests/eval/publication.py | 465 | CODE | |
| LOW | tests/eval/eval_runner.py | 413 | CODE | |
| LOW | tests/eval/report.py | 278 | CODE | |
| LOW | tests/eval/report.py | 762 | CODE | |
| LOW | scripts/run_ablation.py | 102 | CODE | |
| LOW | scripts/migrate_eval_jsonl_gguf_identity.py | 100 | CODE | |
| LOW | scripts/standalone/release.py | 297 | CODE | |
| LOW | scripts/standalone/release.py | 401 | CODE | |
| LOW | scripts/standalone/evidence.py | 23 | CODE | |
| LOW | scripts/standalone/evidence.py | 29 | CODE | |
| LOW | src/forge/server.py | 1004 | CODE | |
| LOW | src/forge/clients/llamafile.py | 215 | CODE | |
| LOW | src/forge/clients/llamafile.py | 258 | CODE | |
| LOW | src/forge/clients/anthropic.py | 261 | CODE | |
| LOW | src/forge/clients/anthropic.py | 388 | CODE | |
| LOW | src/forge/clients/anthropic.py | 558 | CODE | |
| LOW | src/forge/clients/ollama.py | 37 | CODE | |
| LOW | src/forge/clients/ollama.py | 399 | CODE | |
| LOW | src/forge/clients/base.py | 218 | CODE | |
| LOW | src/forge/context/strategies.py | 248 | CODE | |
| LOW | src/forge/core/steps.py | 53 | CODE | |
| LOW | src/forge/core/runner.py | 89 | CODE | |
| LOW | src/forge/core/workflow.py | 68 | CODE | |
| LOW | src/forge/proxy/server.py | 320 | CODE | |
| LOW | src/forge/proxy/server.py | 530 | CODE | |
| LOW | src/forge/proxy/server.py | 792 | CODE | |
| LOW | src/forge/proxy/convert.py | 17 | CODE | |
| LOW | src/forge/proxy/convert_anthropic.py | 20 | CODE | |
| LOW | src/forge/proxy/_profiles.py | 60 | CODE | |
| LOW | src/forge/proxy/_installer.py | 815 | CODE | |
| LOW | src/forge/proxy/__main__.py | 152 | CODE | |
| LOW | src/forge/prompts/templates.py | 12 | CODE | |
| LOW | src/forge/prompts/templates.py | 55 | CODE | |
| LOW | src/forge/prompts/templates.py | 185 | CODE | |
| LOW | src/forge/prompts/templates.py | 238 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/eval/batch_eval.py | 961 | except Exception: | CODE |
| LOW⚡ | tests/eval/batch_eval.py | 971 | except Exception as exc: | CODE |
| LOW | tests/eval/dataset_builder.py | 709 | except Exception as exc: | STRING |
| LOW | tests/eval/dataset_builder.py | 950 | except Exception as exc: | STRING |
| LOW | tests/eval/dataset_builder.py | 989 | except Exception as exc: | CODE |
| MEDIUM | tests/eval/dataset_builder.py | 91 | def _require_pyarrow() -> tuple[Any, Any]: | CODE |
| LOW | tests/eval/eval_runner.py | 218 | except Exception as exc: | CODE |
| LOW | tests/eval/eval_runner.py | 223 | except Exception as exc: | CODE |
| LOW | tests/eval/eval_runner.py | 377 | except Exception as exc: | CODE |
| LOW | tests/eval/eval_runner.py | 674 | except Exception as exc: | CODE |
| LOW | docs/ARCHITECTURE.md | 27 | except Exception: | CODE |
| LOW | scripts/integration_test_proxy.py | 291 | except Exception as exc: | CODE |
| LOW | scripts/integration_test_proxy.py | 839 | except Exception as exc: | CODE |
| LOW | scripts/run_ablation.py | 170 | except Exception as e: | CODE |
| LOW | scripts/smoke_test_proxy.py | 161 | except Exception as exc: # make fixture bugs visible at the HTTP boundary | CODE |
| LOW | scripts/smoke_test_proxy.py | 318 | except Exception: | CODE |
| LOW | scripts/standalone/lifecycle_smoke.py | 263 | except Exception: | CODE |
| LOW | src/forge/server.py | 451 | except Exception as exc: | CODE |
| LOW | src/forge/server.py | 459 | except Exception as exc: | CODE |
| LOW | src/forge/server.py | 559 | except Exception: | CODE |
| LOW | src/forge/core/runner.py | 346 | except Exception as exc: | CODE |
| LOW | src/forge/core/slot_worker.py | 137 | except Exception as exc: | CODE |
| LOW | src/forge/proxy/server.py | 269 | except Exception: | CODE |
| LOW | src/forge/proxy/server.py | 314 | except Exception as exc: | CODE |
| LOW⚡ | src/forge/proxy/server.py | 390 | except Exception: | CODE |
| LOW⚡ | src/forge/proxy/server.py | 394 | except Exception: | CODE |
| LOW⚡ | src/forge/proxy/server.py | 400 | except Exception: | CODE |
| LOW | src/forge/proxy/server.py | 640 | except Exception: | CODE |
| LOW | src/forge/proxy/server.py | 789 | except Exception as exc: | CODE |
| LOW | src/forge/proxy/server.py | 882 | except Exception as exc: | CODE |
| LOW | src/forge/proxy/_installer.py | 896 | except Exception: | CODE |
| LOW | src/forge/proxy/__main__.py | 347 | except Exception as exc: | STRING |
| LOW | src/forge/proxy/__main__.py | 370 | except Exception as exc: | STRING |
| LOW | src/forge/proxy/__main__.py | 389 | except Exception as exc: | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/eval/dataset_builder.py | 696 | if not parquet_file.schema_arrow.equals(schema, check_metadata=True): | STRING |
| HIGH⚡ | src/forge/proxy/_installer.py | 760 | 'while kill -0 "$parent" 2>/dev/null; do sleep 0.1; done', | CODE |
| HIGH⚡ | src/forge/proxy/_installer.py | 763 | '[ "$(cat "$marker" 2>/dev/null)" = "$expected" ] || exit 2', | CODE |
| HIGH | src/forge/proxy/_installer.py | 788 | f"rmdir -- {q(str(paths.command_dir))} 2>/dev/null || true", | CODE |
| HIGH | src/forge/proxy/_installer.py | 789 | f"rmdir -- {q(str(paths.root))} 2>/dev/null || true", | CODE |
| HIGH | src/forge/prompts/nudges.py | 69 | args content (e.g. an empty string, null, a list, or a primitive | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 532 | # Step 1: patient MRN (not in user message) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 534 | # Step 3: lab values (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 536 | # Step 4: imaging findings (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 538 | # Step 5: specialist (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 540 | # Step 6: medication concern (only from tool result) | COMMENT |
| LOW | docs/decisions/003-thinking-label-ux.md | 64 | ### Step 1: Add `_resolve_reasoning()` to OllamaClient | COMMENT |
| LOW | docs/decisions/003-thinking-label-ux.md | 86 | ### Step 2: Use it in `send()` (batch path) | COMMENT |
| LOW | docs/decisions/003-thinking-label-ux.md | 102 | ### Step 3: Use it in `_iter_stream()` (streaming path) | COMMENT |
| LOW | docs/decisions/003-thinking-label-ux.md | 124 | ### Step 4: Add unit tests | COMMENT |
| LOW | docs/decisions/003-thinking-label-ux.md | 187 | ### Step 5: Update README roadmap | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 75 | ### Step 1: Change type signature | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 91 | ### Step 2: Await the callback in `_send_streaming()` | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 107 | ### Step 3: Update `_make_runner` helper type hint | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 127 | ### Step 4: Update the test | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 171 | ### Step 5: Update docstring | COMMENT |
| LOW | docs/decisions/004-async-on-chunk.md | 180 | ### Step 6: Update README roadmap | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/forge/server.py | 656 | Resolve the ContextManager budget for the given mode. Args: mode: The budget mode to use. | STRING |
| HIGH | src/forge/server.py | 711 | Start server with the specified budget mode and return the resolved budget. Handles the mode-specific startup d | STRING |
| HIGH | src/forge/clients/sampling_defaults.py | 254 | Apply the recommended-sampling policy for ``model``. Called by client constructors at instantiation time. The four- | STRING |
| HIGH | src/forge/core/inference.py | 200 | Send messages to the LLM with compaction, folding, validation, and retry. Retries are handled internally — the call | STRING |
| HIGH | src/forge/core/slot_worker.py | 65 | Submit a workflow for execution and wait for the result. Args: workflow: The workflow to execute. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/unit/test_argument_transformation.py | 68 | "Acme Corp", | CODE |
| LOW | tests/unit/test_argument_transformation.py | 87 | {"vendor_name": "Acme Corp"}, | CODE |
| LOW | tests/unit/test_argument_transformation.py | 237 | assert "Acme Corp" in system.get_approved_vendors() | CODE |
| LOW⚡ | tests/unit/test_inconsistent_api_recovery.py | 38 | assert "Acme Corp" in out | CODE |
| LOW⚡ | tests/unit/test_inconsistent_api_recovery.py | 261 | assert "Acme Corp" in out | CODE |
| LOW | tests/eval/scenarios/_base.py | 15 | placeholder_field: str = Field(description="placeholder") | CODE |
| LOW⚡ | tests/eval/scenarios/_base.py | 49 | spec=ToolSpec(name=terminal_tool, description="placeholder", | CODE |
| LOW⚡ | tests/eval/scenarios/_base.py | 56 | spec=ToolSpec(name=s, description="placeholder", | CODE |
| LOW⚡ | tests/eval/scenarios/_base.py | 64 | description="placeholder", | CODE |
| LOW | tests/eval/scenarios/_model_reasoning.py | 300 | # approved 'Acme Corp'. Literal string compare over-flags it; | COMMENT |
| LOW | tests/eval/scenarios/_model_reasoning.py | 313 | "Acme Corp", | CODE |
| LOW | tests/eval/scenarios/_model_reasoning.py | 326 | ("TX-1002", "2024-10-12", "Acme Corp", 12000, "USD", False), # approved | CODE |
| LOW | tests/eval/scenarios/_model_reasoning.py | 377 | if name == "Acme Corp": | CODE |
| LOW | tests/eval/scenarios/_model_reasoning.py | 621 | (12345, "Acme Corp"), | CODE |
| LOW⚡ | tests/eval/scenarios/_stateful_model_reasoning.py | 368 | "Acme Corp", | CODE |
| LOW⚡ | tests/eval/scenarios/_stateful_model_reasoning.py | 378 | ("TX-1002", "2024-10-12", "Acme Corp", 12000, "USD"), | CODE |
| LOW | tests/eval/scenarios/_stateful_model_reasoning.py | 441 | if name == "Acme Corp": | CODE |
| LOW | tests/eval/scenarios/_stateful_model_reasoning.py | 681 | (12345, "Acme Corp"), | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/forge/clients/vllm.py | 0 | per-call headers to apply, enforcing the one-credential rule. returns the dict to pass as httpx ``headers=`` (merged ove | STRING |
| HIGH | src/forge/clients/llamafile.py | 0 | per-call headers to apply, enforcing the one-credential rule. returns the dict to pass as httpx ``headers=`` (merged ove | STRING |
| HIGH | src/forge/clients/openai_compat.py | 0 | per-call headers to apply, enforcing the one-credential rule. returns the dict to pass as httpx ``headers=`` (merged ove | STRING |
| HIGH | src/forge/clients/ollama.py | 0 | per-call headers to apply, enforcing the one-credential rule. returns the dict to pass as httpx ``headers=`` (merged ove | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | install.sh | 1 | #!/bin/sh | COMMENT |
| LOW | tests/eval/report.py | 501 | # model under different identity strings: | COMMENT |
| LOW | tests/eval/scenarios/_model_reasoning.py | 61 | top_vendor: str = Field(description="Vendor of the single largest flagged transaction") | COMMENT |
| LOW | tests/eval/scenarios/_model_reasoning.py | 281 | tags=["advanced_reasoning", "reasoning", "model_quality"], | COMMENT |
| LOW | tests/eval/scenarios/_model_reasoning.py | 561 | COMMENT | |
| LOW | tests/eval/scenarios/_model_reasoning.py | 881 | "txn_count (int)." | COMMENT |
| LOW | tests/eval/scenarios/_model_reasoning.py | 901 | # Sarah Chen — top-decile attractor; BLOCKER: Stripe non-compete | COMMENT |
| LOW | examples/foreign_loop.py | 141 | # The respond tool eliminates this ambiguity: the model calls | COMMENT |
| LOW | src/forge/clients/sampling_defaults.py | 101 | "gemma4:e4b-it-q4_K_M": {"temperature": 1.0, "top_p": 0.95, "top_k": 64}, # https://huggingface.co/go | COMMENT |
| LOW | src/forge/clients/sampling_defaults.py | 121 | # supports low/high/max reasoning effort. This one registry value is the | COMMENT |
| LOW | src/forge/clients/sampling_defaults.py | 141 | # so the model emits something substantive instead of empty <think> blocks. Native tool format is | COMMENT |
| LOW | src/forge/clients/sampling_defaults.py | 181 | "ministral-3:8b-reasoning-2512-q8_0": {"temperature": 0.7}, # https://huggingface.co/mistralai/Ministral-3-8B-Re | COMMENT |
| LOW | src/forge/clients/sampling_defaults.py | 201 | "Mellum2-12B-A2.5B-Instruct-Q4_K_M": {"temperature": 0.6, "top_p": 0.95, "top_k": 20}, # https://huggingface.co/ | COMMENT |
| LOW | src/forge/clients/llamafile.py | 41 | # index is filesystem layout, not model identity, so strip it for the | COMMENT |
| LOW | src/forge/clients/llamafile.py | 61 | # The gate is STRUCTURAL, not phrase-based: a 500 is rescuable iff its body | COMMENT |
| LOW | src/forge/clients/anthropic.py | 41 | # lowercases all inbound header keys, so a relocated ``x-api-key`` would fail | COMMENT |
| LOW | src/forge/clients/anthropic.py | 121 | ) -> None: | COMMENT |
| LOW | src/forge/clients/anthropic.py | 141 | log.debug( | COMMENT |
| LOW | src/forge/guardrails/nudge.py | 41 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/unit/test_runner.py | 69 | CODE | |
| LOW | tests/unit/test_proxy_server.py | 143 | CODE | |
| LOW | tests/eval/batch_eval.py | 1065 | CODE | |
| LOW | src/forge/server.py | 1004 | CODE | |
| LOW | src/forge/server.py | 1106 | CODE | |
| LOW | src/forge/server.py | 236 | CODE | |
| LOW | src/forge/server.py | 695 | CODE | |
| LOW | src/forge/clients/vllm.py | 67 | CODE | |
| LOW | src/forge/clients/llamafile.py | 332 | CODE | |
| LOW | src/forge/clients/openai_compat.py | 61 | CODE | |
| LOW | src/forge/clients/anthropic.py | 108 | CODE | |
| LOW | src/forge/clients/ollama.py | 106 | CODE | |
| LOW | src/forge/core/runner.py | 35 | CODE | |
| LOW | src/forge/core/inference.py | 179 | CODE | |
| LOW | src/forge/proxy/server.py | 180 | CODE | |
| LOW | src/forge/proxy/handler.py | 256 | CODE | |
| LOW | src/forge/proxy/proxy.py | 62 | CODE | |
| LOW | src/forge/proxy/_installer.py | 924 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/eval/scenarios/__init__.py | 81 | __all__ = [ | CODE |
| LOW | scripts/integration_test_proxy.py | 98 | def _setup_logging() -> None: | CODE |
| LOW | src/forge/server.py | 221 | def _set_resolved_daemon_target(self, target: ResolvedBackend) -> None: | CODE |
| LOW | src/forge/__init__.py | 78 | __all__ = [ | CODE |
| LOW | src/forge/clients/vllm.py | 173 | def _set_model_identity(self, wire_id: str | Path) -> None: | CODE |
| LOW | src/forge/clients/__init__.py | 14 | __all__ = [ | CODE |
| LOW | src/forge/clients/ollama.py | 462 | def set_num_ctx(self, num_ctx: int | None) -> None: | CODE |
| LOW | src/forge/tools/__init__.py | 9 | __all__ = [ | CODE |
| LOW | src/forge/context/__init__.py | 20 | __all__ = [ | CODE |
| LOW | src/forge/context/hardware.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW | src/forge/context/manager.py | 131 | def update_token_count(self, total_tokens: int) -> None: | CODE |
| LOW | src/forge/core/__init__.py | 3 | __all__ = ["WorkflowRunner"] | CODE |
| LOW | src/forge/guardrails/__init__.py | 19 | __all__ = [ | CODE |
| LOW | src/forge/proxy/__init__.py | 5 | __all__ = ["ProxyServer"] | CODE |
| LOW | src/forge/prompts/__init__.py | 6 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 532 | # Step 1: patient MRN (not in user message) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 534 | # Step 3: lab values (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 536 | # Step 4: imaging findings (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 538 | # Step 5: specialist (only from tool result) | COMMENT |
| LOW⚡ | tests/eval/scenarios/_compaction_chain.py | 540 | # Step 6: medication concern (only from tool result) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/unit/test_proxy_auth.py | 45 | # The proxy lowercases keys, but be robust to mixed case anyway. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/foreign_loop.py | 175 | # Check if the model called respond -- extract the message | COMMENT |