Spaces:
Runtime error
Runtime error
File size: 8,408 Bytes
aacc29a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | # CarePath Unified Deploy
Use `https://carepath-medicaltranslation.vercel.app` as the public Scribe site. One Hugging
Face Space runs the Scribe tool at `/ghi-chep-lam-sang/`, the Scribe API at
`/api/v1/*`, and the retained Interpreter API at `/api/*` + `/ws/*`.
`/phien-dich-y-khoa/*` and `/console/*` are intentionally public 404s while
the Interpreter remains in development.
## Hugging Face Space
Reuse the existing Docker Space
[`tranth3truong/carepath-api`](https://huggingface.co/spaces/tranth3truong/carepath-api),
served at `https://tranth3truong-carepath-api.hf.space`. Deploy this unified
repository there; it retains the Interpreter API but does not serve the
unfinished Interpreter browser workflow.
1. Rebuild the existing `tranth3truong/carepath-api` Space with **Docker** as
the SDK. Create a replacement only if that Space is no longer available.
2. Copy `README.hf-space.md` to the Space as `README.md` so the Space has:
```yaml
---
title: CarePath
sdk: docker
app_port: 7860
---
```
3. Push this repo to the Space. The root `Dockerfile` builds `scribe/frontend/`
in a node stage (that build enforces the Vietnamese diacritics gate),
installs both API packages, pre-downloads the Gipformer int8 ONNX files, and
starts Uvicorn on port `7860`.
4. Set these Space secrets:
```text
LLM_PROVIDER=ckey
LLM_API_KEY=<your CKey key>
LLM_MODEL=gpt-5.4
TEAM_CODE=<shared internal demo code>
SOAP_RATE_LIMIT_PER_IP_HOUR=3
SOAP_RATE_LIMIT_PER_IP_DAY=10
SOAP_RATE_LIMIT_GLOBAL_DAY=100
APP_ENV=prod
CORS_ORIGINS=https://carepath-medicaltranslation.vercel.app
```
The interpreter defaults to mock mode, which returns `[vi->en] …` echoes. For
`/kham-song-ngu/` to actually translate on the deployed Space, add one more
secret:
```text
PROVIDER_MODE=ckey
```
It reuses `LLM_BASE_URL`, `LLM_API_KEY` and `LLM_MODEL` above — one CKey
account configures both modules. Measured latency across 50 turns: median 15s,
p90 54s, max 206s, so a live visitor waits. `PROVIDER_MODE=demo` is the
offline scripted scenario for the pitch laptop, not for a public URL, because
anything off-script falls back to a visible placeholder.
The public demo hub at `/thu-nghiem/` is built for both cases and reads
`GET /api/health` to decide what it may honestly offer:
| `provider_mode` | What the hub shows |
| --- | --- |
| `ckey` | Everything: the scripted sample, own-document upload, and the two-way conversation. |
| `demo` | The scripted sample only. Own-upload and the conversation panel are hidden, because in this mode `read_document` ignores the uploaded bytes and the canned map covers nothing a visitor would actually type. This is what makes `demo` safe on a public URL. |
| `mock` or unreachable | Nothing runnable, and a notice saying so. It never invents output. |
The sample path sends `X-CarePath-Sample: 1`, which forces scripted mode for
that one request, so samples stay instant and free even on `ckey`. Own-uploads
and conversation turns on `ckey` bill real tokens, capped at five runs per IP
per day by the `/api/demo/*` functions.
The `cloud` mode (Anthropic/OpenAI direct) additionally needs
`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, and a non-default `ADMIN_TOKEN`
(startup refuses `change-me` in cloud mode).
The Vercel site uploads Scribe audio directly to the Space, so its exact origin
must be present in `CORS_ORIGINS`. Add local Vite origins as comma-separated
values only when testing local frontends against the deployed API.
Requests with header `X-Team-Code: <TEAM_CODE>` bypass the SOAP rate limits
for internal doctor-comparison runs. Limited requests return HTTP `429`,
`Retry-After`, and JSON body
`{"detail":{"message":"...","retry_after_seconds":3600}}` — the Scribe tool
surfaces that message to the user.
## Local Docker Check
```powershell
docker build -t carepath .
docker run --rm -p 7860:7860 `
-e LLM_PROVIDER=ckey `
-e "LLM_API_KEY=$env:LLM_API_KEY" `
-e LLM_MODEL=gpt-5.4 `
-e APP_ENV=prod `
carepath
```
Keyless variant (mock ASR + offline LLM + mock interpreter — must also work):
```powershell
docker run --rm -p 7860:7860 `
-e ASR_PROVIDER=mock -e ALLOW_MOCK_ASR=true -e LLM_PROVIDER=offline `
carepath
```
In another terminal:
```powershell
curl.exe http://127.0.0.1:7860/api/v1/health
curl.exe http://127.0.0.1:7860/api/health
curl.exe -o NUL -w "%{http_code}`n" http://127.0.0.1:7860/
curl.exe -o NUL -w "%{http_code}`n" http://127.0.0.1:7860/ghi-chep-lam-sang/
curl.exe -o NUL -w "%{http_code}`n" http://127.0.0.1:7860/phien-dich-y-khoa/
curl.exe -X POST http://127.0.0.1:7860/api/v1/soap-notes `
-F "audio=@C:\path\to\demo.wav" `
-F "encounter_context=Phòng khám nội tổng quát"
```
## Canonical Vercel site
The `scribe/frontend/` directory is the static marketing deployment at
`https://carepath-medicaltranslation.vercel.app`:
1. In the Vercel project settings, change **Root Directory** from the removed
`apps/web-next` to `scribe/frontend` (framework/build/output come from
`scribe/frontend/vercel.json`).
2. Set these Vercel environment variables:
```text
VITE_API_BASE=
VITE_WS_BASE=https://tranth3truong-carepath-api.hf.space
DEMO_API_BASE=https://tranth3truong-carepath-api.hf.space
VITE_LEAD_ENDPOINT=<optional lead endpoint>
VITE_LEAD_EMAIL=<pilot contact email>
```
`VITE_API_BASE` is **empty on purpose** (DEC-0021). `vercel.json` rewrites
`/api/*` to the Space, so the browser calls its own origin and no
`CORS_ORIGINS` entry stands between the site and the backend. Setting it to an
absolute origin restores the cross-origin coupling that took both tool routes
down when the domain moved to `carepath-medicaltranslation.vercel.app` while
the Space still allowed only `carepath-omega.vercel.app`.
`VITE_WS_BASE` is required whenever `VITE_API_BASE` is empty: a Vercel rewrite
will not carry a websocket upgrade to an external host, so `/ws/*` still goes
direct. That is safe — the origin check in `scribe/carepath/main.py` is HTTP
middleware and never runs for a websocket scope.
`DEMO_API_BASE` is read server-side by the `/api/demo/*` functions, so the API
host no longer appears in the client bundle.
3. Earlier guidance here said not to add Vercel API rewrites because the Space
owns those routes. That is superseded: the `/api/*` rewrite is what makes the
API same-origin. It excludes `/api/demo/*`, which are Vercel functions.
The Vercel build runs `npm run validate:deploy` before compiling. It fails when
`VITE_API_BASE` is set but invalid, does not use HTTPS, contains a
query/fragment, or is not the bare `/` pathname; when both `VITE_API_BASE` and
`VITE_WS_BASE` are empty; or when an SPA route
in `src/App.tsx` has no matching rewrite in `vercel.json` — without one, a direct
visit to that route is a hard 404. Local and combined-service builds still use
same-origin fallbacks because the normal `npm run build` skips this
deployment-only check.
The interpreter console was deleted once `/kham-song-ngu/` replaced it; its
backend stays on the Space for the WebSocket API, and `/phien-dich-y-khoa/` and
`/console/` return an explicit 404. The pilot form remains client-side unless
`VITE_LEAD_ENDPOINT` is configured.
## Keep-Alive
The workflow in `.github/workflows/keepalive.yml` pings the Space every 12
hours. Set the GitHub repository variable:
```text
SPACE_URL=https://tranth3truong-carepath-api.hf.space
```
Then run **Actions > Keep HF Space Awake > Run workflow** once and confirm the
job succeeds.
## Final Smoke
1. Open the Space URL: the landing renders, Vietnamese by default, and the
English resolves under each prescription line within about two seconds.
2. Open `/kham-song-ngu/`, consent, start a visit, and type a Vietnamese dose.
Confirm the turn is gated and the patient pane shows nothing until you
confirm it.
3. Open `/ghi-chep-lam-sang/`, upload a short clip, and verify the SOAP draft renders
with the review banner.
4. Confirm `/phien-dich-y-khoa/` and `/console/` return HTTP 404.
5. Confirm `GET /api/v1/health` reports `llm_provider: ckey` and
`asr_ready: true`, and `GET /api/health` reports `provider_mode: ckey`.
Note the deploy commit shape: the Space's `README.md` carries the
`sdk: docker` frontmatter, so a plain branch push would overwrite it with the
repository README and break the Space's build configuration. Deploy by
building a commit that copies `README.hf-space.md` over `README.md` first.
|