Pride deploy - #27
Merged
Merged
Pride deploy#27
Conversation
…wiring Adds a Dockerfile (repo-root build context, needed for sibling sdrf-proteomics/ cell-line tables), GitHub Actions build-and-push to GHCR, and plain kubectl manifests (namespace/configmap/secret/deployment/service/ ingress). LLM config is env-driven via the ConfigMap/Secret, no rebuild needed to change it. Also adds ROOT_PATH support to FastAPI for the path-prefixed ingress.
The k8s Deployment forces runAsUser/runAsGroup/fsGroup: 1000, but the Dockerfile created appuser with an arbitrary auto-assigned system UID, so chown -R appuser:appuser /app didn't match the runtime UID. The docker-entrypoint.sh index-build step then failed with PermissionError writing to backend/data/spec_index/ (confirmed in pod logs after the first deploy to hh-11 -- specIndexReady stayed false, chunkCount 0). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Add LLM_AUTH_HEADER so LlmClient can send X-API-Key instead of Authorization: Bearer, for OpenAI-compatible gateways that reserve the Authorization header for a different credential type. Defaults to Authorization: Bearer, unchanged for every other provider. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
…client
Found by replaying the real agent.py request against pride-llm-api's gateway:
vLLM's chat template rejects a messages array with more than one system-role
entry, or a system message anywhere but the first position ("System message
must be at the beginning"). agent.py built 3-6 separate system messages
(prompt, wizard context, step focus, skill, evidence, accession) plus a later
one injected mid-conversation when tool rounds are exhausted.
Fix: consolidate all leading system content into one message; the
mid-conversation "wrap up" reminder becomes a user-role message instead
(safe at any position).
Also: the failure above came back as HTTP 200 with the error embedded in an
SSE chunk, not a 4xx -- client.py only checked for a "choices" key, so it
silently dropped the error chunk and produced an empty response with no
error surfaced anywhere. Now raises LlmError with the upstream detail.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
…sting Adds an additional k8s deployment path for the Angular frontend, alongside the existing GitHub Pages and SSH-to-server deployments (untouched). Served at /pride/services/sdrf-editor -- built with --base-href baked in since Angular's client-side router ties routing to <base href>, unlike the backend's ingress-rewrite approach. backend-build-and-push.yml and frontend-build-and-push.yml now also trigger on push to this branch (pride-deploy), tagging images :pride for hh-11 testing without touching :latest (which only moves on a push to main). Both k8s deployments reference :pride accordingly. No real endpoint values or secrets are in this branch: configmap.yaml keeps the generic placeholder LLM_BASE_URL, and the actual pride-llm-api address plus all API keys are applied straight to the cluster via kubectl from gitignored, untracked local files (secret.yaml) -- never committed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Nothing in assistantUrlCandidates() could find the hh-11 backend: location.origin (tried first) assumes the backend is at the origin root (/api/health), but it's served under /pride/services/sdrf-assistant; the existing HOSTED_ASSISTANT_ORIGINS entries are for the sdrf.site deployment; and the compiled environment.assistantBaseUrl is the dev default (http://localhost:8000, no production environment file replaces it). Net effect: the assistant panel never appeared on the hh-11-deployed frontend. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
This model writes its reasoning inline in content (confirmed directly against the deployed gateway) rather than a separate field, so the panel was showing hundreds of tokens of chain-of-thought before the actual answer. SYSTEM_PROMPT now instructs the model to wrap reasoning in <think>...</think> before the final answer. Empirically (tested directly against the model) it reliably emits the closing </think> but usually omits the opening <think> -- it treats generation as already inside the block. ThinkingSplitter (new) accounts for this: each round is assumed to start "thinking" by default, suppressing content until </think>; if </think> never appears at all (model answered directly), flush() releases everything buffered so that text isn't silently lost. agent.py's two streaming rounds now emit one "Thinking..." status event per round instead of streaming the reasoning text itself -- only content after </think> streams as visible tokens. This also keeps the SSE connection alive throughout (avoiding the idle-timeout on slow responses discussed earlier) without exposing the reasoning to the user. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Builds started failing ("permission_denied: The requested installation does
not exist") once this repo moved orgs -- GITHUB_TOKEN's package-write scope
follows the repo's current owner, but IMAGE_NAME was hardcoded to the old
bigbio/ path. Compute it from github.repository instead (lowercased in
bash -- GHCR/Docker image names must be lowercase, GitHub Actions
expressions have no toLower(), and this org, "PRIDE-Archive", isn't already
lowercase). Updates the k8s deployment.yaml image references and READMEs to
match (ghcr.io/pride-archive/...).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Found by direct testing against the deployed model: it can spiral into repetitive reasoning for thousands of tokens before ever emitting </think>, getting cut off by the token cap while still "thinking." Since ThinkingSplitter's flush() has to release unclosed content rather than silently dropping a genuine no-think direct answer, that runaway text was landing on the user as-is -- the exact opposite of hiding chain-of-thought. ThinkingSplitter now exposes saw_close_tag so a caller can tell "answered directly" (flush() text is legitimate, any length) apart from "still mid-thought when the round ended" (flush() text is raw reasoning). agent.py replaces the latter with a short fallback message when it's implausibly long for a direct answer (>800 chars) -- text that already streamed live after a genuine </think> is never touched by this, whatever its length. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4DK78AWBWKoFPoQ1mNJqf
Build backend/frontend images and push to GitLab Container Registry, deploy to hh-11 via kubectl using GitLab CI/CD variables for secrets and kubeconfig instead of a manually-applied local secret.yaml. Layout follows pride-archive-api's .gitlab-ci.yml/.kubernetes.yml convention: one envsubst-templated kubernetes.yml per app, namespace and imagePullSecret created imperatively by the pipeline, ingress applied manually/once outside CI. Also fills in the backend ConfigMap's real pride-llm-api values (LLM_AUTH_HEADER, LLM_MODEL) and moves LLM_BASE_URL/EMBEDDING_BASE_URL to GitLab CI/CD variables rather than committed values -- both point at internal hh-44 worker hostnames, not something to put in a repo that's mirrored to public GitHub.
Replaces Chinese strings in the wizard AI assistant components (tool-call-list, wizard-ai-panel) and translates USER.md and the wizard mobile/AI implementation notes so the whole project is English-only.
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 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. Comment |
The workflow ran the plain \`pytest\` console script, which doesn't add the cwd to sys.path, so \`import app\` failed in CI even though tests pass locally with \`python -m pytest\` (as README.md documents). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011RMFv4AaKDNPeCQ9NFLCc3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.