argus-code-review 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/.gitignore +1 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/CHANGELOG.md +31 -1
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/PKG-INFO +3 -1
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/README.md +2 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/config.py +5 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/gemini_runner.py +15 -1
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/llm/models.py +6 -1
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-llm-patterns.md +1 -1
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_config.py +16 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_gemini_runner.py +119 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_llm_models.py +15 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/LICENSE +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/bench.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/bench_default.toml +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/cli.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/coverage.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/dotenv_utils.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/gemini_cache.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/github_client.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/graph.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/helpers.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/llm/output_models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/llm/pricing.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/openai_client.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/openai_runner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/pipeline_models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/actions_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/engine.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/.gitignore +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/README.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/eslint.config.js +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/package-lock.json +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/package.json +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/js_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/migration_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/rules/README.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/sarif.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/scanner_utils.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/secrets_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/shadow.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/terraform_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/workflow_lint_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-blocking-validator.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-coverage-check.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-cross-cutting.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-feedback-verifier.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-lite.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-planner.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-preflight-router.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-prior-art.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-deployment.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-frontend.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-infra.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-observability.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-orchestration.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-security.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-slackbot.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-sql.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-subagent.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-tests-and-docs.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-writer.md +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts_runtime.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/repo_provision.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/review_tools.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/runners.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/http.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/precheck.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/resolver.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/session.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/sql.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/storage/sqlite.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/pyproject.toml +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/008_add_code_reviews.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/009_add_reviewer_version.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/010_add_review_patterns.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/011_add_review_progress_columns.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/015_create_agent_runs.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/016_add_agent_runs_failure_reason.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/017_add_precheck_rules.sql +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/conftest.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/golden/review_response.schema.json +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/__init__.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_backend_contract.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_http.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_resolver.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_session.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_sql.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/storage/test_sqlite_backend.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_actions_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_argus_review_local.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_bench.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_catchup_gate.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_cli_args.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_cli_output_contract.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_cli_post_review.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_cli_preflight.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_cli_prompts.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_conftest.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_gemini_cache.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_github_client_checks_signal.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_github_client_write.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_fetch_diff.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_get_llm_temperature.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_http_guards.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_precheck.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_preflight_image_bump.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_progress.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_storage_resolution.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_timeout_surfacing.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_js_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_lite_review_cost.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_llm_models_override.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_llm_pricing.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_migration_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_models.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_multi_round.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_openai_client.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_openai_runner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_packaging.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_plan_review.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_engine.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_engine_integration.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_sarif.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_shadow.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_shadow_integration.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_prompts.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_repo_provision.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_review_patterns_integration.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_review_tools.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_runners_context7.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_runners_context_usage.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_runners_helpers.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_runners_new.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_scanner_utils.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_secrets_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_specialist_validation.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_storage_precheck.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_terraform_scanner.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_terraform_scanner_integration.py +0 -0
- {argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_workflow_lint_scanner.py +0 -0
|
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2026-09-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `docs/BENCH.md`, documenting the reviewer bench's config-driven platform,
|
|
15
|
+
model, and caching selection for leaf-reviewer roles, including the override
|
|
16
|
+
chain, valid values, platform credentials, and a worked Gemini configuration.
|
|
17
|
+
README and `docs/BUILDING_A_REVIEW_LOOP.md` now point to the new guide.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Updated the `gemini-mini` alias from the superseded `gemini-3-flash-preview`
|
|
22
|
+
model to the stable `gemini-3.8-flash` release. The approved-model policy
|
|
23
|
+
table's Google default now matches, and a regression test pins the alias to
|
|
24
|
+
the approved value.
|
|
25
|
+
|
|
26
|
+
## [0.2.1] - 2026-09-10
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `GOOGLE_BASE_URL` proxy support for the Gemini runner (`argus/gemini_runner.py`),
|
|
31
|
+
mirroring `OPENAI_BASE_URL`: closes a gap where the Gemini platform could only
|
|
32
|
+
be used with a raw, unproxied `GOOGLE_API_KEY` talking directly to
|
|
33
|
+
`generativelanguage.googleapis.com`, unlike the OpenAI (`OPENAI_BASE_URL`) and
|
|
34
|
+
Claude (`ANTHROPIC_BASE_URL`) paths that the `argus-review-loop` skill relies
|
|
35
|
+
on to route through a short-lived, PR-scoped credential proxy instead of a
|
|
36
|
+
standing API key.
|
|
37
|
+
|
|
10
38
|
## [0.2.0] - 2026-09-10
|
|
11
39
|
|
|
12
40
|
### Added
|
|
@@ -175,7 +203,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
175
203
|
packaged set.
|
|
176
204
|
- `argus --version`, `argus prompts list`, and `argus prompts export`.
|
|
177
205
|
|
|
178
|
-
[Unreleased]: https://github.com/redesignhealth/argus-review/compare/v0.2.
|
|
206
|
+
[Unreleased]: https://github.com/redesignhealth/argus-review/compare/v0.2.2...HEAD
|
|
207
|
+
[0.2.2]: https://github.com/redesignhealth/argus-review/compare/v0.2.1...v0.2.2
|
|
208
|
+
[0.2.1]: https://github.com/redesignhealth/argus-review/compare/v0.2.0...v0.2.1
|
|
179
209
|
[0.2.0]: https://github.com/redesignhealth/argus-review/compare/v0.1.5...v0.2.0
|
|
180
210
|
[0.1.5]: https://github.com/redesignhealth/argus-review/compare/v0.1.4...v0.1.5
|
|
181
211
|
[0.1.4]: https://github.com/redesignhealth/argus-review/compare/v0.1.3...v0.1.4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: argus-code-review
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Self-orchestrated PR review agent using LangGraph + Claude Agent SDK
|
|
5
5
|
Project-URL: Repository, https://github.com/redesignhealth/argus-review
|
|
6
6
|
Project-URL: Issues, https://github.com/redesignhealth/argus-review/issues
|
|
@@ -437,6 +437,8 @@ see the [write-up](https://www.redesignhealth.com/content/agentic-code-review-ha
|
|
|
437
437
|
contract for self-hosters.
|
|
438
438
|
- [`docs/BUILDING_A_REVIEW_LOOP.md`](docs/BUILDING_A_REVIEW_LOOP.md) — how to
|
|
439
439
|
wrap Argus in a review → fix → re-review automation loop gated on CI.
|
|
440
|
+
- [`docs/BENCH.md`](docs/BENCH.md) — configure the static reviewer bench to
|
|
441
|
+
choose platforms and models for leaf reviewers.
|
|
440
442
|
- [`docs/PRECHECKS.md`](docs/PRECHECKS.md) — the deterministic, non-LLM gate
|
|
441
443
|
that runs before the LLM pipeline: CI-status routing signal and custom
|
|
442
444
|
semgrep rules mined from Argus's own recurring findings.
|
|
@@ -385,6 +385,8 @@ see the [write-up](https://www.redesignhealth.com/content/agentic-code-review-ha
|
|
|
385
385
|
contract for self-hosters.
|
|
386
386
|
- [`docs/BUILDING_A_REVIEW_LOOP.md`](docs/BUILDING_A_REVIEW_LOOP.md) — how to
|
|
387
387
|
wrap Argus in a review → fix → re-review automation loop gated on CI.
|
|
388
|
+
- [`docs/BENCH.md`](docs/BENCH.md) — configure the static reviewer bench to
|
|
389
|
+
choose platforms and models for leaf reviewers.
|
|
388
390
|
- [`docs/PRECHECKS.md`](docs/PRECHECKS.md) — the deterministic, non-LLM gate
|
|
389
391
|
that runs before the LLM pipeline: CI-status routing signal and custom
|
|
390
392
|
semgrep rules mined from Argus's own recurring findings.
|
|
@@ -135,6 +135,10 @@ class Settings(BaseSettings):
|
|
|
135
135
|
``platform = "gemini"``. Only required if you actually
|
|
136
136
|
opt a role into that platform (see ``argus.bench``'s
|
|
137
137
|
override chain) -- the packaged default bench never does.
|
|
138
|
+
GOOGLE_BASE_URL: Optional override for the Gemini API endpoint (e.g. for
|
|
139
|
+
proxying). Mirrors ``OPENAI_BASE_URL`` above. Note that GOOGLE_API_KEY
|
|
140
|
+
will be forwarded to whatever endpoint is configured here; point only
|
|
141
|
+
at trusted proxy hosts.
|
|
138
142
|
ARGUS_BENCH_FILE: Highest-priority bench-config override file. See
|
|
139
143
|
``argus.bench`` for the full override search chain.
|
|
140
144
|
ARGUS_NO_BENCH_OVERRIDES: Set truthy to ignore every bench override
|
|
@@ -154,6 +158,7 @@ class Settings(BaseSettings):
|
|
|
154
158
|
OPENAI_API_KEY: str
|
|
155
159
|
OPENAI_BASE_URL: str | None = None
|
|
156
160
|
GOOGLE_API_KEY: str | None = None
|
|
161
|
+
GOOGLE_BASE_URL: str | None = None
|
|
157
162
|
|
|
158
163
|
ARGUS_DB_URL: str | None = None
|
|
159
164
|
SUPABASE_DB_URL: str | None = None
|
|
@@ -607,7 +607,21 @@ async def _run_turns(
|
|
|
607
607
|
# clause catches and translates into a clean `failure_reason="timeout"` result
|
|
608
608
|
# -- rather than racing the outer deadline so closely that the raw
|
|
609
609
|
# httpx exception could escape uncaught instead.
|
|
610
|
-
|
|
610
|
+
#
|
|
611
|
+
# `base_url` is only set when truthy; `None` safely defaults to the
|
|
612
|
+
# standard Gemini endpoint (`generativelanguage.googleapis.com`) --
|
|
613
|
+
# mirrors `OPENAI_BASE_URL`'s exact same optional-proxy pattern in
|
|
614
|
+
# `argus.openai_runner`/`argus.openai_client`. This same `http_options`
|
|
615
|
+
# instance is reused as-is by `_maybe_activate_cache`'s own
|
|
616
|
+
# short-lived `genai.Client` (see that function's docstring for why it
|
|
617
|
+
# needs a separate client instance), so threading `base_url` through
|
|
618
|
+
# here covers both `genai.Client(...)` construction sites in this
|
|
619
|
+
# module without a second read of `settings.GOOGLE_BASE_URL`.
|
|
620
|
+
base_url = getattr(settings, "GOOGLE_BASE_URL", None)
|
|
621
|
+
http_options = types.HttpOptions(
|
|
622
|
+
timeout=int(timeout_s * _HTTP_TIMEOUT_FRACTION * 1000),
|
|
623
|
+
base_url=base_url if isinstance(base_url, str) and base_url else None,
|
|
624
|
+
)
|
|
611
625
|
client = genai.Client(api_key=api_key, http_options=http_options)
|
|
612
626
|
logger.info(
|
|
613
627
|
"Gemini session started: %s model=%s caching=%s timeout=%ss",
|
|
@@ -105,7 +105,12 @@ ALIAS_MAP: Final[dict[str, str]] = {
|
|
|
105
105
|
# TODO: upgrade to stable gemini-3.1-pro (non-preview) when GA;
|
|
106
106
|
# re-eval by 2026-11-01.
|
|
107
107
|
"gemini-frontier": "gemini-3.1-pro-preview",
|
|
108
|
-
|
|
108
|
+
# gemini-3-flash-preview has been superseded by gemini-3.8-flash, the
|
|
109
|
+
# stable (non-preview) release -- same reasoning as gemini-frontier's
|
|
110
|
+
# move off a deprecated preview above: prefer the stable successor over
|
|
111
|
+
# a preview model once one exists. test_llm_models.py pins this exact
|
|
112
|
+
# value as a regression guard.
|
|
113
|
+
"gemini-mini": "gemini-3.8-flash",
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
# Short-lived pins for evals / preview models. Anything in here is a known
|
|
@@ -9,7 +9,7 @@ Only approved model families. Check model strings in code against this table:
|
|
|
9
9
|
|----------|----------|---------|
|
|
10
10
|
| Anthropic | claude-opus-4, claude-sonnet-4, claude-haiku-4 (use `CLAUDE_MINI`), claude-fable-5 (use `CLAUDE_FRONTIER`), claude-opus-5 (use `CLAUDE_OPUS`), claude-sonnet-4-6 (use `CLAUDE_DEFAULT`) families; claude-sonnet-5 (the previous `CLAUDE_DEFAULT` pin) remains valid as an explicit `ARGUS_SPECIALIST_MODEL`/`--specialist-model` override value, not as a new hardcoded default | claude-sonnet-4-6 |
|
|
11
11
|
| OpenAI | gpt-5.4 family (gpt-5.4, gpt-5.4-mini) and gpt-5.6 family | gpt-5.6-luna |
|
|
12
|
-
| Google | gemini-3 family | gemini-3-flash |
|
|
12
|
+
| Google | gemini-3 family | gemini-3.8-flash |
|
|
13
13
|
|
|
14
14
|
Flag any use of: o3, o1, gpt-4 family, gpt-5-mini, claude-3/3.5 family, gemini-1.5/2.5 family.
|
|
15
15
|
|
|
@@ -149,6 +149,7 @@ def test_optional_fields_default_to_none(monkeypatch: pytest.MonkeyPatch) -> Non
|
|
|
149
149
|
"ARGUS_CONTEXT7_LIBRARY_ID",
|
|
150
150
|
"ARGUS_CONTEXT7_BASE_URL",
|
|
151
151
|
"GOOGLE_API_KEY",
|
|
152
|
+
"GOOGLE_BASE_URL",
|
|
152
153
|
"ARGUS_BENCH_FILE",
|
|
153
154
|
"ARGUS_GEMINI_CACHE_DIR",
|
|
154
155
|
):
|
|
@@ -160,6 +161,7 @@ def test_optional_fields_default_to_none(monkeypatch: pytest.MonkeyPatch) -> Non
|
|
|
160
161
|
assert settings.ARGUS_CONTEXT7_BASE_URL is None
|
|
161
162
|
assert settings.ARGUS_PROMPTS_DIR is None
|
|
162
163
|
assert settings.GOOGLE_API_KEY is None
|
|
164
|
+
assert settings.GOOGLE_BASE_URL is None
|
|
163
165
|
assert settings.ARGUS_BENCH_FILE is None
|
|
164
166
|
assert settings.ARGUS_GEMINI_CACHE_DIR is None
|
|
165
167
|
|
|
@@ -252,3 +254,17 @@ def test_openai_base_url_override(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
252
254
|
monkeypatch.setenv("OPENAI_BASE_URL", "https://proxy.example.com/v1")
|
|
253
255
|
settings = get_settings()
|
|
254
256
|
assert settings.OPENAI_BASE_URL == "https://proxy.example.com/v1"
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def test_google_base_url_defaults_to_none(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
260
|
+
_set_required(monkeypatch)
|
|
261
|
+
monkeypatch.delenv("GOOGLE_BASE_URL", raising=False)
|
|
262
|
+
settings = get_settings()
|
|
263
|
+
assert settings.GOOGLE_BASE_URL is None
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_google_base_url_override(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
267
|
+
_set_required(monkeypatch)
|
|
268
|
+
monkeypatch.setenv("GOOGLE_BASE_URL", "https://proxy.example.com/v1beta")
|
|
269
|
+
settings = get_settings()
|
|
270
|
+
assert settings.GOOGLE_BASE_URL == "https://proxy.example.com/v1beta"
|
|
@@ -1395,3 +1395,122 @@ class TestGeminiRedactionHooks:
|
|
|
1395
1395
|
inputs = {"label": "test"}
|
|
1396
1396
|
redacted = _redact_gemini_inputs(inputs)
|
|
1397
1397
|
assert redacted == {"label": "test"}
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
# ---------------------------------------------------------------------------
|
|
1401
|
+
# GOOGLE_BASE_URL threading (mirrors OPENAI_BASE_URL in
|
|
1402
|
+
# tests/test_openai_runner.py / tests/test_openai_client.py): a proxy base
|
|
1403
|
+
# URL configured via settings must reach the underlying `genai.Client`'s
|
|
1404
|
+
# `http_options.base_url`, at every `genai.Client(...)` construction site in
|
|
1405
|
+
# this module -- the session's own client (`_run_turns`) AND the dedicated,
|
|
1406
|
+
# short-lived client `_maybe_activate_cache`'s `_create_fn` builds for
|
|
1407
|
+
# `caches.create()`.
|
|
1408
|
+
# ---------------------------------------------------------------------------
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
class TestGoogleBaseUrlOverride:
|
|
1412
|
+
async def test_settings_google_base_url_reaches_session_client_http_options(self) -> None:
|
|
1413
|
+
"""GOOGLE_BASE_URL on settings is threaded through to the session's
|
|
1414
|
+
own `genai.Client`'s `http_options.base_url`."""
|
|
1415
|
+
entry = _make_entry(caching="off")
|
|
1416
|
+
settings = _make_settings()
|
|
1417
|
+
settings.GOOGLE_BASE_URL = "https://proxy.example.com/v1beta"
|
|
1418
|
+
response = _make_response(calls=[("finish_review", {"files_explored": []})])
|
|
1419
|
+
fake_client = _make_fake_client([response])
|
|
1420
|
+
|
|
1421
|
+
with patch("argus.gemini_runner.genai.Client", return_value=fake_client) as mock_ctor:
|
|
1422
|
+
result = await run_session_gemini(
|
|
1423
|
+
entry=entry,
|
|
1424
|
+
system_prompt="sys",
|
|
1425
|
+
user_message="msg",
|
|
1426
|
+
settings=settings,
|
|
1427
|
+
repo_root="/tmp/does-not-need-to-exist",
|
|
1428
|
+
)
|
|
1429
|
+
|
|
1430
|
+
assert result.failure_reason is None
|
|
1431
|
+
mock_ctor.assert_called_once()
|
|
1432
|
+
http_options = mock_ctor.call_args.kwargs["http_options"]
|
|
1433
|
+
assert http_options.base_url == "https://proxy.example.com/v1beta"
|
|
1434
|
+
|
|
1435
|
+
async def test_no_google_base_url_defaults_to_sdk_default(self) -> None:
|
|
1436
|
+
"""Without an override, `http_options.base_url` stays `None` -- the
|
|
1437
|
+
SDK's own default (`generativelanguage.googleapis.com`) applies,
|
|
1438
|
+
exactly like the OPENAI_BASE_URL/AsyncOpenAI pattern this mirrors."""
|
|
1439
|
+
entry = _make_entry(caching="off")
|
|
1440
|
+
settings = _make_settings() # GOOGLE_BASE_URL never set on this MagicMock
|
|
1441
|
+
response = _make_response(calls=[("finish_review", {"files_explored": []})])
|
|
1442
|
+
fake_client = _make_fake_client([response])
|
|
1443
|
+
|
|
1444
|
+
with patch("argus.gemini_runner.genai.Client", return_value=fake_client) as mock_ctor:
|
|
1445
|
+
result = await run_session_gemini(
|
|
1446
|
+
entry=entry,
|
|
1447
|
+
system_prompt="sys",
|
|
1448
|
+
user_message="msg",
|
|
1449
|
+
settings=settings,
|
|
1450
|
+
repo_root="/tmp/does-not-need-to-exist",
|
|
1451
|
+
)
|
|
1452
|
+
|
|
1453
|
+
assert result.failure_reason is None
|
|
1454
|
+
http_options = mock_ctor.call_args.kwargs["http_options"]
|
|
1455
|
+
assert http_options.base_url is None
|
|
1456
|
+
|
|
1457
|
+
async def test_google_base_url_composes_with_existing_timeout(self) -> None:
|
|
1458
|
+
"""A `base_url` override must compose with the existing `timeout=`
|
|
1459
|
+
`HttpOptions` field -- both set together on the same instance --
|
|
1460
|
+
rather than one replacing the other."""
|
|
1461
|
+
from argus.gemini_runner import _HTTP_TIMEOUT_FRACTION
|
|
1462
|
+
|
|
1463
|
+
entry = _make_entry(caching="off")
|
|
1464
|
+
settings = _make_settings(session_timeout=300)
|
|
1465
|
+
settings.GOOGLE_BASE_URL = "https://proxy.example.com/v1beta"
|
|
1466
|
+
response = _make_response(calls=[("finish_review", {"files_explored": []})])
|
|
1467
|
+
fake_client = _make_fake_client([response])
|
|
1468
|
+
|
|
1469
|
+
with patch("argus.gemini_runner.genai.Client", return_value=fake_client) as mock_ctor:
|
|
1470
|
+
result = await run_session_gemini(
|
|
1471
|
+
entry=entry,
|
|
1472
|
+
system_prompt="sys",
|
|
1473
|
+
user_message="msg",
|
|
1474
|
+
settings=settings,
|
|
1475
|
+
repo_root="/tmp/does-not-need-to-exist",
|
|
1476
|
+
timeout_s=10.0,
|
|
1477
|
+
)
|
|
1478
|
+
|
|
1479
|
+
assert result.failure_reason is None
|
|
1480
|
+
http_options = mock_ctor.call_args.kwargs["http_options"]
|
|
1481
|
+
assert http_options.base_url == "https://proxy.example.com/v1beta"
|
|
1482
|
+
assert http_options.timeout == int(10.0 * _HTTP_TIMEOUT_FRACTION * 1000)
|
|
1483
|
+
|
|
1484
|
+
async def test_google_base_url_also_reaches_the_cache_creation_client(self) -> None:
|
|
1485
|
+
"""`_maybe_activate_cache`'s `_create_fn` builds its own, separate
|
|
1486
|
+
`genai.Client` for `caches.create()` (see that function's docstring)
|
|
1487
|
+
-- it must carry the same `base_url` override as the session's own
|
|
1488
|
+
client, not silently fall back to the real API host."""
|
|
1489
|
+
entry = _make_entry(caching="on")
|
|
1490
|
+
settings = _make_settings()
|
|
1491
|
+
settings.GOOGLE_BASE_URL = "https://proxy.example.com/v1beta"
|
|
1492
|
+
response = _make_response(calls=[("finish_review", {"files_explored": []})])
|
|
1493
|
+
fake_client = _make_fake_client([response], cache_name="cachedContents/abc123")
|
|
1494
|
+
|
|
1495
|
+
constructed_http_options: list[types.HttpOptions] = []
|
|
1496
|
+
|
|
1497
|
+
def _new_client(*args: Any, **kwargs: Any) -> MagicMock:
|
|
1498
|
+
constructed_http_options.append(kwargs["http_options"])
|
|
1499
|
+
return fake_client
|
|
1500
|
+
|
|
1501
|
+
with patch("argus.gemini_runner.genai.Client", side_effect=_new_client):
|
|
1502
|
+
result = await run_session_gemini(
|
|
1503
|
+
entry=entry,
|
|
1504
|
+
system_prompt="sys",
|
|
1505
|
+
user_message="msg",
|
|
1506
|
+
settings=settings,
|
|
1507
|
+
repo_root="/tmp/does-not-need-to-exist",
|
|
1508
|
+
)
|
|
1509
|
+
|
|
1510
|
+
assert result.failure_reason is None
|
|
1511
|
+
# Two `genai.Client` constructions: the session's own, and the
|
|
1512
|
+
# dedicated cache-creation client -- both must carry the override.
|
|
1513
|
+
assert len(constructed_http_options) == 2
|
|
1514
|
+
assert all(
|
|
1515
|
+
ho.base_url == "https://proxy.example.com/v1beta" for ho in constructed_http_options
|
|
1516
|
+
)
|
|
@@ -14,6 +14,7 @@ from argus.llm.models import (
|
|
|
14
14
|
CLAUDE_DEFAULT,
|
|
15
15
|
EXPERIMENTAL_MODELS,
|
|
16
16
|
GEMINI_FRONTIER,
|
|
17
|
+
GEMINI_MINI,
|
|
17
18
|
GPT_FRONTIER,
|
|
18
19
|
GPT_MINI,
|
|
19
20
|
estimate_cost_usd,
|
|
@@ -163,6 +164,20 @@ class TestEstimateCostUsd:
|
|
|
163
164
|
cost = estimate_cost_usd(GPT_MINI, input_tokens=1000, output_tokens=500)
|
|
164
165
|
assert cost > 0.0
|
|
165
166
|
|
|
167
|
+
def test_gemini_mini_pinned_to_approved_model(self) -> None:
|
|
168
|
+
"""Regression guard for gemini-mini, alongside gpt-frontier and
|
|
169
|
+
gpt-mini's guards above: gemini-3-flash-preview has been superseded by
|
|
170
|
+
gemini-3.8-flash, the stable (non-preview) release on the approved model
|
|
171
|
+
list (see pr-review-specialist-llm-patterns.md). Pin the alias to that
|
|
172
|
+
approved value so an accidental regression to a preview model or
|
|
173
|
+
unapproved string is caught here instead of at review time.
|
|
174
|
+
|
|
175
|
+
Also exercises estimate_cost_usd(GEMINI_MINI, ...) directly."""
|
|
176
|
+
assert ALIAS_MAP["gemini-mini"] == "gemini-3.8-flash"
|
|
177
|
+
assert GEMINI_MINI == "gemini-3.8-flash"
|
|
178
|
+
cost = estimate_cost_usd(GEMINI_MINI, input_tokens=1000, output_tokens=500)
|
|
179
|
+
assert cost > 0.0
|
|
180
|
+
|
|
166
181
|
|
|
167
182
|
class TestResolveOverrides:
|
|
168
183
|
def test_resolve_claude_default_honors_env_override(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/eslint.config.js
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/package-lock.json
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/precheck/eslint_bundle/package.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-blocking-validator.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-coverage-check.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-cross-cutting.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-feedback-verifier.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-preflight-router.md
RENAMED
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-deployment.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-frontend.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-infra.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-security.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-slackbot.md
RENAMED
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-specialist-sql.md
RENAMED
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/argus/prompts/pr-review-tests-and-docs.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/011_add_review_progress_columns.sql
RENAMED
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/schema/016_add_agent_runs_failure_reason.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/golden/review_response.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_github_client_checks_signal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_graph_preflight_image_bump.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_engine_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_precheck_shadow_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_review_patterns_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{argus_code_review-0.2.0 → argus_code_review-0.2.2}/tests/test_terraform_scanner_integration.py
RENAMED
|
File without changes
|
|
File without changes
|