Architecture
Turns each patient survey into two reports.Gemini writes the doctor's page.
A patient's survey becomes one named Cloud Task, and the renderer turns it into PDFs, with Gemini writing the doctor's page and, on demand, a panorex read under the founder's written ruleset. Every Gemini call retries and falls back through newer models, and the clinic email waits until both reports exist.
0.3 s
for an experience survey submit to return; the reports follow in the queue
2 of 2
reports before the clinic list gets an email. Until then it waits and retries
1.3 hours
from the first commit at 1:48 AM on Jun 19 to a branded shell on Cloud Run
6 Gemini calls
psychographic, panorex read, risk read, intake extract, feedback summary and voice, all through one fallback
New York --:-- simulated
Hover a part to trace what it touches. Click it for its notes.
- Built by me
- Managed by Google
- Outside system
- Main data path
- On demand
- Credentials cross
When it breaks
What each failure does, and what it does not do.
-
Gemini answers 429
The same model is tried three times with a growing wait, then the next model. Before Oct 23 a single 429 cost a clinic one patient's doctor report.
packages/lib/src/gemini-models.ts:5
-
A model is retired
A 404 skips that model for six hours on that instance, and one alert per retired model goes out, once.
apps/pdf-renderer/src/delivery-alerts.ts:130
-
Delivery dies halfway
The renderer answers 5xx while anything is missing and Cloud Tasks comes back; each retry only does what has not landed. The hourly sweep is the backstop.
apps/pdf-renderer/src/server.ts:647
What I tuned
Small choices that keep it fast and cheap.
-
Flash where speed matters
The feedback summary and voice transcription run on the flash chain with 60 and 45 second budgets. The reports use pro.
packages/lib/src/experience-summary.ts:218
-
CPU stays on after replying
Delivery kept dying after the response until v0.15.1 kept CPU allocated. Concurrency is 8 because each render forks a browser.
infra/cloudbuild.pdf-renderer.yaml:46
-
Default temperature on newer models
Our prompts pin a low temperature tuned on 2.5. Google's own guide says newer models loop at low values, so they get their default.
packages/lib/src/gemini-models.ts:238
Guards
Rules the code enforces, not rules people remember.
-
The model observes, code counts
The panorex read lists teeth. The destruction score and its band are recomputed in plain code, and the per arch rule is enforced in code.
packages/lib/src/cdf-generate.ts:20
-
Uncited points are dropped
Every point in the feedback summary must cite a real quote. One whose citation does not resolve is dropped in code, not trusted.
packages/lib/src/experience-summary.ts:16
-
No risk score for patients
The patient's copy is a cover and a one page summary with no risk score. The 0 to 200 number is for the doctor to explain in the room.
apps/pdf-renderer/src/templates/Report.tsx:175
