Chat-Werkzeuge & Tools im Detail
Vollständige Referenz aller Werkzeuge, die das Chat-Modell aufrufen kann — Built-ins, Code-Sandbox, SQL, Skills, Sub-Agenten und Integrationen samt Aktivierung, Limits und Sicherheit.
Das Chat-Modell von Kasimir ist agentisch: Es kann während einer Antwort Werkzeuge (Funktionen) aufrufen, deren Ergebnisse zurückbekommen und darauf aufbauend weiterarbeiten — bis es eine finale Antwort formuliert. Welche Werkzeuge in einem Turn zur Verfügung stehen, hängt davon ab, was der Nutzer im Tools-Menü aktiviert hat, welche Integrationen verbunden sind und welche serverseitigen Sidecars konfiguriert sind. Diese Seite dokumentiert jedes Werkzeug exakt so, wie es im Code (server/api/chat/conversations/[id]/messages.post.ts, server/utils/tools/adapters/*, app/components/chat/ChatToolsMenu.vue) implementiert ist.
Architektur in einem Satz
Es gibt zwei Kategorien: Built-ins (render_chart, render_scene, web_search, fetch_page) sind direkt im Chat-Handler verdrahtet; alle übrigen Werkzeuge kommen über das Provider-Adapter-Registry (server/utils/tools/registry.ts), das pro Anfrage ermittelt, welche Adapter verbunden/aktiviert sind und deren Werkzeuge in den LLM-Prompt einspeist.
Wie ein Tool-Aufruf abläuft
Der Chat-Handler baut für jeden Turn ein tools-Array aus drei Quellen zusammen: Built-ins, Adapter-Werkzeuge (über getAvailableTools) und Sub-Agenten (ask_*). Das Modell läuft dann in einer ReAct-Schleife mit maximal MAX_ROUNDS = 8 Runden. In jeder Runde darf das Modell ein oder mehrere Werkzeuge aufrufen; der Handler führt sie aus, hängt die Ergebnisse als tool-Nachrichten an und ruft das Modell erneut auf. In der letzten Runde wird das tools-Array weggelassen (roundTools = round < MAX_ROUNDS - 1 ? tools : undefined), damit das Modell zwingend antwortet statt endlos zu suchen.
Phase | Verhalten |
|---|---|
Tool-Liste bauen |
|
Dispatch |
|
Live-Feedback | Jeder Aufruf sendet |
Ergebnis-Cap | Live an das Modell zurückgereichte Ergebnisse werden bei |
Persistenz | Adapter-Tool-Aufrufe landen in |
Geleakte Aufrufe | Wenn ein Modell einen Tool-Call als Text leakt (Mistral |
Robustheit gegen kaputte Argumente
vLLM-Modelle streamen gelegentlich abgeschnittene Tool-Argumente. Der Handler normalisiert function.arguments vor dem Echo per JSON.stringify(JSON.parse(...)); ein unrettbarer Payload degradiert zu {} (Tool no-opt + Modell-Retry) statt den ganzen Turn mit „Unterminated string" zu killen. Tool-Call-IDs werden zudem auf das von Mistral erzwungene Format ^[a-zA-Z0-9]{9}$ gebracht.
Aktivierung über das Tools-Menü
Das Tools-Menü (ChatToolsMenu.vue) ist eine flache Aktionsliste (kein Toggle-Schalter): Ein Klick aktiviert ein Werkzeug für den Chat-Zustand und schließt das Menü; aktive Werkzeuge erscheinen als entfernbare Pills über der Composer-Leiste. Das Häkchen (✓) markiert den aktiven Zustand. Die Aktivierungen werden im Request-Body von POST …/messages mitgesendet.
Menüpunkt | Body-Feld | Default | Semantik |
|---|---|---|---|
Web-Suche |
| aktiv, wenn Provider konfiguriert | Schaltet |
Unternehmenswissen |
| leer (aus) | Aktivieren wählt ALLE sichtbaren, fertigen Dokumente; RAG statt Tool |
Datenanalyse |
|
| Schaltet |
Datenbank (pro Verbindung) |
| leer (aus) | Aktiviert genau die gewählten SQL-Verbindungen |
Skills | — (immer aktiv) | self-gating | Nur-Anzeige; |
Integrationen |
| leer (Opt-in) | Eine Integration liefert NUR Werkzeuge, wenn ihre Provider-ID hier steht |
Opt-in nach Langdock-Muster
Integrationen sind grundsätzlich opt-in: Ein verbundener Adapter trägt pro Turn null Werkzeuge bei, solange seine Provider-ID nicht in enabled_tool_providers steht. Ausnahmen, die sich selbst freischalten: sql (über den Verbindungs-Picker), code (über code_interpreter) und skills (immer aktiv). Ein an die Konversation gebundener Assistent (ai_apps.tool_providers) aktiviert seine Integrationen automatisch — der Nutzer muss nur die OAuth-Verbindung herstellen.
Built-in-Werkzeuge
Diese vier sind hartkodiert im Chat-Handler. render_chart und render_scene sind immer registriert (kein Provider/Config nötig); web_search und fetch_page nur, wenn ein Such-Provider konfiguriert ist.
render_chart — Diagramm inline
Aspekt | Detail |
|---|---|
Zweck | Numerische Daten als interaktives Chart.js-Diagramm in der Chat-Bubble rendern |
Wann | Immer verfügbar; das Modell wird angewiesen, es nach SQL-Abfragen / bei Tabellen statt ASCII-Charts zu nutzen |
Typen |
|
Eingabe |
|
Limits | ≤ 1000 Labels, ≤ 12 Datasets, ≤ 1000 Datenpunkte/Dataset, Titel/Label ≤ 200 Zeichen, Farbe ≤ 64 Zeichen |
Sicherheit |
|
Ausgabe | SSE-Event |
Fehler | Ungültiger Spec ⇒ Fehler-Hinweis an das Modell (inkl. Downsampling-/ |
render_scene — interaktive 3D-Szene
Aspekt | Detail |
|---|---|
Zweck | Einfache 3D-Szene (Raum/Grundriss) mit three.js inline rendern |
Wann | NUR wenn der Nutzer ausdrücklich eine räumliche/3D-Visualisierung will; nicht für Diagramme |
Eingabe |
|
Limits | Raum 0,5–100 m (Höhe 0,5–20 m), ≤ 20 Öffnungen, ≤ 100 Objekte |
Sicherheit |
|
Ausgabe | SSE-Event |
web_search — Schritt 1 der Web-Recherche
Aspekt | Detail |
|---|---|
Zweck | Liefert NUR Titel + URLs + 1-Zeilen-Snippets (Top 5) |
Aktivierung |
|
Provider |
|
Eingabe |
|
Limits | Top 5 Treffer, Snippet ≤ 300 Zeichen; Isolate-Semaphore |
Pflicht-Folge | Der System-Prompt erzwingt: niemals nur aus Snippets antworten — danach |
Persistenz | Treffer werden zu nummerierten |
fetch_page — Schritt 2 der Web-Recherche
Aspekt | Detail |
|---|---|
Zweck | Holt den lesbaren Volltext einer Seite (bis 30.000 Zeichen bereinigten Text) |
Eingabe |
|
Pfad | Bevorzugt Scrapling-Sidecar ( |
Sicherheit |
|
Fehlerverhalten | 403/429/451/Timeout sind NORMAL (Cloud-IP-Blocks) — der Prompt weist an, EINE Alternativ-URL zu versuchen und sonst ehrlich aus Snippets + URLs zu antworten |
Concurrency | Isolate-Semaphore |
„Konkrete Produkte"-Zwang
Ist ein Such-Provider aktiv, fügt der Handler eine Prompt-Regel hinzu: Bei Fragen nach konkreten Produkten, Herstellern, Modellnummern, Datenblättern, Normen, Preisen oder LV-Positionen MUSS das Modell zuerst web_search (dann fetch_page) nutzen und darf solche Fakten niemals aus dem Gedächtnis erfinden.
run_python — Datenanalyse (Code-Sandbox)
Aspekt | Detail |
|---|---|
Adapter |
|
Aktivierung |
|
Zweck | Führt ein vollständiges Python-Skript in isolierter Sandbox aus (pandas, numpy, matplotlib, openpyxl); kein Internetzugriff |
Statefulness | Stateless — jeder Aufruf startet frisch, Variablen überleben nicht; immer das komplette Skript schicken |
Datei-Injektion | Die zuletzt geclaimten Chat-Anhänge ( |
Artefakt-Rückweg | Erzeugte Dateien (z. B. |
Limits | Sidecar: CPU 30 s, RAM 768 MB, FSIZE 20 MB; |
Sicherheit | Read-only-Rootfs, festes Subnetz + iptables-Egress-DROP (kein Netz), frisches tmp-Workspace pro Lauf |
SQL-Werkzeuge — lesender Datenbankzugriff
Vier Werkzeuge des sqlAdapter (Provider sql), die über den read-only kasimir-sqlbridge-Sidecar laufen. Aktiv, sobald der Sidecar konfiguriert ist UND der Nutzer ≥ 1 Verbindung im Picker aktiviert hat (sql_connection_ids). Leeres Array ⇒ keine SQL-Tools in diesem Turn.
Tool | Zweck | Wichtige Regeln |
|---|---|---|
| Listet verfügbare Verbindungen (Name, Engine, Host-Label, | ZUERST aufrufen; niemals Zugangsdaten; nur sichtbare Verbindungen |
| Tabellen einer Verbindung | Liste wird bei > 20.000 Zeichen gekürzt ( |
| Spalten (Name, Typ, Nullable) einer Tabelle | Exakten Tabellennamen aus |
| Eine einzelne lesende Abfrage, liefert Spalten + Zeilen | NUR |
Harte Invarianten des SQL-Adapters
Der entschlüsselte DSN verlässt niemals ein Tool-Ergebnis. sql_query lehnt alles, was nicht eine einzelne SELECT/WITH-Anweisung ist, vor dem Sidecar-Aufruf ab (assertReadOnlySql); der Sidecar prüft erneut (read-only-Transaktion, Row-Cap, Timeouts). Zugriff wird pro Verbindung geprüft: eigene user-Scope-Zeilen, beliebige company-Scope-Zeilen der Firma und — nur im Projekt-Chat — project-Scope-Zeilen genau dieses Projekts. Eine projektgebundene Verbindung ist in einem Privat-Chat oder fremden Projekt unsichtbar. Fehler werden als Fehler:-Ergebnis zurückgegeben, nicht geworfen (außer AbortError).
use_skill — Skills (Progressive Disclosure)
Aspekt | Detail |
|---|---|
Adapter |
|
Verfügbarkeit | Nur wenn aktive Skills für die Firma (bzw. den Assistenten via |
Muster | Ein einziges Tool |
Eingabe |
|
Ablauf |
|
Kosten | Rein DB-seitig — kein externer Provider, kein zusätzlicher Token-Verbrauch außer der Beschreibung |
ask_* — Delegation an Sub-Agenten
Ist die Konversation an einen Assistenten gebunden, der direkte Sub-Agenten hat (ai_app_subagents), wird pro Kind-Assistent ein Werkzeug ask_<sanitized-id> registriert. Eingabe ist task (die vollständig formulierte Teilaufgabe). Die Ausführung läuft über runSubagent, das alle Schutzmechanismen erzwingt: Tiefe ≤ MAX_DELEGATION_DEPTH, Zyklus-Erkennung über ein Chain-Set (ein Enkel kann nie zu einer Top-Persona zurückschleifen) und ein geteiltes Pro-Turn-Budget MAX_SUBAGENT_CALLS. Ist das Budget erschöpft, bekommt das Modell die Anweisung, die Aufgabe selbst zu lösen.
Integrationen (Provider-Adapter)
Alle folgenden sind opt-in über enabled_tool_providers (außer wenn ein gebundener Assistent sie aktiviert). Jeder Adapter prüft per isAvailableFor seine eigene Verbindung; ist sie nicht da, zeigt das Quellen-Popover einen „Verbinden"-CTA (connectUrl() → /integrations).
Provider | Werkzeuge (Auswahl) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| dynamisch vom Upstream-MCP-Server geladen (nur registriert, wenn eine Server-URL in der Runtime-Config gesetzt ist) |
Kollisions-Regel
Werden zwei Adapter mit gleichem Tool-Namen registriert, gewinnt der zuerst registrierte. Die Reihenfolge in ensureToolsReady() setzt First-Party-Adapter bewusst vor den MCP-Bridge-Adapter.
Was es im Chat NICHT gibt
Kein Bildgenerierungs-Tool im Chat
Es gibt kein generate_image/Image-Gen-Werkzeug im Chat-Tool-Loop. Bildgenerierung ist ein Workflow-Knoten (#7/#11), nicht ein vom Chat-Modell aufrufbares Tool. Ebenso ist load_table ein Workflow-Konzept, und das in agentTools.ts definierte doc_search ist das Tool des agentischen Workflow-LLM-Knotens — der Chat nutzt für Dokumentwissen stattdessen RAG-Retrieval (Built-in, kein Tool-Call) über die Composer-Auswahl.