You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.9 KiB

How i-RCFA Works

This document explains how the memory-enabled i-RCFA application connects the chat screen, backend, databases, technical tools, and remote AI model.

The big picture

The AI is one worker inside the application, not the entire application.

User
  |
  v
React chat screen
  |
  v
Frontend nginx container
  |  /ircfa is removed here
  v
i-RCFA FastAPI backend :8005
  |
  +--> PostgreSQL: chat history, RCFA state, model configuration, memories
  |
  +--> Technical tools: sensor, reliability, PFI, RCFA and plant-status APIs
  |
  +--> Remote Gemma service
  |
  v
Streaming answer back to the browser

The current i-RCFA setup uses the established remote Gemma service. It does not use local Ollama, llama.cpp, or vLLM for the normal i-RCFA chat flow.

1. The browser

The React frontend is responsible for:

  • displaying messages;
  • sending the user's question;
  • sending the login token;
  • displaying streamed answer text;
  • displaying tool/status events and suggested questions.

The main chat request is in newChat.tsx. It sends a request to:

POST /ircfa/chat/stream

The request contains information such as:

{
  "messages": [
    {
      "role": "user",
      "content": "What is the condition of 3DP-FDR711F?"
    }
  ],
  "conversation_id": "...",
  "location_tag": "3DP-FDR711F"
}

The browser does not call Gemma directly.

2. Frontend nginx

The frontend container uses nginx as a proxy. The nginx configuration is in nginx.conf.

When nginx receives:

/ircfa/chat/stream

it removes the /ircfa prefix and forwards the request to the backend:

http://host.docker.internal:8005/chat/stream

Therefore the first part of the real request path is:

Browser -> nginx -> backend port 8005

Nginx also keeps the streaming connection open long enough for a remote model response.

3. FastAPI backend

The backend route is in router.py. The POST /chat/stream route:

  1. reads the incoming JSON;
  2. extracts the latest user message;
  3. reads the conversation and equipment information;
  4. reads uploaded files, if present;
  5. identifies the authenticated user;
  6. creates a structured ChatRequest;
  7. starts the main orchestration function in stream2.py.

The backend is the control center. It decides what context and tools are available to the AI.

4. The orchestration layer

The main function in stream2.py is the director of one chat turn. Before calling the model, it gathers:

  • recent conversation history;
  • the current RCFA state;
  • relevant private memories;
  • uploaded document content;
  • equipment and location information;
  • system instructions;
  • available technical tools.

It then builds the complete model input. Conceptually, the model receives:

System instructions:
  You are an RCFA assistant.
  Follow memory privacy rules.
  Use technical tools when necessary.

Conversation history:
  Previous questions and answers.

Relevant memory:
  Active private memories that match the current question.

Evidence:
  Sensor, reliability, PFI or document data.

Current question:
  The user's latest message.

The model does not receive the entire database. The backend selects and prepares the information first.

5. The remote Gemma service

The model adapter is gemma_llamacpp.py.

It converts the backend request into an OpenAI-compatible request to:

https://gemma.digitaltwin.my.id/v1/chat/completions

The request can include:

{
  "model": "...",
  "messages": [],
  "tools": [],
  "tool_choice": "auto",
  "stream": true
}

The active model information comes from the rcfa_model_config PostgreSQL table. This includes the model name, server URL, provider, streaming setting, and generation settings.

The backend therefore communicates with Gemma like this:

i-RCFA backend -> remote Gemma API

It does not normally communicate with local Ollama.

6. How technical tools work

Gemma cannot magically see the sensor or PFI database. The backend gives it a list of controlled tools.

Examples include tools for:

  • current sensor data;
  • historical sensor data;
  • current reliability data;
  • PFI predictions;
  • failure modes;
  • root-cause information;
  • plant status.

The tool loop looks like this:

User asks about sensor data
  |
  v
Gemma decides it needs sensor information
  |
  v
Gemma requests a technical tool
  |
  v
i-RCFA backend executes that tool
  |
  v
Tool calls the appropriate PFI/reliability API
  |
  v
Tool result returns to the backend
  |
  v
Backend gives the result back to Gemma
  |
  v
Gemma explains the result to the user

For PFI sensor information, the usual relationship is:

Gemma
  -> i-RCFA tool
  -> PFI API
  -> PFI database or system

The AI normally does not directly query the PFI database.

7. Where memory fits

Memory is loaded before the model is called.

The backend:

  1. searches memories belonging to the signed-in user;
  2. ignores archived memories;
  3. ignores expired memories;
  4. scores memories for relevance;
  5. gives pinned memories a small priority boost;
  6. places relevant memories into the model context.

Memory retrieval is implemented in stream2.py.

Memory saving happens after the response is completed. The backend only saves when the user explicitly asks it to remember something.

The save path:

User explicitly asks to remember something
  |
  v
Backend checks the request
  |
  +--> blocks obvious passwords, tokens and credentials
  |
  +--> checks for a duplicate
  |
  +--> checks the active-memory limit
  |
  v
Memory is saved to PostgreSQL

The assistant's answer is not automatically turned into a memory. An explicit user request is required.

8. Streaming the answer

The backend returns a streaming response instead of waiting for the complete answer.

During one response it can send:

  • answer text;
  • tool progress;
  • usage information;
  • RCFA state;
  • suggested questions;
  • error events.

The frontend reads these pieces from the response body and updates the chat screen while the answer is being generated.

Gemma produces a piece
  -> backend receives it
  -> backend sends it through the stream
  -> frontend reads it
  -> chat screen displays it

After the response is complete, the backend saves the conversation and any approved memory in the database.

9. What a 503 means

A 503 means that a service was temporarily unavailable. In the common i-RCFA case, the failing link is near the remote Gemma service:

Browser -> nginx -> i-RCFA backend -> remote Gemma -> 503

Possible causes include:

  • the remote model is overloaded;
  • the remote model is restarting;
  • too many requests arrived at once;
  • the remote proxy timed out;
  • the remote service temporarily rejected the request.

A Gemma 503 does not automatically mean that the PFI database, sensor timestamp, memory, or frontend is broken.

The useful debugging question is: which room failed?

Browser room       Did the request leave the browser?
Nginx room         Did the proxy forward it?
Backend room       Did FastAPI start orchestration?
Tool room          Did the PFI/reliability API respond?
Gemma room         Did the remote AI answer?
Database room      Did chat/memory saving succeed?

The complete request loop

1. Prepare context
2. Ask Gemma
3. Gemma may request a tool
4. Backend executes the tool
5. Backend returns the tool result to Gemma
6. Gemma writes the explanation
7. Backend streams the explanation to the browser
8. Backend saves the conversation

The most important architectural idea is that Gemma does not own the application. The backend controls what Gemma can see, which tools it can use, which user's memory it can receive, and how the final answer reaches the browser.

Main files

Responsibility File
Chat UI and streaming reader newChat.tsx
Frontend-to-backend proxy nginx.conf
FastAPI chat routes router.py
Main AI orchestration stream2.py
Remote Gemma adapter gemma_llamacpp.py
Model configuration config.py and rcfa_model_config
Memory privacy rules memory_policy.py
Memory lifecycle rules memory_lifecycle.py
Memory Lab UI MemoryLabModal.tsx