Overview

RAG Chatbot

Angular component <wuic-rag-chatbot> that allows querying the WUIC codebase

in natural language, with two operating modes: pure retrieval

(top-K code snippets) and RAG + LLM (response generated by Claude using

the top-K as context). Automatically degrades to retrieval-only if the Claude

API key is not configured on the server.

Architecture

3-layer stack, all already deployed in the project:

  • Layer 1 -- Python FastAPI server rag_server.py on 127.0.0.1:8765,

loads at boot the hybrid BM25 + bge-m3 + LoRA cross-encoder Phase C index

from c:/src/Wuic/codebase_embeddings/.

  • Layer 2 -- C# bridge RagController in KonvergenceCore (/api/Rag/Query,

/api/Rag/Chat, /api/Rag/Health, /api/Rag/Reload), authenticated proxy

via k-user cookie.

  • Layer 3 -- Angular standalone component <wuic-rag-chatbot> exported

from wuic-framework-lib.

See also the operational skill skills/rag-chatbot-creation/SKILL.md for the

end-to-end creation/maintenance playbook, and

skills/rag-rebuild-pipeline/SKILL.md for the index/LoRA rebuild.

Page context and dynamic metadata retrieval

When the user chats from an app page, the component injects a **minimal page

context** into the prompt: only the current route/page (e.g. cities/list,

cities/edit, designer). It does NOT inline the column list, SQL identity or

lookup details — inlining them bloated every request regardless of the prompt and

saturated the context window.

The missing details are fetched on-demand by the model via the non-terminal

tool request_metadata_detail, resolved on the backend by

RagController.ResolveMetadataDetail (the engine has no access to the metadata DB).

The model calls the tool, receives the result as a tool_result, and ONLY THEN

emits the propose_* with the real names. The multi-turn loop is handled by the

engine (max 3 retrieval turns).

Supported detail:

detailReturnsWhen
columnsSQL identity (schema/table + full qualifier) and the real column list (name, type, lookup, required, pk, SQL name)the real column names of a route are needed
lookup_columnsjoin_alias, value_field, text_field, related_route, related_columns[] of a lookupByID columncomposing a SQL snippet on a lookup

Join-alias convention (lookup): the WUIC auto-generated query joins the related

table of a lookupByID column with alias <column>_<entity> (e.g. the StateProvinceID

column looking up stateprovinces has alias StateProvinceID_stateprovinces). In SQL

snippets the related table fields are referenced as [<join_alias>].[<col>], e.g.

[StateProvinceID_stateprovinces].[StateProvinceName]. The exact alias value must

always be obtained via request_metadata_detail{detail:'lookup_columns'}, never

deduced by hand.

The mechanism is extensible: new detail kinds (e.g. physical_columns, related_routes,

enum_values) are added in the resolver without touching the Angular component or

bloating the context.

Modes

mode inputBehavior
auto (default)Uses chat if the backend exposes a Claude API key, otherwise retrieval
chatForces RAG + LLM. If the API key is missing, the backend returns mode=retrieval-only with a visible warning
retrievalForces retrieval-only, skips the LLM call (useful to reduce costs)

Inputs

InputTypeDefaultDescription
titlestring'Assistente codebase WUIC'Header label
mode'auto' | 'chat' | 'retrieval''auto'Operating mode
topKnumber5Number of chunks to retrieve from the RAG
showSourcesbooleantrueShows/hides source chips in assistant messages
maxHistorynumber20Maximum number of turns kept in memory
placeholderstring'Chiedi qualcosa...'Input placeholder
modelstring'claude-haiku-4-5-20251001'Claude model for chat mode
chatHeightstring'420px'Fixed chat area height
showClearButtonbooleantrueShows the "Clear history" button

Outputs

OutputPayloadDescription
resultSelectedRagSourceClick on a source chip; the component also attempts a deep-link vscode://file/...
errorOccurred{message, details?}Non-recoverable HTTP errors
turnAddedRagChatbotTurnEmitted after each turn (user or assistant) added to the history

Usage Example

Standalone import in the parent component:

  • HTML selector: <wuic-rag-chatbot mode="auto" [topK]="5" (resultSelected)="onSrc($event)"></wuic-rag-chatbot>
  • TypeScript import: import { WuicRagChatbotComponent, RagSource } from 'wuic-framework-lib';
  • Add WuicRagChatbotComponent to the standalone parent component's imports.

For a complete demo page with debug aside and event handling, see

WuicTest/wwwroot/src/app/component/rag-chatbot-demo-page/.

Auth

All HTTP calls are sent with withCredentials: true and the C# bridge

applies the same authentication checks as other WUIC controllers

(session cookie k-user, rule 10 of AGENTS). Never expose the Python server

127.0.0.1:8765 directly to the browser: it must always be proxied

through C#.

WuicRagService Service

Typed API over RagController, exported from wuic-framework-lib.

Three main methods:

  • query(text, {topK, useLora}) -> Observable<RagQueryResponse>
  • chat(text, history, {topK, model}) -> Observable<RagChatResponse>
  • health() -> Observable<RagHealthResponse>
  • reload() -> Observable<{status, ...}> (post RAG rebuild)

*Async variants return Promise via firstValueFrom().

All interfaces RagSource, RagQueryResponse, RagChatResponse,

RagHealthResponse, RagChatTurn are exported.

Claude Model

Default: claude-haiku-4-5-20251001 (fast, native Italian, ~$0.001 per

5-chunk query). Override possible via the component's [model] input

or by passing options.model to the service's chat() method.

System prompt used server-side:

> You are an expert assistant for the WUIC codebase. Answer the user's question

> using EXCLUSIVELY the provided context. If the answer is not in the context,

> reply 'I did not find enough information in the codebase to answer.'

> Always cite relevant files in square brackets in the format

> [file.ext::OptionalSymbol]. Reply in Italian unless another language is

> explicitly requested. Do not make up APIs or method names: if they are not

> in the context, say so explicitly.

Automatic Fallback

When the backend detects one of these conditions, the response includes

mode: 'retrieval-only' + warning + sources:

  • ANTHROPIC_API_KEY not set on the Python server
  • Claude call failed (HTTP error, rate limit, unknown model, etc.)

The Angular component interprets response.mode === 'retrieval-only' and shows

in the assistant turn a textual summary of the top-K chunks + the warning banner,

so the user still sees useful results.

Runtime Prerequisites

  • Python server rag_server.py active on 127.0.0.1:8765 (see skill

rag-chatbot-creation for the NSSM setup in production)

  • KonvergenceCore running (exposes /api/Rag/...)
  • Login with a valid session k-user cookie
  • (Optional) ANTHROPIC_API_KEY env var on the Python server for chat mode

Getting Started (first use)

If, when accessing the rag-chatbot route from the menu, you see the banner

"RAG server unreachable" with status RAG offline, it means the

Python server is not listening.

Prerequisites: Python 3.12 (winget install Python.Python.3.12)

Setup and startup with rag-setup.ps1

The rag-setup.ps1 script automates the venv creation and the installation

of the dependencies. It works both from the source repository and from a

deploy ZIP package (the RAG files are included in both).

Snippet 1PowerShell
# Setup (one time only) — creates venv, installs torch + dependencies
pwsh scripts/rag-setup.ps1

# For CUDA GPU (optional, faster)
pwsh scripts/rag-setup.ps1 -CudaVersion 12.1

# Start the server

The cold start takes ~13 seconds (index + LoRA loading). Once the log

shows Uvicorn running on http://127.0.0.1:8765, reload the page in the

browser: the banner disappears and the chatbot switches to operating mode.

For production (persistent Windows service) see the skill

skills/rag-chatbot-deploy/SKILL.md.

Hot-reload After RAG Rebuild

After regenerating the index/LoRA with the rag-rebuild-pipeline skill, just

call:

  • POST /api/Rag/Reload (via WuicRagService.reload())
  • or restart the Python service

to reload the new index without application downtime.

Tests

The service and component tests are in:

  • projects/wuic-framework-lib/src/lib/service/wuic-rag.service.spec.ts (14 tests)
  • projects/wuic-framework-lib/src/lib/component/rag-chatbot/rag-chatbot.component.spec.ts (18 tests)

Runnable with npm run test:unit:wuic-lib (vitest, default lib runner

post karma->vitest migration).

References

  • Creation skill: skills/rag-chatbot-creation/SKILL.md
  • RAG rebuild skill: skills/rag-rebuild-pipeline/SKILL.md
  • Python server: c:/src/Wuic/codebase_embeddings/rag_server.py
  • C# bridge: c:/src/Wuic/KonvergenceCore/Controllers/RagController.cs
  • Angular service: projects/wuic-framework-lib/src/lib/service/wuic-rag.service.ts
  • Component: projects/wuic-framework-lib/src/lib/component/rag-chatbot/rag-chatbot.component.ts
  • Demo page: c:/src/Wuic/WuicTest/wwwroot/src/app/component/rag-chatbot-demo-page/