- POST /dialog/{token}/events/stream: Server-Sent Events with the agent's steps («Смотрю вашу карту ЕМИАС…»,
«Ищу в клинических рекомендациях…»), the answer as the model writes it (OpenRouter stream=true), then the
final replies (same as /events, incl. the forbidden-output filter and sources). X-Accel-Buffering: no.
- Web: free-text messages use the stream — a live bubble with steps, typing dots and a cursor; falls back to
the plain request if the stream breaks.
- Phones: the bottom tab bar gets «Чат» (it had no way back to the chat).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Greetings / chit-chat answered without the LLM (instant, free, no medical findings dumped into «привет»).
- At most 4 tool calls per turn (one «как дела?» turn fired 23 parallel searches).
- «My drug» is never asked back; analogues → the drug's group, replacement only by the doctor.
- Markdown stripped to plain text with «•»; no sources footer under short replies.
- Diagnosis filter no longer blocks definitions («ПТСР — это расстройство…»); diagnosis-like statements about
the patient are still blocked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Idle chat: all messages go to the agent (greetings, side-effect and substitute questions included); check-in
signals are still recorded silently, quit intent keeps its rule reaction. Seen live: «какие будут побочки»
was logged as a complaint («Спасибо, отметил»), «привет» got a canned phrase.
- Agent prompt: warm short replies to small talk; substitutes → only the doctor changes the drug.
- ЕМИАС demo persona button creates a private copy too (starting from consent + questionnaires, subject to
the screening switch); the web app drops a stored session of the old shared demo account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A question asked mid-questionnaire, mid-check-in or during a crisis is answered right away (agent →
guidelines/instruction); the pending question is re-shown with its buttons (engine remembers the last
prompt), in a crisis the answer carries the emergency contacts and the crisis stays open until the doctor's
ack. Acute messages still get the fixed crisis script. OpenRouter blocks RF IPs: OPENROUTER_PROXY_URL routes
the agent through an HTTP proxy, as vobot does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clinical review of the questionnaires (ADR-013):
- Red-flag block first in stage 1 (config/instruments/red_flags.yaml); any «Да» stops the
questionnaire with an acute alert and the help screen of its category.
- One crisis rule: the crisis screen opens at a HIGH C-SSRS risk only; moderate stops and goes
to a psychiatrist (24 h as a guide), low is a flag with the safety plan. PHQ-9 item 9 with a
negative screener is a discrepancy flag; without a completed screener it asks the C-SSRS at once.
config/questionnaire.yaml: cssrs_positive_policy graded (C01).
- Every crisis leaves a callback task for the doctor on duty (post_crisis_call, one per patient)
and the app asks how the person is the next day, the safety plan one tap away.
- Routing: risk and flags first, scales second; PCL-5 >= 50 no longer means a priority
appointment (pcl5_severe is moderate on the dashboard too).
- Crisis numbers live only in config/texts/crisis.yaml; texts and the agent prompt refer to them
via {phone:<key>}. Fixes the children's helpline offered to adults by the chat agent.
Refs #92
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenRouter returns 403 «Access denied by security policy» from the RF server, and parsing that string error
crashed the request (500 instead of the fallback answer). Error parsing is robust now and any agent exception
degrades to the extractive answer. GigaChat tool provider (GigaChat-2-Pro by default) converts the agent's
OpenAI-style history to function_call / role=function; auto mode prefers GigaChat when credentials are set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live run through the API (Andrey, real OpenRouter): onset questions now answered from the instruction
excerpt, «можно пиво?» reaches the agent although the check-in records alcohol, quit intent keeps the single
rule reaction, findings are mentioned only for intake/combination questions, one retry on a provider error,
provider error message logged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live-tested on OpenRouter: Flash-Lite answers in 3–8 s with correct findings at ~$0.10/$0.40 per 1M tokens
(qwen3.7-flash and gpt-oss-120b took 26–32 s). Force a tool call on the first turn, give the model the
current prescription, let check_drug_for_patient default to it and return composition, intolerance check
and general interactions (alcohol); retry once on an empty final message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Free-text treatment and medication questions go to an LLM agent with read-only tools bound to the current
patient: guideline search (RAG, doses stripped), ЕМИАС record mock (diagnoses, comorbidities, intolerances,
other specialists' drugs, current prescription), drug info (composition, contraindications, interactions)
and a deterministic patient-specific check. Providers: OpenRouter (temporary, synthetic data only) and an
offline mock; GigaChat to follow. Scrubbed input only, forbidden-output filter, any failure falls back to
the existing extractive RAG / instruction answers. Off unless OPENROUTER_API_KEY or CHAT_AGENT=mock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>