Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ dependencies = [
"anthropic>=0.69.0",
"atlassian-python-api==3.41.4",
"azure-devops==7.1.0b4",
"azure-identity==1.25.0",
"boto3==1.43.78",
"azure-identity==1.26.0",
"boto3==1.43.114",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: The boto3 pin moves, and botocore rides along from 1.43.83 to 1.43.114 — 31 patch releases, each one free to rearrange the furniture. Meanwhile pr_agent/algo/ai_handlers/litellm_ai_handler.py does not use boto3 like a normal person: it reaches into session._session (line 993), then rewrites ContainerProvider._environ (line 999), reads AssumeRoleWithWebIdentityProvider._disable_env_vars and ._CONFIG_TO_ENV_VAR (lines 1000-1003), and monkeypatches provider._get_env_config (line 1009). That is four private attributes and one private method, surgically edited, in a library nobody promised to keep stable. The comment on line 996 even admits it — 'already disable environment selection in botocore 1.43.x' — so you already know you are version-coupled; you are just not reading the fine print of 31 more patch releases.

🩹 The Fix: Re-verify those five names against botocore 1.43.114, and fail loudly when they are missing instead of silently falling through to ambient credentials. The unit tests mock boto3/botocore wholesale, so nothing in CI would catch a rename — add one test that runs _bind_aws_workload_token_sources against a real boto3.Session, or pin botocore explicitly next to boto3 so the pair cannot drift apart again.

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"certifi>=2026.7.22",
"dynaconf>=3.3.5,<4",
"fastapi>=0.141.1,<1",
Expand All @@ -57,22 +57,22 @@ dependencies = [
"PyGithub>=2.10,<3",
"PyJWT>=2.13.0,<3",
"PyYAML==6.0.1",
"python-gitlab==8.3.0",
"python-gitlab==8.6.0",
"retry==0.9.2",
"starlette-context==0.3.6",
"starlette-context==0.5.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: Two minor versions of a 0.x library — semver's way of saying 'everything you loved is now a historical footnote.' This is not some peripheral utility: starlette_context owns the request-scoped settings isolation that config_loader.get_settings() reads and that ~20 modules mutate. And the plot twist: pr_agent/servers/github_polling.py:134 already documents 0.5.1's 'bare yield skips the ContextVar reset' bug, so this code was written against 0.5.x semantics while the pin insisted on 0.3.6. This PR finally makes the pin match the code — by flipping the runtime behavior of the context under every webhook, every CLI run and every polling iteration. That reset is the one thing standing between two requests and a cross-request settings leak, and it is being changed in a Dependabot PR with a shrug.

🩹 The Fix: Before merge, run the isolation suites that actually exercise it: PYTHONPATH=. uv run pytest tests/unittest/test_mosaico_isolation.py tests/unittest/test_per_directory_settings.py tests/unittest/test_apply_repo_settings.py tests/unittest/test_extra_config_url.py -q, and confirm starlette_context.errors.ContextDoesNotExistError and starlette_context.middleware.RawContextMiddleware still exist in 0.5.1 (both are imported by first-party code). If the reset semantics moved, re-check the manual __enter__/__exit__ drivers in pr_agent/cli.py and pr_agent/servers/github_polling.py.

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"tiktoken==0.14.0",
"ujson>=5.13.0,<6",
"unidiff==0.7.5",
"uvicorn>=0.31.1,<1",
"tenacity==8.2.3",
"a2a-sdk[http-server]==1.0.3",
"a2a-sdk[http-server]==1.2.2",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: The MOSAICO executor imports resolve_user_scope from a2a.server.tasks.inmemory_task_store (pr_agent/mosaico/executor.py:30) — an internal implementation module of a pre-2.0 SDK — and get_message_text from a2a.helpers.proto_helpers (line 26). Internals in 1.x move when someone renames a folder, not when they file a deprecation notice. Since these are module-level imports, the failure mode is not graceful degradation; it is the entire A2A server failing to import, and mosaico/server.py is a separate app from the webhook, so your smoke test may never notice. Meanwhile the executor tests monkeypatch TaskUpdater with a spy, so they never touch the real signature — the only test that does is test_mosaico_a2a_roundtrip.py.

🩹 The Fix: Run PYTHONPATH=. uv run pytest tests/unittest/test_mosaico_a2a_roundtrip.py tests/unittest/test_mosaico_executor.py -q against 1.2.2 and confirm a2a.server.tasks.inmemory_task_store.resolve_user_scope, a2a.helpers.proto_helpers.get_message_text and TaskUpdater(event_queue, task_id, context_id) still exist. If the internals moved, switch to the public a2a.server.tasks export or vendor the scope resolution locally.

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"langfuse==3.14.5",
"gunicorn==23.0.0",
"pydantic==2.13.3",
"pydantic==2.14.1",
# litellm 1.102.1 declares pydantic-settings as a base dependency and imports it unconditionally from
# litellm/integrations/otel/model/config.py. Keep the exact pin to lock the resolved transitive version.
# Version matches litellm's own constraint (>=2.14.1,<3.0); the existing observability guard covers the callback import.
"pydantic-settings==2.14.2",
"pydantic-settings==2.16.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: The comment right above this line (72-74) is a tiny essay about why this pin exists: litellm imports pydantic-settings unconditionally, so the pin 'locks the resolved transitive version', and 'Version matches litellm's own constraint (>=2.14.1,<3.0)'. Dependabot dutifully bumped 2.14.2 → 2.16.0 and left the essay untouched. But 2.16.0 is no longer 'the resolved transitive version' of litellm 1.102.1 — it is now a deliberate pin that merely satisfies litellm's range, so the sentence that justified it now describes a different relationship than the one that exists. And the guard it leans on (the 'existing observability guard') only asserts that pydantic_settings imports — tests/unittest/test_mosaico_observability_deps.py:59 — it never checks a single field or config behaviour.

🩹 The Fix: Update the comment to state the new rationale (and whether 2.16.0 was picked deliberately over what litellm would resolve on its own), and confirm litellm 1.102.1's declared range still admits it. If the intent is to track litellm's resolution, pin that version instead of letting Dependabot pick a different one.

📏 Severity: nitpick


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"html2text==2024.2.26",
"giteapy==1.0.8",
# pr_agent/telemetry imports these directly; already resolved transitively via
Expand All @@ -82,7 +82,7 @@ dependencies = [
"opentelemetry-exporter-otlp-proto-http==1.43.0",
# Prometheus scrape endpoint for [otel] command telemetry (native /metrics on
# the webhook apps). Multiprocess-capable; see pr_agent/telemetry/prometheus.py.
"prometheus-client==0.21.1",
"prometheus-client==0.26.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: 0.21 → 0.26 in one PR: five minors of a library that ships 0.x for a reason. And your scrape endpoint reaches into the medicine cabinet — pr_agent/telemetry/prometheus.py:92 reads prometheus_values.ValueClass._multiprocess, a private attribute of a private module, to decide whether /metrics serves the whole cluster or one sad little worker. If 0.26 renamed that attribute you do not get an exception; you get a scrape that looks perfectly healthy while quietly reporting one worker's numbers forever. The other landmine is the on-disk multiprocess state format: a rolling deploy leaves 0.21.1 and 0.26.0 workers writing into the same PROMETHEUS_MULTIPROC_DIR, and if that file format moved, the collector merges two dialects into confetti.

🩹 The Fix: Confirm prometheus_client.values.ValueClass._multiprocess still exists in 0.26.0 (and prefer a supported signal if one is available). tests/unittest/test_telemetry_prometheus.py already spawns two worker processes and asserts multiproc aggregation, so PYTHONPATH=. uv run pytest tests/unittest/test_telemetry_prometheus.py -q is your smoke test; add a case that scrapes a directory written by the previous version if rolling deploys are a thing you do.

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

]

[project.urls]
Expand Down Expand Up @@ -130,16 +130,16 @@ pr-agent = "pr_agent.cli:run"
similar-issue = [
"pandas", # imported directly by the qdrant indexing path
"pinecone==10.0.0",
"lancedb==0.38.0",
"qdrant-client==1.15.1",
"lancedb==0.40.0",
"qdrant-client==1.19.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: Your qdrant client still calls client.search(...) (pr_agent/tools/pr_similar_issue.py:497) and client.upload_points(...) (line 887) — the two aliases qdrant-client deprecated in favour of query_points() and upsert(). Bumping 1.15 → 1.19 walks straight through the window where those aliases get deleted, and when they go, the similar-issue tool does not warn you; it just raises AttributeError in the middle of an ingest. The sting in the tail: nothing in CI would notice, because the qdrant tests use fake clients (tests/unittest/test_similar_issue_qdrant_ingest.py and friends never import the real qdrant_client), and this dependency group is not even installed by default.

🩹 The Fix: Migrate the two call sites to query_points(...) and upsert(...) before or with this bump, and add one test that imports the real qdrant_client so the next rename cannot hide from you.

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

]
dev = [
"pytest==9.1.1",
"pytest-asyncio>=1.4.0",
"pytest-cov==7.1.0",
"httpx==0.28.1",
"pre-commit>=4,<5",
"ruff==0.16.8",
"ruff==0.17.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: The linter bump is the quiet one, and quiet ones are the dangerous ones. .pre-commit-config.yaml:40 runs uv run --frozen ruff check, i.e. the locked ruff — so this line does not merely update a dev tool, it changes what CI enforces for the entire repository. Ruff minors add rules to the selected families (E/F/B/I), and this repo's lint.ignore is an explicit ledger of pre-existing violations, so one new rule can redden the whole codebase inside a PR whose title says '21 dependency updates'. The irony: your AGENTS.md treats that ignore list as a debt ledger to burn down, and this PR grows it by proxy.

🩹 The Fix: Run uv run ruff check on 0.17.1 locally, fix what is new, and either drop or justify any added lint.ignore entries — do not let a Dependabot PR quietly become the thing that expands the debt list.

📏 Severity: suggestion


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

]

[tool.uv]
Expand Down
Loading
Loading