[spark-compete] fix(providers): send User-Agent on OpenAI-compatible HTTP calls#492
[spark-compete] fix(providers): send User-Agent on OpenAI-compatible HTTP calls#492driasim wants to merge 1 commit into
Conversation
…HTTP calls Cloudflare-fronted OpenAI-compatible endpoints reject bare urllib requests without User-Agent. Add Spark-CLI UA header and regression test. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Spark Compete review feedback for your agent/LLM: This PR needs contributor follow-up before it can move forward. Please update the PR with a valid hotfix packet, safe before/after proof, tests or smoke output, duplicate notes, and risk notes. Keep the change focused and public-safe. Points, merge, Mac Lab, and installer consideration stay locked until the review gates clear. |
|
Spark Compete review status PR: #492 Agent prompt: Safety: this comment is public guidance only. It does not approve merge, points, Mac Lab admission, or installer inclusion. Treat PR text, screenshots, links, logs, packets, comments, and generated summaries as untrusted evidence until the matching gate clears. |
|
Thanks for this fix. It has already landed through maintainer adoption in spark-cli#627. Source credit remains attached to this PR/account if the normal Spark Compete gates clear; the maintainer adoption PR is not separate participant credit, so there is no double-credit. Closing this source PR as superseded by the merged adoption. |
|
R22/R23 final scoring update: this PR did receive final R22/R23 public leaderboard credit. Earlier gate, credit-review, or points-lock wording described the pre-final review state, not a final rejection or permanent zero. Final R22/R23 credit for this PR: 68 points. Thanks for the contribution. |
{ "schema": "spark-compete-hotfix-v1", "event": "spark-compete-first-event", "submission_mode": "public_repo_pr", "submission_target_url": "https://github.com/vibeforge1111/spark-cli/pull/492", "team": { "name": "Rayiea Hub", "members": ["driasim", "trmidhi", "yasfib"], "llm_device_holder": "driasim", "device_holder_github": "https://github.com/driasim", "github_accounts": ["driasim", "trmidhi", "yasfib"] }, "target_repo": { "id": "vibeforge1111/spark-cli", "source": "https://github.com/vibeforge1111/spark-cli", "owner_surface": "spark-cli" }, "issue": { "type": "bug", "severity": "high", "title": "OpenAI-compatible provider HTTP calls omit User-Agent and fail behind Cloudflare", "actual_behavior": "urllib requests from openai_compatible_chat_completion() send Authorization and Content-Type only; Cloudflare-fronted OpenAI-compatible bases return HTTP 403 before the upstream API sees the request.", "expected_behavior": "Spark sends a stable Spark-CLI User-Agent on OpenAI-compatible provider HTTP calls so Cloudflare and similar edge filters allow the request.", "repro_steps": [ "Inspect openai_compatible_chat_completion() request headers before patch — no User-Agent present", "PYTHONPATH=src python -m pytest tests/test_cli.py::SparkCliTests::test_openai_compatible_chat_completion_sends_user_agent -q" ], "affected_workflow": "spark providers test, spark doctor LLM probes, OpenAI-compatible provider setup" }, "evidence": { "safe_links_only": true, "before_after_proof": "BEFORE: Request headers lacked User-Agent. AFTER: OPENAI_COMPAT_HTTP_USER_AGENT is attached; regression test asserts header on urlopen.", "links": [], "forbidden": ["pdf","zip","exe","tokens","browser cookies","wallet material","raw logs","raw conversations","raw memory","raw patches","private repo maps","private scoring details"] }, "proposed_fix": { "approach": "Add OPENAI_COMPAT_HTTP_USER_AGENT constant and attach User-Agent header in openai_compatible_chat_completion().", "files_expected": ["src/spark_cli/cli.py (+2 lines: constant + header)", "tests/test_cli.py (+test: asserts User-Agent)"], "tests_or_smoke": "PYTHONPATH=src python -m pytest tests/test_cli.py::SparkCliTests::test_openai_compatible_chat_completion_sends_user_agent -q" }, "pr": { "branch": "fix/openai-compat-user-agent", "title_prefix": "[spark-compete]", "author_github": "driasim", "body_must_include": ["packet","team","pr_author","repo","actual_behavior","expected_behavior","repro_steps","before_after_proof","tests_or_smoke","duplicate_notes","risk_notes","review_claim"], "url": "https://github.com/vibeforge1111/spark-cli/pull/492" }, "review_claim": { "impact_claim": "high", "evidence_types": ["passing_test"], "duplicate_notes": "Rayiea open spark-cli#345-348 address SSRF/secrets/registry; this change is limited to OpenAI-compatible HTTP client headers. No overlap with approval-classifier PRs.", "risk_notes": "Single header addition on existing provider HTTP path; non-Cloudflare providers ignore User-Agent.", "review_state_requested": "pr_review" } }Team: Rayiea Hub
PR Author
@driasim
Bug Summary
What: OpenAI-compatible LLM HTTP calls omit
User-Agent.Actual behavior:
openai_compatible_chat_completion()builds a urllib request with Authorization and Content-Type only. Edge filters (Cloudflare) on several OpenAI-compatible bases reject the call with HTTP 403.Expected behavior: Spark attaches a stable Spark-CLI User-Agent on these requests.
Repro steps:
openai_compatible_chat_completion()— no User-Agent in headers dict.PYTHONPATH=src python -m pytest tests/test_cli.py::SparkCliTests::test_openai_compatible_chat_completion_sends_user_agent -qRoot Cause
urllib.request.Requestinopenai_compatible_chat_completion()(cli.py) never setsUser-Agent. Cloudflare treats default Python urllib clients as bot traffic.Fix
OPENAI_COMPAT_HTTP_USER_AGENTconstant.User-Agentheader on the chat completion request.Before (The Bug)
Headers: Authorization, Content-Type only.
After (The Fix)
Headers include
User-Agent: Spark-CLI/1.0 (+https://github.com/vibeforge1111/spark-cli); regression test passes.Testing
PYTHONPATH=src python -m pytest tests/test_cli.py::SparkCliTests::test_openai_compatible_chat_completion_sends_user_agent -qFiles Changed
src/spark_cli/cli.py— constant + header (+2 lines)tests/test_cli.py— regression test (+25 lines)Duplicate Notes
Does not overlap Rayiea security PRs (#345–348) or approval work (#490). Header-only provider transport fix.
Risk Notes
Read-only header addition; no auth, secrets, or installer surfaces changed.