Commit Graph
15 Commits
Author SHA1 Message Date
ElebobaandClaude Opus 5.5 c489ddbdc4 feat(bot): chat answers questions in any state; OpenRouter via proxy from the RF server
CI / ruff · pytest (pull_request) Successful in 2m53s
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>
2026-10-04 17:42:03 +03:00
Arxip222andClaude Opus 5.5 44814b7293 fix(clinical): red flags, one crisis rule, callback after a crisis, one table of numbers
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>
2026-10-04 16:21:16 +03:00
ElebobaandClaude Opus 5.5 ade93d959b feat(bot): GigaChat function-calling provider for the chat agent; never 500 on provider errors
CI / ruff · pytest (pull_request) Successful in 2m15s
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>
2026-10-04 15:46:21 +03:00
ElebobaandClaude Opus 5.5 83ad5d8b33 fix(bot): chat agent — ГРЛС excerpts in drug check, questions with alcohol answered, retry, clearer logs
CI / ruff · pytest (pull_request) Successful in 2m13s
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>
2026-10-04 15:20:18 +03:00
ElebobaandClaude Opus 5.5 9ec61b9a03 feat(bot): chat agent on Gemini 2.5 Flash-Lite — grounded first turn, current-prescription defaults
CI / ruff · pytest (pull_request) Successful in 2m5s
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>
2026-10-04 14:59:38 +03:00
ElebobaandClaude Opus 5.5 6dda5f9b30 feat(bot): tool-using chat agent over RAG, ЕМИАС record and drug-safety reference
CI / ruff · pytest (pull_request) Successful in 2m10s
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>
2026-10-04 14:39:16 +03:00
ElebobaandClaude Opus 5.5 b72af71e66 feat(bot): answer treatment questions from the clinical-guideline knowledge base
CI / ruff · pytest (pull_request) Successful in 1m30s
- menu button «Вопрос о лечении» -> kb.question -> rag.answer (KR quote + source)
  or «уточните у врача»; dose questions get a fixed doctor redirect
- free text in idle that looks like a question (no check-in signals, not a drug
  question) -> knowledge base; no answer -> the usual support phrase
- routing order unchanged: consent/safety first, side effects/quit/alcohol -> check-in,
  own drug -> med_qa (instruction only, SPEC §7 p.5)
- question cues, small talk and texts in config/texts/knowledge.yaml; scrub placeholders
  before "что такое X" no longer hide the definition question

Refs #64

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:27:42 +03:00
ElebobaandClaude Opus 5.5 fe29ebd629 fix(llm): RAG citation pages, scrub placeholders, disease-aware document choice
CI / ruff · pytest (pull_request) Successful in 1m2s
- converter marks a paragraph glued across a page break with ⟦стр. N⟧; the chunker
  strips the marker and extends the chunk's page range (wrong-page citations 24 -> 3,
  the rest are scale-form table rows split by a page)
- [NAME]/[PHONE] placeholders from privacy.scrub() no longer count as unknown words
  (a scrubbed question used to fall below the coverage gate)
- a question naming one disease boosts its guideline in retrieval and passage choice
  ("ТМС при депрессии" was answered from the PTSD guideline); "антидепрессант" is not a cue

Refs #62

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 04:31:59 +03:00
ElebobaandClaude Opus 5.5 6a77831603 feat(llm): RAG knowledge base over clinical guidelines with cited extractive answers
CI / ruff · pytest (pull_request) Successful in 1m30s
- docs/source/rag: PDF sources (KR PTSD 2023, KR depression 2024, meds module spec),
  pdf->txt converter (tables as markdown, page markers, hand-transcribed figures),
  word-level check against pdftotext; fixes HAM-D/MADRS fake headers and split rows
- config/rag: corpus txt + sources.yaml (documents, audiences, retrieval params, synonyms)
- app/llm/rag: Snowball stemmer, section-aware chunker with page citations,
  BM25 + synonym expansion + densest-passage reranking, extractive answer()
  with coverage gate, patient dose/prescribing filter, optional LLM rephrasing
  rejected when it adds content; CLI python -m app.llm.rag
- tests: gold retrieval set (hit@3 >= 15/18), off-topic, safety, faithfulness
- ADR-011

Refs #60

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 04:11:06 +03:00
Eleboba 67cfe29c58 Merge pull request 'feat(bot): LLM-саммари динамики для врача' (#49) from feat/19-doctor-summary into dev
CI / ruff · pytest (push) Successful in 24s
2026-10-03 15:34:46 +03:00
ElebobaandClaude Opus 5.5 49d5f8a4e5 feat(bot): add doctor summary built from structured card data
CI / ruff · pytest (pull_request) Successful in 24s
build_structured() aggregates a PatientCard into scores, flags and
adherence (no patient text, no names); build_summary() sends it through
the LLM gateway, falls back to a config-driven template, keeps an open
acute alert first and caches per (token, provider, data hash).

Refs #19

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:33:37 +03:00
ElebobaandClaude Opus 5.5 51cc259002 feat(bot): med_qa answers about the drug only from ГРЛС excerpts
CI / ruff · pytest (pull_request) Successful in 21s
Topic from engine or keyword classifier, section via integrations.drug_info,
sentence retrieval by keyword overlap (dosing sentences dropped), LLM only
rephrases the excerpt through gateway.phrase("med_answer") with forbidden-output
and added-content guards; dose questions and missing answers -> None + fallback text.

Refs #15

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:32:48 +03:00
ElebobaandClaude Opus 5.5 b4731fb1d6 chore(core): stage 1 contracts — dialog, API schemas + fixtures, integrations, monitoring, modules
CI / ruff · pytest (pull_request) Successful in 22s
Freeze interfaces between lanes A (bot), B (backend), C (dashboard) so three developers work in
parallel without touching each other's files: dialog Event/Reply + engine registry with echo stub,
integration protocols with in-memory defaults, MonitoringService with noop stub, /api/v1 schemas
with fixture-backed routes, frozen main.py wiring, config/modules.yaml + due_scales(), DAR-5,
tzdata, Andrey trajectory, lanes in WORKFLOW, ADR-010.

Refs #34

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:22:25 +03:00
ElebobaandClaude Opus 5.5 924a51c483 feat(bot): LLM gateway with GigaChat and offline mock providers
CI / ruff · pytest (pull_request) Successful in 23s
Single entry point app/llm/gateway.py: extract_item, extract_checkin,
risk_classify, phrase, summarize_for_doctor. Two-level design:
LLMProvider (transport, GigaChat) and LLMTasks (PromptedTasks over a
provider, or rule-based MockTasks). Shared policy in the gateway:
assert_scrubbed backstop, confidence threshold 0.5, risk failure -> NONE,
forbidden-output filter with config/texts/phrases.yaml fallbacks.

Refs #7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:00:41 +03:00
ElebobaandClaude Opus 5.5 107b8dba51 chore(devops): project skeleton — uv, docker compose, Makefile, CI
CI / ruff · pytest (pull_request) Successful in 1m50s
One Postgres with isolated identity/clinical databases and roles (ADR-003),
FastAPI /health, Streamlit placeholder, typed settings with offline defaults.

Refs #1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:46:01 +03:00