How sourcefuse/loopback4-llm-chat-extension works
1. This repository is a reusable LoopBack 4 component package, not a standalone app. The host application imports AiIntegrationsComponent-style pieces from src/component.ts and binds providers/configuration to expose chat and generation endpoints. The architecture is centered on dependency injection and graph-driven orchestration.
2. The top-level functional split is:
- core chat orchestration (src/graphs/chat, src/controllers/chat.controller.ts, src/services/generation.service.ts)
- database query generation (src/components/db-query)
- visualization generation (src/components/visualization)
Each is packaged as a component with its own state, nodes, tools, services, and controller surface.
3. The main request entry points are HTTP controllers and a transport layer. src/transports/http.transport.ts and src/transports/sse.transport.ts indicate the system can return synchronous HTTP responses or streamed SSE responses. Controllers such as generation.controller.ts, chat.controller.ts, dataset.controller.ts, and template.controller.ts are the public API boundary into the internal graphs.
4. Core chat flow is graph-based. src/graphs/chat/chat.graph.ts runs a sequence of nodes such as session initialization, LLM invocation, tool execution, context compression, summarization, and session end. The graph stores conversational state in src/graphs/chat/chat.store.ts and persists messages/chats through repositories. This is the main runtime loop for interactive LLM conversations.
5. Tool execution is a first-class subsystem. Tools are registered via decorators in src/decorators/tool.decorator.ts and src/providers/tools.provider.ts, then executed by the chat graph’s run-tool node. This is how the package turns domain-specific capabilities into LLM-available actions without hardwiring them into the chat logic.
6. The db-query component is the biggest domain-specific subsystem. It turns a user prompt into a structured dataset rather than raw SQL, using a dedicated graph in src/components/db-query/db-query.graph.ts. Its nodes handle permissions, cache checks, schema/table discovery, column discovery, SQL generation, semantic and syntactic validation, query fixing, classification of changes, and saving datasets. The component also exposes tools like generate-query, improve-query, and ask-about-dataset.
7. Database access is isolated behind connector abstractions. src/components/db-query/connectors/pg/pg.connector.ts, rls-pg.connector.ts, and sqlite.connector.ts implement the DB boundary for PostgreSQL, PostgreSQL with row-level security, and SQLite. This lets the generation pipeline work against different dialects while keeping query generation logic mostly independent of storage details.
8. Persistence is split into a chat store and a dataset store. Repositories under src/repositories handle chats/messages, while src/components/db-query/repositories handle datasets and dataset actions. The README and migration files show the package expects a dedicated chatbot schema with datasets, dataset_actions, chats, and messages, so the data layer is a distinct persistence boundary rather than incidental app storage.
9. Knowledge and context enrichment are handled by helper services rather than by the LLM directly. db-schema-helper, permission-helper, template-helper, schema.store, context-search, table-search, and db-knowledge-graph.service.ts assemble model metadata, permissions, schema details, and prompt context before the graph generates or improves a query. This is where application-specific schema knowledge enters the system.
10. LLM integration is provider-pluggable. The src/sub-modules/providers tree contains adapters for Anthropic, AWS Bedrock, Google Gemini, OpenAI, Groq, Cerebras, OpenRouter, and Ollama. The host application binds these into the three logical LLM roles documented in the README: cheap, smart, and file-oriented models. This means the architecture is provider-agnostic at the component level but relies on runtime bindings to choose actual model backends.
11. Caching, vector search, and tracing are supporting infrastructure. src/providers/cache/redis provides Redis-backed cache storage, src/providers/vector-stores and src/sub-modules/db/postgresql/vector-store/pgvector.store.ts indicate optional vector retrieval, and src/sub-modules/obf/langfuse integrates Langfuse/OpenTelemetry observability. These are not core business logic, but they materially affect runtime behavior, performance, and tracing.
12. The visualization component is a downstream consumer of generated datasets. src/components/visualization/visualization.graph.ts pulls dataset data, selects an appropriate visualizer, and renders chart config through visualizer implementations like bar, line, and pie. Its tool layer (generate-visualization.tool.ts) makes visualization available to the LLM as another action, typically after the db-query component has produced a dataset.
13. The repository includes a strong test and contract layer. There are unit, integration, acceptance, and visualization tests under src/__tests__, plus test builders for graph scenarios. The .github/workflows and migration assets show this package is intended to be released and validated like an infrastructure component, not just a library of utilities.
14. For an architecture diagram, the clearest boundaries are: external host app → HTTP/SSE controllers → graph orchestration → tools/providers/services → persistence and external systems. The main external systems are the chosen LLM provider, relational database, Redis cache, optional vector store, and observability backend. The most important internal flow is prompt/context assembly → graph execution → tool calls/DB queries → dataset/chat persistence → optional visualization generation.
Main entry points: db-query.graph.ts DB-query graph · chat.graph.ts Chat graph · generation.service.ts Generation svc · controllers Controllers
Components 20
Package API
LoopBack component entrypoints and public request surfaces.
- Component · Package entry that wires the reusable component into a host application.
src/component.ts - Controllers · Public API surface for chat, generation, datasets, and templates.
src/controllers - Transports · HTTP and SSE response adapters for synchronous or streamed output.
src/transports
Chat runtime
Graph-driven conversational orchestration and session state.
- Generation svc · Top-level service that coordinates request handling and graph execution.
src/services/generation.service.ts - Chat graph · Main conversational graph: session init, LLM calls, tool runs, compression, summarization, end.
src/graphs/chat/chat.graph.ts - Chat state · In-memory or shared chat state used while the graph is running.
src/graphs/chat/chat.store.ts - Chat tools · Decorators and provider wiring that expose tools to the chat graph.
src/decorators/tool.decorator.ts
Domain components
Dataset/query generation and visualization pipelines.
- DB-query component · Component that turns prompts into validated datasets and query artifacts.
src/components/db-query/db-query.component.ts - DB-query graph · Graph for permissions, schema discovery, SQL generation, validation, fixing, and dataset save.
src/components/db-query/db-query.graph.ts - Schema helpers · Schema, permission, template, search, and knowledge-graph services that enrich prompts.
src/components/db-query/services - Dataset API · Controllers for dataset and template management.
src/components/db-query/controller - Viz component · Component that converts datasets into chart configurations.
src/components/visualization/visualization.graph.ts - Viz graph · Pipeline that selects a visualizer, fetches dataset data, and renders output.
src/components/visualization/visualization.graph.ts - Visualizers · Bar, line, and pie visualizer implementations.
src/components/visualization/visualizers
Infrastructure
Pluggable providers, persistence, cache, and external backends.
- Chat repos · Chat and message repositories used to persist conversation history.
src/repositories - DB connectors · PostgreSQL, RLS PostgreSQL, and SQLite access adapters behind the generation pipeline.
src/components/db-query/connectors - Dataset repos · Repositories for datasets and dataset actions.
src/components/db-query/repositories - LLM providers · Anthropic, Bedrock, Gemini, OpenAI, Groq, Cerebras, OpenRouter, and Ollama bindings.
src/sub-modules/providers - Cache/vector/obs · Redis cache, vector stores, and Langfuse/OpenTelemetry observability integration.
src/providers - External systems · Host app, LLM backends, relational databases, Redis, vector stores, and observability backend.
Connections 24
- Component → Controllers: exposes · The component publishes controller surfaces to the host application.
- Component → Generation svc: binds · The package wires the top-level generation service into the runtime.
- Controllers → Transports: responds via · Controllers can return synchronous HTTP responses or streamed SSE responses.
- Controllers → Generation svc: calls · Incoming requests are delegated to the generation orchestrator.
- Generation svc → Chat graph: runs · The generation service executes the chat graph for interactive conversations.
- Chat graph → Chat state: reads/writes · The graph maintains conversational state while it progresses.
- Chat graph → Chat tools: invokes · Tool execution is embedded in the chat loop as a first-class step.
- Chat tools → LLM providers: resolves models · Tools and chat nodes rely on pluggable LLM provider bindings.
- Chat graph → Chat repos: persists · Chat sessions and messages are stored through repositories.
- DB-query component → DB-query graph: contains · The db-query component centers on its dedicated graph.
- DB-query graph → Schema helpers: enriches with · Prompt context is assembled from schema, permission, search, and knowledge services.
- DB-query graph → DB connectors: queries · Schema discovery and dataset generation are executed against DB connectors.
- DB-query graph → Dataset repos: saves to · Validated datasets and actions are persisted through dataset repositories.
- DB-query component → Dataset API: publishes · Dataset and template endpoints expose the component to callers.
- Dataset API → DB-query graph: drives · REST endpoints initiate the db-query graph workflow.
- Viz component → Viz graph: contains · Visualization is implemented as a graph-based pipeline.
- Viz graph → Visualizers: renders with · The graph selects and executes a concrete visualizer implementation.
- Viz graph → DB-query component: consumes · Visualization typically consumes the dataset artifact produced by db-query.
- Viz component → LLM providers: uses LLMs · Visualization can be exposed as an LLM tool-backed action.
- Generation svc → Cache/vector/obs: uses support · Generation can rely on caching, vector search, and observability support.
- LLM providers → External systems: connects to · Provider adapters reach external model services.
- DB connectors → External systems: connects to · Database connectors reach the relational backend.
- Chat repos → External systems: stores in · Conversation data is persisted in the backing datastore.
- Cache/vector/obs → External systems: integrates with · Cache, vector, and tracing modules talk to external runtime services.