Sibling ticket to oncofiles#441 + oncofiles#442
Oncofiles v5.12 Session 3 plans to ship a budget-gate that skips AI calls past the patient's monthly €10 (steady-state) or €30 (onboarding) budget. This ticket tracks Oncoteam's client-side handling of the new `ai_skipped` signal.
Oncofiles meta: oncofiles#453 (v5.12 Sprint)
Cost model: €30 onboarding (first 90 days) → €10 steady-state, rolling 30-day bucket
Pricing basis: Anthropic Haiku 4.5 token rates × USD→EUR
What changes on the Oncofiles side
- Migration 060 adds `patients.tier` (`free`|`paid`), `patients.onboarding_ends_at`, `patients.monthly_budget_eur`
- `prompt_log.estimated_cost_usd` (migration 058, already shipped) will be populated on every AI call via `log_ai_call()`
- Budget check runs before every `client.messages.create(...)` in `_enhance_document`:
```sql
SELECT SUM(estimated_cost_usd × USD_TO_EUR) FROM prompt_log
WHERE patient_id = ? AND created_at > datetime('now', '-30 days')
```
- On breach: skip the AI call, log `ai_skipped=True`, return a structured response indicating budget-exhausted state
Ways Oncoteam calls Oncofiles AI
Today's Oncoteam calls that invoke Oncofiles-side AI (and thus hit the budget gate):
- `call_oncofiles('enhance_documents', ...)` — bulk summary + tag + metadata
- `call_oncofiles('extract_document_metadata', ...)` — single-doc structured metadata
- `call_oncofiles('detect_and_split_documents', ...)` — multi-doc PDF detection
- `call_oncofiles('detect_and_consolidate_documents', ...)` — multi-file consolidation
- `call_oncofiles('backfill_ai_classification', ...)` — category backfill
Any of these can return `{"status": "budget_exhausted", "spent_eur": 10.23, "budget_eur": 10.00, "next_budget_reset": "2026-05-21"}` after oncofiles v5.12 ships.
What Oncoteam needs to handle
1. Parse the budget-exhausted response
Oncoteam's `call_oncofiles` wrapper should detect the new `status="budget_exhausted"` response and NOT treat it as a transient error (no retry — retrying will hit the same budget).
2. Surface to the caregiver gracefully
The UI should say something like: "Oncofiles budget reached for this patient this month (€10.23 / €10.00). AI processing pauses until 2026-05-21 or the caregiver upgrades." Non-AI paths (lab trend charts from existing stored values, document listing, search on existing metadata) still work.
3. Opt-out for user-initiated MCP tools
When a caregiver explicitly clicks "re-enhance this document", Oncoteam should pass `force=True` to bypass the budget check (same pattern as the AI_NIGHTLY_ONLY guards — user intent trumps budget). Oncofiles v5.12 preserves the `force=True` escape hatch.
4. Budget-aware scheduling
Oncoteam's autonomous cost-reduction (Sprint 92, oncoteam#404) should read the new `/api/patient-budget` endpoint to decide whether to skip overnight AI processing for patients already near budget — avoids burning the rest of the budget on non-urgent work.
5. Dashboard integration
Oncoteam dashboard (if it surfaces budget): use the same `/api/patient-budget` endpoint as Oncofiles. Shape:
```json
{
"patient_id": "...",
"spent_eur": 6.42,
"budget_eur": 10.00,
"tier": "free",
"onboarding_ends_at": "2026-07-15",
"in_onboarding": false,
"next_reset_at": "2026-05-21"
}
```
Timeline
- Oncofiles v5.12 Session 3: migration 060 + budget gate + dashboard pill (2026-04-23 or later)
- Oncoteam client handling: Oncoteam's own sprint cadence
- Integration test: end-to-end call from Oncoteam that hits the budget and handles gracefully
Out of scope (separate tickets)
- Full freemium paywall UI with upgrade flow (oncofiles#411)
- Stripe / billing integration (oncofiles future sprint)
- Prompt caching optimization (separate from budget gate)
- Per-tool cost attribution beyond Haiku 4.5 (add other models in v5.13+)
References
- Oncofiles sprint: oncofiles#453 (v5.12 meta)
- Cost budget memo (Oncofiles): `memory/project_cost_budget.md` — €10/€30 tiered free tier, monthly bucket NOT daily linear
- Related tickets: oncofiles#411 (freemium UI), oncofiles#441 (cost limiter v2), oncofiles#442 (tier plumbing)
Sibling ticket to oncofiles#441 + oncofiles#442
Oncofiles v5.12 Session 3 plans to ship a budget-gate that skips AI calls past the patient's monthly €10 (steady-state) or €30 (onboarding) budget. This ticket tracks Oncoteam's client-side handling of the new `ai_skipped` signal.
Oncofiles meta: oncofiles#453 (v5.12 Sprint)
Cost model: €30 onboarding (first 90 days) → €10 steady-state, rolling 30-day bucket
Pricing basis: Anthropic Haiku 4.5 token rates × USD→EUR
What changes on the Oncofiles side
```sql
SELECT SUM(estimated_cost_usd × USD_TO_EUR) FROM prompt_log
WHERE patient_id = ? AND created_at > datetime('now', '-30 days')
```
Ways Oncoteam calls Oncofiles AI
Today's Oncoteam calls that invoke Oncofiles-side AI (and thus hit the budget gate):
Any of these can return `{"status": "budget_exhausted", "spent_eur": 10.23, "budget_eur": 10.00, "next_budget_reset": "2026-05-21"}` after oncofiles v5.12 ships.
What Oncoteam needs to handle
1. Parse the budget-exhausted response
Oncoteam's `call_oncofiles` wrapper should detect the new `status="budget_exhausted"` response and NOT treat it as a transient error (no retry — retrying will hit the same budget).
2. Surface to the caregiver gracefully
The UI should say something like: "Oncofiles budget reached for this patient this month (€10.23 / €10.00). AI processing pauses until 2026-05-21 or the caregiver upgrades." Non-AI paths (lab trend charts from existing stored values, document listing, search on existing metadata) still work.
3. Opt-out for user-initiated MCP tools
When a caregiver explicitly clicks "re-enhance this document", Oncoteam should pass `force=True` to bypass the budget check (same pattern as the AI_NIGHTLY_ONLY guards — user intent trumps budget). Oncofiles v5.12 preserves the `force=True` escape hatch.
4. Budget-aware scheduling
Oncoteam's autonomous cost-reduction (Sprint 92, oncoteam#404) should read the new `/api/patient-budget` endpoint to decide whether to skip overnight AI processing for patients already near budget — avoids burning the rest of the budget on non-urgent work.
5. Dashboard integration
Oncoteam dashboard (if it surfaces budget): use the same `/api/patient-budget` endpoint as Oncofiles. Shape:
```json
{
"patient_id": "...",
"spent_eur": 6.42,
"budget_eur": 10.00,
"tier": "free",
"onboarding_ends_at": "2026-07-15",
"in_onboarding": false,
"next_reset_at": "2026-05-21"
}
```
Timeline
Out of scope (separate tickets)
References