TaskMonkey Handbuch

Tools, die Dateien erzeugen

PDFs, Bilder, CSVs generieren — Konventionen und Fallstricke.

Wenn ein Tool eine Datei erzeugt (PDF-Rechnung, Logo-Mockup, Report-CSV), willst du sie dem Benutzer zurückgeben, im Chat verlinken oder in einem Cloud-Speicher ablegen. Hier sind die Muster, die sich bewährt haben.

Muster 1: Datei im Chat zum Download verlinken

Nutze das interne Helfer-Tool provideDownload (_shared/tools/files/). Es schreibt den Inhalt nach config/tenants/{tenant}/files/downloads/, hängt einen Zeitstempel-Suffix an den Filename (gegen Kollisionen) und gibt eine Manage-URL zurück, die du als Markdown-Link weitergeben kannst.

'handler' => function (array $results, array $args, array $ctx): array {
    $csv = "tracking_code,from,to\n12345,DHL,DPD\n";

    $download = $ctx['tool']('provideDownload', [
        'filename' => 'carrier_wechsel.csv',  // bekommt -YYYYMMDD-HHMMSS-hex6 angehaengt
        'content' => $csv,
        'mime' => 'text/csv',                 // optional — wird sonst aus der Endung geraten
    ]);

    if (!($download['success'] ?? false)) {
        return ['success' => false, 'error' => $download['error']];
    }

    return [
        'success' => true,
        'download_url' => $download['download_url'],
        'filename' => $download['filename'],
        'size_bytes' => $download['size_bytes'],
        'message' => "CSV bereit: [Download]({$download['download_url']})",
    ];
},

URL-Format: /manage/tenant-files/serve/{tenant}/files/downloads/{filename} — ausgeliefert vom bestehenden Manage/TenantFilesController::serve() (Path-Traversal-sicher per realpath-Check). Auth: Manage-Cookie (admin/manager). End-User im Public-Widget, die nicht eingeloggt sind, sehen den Login-Screen.

Logging: jeder provideDownload-Aufruf landet als verschachtelter Eintrag in task_executions (tool_name=provideDownload, mit args.filename und Result-Size). Audit-Trail welche Datei wann von welchem Chat bereitgestellt wurde — ohne extra Tabelle.

Sanitize: Filename wird auf [A-Za-z0-9._-] reduziert + per basename() von Pfad-Anteilen befreit. Stem auf 80 Zeichen begrenzt. Content max. 50 MB.

Nicht direkt vom LLM aufrufen lassen: provideDownload ist internal: true und nicht in assistants.<slug>.tools oder public.tools gelistet. Domain-Tools rufen es per $ctx['tool']('provideDownload', …) auf — das LLM sieht nur das aufrufende Tool und die fertige URL im Result.

Nicht für Public-Chats: wenn dein Tool aus einem Tenant-Public-Widget heraus läuft und der Endnutzer kein Manage-Login hat, ist der Link nicht klickbar. Dann brauchst du Muster 2 (Cloud-Storage) oder ein eigenes signiertes URL-Schema.

Muster 2: Datei in OAuth-Storage legen

Für persistente Ablage (Google Drive, Dropbox) nutzt du ein schon existierendes Upload-Tool:

'handler' => function (array $results, array $args, array $ctx): array {
    $csv = buildCsv($args);
    $tmp = tempnam(sys_get_temp_dir(), 'report_') . '.csv';
    file_put_contents($tmp, $csv);

    $upload = $ctx->runTool('uploadToDropbox', [
        'path' => '/Reports/' . date('Y-m') . '/report.csv',
        'localPath' => $tmp,
    ]);

    unlink($tmp);
    return $upload; // enthält Dropbox-URL
},

Muster 3: Binary direkt ans Modell zurückgeben

Tu das nicht. Bilder oder PDFs direkt als Base64 im Tool-Result zurückzugeben explodiert dir den Token-Verbrauch und die Latenz. Gib immer eine URL oder einen Dateipfad zurück, nicht den Rohinhalt.

PDF-Generierung

Für PDFs gibt es mehrere Wege:

  • HTML → PDF via Headless Chrome / wkhtmltopdf (gut für layoutlastige Templates)
  • Direkter PDF-Build mit einer Library wie TCPDF (feingranulare Kontrolle)
  • Externer Dienst (APITemplate.io, DocRaptor) — kein eigenes Binary nötig, dafür API-Kosten

Workspace-Betreiber hat typisch eine Präferenz. Frage, welcher Weg unterstützt ist.

Bild-Generierung

Zweck Werkzeug
AI-Images (Logos, Mockups) OpenAI Images, Stable Diffusion via eigenem Service
Charts / Diagramme QuickChart.io, Chart.js headless
Dynamische Thumbnails imagecreate* (GD) oder Intervention Image

Speichere das Ergebnis lokal oder in Dropbox/Drive — nicht direkt zurück ans Modell.

Naming-Konventionen

Dateien sollten so heißen, wie der Benutzer sie erwartet:

  • Zeitstempel im Namen, wenn das Tool mehrmals pro Tag läuft (report_2026-04-19.csv)
  • Nutzername / Workspace-Code bei geteilten Ordnern
  • Nie output.pdf oder file.csv — zu generisch, findet keiner wieder

Aufräumen

Tools, die viele temporäre Dateien erzeugen, sollten nach dem Upload aufräumen:

register_shutdown_function(fn() => @unlink($tmp));

Oder ein Scheduled Task, der täglich alte Dateien in uploads/tmp/ löscht.

Sicherheitshinweis

Dateien in webroot/uploads/ sind öffentlich erreichbar. Für vertrauliche Dokumente lege sie in einen nicht-öffentlichen Pfad und liefere sie über eine Download-Action aus, die Auth prüft.

Zuletzt aktualisiert: 2026-04-19