Ga naar inhoud

Atlas (Frontend)

De standalone Atlas-module is een vrije chatomgeving onder de route /atlas. Hij is een ander systeem dan de Atlas-zijbalk in de medicatiebeoordeling: die laatste leeft in src/features/medicatiebeoordeling/ en is aan een patientdossier gekoppeld. Deze pagina beschrijft uitsluitend de standalone module in src/features/atlas/.

UI-Architectuur & Design

Het scherm draait om de overgang van "denken" naar "antwoorden" met genummerde bronnen. AtlasScreen is de container die de thread-lifecycle, de SSE-streaming en de lokale berichtenstate beheert. Threads staan in een lade (ChatHistoryDrawer), het actieve gesprek in een lijst van ChatBubble-componenten.

  • AtlasScreen: hoofdcontainer. Beheert threads, het versturen van berichten, de SSE-streaming, de PubMed-goedkeuringsflow, de modelkeuze en het push-toestemmingsbanner.
  • ChatList / ChatBubble: tonen de berichtenstroom per rol (gebruiker versus assistent), met de redeneerfase en de bronnen onder elk assistent-bericht.
  • CitedMarkdown: de gedeelde markdown-renderer. Rendert het antwoord met react-native-markdown-display, past safeMarkdownRules toe, normaliseert math (normalizeMath) en plaatst [N]-citaties als CitationBadge. Tekst verschijnt met een gestaggerde fade-in reveal (gerespecteerd bij reduced-motion).
  • CollapsibleThinking / ThinkingPanel / ThinkingTimeline: tonen de gedachtegang van het model tijdens en na het streamen.
  • BronnenAccordion: uitklapbare bronnenlijst onder een assistent-bericht, met links en (voor richtlijn-bronnen) text-fragment anchors naar het origineel.
  • ToolApprovalCard: de akkoord/weiger-kaart voor een PubMed-zoekopdracht; RichtlijnenInfoModal legt de context uit.
  • ModelSelector: keuze tussen Atlas Pro en Atlas Fast; de keuze wordt via updateModelPreference op het account opgeslagen.
  • ReportMessageModal: meldt een assistent-bericht via reportAtlasThreadMessage.
  • EmptyState / StarterCard / AtlasChatSkeleton: lege-staat, suggestiekaarten en laad-skeleton.
graph TD
    A[AtlasScreen] --> H[ChatHistoryDrawer]
    A --> B[ChatList]
    A --> C[ChatComposer]
    A --> M[ModelSelector]
    B --> D[ChatBubble]
    D --> E[CollapsibleThinking]
    D --> F[CitedMarkdown]
    F --> G[CitationBadge]
    D --> S[BronnenAccordion]
    D --> T[ToolApprovalCard]
    D --> R[ReportMessageModal]

State & Data Flow

Streaming via SSE

Antwoorden komen binnen via Server-Sent Events. streamChat in api/atlas.ts kiest per platform: op web een fetch-reader, op native react-native-sse. De payload is { thread_id, message, client_platform }. De client verwerkt SSE-frames in handlePayload en roept per event-type een callback aan:

  • thinking: fragmenten van de redeneerfase.
  • guidelines_results / sources_ready: de geraadpleegde richtlijn-bronnen.
  • delta: tekstfragmenten van het antwoord.
  • tool_request: Atlas vraagt om akkoord voor een PubMed-zoekopdracht (toont ToolApprovalCard).
  • pubmed_searching / pubmed_results: voortgang van de literatuur-zoekactie.
  • system_warning: fair-use-waarschuwing (toont een toast).
  • done: einde van de stroom met de definitieve bronnen, geciteerde tekst en citatie-map.
  • error: foutmelding.

De PubMed-flow gebruikt aparte endpoints: streamPubMedSearch (akkoord) en streamToolDecline (weigeren) hervatten de stream zonder een nieuw bericht te sturen (payload { thread_id, client_platform }).

sequenceDiagram
    participant UI as AtlasScreen
    participant API as api/atlas.ts
    participant BE as Backend (/api/atlas/)

    UI->>API: streamChat(thread_id, message)
    API->>BE: POST /stream/ (SSE)
    BE-->>UI: thinking, sources_ready, delta...
    alt richtlijnen dekken vraag niet
        BE-->>UI: tool_request (search_pubmed)
        UI->>API: streamPubMedSearch / streamToolDecline
        API->>BE: POST /pubmed-search/ of /tool-decline/ (SSE)
        BE-->>UI: pubmed_results, delta...
    end
    BE-->>UI: done (sources, cited_text, citations)

Threads en push

Threads worden geladen via listChatThreads en getChatThread; verwijderen gaat via archiveChatThread (DELETE). Het push-toestemmingsbanner verschijnt eenmalig per apparaat, kort nadat een antwoord begint te streamen, en alleen na een directe actie van de gebruiker. De voorkeur wordt lokaal vastgelegd onder de sleutel atlas_push_prompt_seen_v1. Web gebruikt subscribeWebPush, native registerForPushToken.

  • Route: /atlas (app/atlas.tsx), die AtlasScreen rendert.
  • Gating: de route redirect naar /login zonder sessie en toont een forbidden-state zonder de permissie atlas.view.
  • De Atlas-zijbalk in /medicatiebeoordeling/[id]/[patientId] is een aparte module en valt buiten deze pagina.

Bestandsstructuur & Verantwoordelijkheden

  • src/features/atlas/screens/AtlasScreen.tsx: hoofdcontainer voor threads, streaming, PubMed-flow, modelkeuze en push-banner.
  • src/features/atlas/api/atlas.ts: SSE-streaming-client (web en native), thread-endpoints, modelvoorkeur en archiveren.
  • src/features/atlas/api/reportApi.ts: reportAtlasThreadMessage om een bericht te melden.
  • src/features/atlas/components/: chat-UI: ChatList, ChatBubble, ChatComposer, ChatHistoryDrawer, CitedMarkdown, CitationBadge, BronnenAccordion, CollapsibleThinking, ThinkingPanel, ThinkingTimeline, ToolApprovalCard, RichtlijnenInfoModal, ModelSelector, ReportMessageModal, EmptyState, StarterCard, skeletons/AtlasChatSkeleton.
  • src/features/atlas/lib/: hulpfuncties: source (bronlabels), normalizeMath, safeMarkdown-aanvulling, stripMarkdown, textFragment, recentThread, layout, useTokenLimitToast, thinkingMarkdownRules.
  • src/features/atlas/types.ts: lokale chat-types (ChatMessage, ChatThread).

Belangrijke bestanden

  • src/features/atlas/screens/AtlasScreen.tsx
  • src/features/atlas/api/atlas.ts
  • src/features/atlas/components/CitedMarkdown.tsx
  • src/features/atlas/components/ChatBubble.tsx