Skip to content

fix: address all review comments — os.environ fallbacks, isinstance guards, package structure#262

Closed
sheepdestroyer wants to merge 17 commits into
masterfrom
test/canonical-endpoint-verification
Closed

fix: address all review comments — os.environ fallbacks, isinstance guards, package structure#262
sheepdestroyer wants to merge 17 commits into
masterfrom
test/canonical-endpoint-verification

Conversation

@sheepdestroyer

@sheepdestroyer sheepdestroyer commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Fresh PR replacing #261 — all review comments from Gemini Code Assist and Sourcery addressed.

Review Fixes Applied

Gemini Code Assist (3/3)

  1. load_env() now respects shell env overrides — checks os.environ.get() before .env file values for all config keys (ROUTER_PORT, LITELLM_PORT, LANGFUSE_WEB_PORT, LITELLM_MASTER_KEY, ROUTER_API_KEY, PUBLIC_BASE_URL, MINIO_S3_PORT, CLICKHOUSE_HTTP_PORT)
  2. Skip message for missing PUBLIC_BASE_URL — prints ── Canonical URLs — SKIPPED (PUBLIC_BASE_URL not set) ── instead of silently returning
  3. isinstance guards in parse_chat_response() — checks isinstance(content_val, str) before .strip() to prevent AttributeError on non-string values

Sourcery (2/2)

  1. scripts/ is now a proper Python package — added scripts/__init__.py and scripts/verification/__init__.py. All scripts now import via from scripts.chat_helpers import parse_chat_response with a single WORKDIR-level sys.path.insert instead of per-script hacks to scripts/.
  2. Improved .env value parsing — added final .strip() after quote removal to handle trailing whitespace

Global Consistency

  • verification_helpers.py: replaced unsafe inline choices[0]["message"].get("content") indexing with shared parse_chat_response()
  • verify_ollama_routing.py: same fix
  • scripts/README.md: added chat_helpers.py module documentation

Files Changed

  • scripts/__init__.py (new)
  • scripts/verification/__init__.py (new)
  • scripts/chat_helpers.py — isinstance guards
  • scripts/verification/verify_canonical_endpoints.py — os.environ, skip msg, parser, package import
  • scripts/verification/verification_helpers.py — use parse_chat_response + package import
  • scripts/verification/verify_ollama_routing.py — use parse_chat_response + package import
  • scripts/benchmark_classifier.py — package import
  • scripts/classify_direct.py — package import
  • scripts/reclassify_all.py — package import
  • scripts/retry_errors.py — package import
  • scripts/README.md — chat_helpers docs

Summary by Sourcery

Add canonical endpoint verification tooling, centralize chat response parsing, and update health checks and deployment configuration for LiteLLM and Langfuse.

New Features:

  • Introduce a canonical endpoint verification script that validates router, LiteLLM, Langfuse, infrastructure, E2E chat, and public HTTPS endpoints for prod and dev.
  • Add a production upgrade helper script to sync runtime files from the latest GitHub release and redeploy with updated container images.

Bug Fixes:

  • Adjust LiteLLM and Langfuse liveness/readiness probe paths to use current health endpoints.
  • Ensure environment-derived URLs such as NEXTAUTH_URL and PUBLIC_BASE_URL are correctly propagated into pod configuration and used by verification tooling.
  • Harden chat completion response handling across scripts to avoid failures on malformed or unexpected API responses.

Enhancements:

  • Convert scripts into a proper Python package with shared chat_helpers utilities reused by classifier and verification scripts.
  • Update verification and classifier scripts to consume the shared chat response parser for consistent behavior and reduced duplication.
  • Improve .env parsing logic for verification tooling with trimming and explicit support for shell overrides.
  • Extend router and LiteLLM verification coverage with additional endpoints including admin UI and metrics.

Documentation:

  • Document the new canonical endpoint verification workflow and coverage in the main README.
  • Update scripts README to describe the shared chat_helpers module and its role in classifier and verification scripts.

Summary by CodeRabbit

  • New Features

    • Added a production upgrade utility with release selection, dry-run comparison, confirmation, and redeployment support.
    • Added canonical endpoint verification covering service health, chat requests, infrastructure checks, and public URLs.
    • Added configurable LiteLLM UI credentials and automatic Langfuse URL configuration.
  • Bug Fixes

    • Improved handling of varied or incomplete chat responses across classification and verification workflows.
    • Updated service health checks to use the correct liveness and public health endpoints.
  • Documentation

    • Documented health-check updates, production upgrade tooling, endpoint verification, and required public URL configuration.

boy added 15 commits July 11, 2026 22:47
Reads ports/URLs from .env (and .env.dev overlay), validates:
- Router: /v1/models, /metrics, /dashboard, /api/dashboard-stats
- LiteLLM: /health/liveness, /health/readiness, /v1/models
- Langfuse: /api/public/health
- E2E: 3 chat completions through triage router
- Canonical HTTPS URLs (graceful skip on DNS failure)

Usage:
  python scripts/verification/verify_canonical_endpoints.py         # prod
  python scripts/verification/verify_canonical_endpoints.py --dev   # dev
- Pass UI_USERNAME/UI_PASSWORD from .env to LiteLLM container as
  LITELLM_UI_USERNAME/LITELLM_UI_PASSWORD (LiteLLM's expected env vars)
- Derive NEXTAUTH_URL from PUBLIC_BASE_URL instead of hardcoding
  localhost — fixes Langfuse post-login redirect to broken URL
- LiteLLM: /llm-routing/litellm/ui/ (SERVER_ROOT_PATH prefix required)
- Langfuse: / (web UI root)
- Canonical URLs: /litellm/ui/ and /langfuse
…cation

- Router: /visualizer endpoint
- Infrastructure: MinIO /minio/health/live, ClickHouse /ping
- LiteLLM: direct chat completion (bypasses triage router)
- Canonical URLs: /visualizer
- POST agent-simple-core through public URL (dev.vendeuvre.lan)
- Validates full HTTPS path: HAProxy → dev router → LiteLLM → model
- Graceful DNS skip when host unreachable
- All three chat completion parsers now use .get() on choices/message
  instead of direct indexing (Gemini Code Assist review)
- Canonical URL skipped checks are tracked separately and shown
  in summary as 'X skipped' (Sourcery review)
… ports, .env logging

- Extract parse_chat_response() helper to deduplicate chat completion parsing
  across test_e2e_chat, test_litellm_direct_chat, and test_canonical_urls
- Add isinstance guards for defensive JSON response parsing (Gemini suggestion)
- Load MinIO and ClickHouse ports from .env (MINIO_S3_PORT, CLICKHOUSE_HTTP_PORT)
  instead of hardcoding 9002/8123 (Sourcery suggestion)
- Log which .env files were loaded and warn on missing files (Sourcery suggestion)
- Handle export prefix and inline comments in .env parser (Gemini suggestion)
Apply isinstance guards on choices/message across benchmark_classifier.py,
retry_errors.py, and reclassify_all.py — same pattern as the verification
script's parse_chat_response() helper. Prevents unhandled exceptions when
the API returns unexpected response structures.
- Drop fragile inline-comment stripping from env parser (Sourcery + Gemini):
  heuristic truncated '#' in passwords/URLs — only full-line comments now
- Add encoding='utf-8' to open() call (Gemini)
- Add isinstance(data, dict) guards before .get() calls in all 4 classifier
  scripts: benchmark_classifier, reclassify_all, retry_errors, classify_direct
- Use 'or' fallback for UI_USERNAME/UI_PASSWORD (Gemini):
  os.environ.get('X') or 'admin' handles empty-string exports
- Send auth headers on canonical GET endpoints (Sourcery):
  defense-in-depth even though router public endpoints don't require auth
- Fix exit condition: skipped DNS-unreachable endpoints no longer cause
  non-zero exit code (Sourcery high-level)
- Security: UI_PASSWORD defaults to LITELLM_MASTER_KEY (not 'admin')
  when UI_PASSWORD env var is unset (Gemini Code Assist)
- Robustness: strip trailing slash from PUBLIC_BASE_URL to prevent
  double-slash URLs (Gemini Code Assist)
- Deduplication: extract parse_chat_response() into shared
  scripts/chat_helpers.py, imported by all 4 classifier scripts +
  verification script (Sourcery)
- UX: skipped canonical URL tests show '⚠ SKIP' instead of ✓
  (Sourcery)
- Cleanup: remove unused 'base_url' from load_env() return dict
  (Sourcery)
- LiteLLM liveness: /ping (404) → /health/liveness (200)
- Langfuse liveness+readiness: /api/health (404) → /api/public/health (200)

Both containers were crash-looping because Podman's
HealthcheckOnFailureAction=restart kept killing them when the health
checks hit the wrong endpoints (404). RestartCount was 22+ on both
dev and prod before the fix; now 0 and healthy.
Pulls the latest GitHub release tag, clones it, rsyncs runtime files
(pod.yaml, start-stack.sh, litellm/, router/, scripts/) into ~/prod/
without touching .env or data/, then redeploys via start-stack.sh --pull.

Prevents temptation to patch prod directly — all config changes flow
through git releases.
- LiteLLM liveness: /ping → /health/liveness
- Langfuse liveness+readiness: /api/health → /api/public/health
- Add upgrade-prod.sh to directory layout
## Gemini Code Assist fixes
- load_env() now checks os.environ before .env values for config resolution
- test_canonical_urls() prints skip message when PUBLIC_BASE_URL not set
- parse_chat_response() uses isinstance guards before .strip() to prevent
  AttributeError on non-string content/reasoning_content values

## Sourcery fixes
- Created scripts/__init__.py and scripts/verification/__init__.py to
  turn scripts/ into a proper Python package
- All scripts now import via
  with a single WORKDIR sys.path.insert instead of per-script hacks
- .env value parser now strips trailing whitespace after quote removal

## Global consistency
- verification_helpers.py: replaced unsafe inline content extraction
  with shared parse_chat_response()
- verify_ollama_routing.py: same — uses parse_chat_response() instead
  of direct choices[0]["message"].get("content") indexing
- scripts/README.md: added chat_helpers.py module documentation
@sourcery-ai

sourcery-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Makes the scripts directory a proper Python package, centralizes chat completion response parsing via a shared helper with defensive isinstance guards, improves environment loading with os.environ fallbacks and stricter .env parsing, adds a comprehensive canonical endpoint verification script, updates health check endpoints and auth-related placeholders in pod/start-stack, and adds a production upgrade helper script plus README docs for the new behavior.

Sequence diagram for canonical endpoint verification flow

sequenceDiagram
    actor Operator
    participant verify_canonical_endpoints as verify_canonical_endpoints.main
    participant load_env
    participant router as triage_router
    participant litellm as litellm_gateway
    participant langfuse as langfuse_web
    participant parse_chat_response

    Operator->>verify_canonical_endpoints: run with --dev/--prod
    verify_canonical_endpoints->>load_env: load_env(dev)
    load_env-->>verify_canonical_endpoints: cfg (ports, keys, public_base_url)

    verify_canonical_endpoints->>router: test_router_endpoints(cfg)
    verify_canonical_endpoints->>litellm: test_litellm_endpoints(cfg)
    verify_canonical_endpoints->>langfuse: test_langfuse_endpoints(cfg)

    verify_canonical_endpoints->>router: test_e2e_chat(cfg)
    router-->>verify_canonical_endpoints: chat completion JSON
    verify_canonical_endpoints->>parse_chat_response: parse_chat_response(data)
    parse_chat_response-->>verify_canonical_endpoints: content, reasoning_content

    verify_canonical_endpoints->>litellm: test_litellm_direct_chat(cfg)
    litellm-->>verify_canonical_endpoints: chat completion JSON
    verify_canonical_endpoints->>parse_chat_response: parse_chat_response(data)
    parse_chat_response-->>verify_canonical_endpoints: content, reasoning_content

    verify_canonical_endpoints->>router: test_canonical_urls(cfg)
    router-->>verify_canonical_endpoints: HTTPS responses via PUBLIC_BASE_URL

    verify_canonical_endpoints-->>Operator: summary (passed, failed, skipped)
Loading

File-Level Changes

Change Details Files
Introduce a shared, defensive chat completion response parser and use it across classifier and verification scripts.
  • Add scripts/chat_helpers.py with parse_chat_response() performing isinstance checks and safely extracting content and reasoning_content.
  • Replace inline choices[0]["message"].get("content") access patterns in verification and classifier scripts with parse_chat_response().
  • Update multiple scripts to import parse_chat_response via the scripts package using a single WORKDIR-level sys.path.insert.
scripts/chat_helpers.py
scripts/retry_errors.py
scripts/benchmark_classifier.py
scripts/reclassify_all.py
scripts/classify_direct.py
scripts/verification/verification_helpers.py
scripts/verification/verify_ollama_routing.py
Make scripts a proper Python package and clean up imports for verification and classifier tooling.
  • Add empty init.py modules to scripts/ and scripts/verification/ to define packages.
  • Standardize imports of shared helpers (parse_chat_response) through the scripts package rather than per-script sys.path hacks.
  • Update scripts/README.md to document chat_helpers.py and its usage.
scripts/__init__.py
scripts/verification/__init__.py
scripts/retry_errors.py
scripts/benchmark_classifier.py
scripts/reclassify_all.py
scripts/classify_direct.py
scripts/verification/verification_helpers.py
scripts/verification/verify_ollama_routing.py
scripts/README.md
Improve environment loading and configuration wiring, including PUBLIC_BASE_URL handling, os.environ precedence, and derived URLs for auth and health checks.
  • Implement load_env() in verify_canonical_endpoints.py that parses .env/.env.dev with whitespace stripping and gives precedence to existing os.environ values.
  • Ensure PUBLIC_BASE_URL is read from env, trimmed, and used for canonical URL tests; emit an explicit SKIPPED message if it is not set.
  • Update start-stack.sh pod rendering to export UI_USERNAME/UI_PASSWORD and derive NEXTAUTH_URL from PUBLIC_BASE_URL, wiring these into pod.yaml placeholders.
  • Adjust .env line parsing to strip quotes then final whitespace to avoid trailing-space bugs.
scripts/verification/verify_canonical_endpoints.py
start-stack.sh
Add a comprehensive canonical endpoint verification script covering router, LiteLLM, Langfuse, infrastructure, E2E chat, and public HTTPS endpoints.
  • Create scripts/verification/verify_canonical_endpoints.py with load_env(), sectioned test_* functions, and a main() that aggregates pass/skip counts and exits non-zero on failures.
  • Implement checks for router endpoints (/v1/models, /metrics, /dashboard, /api/dashboard-stats, /visualizer), LiteLLM health (/health/liveness, /health/readiness, /v1/models, /llm-routing/litellm/ui/), Langfuse health (/api/public/health, web UI), MinIO and ClickHouse health, E2E chat via triage router, LiteLLM direct chat, and canonical HTTPS URLs (GET and POST).
  • Use parse_chat_response() for all chat completion validations and provide detailed logging for each test label and outcome.
scripts/verification/verify_canonical_endpoints.py
Align health-check endpoints and auth-related configuration in pod.yaml and README with current Langfuse and LiteLLM endpoints.
  • Change litellm-gateway liveness probe from /ping to /health/liveness in README and pod.yaml.
  • Change Langfuse web health probes from /api/health to /api/public/health in README and pod.yaml.
  • Update NEXTAUTH_URL in pod.yaml to use a placeholder and derive its value from PUBLIC_BASE_URL via start-stack.sh.
  • Add LITELLM_UI_USERNAME and LITELLM_UI_PASSWORD environment variables in pod.yaml populated from UI_USERNAME/UI_PASSWORD or fallbacks.
README.md
pod.yaml
start-stack.sh
Introduce a production upgrade helper script that syncs runtime files from a tagged GitHub release and redeploys.
  • Add scripts/upgrade-prod.sh to fetch the latest or specified GitHub release tag, clone it into a temp directory, validate expected runtime files, and rsync pod.yaml, start-stack.sh, litellm/, router/, and scripts/ into the PROD_DIR without touching .env or data.
  • Implement a --dry-run mode to show diffs of the runtime files that would change and a confirmation prompt before applying changes.
  • Stop the existing podman pod gracefully before syncing and then redeploy via start-stack.sh --pull.
scripts/upgrade-prod.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@sheepdestroyer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 44adc70a-f042-478a-aa6b-dd7224c4ec65

📥 Commits

Reviewing files that changed from the base of the PR and between ad2ec89 and 6a27eac.

📒 Files selected for processing (2)
  • scripts/upgrade-prod.sh
  • scripts/verification/verify_canonical_endpoints.py
📝 Walkthrough

Walkthrough

The change updates LiteLLM and Langfuse health configuration, adds shared defensive chat-response parsing, introduces canonical endpoint verification, and adds a tagged production upgrade utility with corresponding documentation.

Changes

Runtime and verification updates

Layer / File(s) Summary
Service endpoint and runtime configuration
pod.yaml, start-stack.sh, README.md
Updates health probes, LiteLLM UI credentials, and dynamic Langfuse NEXTAUTH_URL rendering.
Shared chat response parsing
scripts/chat_helpers.py, scripts/benchmark_classifier.py, scripts/classify_direct.py, scripts/reclassify_all.py, scripts/retry_errors.py, scripts/verification/*
Adds parse_chat_response and adopts it across classification and verification flows, with package and standalone import support.
Canonical endpoint verification
scripts/verification/verify_canonical_endpoints.py, README.md
Adds environment loading and checks for router, LiteLLM, Langfuse, infrastructure, chat, and optional canonical HTTPS endpoints.
Production release synchronization
scripts/upgrade-prod.sh, README.md
Adds tagged release cloning, validation, dry-run comparison, confirmation, synchronization, and redeployment for production runtime files.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant verifier as verify_canonical_endpoints.py
  participant env as .env
  participant router as Router API
  participant litellm as LiteLLM
  participant langfuse as Langfuse
  verifier->>env: load service configuration
  verifier->>router: check endpoints and routed chat
  verifier->>litellm: check health and direct chat
  verifier->>langfuse: check public health and web UI
  verifier->>router: check canonical URLs when PUBLIC_BASE_URL is configured
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main themes: environment precedence, defensive parsing guards, and package structure changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/canonical-endpoint-verification

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.

@sourcery-ai sourcery-ai Bot 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.

Hey - I've left some high level feedback:

  • Now that scripts is a proper package, consider replacing the repeated sys.path.insert hacks in the various scripts with standard package-relative imports (e.g., running via python -m scripts... or adjusting the project’s PYTHONPATH) to make module resolution more robust and cleaner.
  • In upgrade-prod.sh, the dry-run diff logic uses diff -rq on individual files, which can print somewhat noisy output and then echo a generic "differs" line; you could simplify this by using non-recursive diff -q for files and diff -rq only for directories to make the summary clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Now that `scripts` is a proper package, consider replacing the repeated `sys.path.insert` hacks in the various scripts with standard package-relative imports (e.g., running via `python -m scripts...` or adjusting the project’s PYTHONPATH) to make module resolution more robust and cleaner.
- In `upgrade-prod.sh`, the dry-run diff logic uses `diff -rq` on individual files, which can print somewhat noisy output and then echo a generic "differs" line; you could simplify this by using non-recursive `diff -q` for files and `diff -rq` only for directories to make the summary clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

verify_ollama_routing.py, verify_ollama_cooldown.py, and
verify_direct_ollama_cooldown.py now try relative imports first
(from .verification_helpers) and fall back to absolute imports.
This allows them to work both as package imports and when run
directly from the command line.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new production upgrade script (upgrade-prod.sh), a comprehensive canonical endpoint verification script (verify_canonical_endpoints.py), and a shared chat response parser (chat_helpers.py) to streamline deployments and health checks. It also updates container health probes and configures additional environment variables for LiteLLM and Langfuse. The review feedback highlights a critical data loss risk in the upgrade script where rsync -a --delete would inadvertently delete the production database, environment configuration, and backups. Additionally, the feedback addresses potential script failures in non-interactive environments, SSL verification issues with self-signed certificates in local environments, and a minor string formatting typo.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/upgrade-prod.sh
Comment on lines +95 to +101
rsync -a --delete \
"$TEMP_DIR/pod.yaml" \
"$TEMP_DIR/start-stack.sh" \
"$TEMP_DIR/litellm/" \
"$TEMP_DIR/router/" \
"$TEMP_DIR/scripts/" \
"$PROD_DIR/"

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.

critical

⚠️ Catastrophic Data Loss Risk

Using rsync -a --delete with multiple source arguments targeting a parent destination directory ($PROD_DIR/) will cause rsync to delete any file or directory in the destination that is not explicitly present in the sources list.

Since .env, data/, and backups/ are located in $PROD_DIR/ but are not in the list of sources, this command will completely delete your production database, environment configuration, and backups, contradicting the script's comments.

Suggested Fix

To safely sync the runtime files while preserving other files in $PROD_DIR/, you should sync the directories and files individually:

Suggested change
rsync -a --delete \
"$TEMP_DIR/pod.yaml" \
"$TEMP_DIR/start-stack.sh" \
"$TEMP_DIR/litellm/" \
"$TEMP_DIR/router/" \
"$TEMP_DIR/scripts/" \
"$PROD_DIR/"
rsync -a "$TEMP_DIR/pod.yaml" "$PROD_DIR/pod.yaml"
rsync -a "$TEMP_DIR/start-stack.sh" "$PROD_DIR/start-stack.sh"
rsync -a --delete "$TEMP_DIR/litellm/" "$PROD_DIR/litellm/"
rsync -a --delete "$TEMP_DIR/router/" "$PROD_DIR/router/"
rsync -a --delete "$TEMP_DIR/scripts/" "$PROD_DIR/scripts/"

Comment thread scripts/upgrade-prod.sh Outdated
Comment on lines +80 to +84
read -rp "Proceed with upgrade to $TAG? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi

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.

medium

In non-interactive environments (such as cron jobs, CI/CD pipelines, or automated deployment scripts), the read command will fail or block because stdin is not a TTY. Since set -e is active, this failure will cause the script to terminate abruptly.

Consider checking if the script is running in an interactive shell before prompting, or adding a way to bypass the confirmation.

Suggested change
read -rp "Proceed with upgrade to $TAG? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
if [ -t 0 ]; then
read -rp "Proceed with upgrade to $TAG? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
else
echo "Non-interactive shell detected, proceeding with upgrade..."
fi

Comment on lines +382 to +383
r = httpx.get(url, timeout=15, follow_redirects=True,
headers={"Authorization": f"Bearer {cfg['router_api_key']}"})

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.

medium

In local or home lab environments (such as .lan domains), services often use self-signed SSL certificates. By default, httpx will fail with an SSL verification error when connecting to these endpoints.

Since this is a verification and health-check script, consider disabling SSL verification by passing verify=False to the httpx requests, or making it configurable.

Suggested change
r = httpx.get(url, timeout=15, follow_redirects=True,
headers={"Authorization": f"Bearer {cfg['router_api_key']}"})
r = httpx.get(url, timeout=15, follow_redirects=True, verify=False,
headers={"Authorization": f"Bearer {cfg['router_api_key']}"})

total_passed += p
total_tests += t

print(f"\\n{'='*60}")

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.

medium

The double backslash \\n in the f-string will print a literal \n string instead of a newline character. Use a single backslash \n to print a newline.

Suggested change
print(f"\\n{'='*60}")
print(f"\n{'='*60}")

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/upgrade-prod.sh`:
- Around line 95-101: Update the rsync source entries in the deployment command
to remove trailing slashes from the TEMP_DIR/litellm, TEMP_DIR/router, and
TEMP_DIR/scripts paths. Preserve the directory names under PROD_DIR so
start-stack.sh paths remain valid and --delete does not merge or remove
protected root entries.

In `@scripts/verification/verify_canonical_endpoints.py`:
- Line 463: Update the summary separator print statement to use an actual
newline escape instead of the literal backslash-n sequence, while preserving the
existing equals-sign separator formatting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8ca67854-e377-4fd8-a3d8-a11d8fd20616

📥 Commits

Reviewing files that changed from the base of the PR and between 6d064bb and ad2ec89.

📒 Files selected for processing (17)
  • README.md
  • pod.yaml
  • scripts/README.md
  • scripts/__init__.py
  • scripts/benchmark_classifier.py
  • scripts/chat_helpers.py
  • scripts/classify_direct.py
  • scripts/reclassify_all.py
  • scripts/retry_errors.py
  • scripts/upgrade-prod.sh
  • scripts/verification/__init__.py
  • scripts/verification/verification_helpers.py
  • scripts/verification/verify_canonical_endpoints.py
  • scripts/verification/verify_direct_ollama_cooldown.py
  • scripts/verification/verify_ollama_cooldown.py
  • scripts/verification/verify_ollama_routing.py
  • start-stack.sh

Comment thread scripts/upgrade-prod.sh
Comment thread scripts/verification/verify_canonical_endpoints.py Outdated
…d, f-string typo

- upgrade-prod.sh: drop trailing slashes on rsync directory sources to prevent
  --delete from wiping .env/data/backups in PROD_DIR root (Gemini + CodeRabbit)
- upgrade-prod.sh: add [ -t 0 ] guard around interactive read prompt so the
  script doesn't fail with set -e in CI/cron/non-TTY environments (Gemini)
- verify_canonical_endpoints.py: fix \\n literal to actual newline escape
  in summary separator f-string (CodeRabbit)
@sheepdestroyer

Copy link
Copy Markdown
Owner Author

Closing in favor of a fresh PR with all review comments addressed. See #263.

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.

1 participant