Fix ocr-scan: correct package, add LLM config, fix output handling

Root cause analysis (5-perspective adversarial review):

1. Wrong NPM package — used @open-code-review/cli (doesn't exist),
   correct is @alibaba-group/open-code-review (verified on npmjs.com)

2. Missing LLM config — OCR_LLM_URL/OCR_LLM_TOKEN are custom env vars
   OCR doesn't read. Added ocr config set step mapping to a custom
   provider with the protocol/url/key from workflow secrets.

3. No install verification — previous install step swallowed all
   errors with 2>/dev/null || true. Now uses npm install -g + ocr
   scan --help + ocr llm test for fail-fast verification.

4. Wrong output path — scan --format json writes JSON to stdout, not
   .ocr/result.json. Now captures stdout directly to .ocr/result.json.

5. Missing comments field in envelope — build-envelope.sh didn't
   handle .comments[] from scan output (only handled .issues and
   .review_comments). Added .comments extraction with field mapping.

Fixes:
- .github/workflows/ocr-scan.yml: Split into Install & Configure +
  Run Scan steps. Correct package, LLM config via custom provider,
  direct output capture, explicit --model flag.
- .github/actions/ocr-envelope/build-envelope.sh: Handle .comments[]
  from scan output, map to uniform findings format with file/line/
  message/severity, handle object-typed .summary field.
This commit is contained in:
John Smith
2026-07-30 12:18:44 -04:00
parent 23bd0ccee3
commit b378f5b67d
2 changed files with 86 additions and 18 deletions
+36 -6
View File
@@ -23,9 +23,28 @@ WARNING_COUNT=0
if [ -f "$OCR_RESULT_FILE" ]; then
echo "Reading OCR results from ${OCR_RESULT_FILE}"
# Parse OCR JSON output — the format varies by OCR version
# Common fields: issues, warnings, errors, summary, review_comments
FINDINGS=$(cat "$OCR_RESULT_FILE" | jq '[.issues // (.review_comments // (.results // []))] | flatten' 2>/dev/null || echo '[]')
# Parse OCR JSON output — format varies by command and version
# ocr review: .issues[] or .review_comments[]
# ocr scan: .comments[] with {path, content, start_line, end_line, ...}
RAW_JSON=$(cat "$OCR_RESULT_FILE")
# Extract comment-like findings from the various OCR output shapes
FINDINGS=$(echo "$RAW_JSON" | jq '
if .issues then .issues
elif .review_comments then .review_comments
elif .comments then
# Map scan comments to uniform findings format
[.comments[] | {
file: .path,
line: (.start_line // 0),
message: .content,
severity: "warning",
suggestion: (.suggestion_code // "")
}]
elif .results then .results
else []
end | flatten
' 2>/dev/null || echo '[]')
# Count by severity
ERROR_COUNT=$(echo "$FINDINGS" | jq '[.[] | select(.severity == "error" or .severity == "critical" or .severity == "high")] | length' 2>/dev/null || echo 0)
@@ -42,15 +61,26 @@ if [ -f "$OCR_RESULT_FILE" ]; then
fi
# Build summary from OCR report
REVIEW_SUMMARY=$(cat "$OCR_RESULT_FILE" | jq -r '.summary // (.review_summary // "\(.issues | length) issues found")' 2>/dev/null || echo "OCR ${OCR_COMMAND} completed")
COMMENT_COUNT=$(echo "$FINDINGS" | jq 'length' 2>/dev/null || echo 0)
REVIEW_SUMMARY=$(echo "$RAW_JSON" | jq -r '
if .summary | type == "object" then
"\(.summary.files_reviewed // "?") file(s) reviewed, \(.summary.comments // 0) comment(s)"
elif .summary | type == "string" then .summary
elif .review_summary then .review_summary
else "\(.issues | length) issues found"
end
' 2>/dev/null || echo "OCR ${OCR_COMMAND} completed")
SUMMARY="${ERROR_COUNT} errors, ${WARNING_COUNT} warnings, ${INFO_COUNT:-0} info — ${REVIEW_SUMMARY}"
# Build outputs containing the raw OCR data
AGENT_OUTPUTS=$(cat "$OCR_RESULT_FILE" | jq '{ocr_command: $cmd, issue_count: (.issues | length)}' --arg cmd "$OCR_COMMAND" 2>/dev/null || echo '{}')
AGENT_OUTPUTS=$(echo "$RAW_JSON" | jq '{ocr_command: $cmd, comment_count: $count}' \
--arg cmd "$OCR_COMMAND" \
--argjson count "$COMMENT_COUNT" \
2>/dev/null || echo '{}')
export AGENT_OUTPUTS
# Only include findings if there are any
if [ "$(echo "$FINDINGS" | jq 'length' 2>/dev/null || echo 0)" -gt 0 ]; then
if [ "$COMMENT_COUNT" -gt 0 ]; then
export AGENT_FINDINGS="$FINDINGS"
fi
+50 -12
View File
@@ -57,34 +57,72 @@ jobs:
with:
fetch-depth: "0"
- name: "Run OCR Scan"
id: scan
- name: "Install and Configure OCR"
id: setup
shell: bash
env:
OCR_LLM_URL: ${{ secrets.ocr_llm_url }}
OCR_LLM_TOKEN: ${{ secrets.ocr_llm_token }}
OCR_LLM_MODEL: ${{ secrets.ocr_llm_model || inputs.ocr-llm-model || vars.OCR_LLM_MODEL || 'claude-sonnet-4-20250514' }}
OCR_USE_ANTHROPIC: ${{ inputs.ocr-use-anthropic || vars.OCR_LLM_USE_ANTHROPIC || 'true' }}
run: |
# Install OCR CLI globally (puts ocr on PATH)
npm install -g @alibaba-group/open-code-review
echo "✅ ocr installed: $(ocr --version 2>&1 || true)"
# Verify scan subcommand exists
if ! ocr scan --help >/dev/null 2>&1; then
echo "❌ 'ocr scan' subcommand not found"
exit 1
fi
# Configure LLM provider from workflow secrets
PROVIDER="ci-custom"
ocr config set provider "${PROVIDER}"
ocr config set "custom_providers.${PROVIDER}.url" "${OCR_LLM_URL}"
ocr config set "custom_providers.${PROVIDER}.api_key" "${OCR_LLM_TOKEN}"
ocr config set "custom_providers.${PROVIDER}.model" "${OCR_LLM_MODEL}"
if [ "${OCR_USE_ANTHROPIC}" = "true" ]; then
ocr config set "custom_providers.${PROVIDER}.protocol" "anthropic"
else
ocr config set "custom_providers.${PROVIDER}.protocol" "openai"
fi
# Test LLM connectivity
echo "🔌 Testing LLM connection..."
ocr llm test
- name: "Run OCR Scan"
id: scan
shell: bash
env:
OCR_LLM_MODEL: ${{ secrets.ocr_llm_model || inputs.ocr-llm-model || vars.OCR_LLM_MODEL || 'claude-sonnet-4-20250514' }}
SCAN_PATH: ${{ inputs.scan-path || github.event.inputs.scan-path || '.' }}
run: |
mkdir -p .ocr
# Run full repo scan via npx (guarantees latest OCR CLI version)
echo "🔍 Scanning: ${SCAN_PATH}"
npx @open-code-review/cli@latest scan \
# Run full repo scan — JSON output goes to stdout with --audience agent
ocr scan \
--path "${SCAN_PATH}" \
--format json \
--audience agent \
2>&1 | tee .ocr/scan-output.txt
--model "${OCR_LLM_MODEL}" \
> .ocr/result.json 2>.ocr/scan-stderr.txt
# Check for result.json output (OCR writes here)
if [ -f ".ocr/result.json" ]; then
echo "OCR results saved to .ocr/result.json"
elif [ -f ".ocr/report.json" ]; then
echo "OCR results saved to .ocr/report.json"
# Show stderr (if any) for debugging
if [ -s .ocr/scan-stderr.txt ]; then
cat .ocr/scan-stderr.txt >&2
fi
if [ -s .ocr/result.json ]; then
echo "✅ OCR results saved to .ocr/result.json"
else
# Try to extract from stdout
tail -c 100000 .ocr/scan-output.txt | grep -oP '\{.*\}' | head -1 > .ocr/result.json 2>/dev/null || true
echo "⚠️ No JSON output from OCR scan — scan produced no results or failed"
rm -f .ocr/result.json
fi
- name: "Build Agent Envelope"