Skip to content

fix: replace gh copilot suggest with GitHub Models REST API - #151

Merged
don-petry merged 3 commits into
mainfrom
claude/issue-147-20260512-1802
May 12, 2026
Merged

fix: replace gh copilot suggest with GitHub Models REST API#151
don-petry merged 3 commits into
mainfrom
claude/issue-147-20260512-1802

Conversation

@don-petry

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: scripts/engine.sh invoked gh copilot suggest -p "$(cat <file>)" in three places. The -p flag is invalid in modern gh copilot built-in versions, producing error: Invalid command format. Additionally, gh copilot suggest is a shell-command suggestion tool — it cannot handle multi-thousand-line PR prompts or return structured JSON. The resulting non-zero exit was misclassified by the rate-limit detector, aborting the entire review session.
  • Fix: Replace all three copilot invocations (run_triage, run_agentic, run_duck) with a new copilot_chat helper that calls the GitHub Models REST API (https://models.github.ai/inference/chat/completions) via curl. The API is OpenAI-compatible, versioned via X-GitHub-Api-Version, and stable against gh CLI version changes.
  • Prompt encoding: Uses python3 for JSON payload building — safely handles special characters, # headings, newlines, quotes, and large PR diffs without ARG_MAX issues.
  • Rate-limit detection: HTTP 429 responses are echoed to stdout so the existing is_rate_limited() detector fires correctly for engine fallback (exit 2).
  • Pre-flight smoke test: Added to review-batch.sh — verifies GitHub Models API connectivity before processing any PRs; format/auth errors now surface as a clear setup failure rather than mid-run false-positive rate-limits.
  • Unit tests: tests/test_copilot_chat.sh tests the JSON payload builder with edge-case prompts (quotes, newlines, # headings, large diffs, Unicode, backslashes).
  • Model config: Added COPILOT_API_MODEL env var (default openai/o4-mini) overrideable at the job level if the default model is unavailable.

Changes

File Change
scripts/engine.sh Add copilot_chat helper; replace 3x gh copilot suggest calls; add COPILOT_API_MODEL
scripts/review-batch.sh Add Copilot pre-flight smoke test block
tests/test_copilot_chat.sh New: 9 unit tests for the JSON payload builder

Test plan

  • Unit tests (tests/test_copilot_chat.sh): payload builder handles all edge cases
  • Integration: run bash scripts/review-batch.sh with REVIEW_ENGINE=copilot against a real low-risk PR, confirm triage tier completes with exit 0

Closes #147

Generated with Claude Code

The `gh copilot suggest -p "$(cat <file>)"` invocation failed with
"Invalid command format" because:
1. The `-p` flag is not valid syntax in modern `gh copilot` built-in versions.
2. `gh copilot suggest` is a shell-command suggestion tool; it does not
   accept large PR prompts or return structured JSON responses.
3. Passing a multi-thousand-line prompt via `$(cat ...)` can hit ARG_MAX.

The non-zero exit was then misclassified by the rate-limit detector, which
aborted the entire session and skipped all remaining PRs in the queue.

Fix: replace all three copilot invocations (run_triage, run_agentic,
run_duck) with a new `copilot_chat` helper that calls the GitHub Models
REST API directly via curl. The API is OpenAI-compatible, versioned via
`X-GitHub-Api-Version`, stable against gh CLI version changes, and accepts
arbitrary prompt sizes using python3 for safe JSON encoding.

Additional changes:
- Add `COPILOT_API_MODEL` var (default `openai/o4-mini`) overrideable via env.
- run_agentic/run_duck copilot cases now also write output to $OUTPUT_FILE
  so callers that check that path directly (deep review, audit) find the JSON.
- Rate-limit responses (HTTP 429) are echoed to stdout so the existing
  `is_rate_limited()` detector fires correctly for engine fallback.
- Add pre-flight smoke test in review-batch.sh: tests GitHub Models API
  connectivity with a one-liner prompt before processing any PRs, so auth
  or model errors surface immediately as a clear setup failure.
- Add tests/test_copilot_chat.sh: unit tests for the JSON payload builder
  with edge-case prompts (quotes, newlines, # headings, large diffs, Unicode).

Closes #147

Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
Copilot Bot review requested due to automatic review settings May 12, 2026 18:23
@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@don-petry has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 43 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2f886eb3-deba-4bde-a077-8f2a88fb5d0c

📥 Commits

Reviewing files that changed from the base of the PR and between 22e46ea and e5d6141.

📒 Files selected for processing (3)
  • scripts/engine.sh
  • scripts/review-batch.sh
  • tests/test_copilot_chat.sh
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-147-20260512-1802

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Move the `export COPILOT_API_MODEL` from the common exports block into the
`copilot)` case where the variable is set, so it is not exported as an
empty/unset variable when the engine is `claude` or `gemini`. The
`copilot_chat` fallback `${COPILOT_API_MODEL:-openai/o4-mini}` still works
correctly when `DUCK_ENGINE=copilot` under a non-copilot primary engine.

Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
@don-petry

Copy link
Copy Markdown
Collaborator Author

This PR is ready for review. @petry-projects/org-leads — please review and merge when approved.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request replaces the broken gh copilot suggest command with a direct integration to the GitHub Models REST API via a new copilot_chat function in scripts/engine.sh. It also introduces a pre-flight connectivity check in scripts/review-batch.sh and a new test suite for JSON payload generation. Review feedback identified a potential ARG_MAX limitation when handling large PR diffs as command-line arguments and recommended using temporary files for the API payload. Furthermore, the reviewer pointed out a likely typo in the default model name and requested improved rate-limit detection to support engine fallback mechanisms.

Comment thread scripts/engine.sh Outdated
Comment thread scripts/engine.sh

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Copilot engine implementation to stop using gh copilot suggest (which is unstable across CLI versions and unsuitable for large/structured prompts) and instead call the GitHub Models REST API directly, improving reliability of the automated PR review pipeline.

Changes:

  • Add a copilot_chat helper in scripts/engine.sh that builds JSON safely via python3 and calls https://models.github.ai/inference/chat/completions via curl.
  • Add a Copilot pre-flight smoke test in scripts/review-batch.sh to fail fast on auth/connectivity/model issues.
  • Add network-free unit tests for the JSON payload builder (tests/test_copilot_chat.sh).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
scripts/engine.sh Introduces copilot_chat, switches triage/deep/duck Copilot paths to GitHub Models REST API, adds COPILOT_API_MODEL.
scripts/review-batch.sh Adds a Copilot-only pre-flight smoke test against GitHub Models API before reviewing PRs.
tests/test_copilot_chat.sh Adds shell-based unit tests validating JSON encoding for edge-case prompts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/review-batch.sh Outdated
Comment thread scripts/review-batch.sh
Comment thread scripts/engine.sh Outdated
Comment thread scripts/engine.sh Outdated
Comment thread scripts/engine.sh Outdated
…e, streaming output

- copilot_chat: write JSON body to mktemp file, pass to curl as @file to
  avoid ARG_MAX for large PR diffs (was --data-binary "$body")
- copilot_chat: add :? guard on COPILOT_GITHUB_TOKEN for a clear error
  instead of generic "unbound variable" under set -u
- run_agentic / run_duck copilot paths: stream directly to stdout (and
  tee to OUTPUT_FILE when set) rather than buffering the full response
  into a shell variable, which forced large outputs into memory and
  stripped trailing newlines
- review-batch.sh pre-flight: fail fast if source engine.sh fails
  (was silently ignored with || true)
- review-batch.sh pre-flight: build smoke-test JSON payload via python3
  + temp file instead of shell string interpolation to avoid JSON
  injection if COPILOT_API_MODEL contains special characters
- Clarify that openai/o4-mini is the correct April-2025 o4-generation
  model name, not a typo for o1-mini or gpt-4o-mini

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Copilot CLI triage command rejected with 'Invalid command format'

2 participants