Skip to content

chore: subdirectory routing, configurable domain, and deployment guidelines (PR #242 fixes)#243

Closed
sheepdestroyer wants to merge 19 commits into
masterfrom
chore/learn-deployment-guidelines
Closed

chore: subdirectory routing, configurable domain, and deployment guidelines (PR #242 fixes)#243
sheepdestroyer wants to merge 19 commits into
masterfrom
chore/learn-deployment-guidelines

Conversation

@sheepdestroyer

@sheepdestroyer sheepdestroyer commented Jul 8, 2026

Copy link
Copy Markdown
Owner

This PR resolves review comments from PR #242, syncs recent production changes from boy, and introduces subdirectory proxy routing.

Key Changes

  1. Subdirectory Routing & Dynamic Resolution:
    • Router dashboard URLs dynamically map /llm-routing/litellm, /llm-routing/langfuse, and /llm-routing/llama/ subdirectories depending on request headers/domain.
    • Fixed LiteLLM SERVER_ROOT_PATH and added PROXY_BASE_URL behind HAProxy.
    • Refactored hostname resolution to cleanly validate hostnames and port mappings while preventing HTML injection/XSS.
  2. Configurable Domain:
    • Extracted the production domain configuration to ROUTING_DOMAIN env variable in router/main.py (default: vendeuvre.lan).
  3. LiteLLM Health Probes:
    • Configured livenessProbe and readinessProbe to use direct in-pod endpoints (/ping and /health/readiness) rather than the reverse proxy paths.
    • Increased readiness probe delay to 45 seconds to prevent false startup failures.
  4. Synced Prod Updates from boy:
    • Re-enabled local-qwen-3.6 model on port 8081 in litellm/config.yaml.
    • Updated openrouter free model roster lists.
  5. Deployment guidelines (.agents/AGENTS.md):
    • Added production checklist for deployer agents under boy.
    • Cleaned up credentials, documented self-signed SSL cert verify commands, and added missing ssh boy prefixes.

Addressed PR #242 Review Fixes:

  • PUBLIC_BASE_URL slash normalization: Standardized PUBLIC_BASE_URL and LOCAL_BASE_URL to trim any trailing slash, preventing double slashes (e.g. //v1) in concatenations.
  • Sanitized pod.yaml placeholders: Reverted all hardcoded path (/mnt/DATA/boy/...) and user ID (1002) bindings back to generic WORKDIR_PLACEHOLDER, HOME_PLACEHOLDER, and RUN_USER_PLACEHOLDER templates, ensuring portability across multiple environments and restoring proper validation.
  • Deduplicated script scope: Centralized base URL configuration at the top of start-stack.sh right after environment file loading.
  • LiteLLM Fallback configurations: Re-enabled local-qwen-3.6 model in the fallback chains.
  • Sanitized Documentation: Removed remaining legacy developer paths (/home/gpav/...) from README.md and comments.

Summary by Sourcery

Introduce subdirectory-aware routing and environment-driven public URLs while sanitizing deployment templates and documentation for portability.

New Features:

  • Add dynamic dashboard link generation that routes Langfuse, LiteLLM, and llama-server through /llm-routing subpaths based on the external hostname and configured routing domain.
  • Expose PUBLIC_BASE_URL and LOCAL_BASE_URL environment-derived configuration for user-facing entrypoints and proxy URLs.

Bug Fixes:

  • Normalize public and local base URLs to avoid double slashes in routed endpoints and derived proxy base URLs.
  • Harden dashboard URL construction by validating hostnames/netlocs to avoid malformed URLs and potential injection issues.

Enhancements:

  • Parameterize router domain via a ROUTING_DOMAIN environment variable with a sensible default for production.
  • Re-enable the local-qwen-3.6 model, wiring it to the updated llama.cpp port and integrating it into LiteLLM fallback chains.
  • Increase LiteLLM readiness probe delay and switch health checks to in-pod endpoints for more reliable startup in the pod spec.
  • Restore pod.yaml and stack templates to use generic WORKDIR, HOME, and RUN_USER placeholders for paths and DBus configuration.
  • Update deployment script output to surface externally-routable URLs, including the dashboard and LiteLLM admin UI.
  • Generalize hardcoded local filesystem paths in code comments and README references to be environment-agnostic.

Documentation:

  • Add a production deployment checklist and GitHub operations policy for the boy environment, including HAProxy, agy daemon, and verification steps.
  • Retitle and relink the primary NotebookLM knowledge base and clean up user-specific path references in README and comments.

sheepdestroyer and others added 18 commits July 8, 2026 21:04
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…al_host/port resolution, fix agy startup SSH commands
…add fallbacks, avoid duplicate variables)
…PLACEHOLDER, HOME_PLACEHOLDER, and RUN_USER_PLACEHOLDER
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

An error occurred during the review process. Please try again later.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/learn-deployment-guidelines

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 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Implements subdirectory-aware routing and configurable public/local base URLs, wires LiteLLM behind HAProxy with SERVER_ROOT_PATH/PROXY_BASE_URL, hardens hostname/domain handling in the dashboard, restores portable pod.yaml templating, re-enables the local-qwen-3.6 model, and adds a concrete production deployment checklist for the boy host.

Sequence diagram for subdirectory-aware dashboard routing

sequenceDiagram
    actor User
    participant HAProxy
    participant Router as FastAPI_Router

    User->>HAProxy: HTTPS GET /llm-routing/dashboard
    HAProxy->>Router: GET /dashboard

    Router->>Router: get_dashboard(request)
    alt BASEURL or BASE_URL set
        Router->>Router: urlparse(external_host_env)
        Router->>Router: validate external_host, external_netloc
    else no external host env
        Router->>Router: use request.base_url
        Router->>Router: validate hostname/netloc
    end

    Router->>Router: domain = ROUTING_DOMAIN or vendeuvre.lan
    alt external host in ROUTING_DOMAIN
        Router->>Router: langfuse_url = https://external_netloc/llm-routing/langfuse
        Router->>Router: litellm_url = https://external_netloc/llm-routing/litellm/ui
        Router->>Router: llama_url = https://external_netloc/llm-routing/llama/
    else base_url in ROUTING_DOMAIN
        Router->>Router: base = scheme://netloc
        Router->>Router: langfuse_url = base + /llm-routing/langfuse
        Router->>Router: litellm_url = base + /llm-routing/litellm/ui
        Router->>Router: llama_url = base + /llm-routing/llama/
    else fallback (non-matching domain)
        Router->>Router: langfuse_url = http://external_host:3001
        Router->>Router: litellm_url = http://external_host:4000/ui
        Router->>Router: llama_url = http://external_host:8080
    end

    Router->>Router: get_dashboard_data()
    Router-->>HAProxy: HTML dashboard (links use langfuse_url, litellm_url, llama_url)
    HAProxy-->>User: HTML response
Loading

File-Level Changes

Change Details Files
Normalize and centralize public/local base URLs and inject them into pod.yaml rendering and user-facing output.
  • Derive PUBLIC_BASE_URL/LOCAL_BASE_URL once in start-stack.sh from env/BASE_URL variants, force https scheme and /llm-routing suffix, and strip trailing slashes.
  • Export PUBLIC_BASE_URL into the pod.yaml renderer, validate presence of a new PROXY_BASE_URL placeholder, and compute PROXY_BASE_URL as PUBLIC_BASE_URL + /litellm in the inline Python.
  • Update deployment success logs to reference PUBLIC_BASE_URL and LOCAL_BASE_URL for API, dashboard, and LiteLLM admin URLs instead of hard-coded localhost ports.
start-stack.sh
Make router dashboard links domain- and subdirectory-aware while validating hostnames to avoid XSS/HTML injection and misrouted links.
  • Extend the /dashboard handler to inspect BASEURL/BASE_URL env vars or the incoming request to derive a sanitized external_host/external_netloc.
  • Introduce ROUTING_DOMAIN (default vendeuvre.lan) and enforce strict domain matching for both external URL and request.base_url.
  • Compute Langfuse, LiteLLM, and llama URLs using https and /llm-routing/* subpaths when the host is within the routing domain, otherwise fall back to localhost:3001/4000/8080, and interpolate these into the HTML template instead of hard-coded localhost links.
router/main.py
Adjust pod definition for generic, portable host paths and wire LiteLLM to run behind a /llm-routing/litellm proxy with correct health probes.
  • Add SERVER_ROOT_PATH=/llm-routing/litellm and PROXY_BASE_URL envs to the LiteLLM container and point PROXY_BASE_URL at a template placeholder.
  • Increase LiteLLM readinessProbe initialDelaySeconds from 10 to 45 and probe the in-pod readiness endpoint directly.
  • Replace all hard-coded /home/gpav and /run/user/1000 host paths in volumes and env with WORKDIR_PLACEHOLDER, HOME_PLACEHOLDER, and RUN_USER_PLACEHOLDER for portability, including DBUS paths/mounts.
pod.yaml
Update the pod.yaml rendering script to use placeholder-based paths and support the new proxy base URL parameter.
  • Replace hard-coded absolute HOME/WORKDIR/RUN_USER paths in the Python renderer with WORKDIR_PLACEHOLDER, HOME_PLACEHOLDER, and RUN_USER_PLACEHOLDER and ensure these placeholders are enforced.
  • Extend the required placeholder list to include PROXY_BASE_URL_PLACEHOLDER and map it to an encoded PROXY_BASE_URL computed from PUBLIC_BASE_URL.
  • Keep password and key placeholders plus unresolved placeholder detection to fail fast on stale templates.
start-stack.sh
Re-enable the local-qwen-3.6 model and integrate it into LiteLLM fallback chains using the new 8081 llama.cpp endpoint.
  • Uncomment local-qwen-3.6 entries in all relevant fallback chains so agents can transparently fall back to the local model.
  • Add a new model_list entry mapping local-qwen-3.6 to api_base http://127.0.0.1:8081/v1 with a 300s timeout, documenting the llama.cpp port change in comments.
litellm/config.yaml
Sanitize and generalize documentation and comments, and add a production deployment runbook for the boy host.
  • Rename the NotebookLM knowledge base and link in AGENTS.md and append a detailed production deployment checklist for the boy user including one-time host setup, fresh deploy steps, HAProxy/agy daemon commands, and GitHub CLI usage rules.
  • Replace remaining developer-specific absolute paths in README, AGENTS docs, and agy_proxy comments with generic /path/to/… or home-based paths, and fix the memory MCP link to be repo-relative.
  • Clarify systemd ProtectHome description to refer generically to the user home directory.
.agents/AGENTS.md
README.md
router/agy_proxy.py

Possibly linked issues

  • #LHF-03: PR introduces LITELLM_URL/LLAMA_SERVER_URL/LANGFUSE_URL and updates dashboard links, resolving hardcoded endpoint bindings in router/main.py.

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

@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:

  • The get_dashboard handler is introducing another set of URL/domain env vars (BASEURL/BASE_URL/ROUTING_DOMAIN) while start-stack.sh now derives a normalized PUBLIC_BASE_URL; consider centralizing this base URL/domain resolution into a single helper or env convention to avoid subtle drift between shell and Python logic.
  • In get_dashboard, the logic that parses and validates external_host_env and request.base_url (hostname/netloc, scheme) is fairly involved and duplicated in branches; extracting this into a small utility (e.g., resolve_external_base(request)) would make the routing rules easier to reason about and safer to evolve.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `get_dashboard` handler is introducing another set of URL/domain env vars (`BASEURL`/`BASE_URL`/`ROUTING_DOMAIN`) while `start-stack.sh` now derives a normalized `PUBLIC_BASE_URL`; consider centralizing this base URL/domain resolution into a single helper or env convention to avoid subtle drift between shell and Python logic.
- In `get_dashboard`, the logic that parses and validates `external_host_env` and `request.base_url` (hostname/netloc, scheme) is fairly involved and duplicated in branches; extracting this into a small utility (e.g., `resolve_external_base(request)`) would make the routing rules easier to reason about and safer to evolve.

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.

@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 updates the LLM Routing project by replacing hardcoded user paths with generic placeholders across configuration files (such as pod.yaml, README.md, and start-stack.sh) to support flexible deployments. It re-enables the local-qwen-3.6 model in LiteLLM, updates the free models roster, and enhances the router dashboard to dynamically resolve and validate base URLs with strict domain validation. Additionally, it adds a production deployment checklist and GitHub operations policy to the agent documentation. No review comments were provided, so there is no feedback to address.

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.

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