TaskMonkey Handbuch

tools/

Struktur und Muster für den Tools-Ordner.

Der Tools-Ordner ist das Herzstück deines Workspace. Hier lebt alles, was das Modell tun kann.

Tool-Schichten

Tools können auf vier Ebenen leben. Höhere Ebenen überschreiben niedrigere bei gleichem Tool-Namen, weil der Loader alphabetisch über alle Pfade merged.

Schicht Pfad Wer nutzt es
0 — Built-in (Code) _tool_catalog.php (PHP-Code, nicht Workspace) Eingebaute Tools mit fertigem Handler — getKnowledge, setSuggestions. Wir referenzieren sie via 'extends'.
1 — Plattform-shared config/tenants/_shared/tools/ Tenant-agnostische Tools, die jeder Workspace bekommt. Database-Gateway, Email-Send, generische Google-Drive/Sheets-Tools.
2 — Workspace <workspace>/tools/ Workspace-weit, von mehreren Assistants genutzt. Tenant-spezifische API-Tools (eigene API-Keys, eigene Endpoints).
3 — Assistant-lokal <workspace>/assistants/<id>/tools/ Use-Case-Tools, die nur ein Assistant nutzt. Macht Recipes als Bundle veröffentlichbar (Assistant + seine Tools in einem Ordner).

Wichtig: Auf Schicht 3 sind Tools technisch trotzdem global verfügbar (tools.<name> ist Workspace-Map, kein echter Scope). Die Datei-Lokalität ist nur Doku-/Bundle-Hilfe. Bei Namenskonflikten gewinnt die alphabetisch späteste Datei — wenn du das Risiko vermeiden willst, nutze einen Prefix wie gutscheine_createCode.

Was wo hingehört (Faustregel):

  • Schicht 1 (_shared/): Tool nutzt OAuth-Connection oder Per-User-Token, keine Tenant-spezifischen Endpoints/IDs hardcoded → Plattform-shared.
  • Schicht 2 (workspace-tools): Tool nutzt Tenant-eigene API-Keys, Endpoints oder Datenstrukturen → tenant-lokal.
  • Schicht 3 (assistant-tools): Tool ist nur für diesen einen Use-Case sinnvoll, nicht von anderen Assistants nutzbar.

Empfohlene Struktur (Workspace-Schicht 2)

Nach API gruppieren, dann nach fachlicher Kategorie:

<workspace>/
├── tools/                       # Schicht 2 — workspace-weit
│   ├── shop/
│   │   ├── orders/
│   │   │   ├── getOrder.php
│   │   │   ├── listOrders.php
│   │   │   └── cancelOrder.php
│   │   └── products/
│   │       ├── searchProducts.php
│   │       └── getStock.php
│   └── kb/
│       ├── searchFaq.php
│       └── searchProducts.php
└── assistants/
    └── gutscheine/             # Schicht 3 — assistant-lokal
        ├── gutscheine.php       # Assistant-Config
        └── tools/
            ├── createDiscountCode.php
            └── deactivateDiscountCode.php

Der Loader scannt rekursiv — Ordner-Namen haben keine Bedeutung für die Plattform, nur für dich.

Recipe-Bundling

Wenn du einen Assistant als Recipe veröffentlichen willst (z.B. „Gutschein-Workflow"): leg ihn unter assistants/<id>/ mit assistants/<id>/tools/ an. Dann ist alles in einem Ordner — Assistant-Config + alle nur dafür gebauten Tools. Beim Recipe-Import kopierst du den ganzen Ordner.

Tools, die der Assistant aus Schicht 1/2 nutzt (z.B. setSuggestions, searchItems), werden im Recipe als „Voraussetzungen" dokumentiert, nicht mit-kopiert.

Ein Tool pro Datei

Empfehlung. Gründe:

  • Diffs bleiben klein
  • Umbenennen per Git-Move behält History
  • Einzelne Tools ohne Merge-Konflikte editierbar
  • tm monitor zeigt pro Tool — einfacher nachzuverfolgen

Abweichen nur, wenn mehrere Tools eine private Helperfunktion teilen, die sonst dupliziert würde.

Dateinamen-Konvention

Dateiname = Tool-Name, camelCase. Beispiele:

  • getOrder.php → Tool getOrder
  • sendInvoice.php → Tool sendInvoice
  • listUserDropboxFiles.php → Tool listUserDropboxFiles

Kein technischer Zwang (der Tool-Name steht im Array-Key), aber konsistent macht Refactorings einfacher.

Tool-Datei-Grundform

<?php
return [
    'tools' => [
        '<toolName>' => [
            'description' => '...',
            'parameters' => [
                'type' => 'object',
                'properties' => [ /* ... */ ],
                'required' => [ /* ... */ ],
            ],
            // eines oder mehreres von:
            'api' => '<api_key>',
            'handler' => function (array $results, array $args, array $ctx): array { /* ... */ },
            // optional:
            'preprocess' => function ($args, $ctx) { /* ... */ },
            'postprocess' => function ($result, $args, $ctx) { /* ... */ },
            'mapping' => [ /* ... */ ],
            'statusMessages' => [ /* ... */ ],
            'args_fixture' => [ /* ... */ ],
            'extends' => '<baseToolName>',
        ],
    ],
];

Siehe Tool als Config-Datei für komplette Beispiele.

Mehrere Tools in einer Datei

Wenn Tools eng verwandt sind und Helferfunktionen teilen:

<?php

function calculatePriceWithTax(float $net, float $rate): float {
    return round($net * (1 + $rate), 2);
}

return [
    'tools' => [
        'priceWithTax' => [
            'description' => '...',
            'parameters' => [ /* ... */ ],
            'handler' => function (array $results, array $args, array $ctx) {
                return ['gross' => calculatePriceWithTax($args['net'], 0.19)];
            },
        ],

        'priceWithoutTax' => [
            'description' => '...',
            'parameters' => [ /* ... */ ],
            'handler' => function (array $results, array $args, array $ctx) {
                return ['net' => round($args['gross'] / 1.19, 2)];
            },
        ],
    ],
];

extends für Shared Tools

Tools, die über Workspace-Grenzen hinweg nützlich sind (getKnowledge, setSuggestions, ...), sind in der Shared-Library definiert. Du überschreibst nur das, was spezifisch für deinen Workspace ist:

return [
    'tools' => [
        'searchFaq' => [
            'extends' => 'getKnowledge',
            'description' => 'Kunden-FAQ durchsuchen.',
            'options' => [
                'knowledge_base' => 'faq',
                'limit' => 3,
            ],
        ],
    ],
];

Größen-Budget

Ein Workspace ist nicht dafür gemacht, 500 Tools zu haben. Realistische Größe:

  • Pro Assistant: 5–15 Tools in der Allowlist
  • Pro Workspace total: 20–80 Tools
  • Bei mehr: Zeichen, dass du einige Tools zu generisch gebaut hast — vielleicht kann listOrders mit Filter statt 10 spezialisierter Listen-Tools machen

Refactoring

Wenn sich Muster herauskristallisieren (alle list*-Tools machen dasselbe bis auf Path + Mapping), ziehe eine Helferfunktion oder ein Shared-Tool raus. Aber: drei Vorkommen mindestens, bevor du abstrahierst — sonst baust du Abstraktionen gegen die Glaskugel.

Nach dem Anlegen

tm sync

Syntax-Fehler werden abgewiesen und namentlich gemeldet.

tm test-tool <neuerTool>

Direkter Smoke-Test, bevor du's ins Modell gibst.

Zuletzt aktualisiert: 2026-05-05