🏗️ Technical Design Document: DataPlugin — LM Studio Extension
📖 §1. Introduction
§1.1 Project Overview
[!ABSTRACT] Przegląd projektu
DataPlugin to plugin do ekosystemu LM Studio, który udostępnia modelom LLM zestaw narzędzi do tworzenia, odczytu, zarządzania i modyfikacji danych w plikach .csv oraz strukturach bazodanowych. Działa jako Tools Provider — model może za jego pomocą wykonywać operacje CRUD na danych bez opuszczania kontekstu konwersacji.
Głównym celem jest umożliwienie modelom LLM samodzielnego zarządzania danymi strukturalnymi: tworzenie baz danych (katalogów), tabel (plików CSV ze schematem), dodawanie, edycja, filtrowanie i agregacja rekordów — wszystko przez narzędzia (tools) wywoływane przez model.
Przykład: Model tworzy bazę "Postacie z serialu", gdzie każda postać to osobna tabela (.csv) — walter-white.csv, jesse-pinkman.csv — i zarządza ich danymi (dodawanie atrybutów, edycja, filtrowanie).
§1.2 Scope
[!NOTE] Zakres dokumentu
Niniejszy dokument definiuje architekturę techniczną, przepływ danych, interfejsy API, strategię testowania i deploymentu dla DataPlugin.
Zakres:
Architektura Tools Provider dla LM Studio
Silnik CSV — parsowanie, generowanie, append, edycja
System zarządzania schematami tabel
Indeksowanie baz i tabel
Definicje narzędzi (tools) dla modelu LLM
Konfiguracja pluginu
Poza zakresem:
Import/Export do innych formatów (JSON, XLSX) — planowane po MVP
Foreign keys i relacje między tabelami
Wersjonowanie danych / snapshoty
Interfejs użytkownika (UI) — plugin działa wyłącznie przez tools
Sandboxing — Deno runner z ograniczonym dostępem do FS
🏗️ §2. System Architecture
§2.1 Technology Stack
[!TIP] Stack technologiczny
Warstwa
Technologia
Wersja
Język
TypeScript
^5.8
Runtime
Node.js
^20
Menadżer
Bun
1.3.x
Build
tsc (TypeScript Compiler)
—
SDK
@lmstudio/sdk
^1.x
CSV Parse
csv-parse
^5.x
CSV Stringify
csv-stringify
^6.x
UUID
§2.2 High-Level Architecture
[!IMPORTANT] Architektura systemu
System działa w modelu Tools Provider: LM Studio ładuje plugin, plugin rejestruje narzędzia, model LLM wywołuje narzędzia podczas generowania odpowiedzi.
§2.3 Directory Structure
🧱 §3. Core Components
Komponent
Odpowiedzialność
Specyfikacja
CSV Engine
Parsowanie, zapis, append i edycja plików CSV
docs/components/csv-engine.md
Schema Manager
Definiowanie, walidacja i przechowywanie schematów kolumn
docs/components/schema-manager.md
Index Manager
Zarządzanie metadanymi baz i tabel, szybki lookup
docs/components/index-manager.md
Database Tools
Narzędzia: create, list, delete, info database
docs/components/database-tools.md
Table Tools
Narzędzia: create, list, delete, schema table
docs/components/table-tools.md
CRUD Tools
🔄 §4. Data Flow
§4.1 Główny przepływ — tworzenie rekordu
§4.2 Przepływ — odczyt z filtrowaniem
🔌 §5. Interface Definitions
§5.1 Internal API (Engine Layer)
Funkcja
Parametry
Zwraca
Opis
parseCSV(path)
path: string
Promise<Record<string,any>[]>
Parsuje plik CSV do tablicy obiektów
stringifyCSV(rows, columns)
rows, columns: ColumnDef[]
Promise<string>
Generuje string CSV z nagłówkami
appendToCSV(path, row)
path: string, row: Record<string,any>
Promise<void>
Dopisuje wiersz do pliku CSV
readCSV(path)
path: string
Promise<Record<string,any>[]>
Alias dla parseCSV
writeCSV(path, rows, columns)
path, rows, columns
Promise<void>
Zapisuje cały CSV od nowa
loadSchema(path)
path: string
§5.2 Tool Definitions (LM Studio Tools)
Tool
Parametry
Opis
create_database
name: string
Tworzy nowy katalog bazy + .meta.json
list_databases
—
Zwraca listę baz z liczbą tabel
delete_database
name: string
Usuwa bazę wraz ze wszystkimi plikami
get_database_info
name: string
Zwraca metadane bazy
create_table
database, table, columns: ColumnDef[]
Tworzy plik .csv + .schema.json
list_tables
database: string
Zwraca listę tabel w bazie
delete_table
database, table: string
Usuwa pliki tabeli
get_table_schema
database, table: string
Zwraca definicję kolumn
🔋 §6. State Management
Plugin jest bezstanowy w pamięci — każdy stan przechowywany jest na dysku:
Dane: Pliki CSV w data-root/databases/
Schematy: Pliki .schema.json przy każdej tabeli
Indeks: Plik .meta.json na poziomie bazy
Konfiguracja globalna: data-plugin.config.json w data-root
Przy starcie pluginu (activate()):
Weryfikacja data-root
Załadowanie konfiguracji
Rejestracja narzędzi w LM Studio SDK
🛡️ §7. Error Handling
Scenariusz
Obsługa
Brak data-root
Init z domyślną ścieżką + tworzenie katalogu
Uszkodzony CSV
Rzuca CSVParseError z komunikatem o linii błędu
Brak schematu
Rzuca SchemaNotFoundError
Niezgodność typów
ValidationError z listą konkretnych błędów
Brak tabeli/bazy
NotFoundError z kodem DB_NOT_FOUND / TABLE_NOT_FOUND
I/O Error
Retry 2x, potem FilesystemError z detalem błędu OS
Zapis do istniejącego
Error Classes
🔐 §8. Security
Obszar
Strategia
Autentykacja
Nie wymagana — plugin lokalny
Path Traversal
Walidacja nazw baz/tabel: tylko [a-zA-Z0-9_-], rzuca SecurityError
Input Sanitization
Stripping whitespace, escaping w CSV (csv-stringify)
Filesystem
Ograniczony do data-root — plugin nie operuje poza tym katalogiem
Permissions
LM Studio: "filesystem": "readwrite" w plugin.json
🧪 §9. Testing Strategy
Typ
Framework
Pokrycie
Opis
Unit
Vitest / Bun test
90%+ engine
Testy csv-engine, schema, index-manager
Integration
Vitest / Bun test
80%+
Rzeczywiste operacje na plikach CSV w tmpdir
Tool Tests
Vitest / Bun test
85%+
Symulacja wywołań narzędzi z mockowanym engine
Kluczowe przypadki testowe
csv-engine: parse poprawny CSV, parse pusty CSV, parse z BOM, stringify z quotingiem
DuplicateError przy próbie nadpisania bez potwierdzenia
graph TD A[LM Studio Host] -→ B[DataPlugin activate] B -→ C[Tool Registry] C -→ D[Database Tools] C -→ E[Table Tools] C -→ F[CRUD Tools] C -→ G[Query Tools] D -→ H[CSV Engine] E -→ H F -→ H G -→ H H -→ I[Filesystem] H -→ J[Schema Manager] H -→ K[Index Manager] I -→ L[(data-root/databases/)]
1. User prompt → LLM2. LLM wywołuje insert_row("breaking-bad", "walter-white", data)3. CRUD Tools → CSV Engine.appendToCSV(path, row)4. CSV Engine: a. Sprawdza czy plik istnieje (jeśli nie → błąd) b. Parsuje istniejący CSV (nagłówki) c. Waliduje dane względem schematu d. Generuje UUID jeśli brak id e. Dopisuje wiersz (csv-stringify) f. Aktualizuje indeks (.meta.json)5. Zwraca { success: true, id: "ww-001" }
1. LLM wywołuje select_rows("breaking-bad", "walter-white", { filter: { age: 50 } })2. CRUD Tools → CSV Engine.parseCSV(path)3. CSV Engine: a. Czyta plik CSV b. Parsuje z csv-parse c. Aplikuje filtr d. Zwraca tablicę obiektów4. Zwraca { rows: [...], total: 1 }