mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:01:08 +02:00
feat(forms): M5 AI tools — 7 tools im AI_TOOL_CATALOG
AI-Zugriff aufs Forms-Modul (docs/plans/forms-module.md M5):
Propose (User-Approval erforderlich):
- forms_create — neues Formular im Draft-Status, optional mit Feldern.
Field-Shape im params-Array: { type, label, required?, helpText?,
options?: [{label}] }. Type-Enum aus dem 11-Typ-Katalog. Planner
kann z.B. "Vereins-Anmeldung" mit Name+Email+Position+Trikotgröße
in einem Aufruf bauen.
- forms_add_field — Feld ans Ende anhängen, Reorder bleibt User
vorbehalten (Drag im Builder).
- forms_publish — draft → published. Wirft, wenn Form keine Antwort-
felder hat (nur section/consent würde Public-Submit sinnlos machen).
- forms_close — published → closed, Antworten + Share-Link bleiben.
Auto (silent execution während Planner-Reasoning):
- forms_list — Metadaten (id, title, status, fieldCount, responseCount,
visibility), Status-Filter optional, Default-Limit 50. VaultLocked-
aware → klare Fehlermeldung statt Crash.
- forms_get_responses — Aggregat-Stats: per Form ein
ResponseAggregate {totalCount, statusCounts, choiceHistograms,
textSamples, numericStats}. Choice-Felder mit Option-Label-Mapping
(nicht Option-IDs), Text-Felder als Sample-Array (cap 50, default).
- forms_summarize_responses — gleicher Aggregator mit window-filter
(sinceDays) und höherem Sample-Cap (200), als Daten-Vorlage für
LLM-Clustering im nächsten Planner-Schritt. Augur-style: keine
eigene LLM-Roundtrip, der Planner formuliert Themes selbst.
Verdrahtung:
- AI_TOOL_CATALOG in @mana/shared-ai mit 7 ToolSchema-Einträgen +
defaultPolicy.
- ModuleTool-Implementierungen in modules/forms/tools.ts mit
scopedForModule für Space-Awareness, decryptRecords für encrypted-
table-Reads, VaultLocked-Handling.
- Registriert in data/tools/init.ts.
Validierung:
- mana-ai planner-drift test: 4/4 grün — alle 4 propose-Tools
(forms_create/add_field/publish/close) im SERVER_TOOLS-Subset.
- svelte-check 0 errors in forms/.
- Forms unit tests: 16/16 (csv + branching) unverändert grün.
Tools-executor.test.ts ist pre-existing rot wegen
$lib/modules/context-Drift in module-registry.ts (Parallel-Session-
WIP, nicht durch mich).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a295894ca6
commit
0d85d7c36b
3 changed files with 640 additions and 0 deletions
|
|
@ -2494,6 +2494,156 @@ export const AI_TOOL_CATALOG: readonly ToolSchema[] = [
|
|||
defaultPolicy: 'auto',
|
||||
parameters: [],
|
||||
},
|
||||
|
||||
// ── Forms ───────────────────────────────────────────────────
|
||||
// Eigenes Modul fuer Typeform-aehnliche Formulare. Plan:
|
||||
// docs/plans/forms-module.md M5.
|
||||
{
|
||||
name: 'forms_create',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Legt ein neues Formular an. Status ist immer "draft" (publishen via forms_publish). Felder optional als Array — der Planner kann z.B. fuer eine Vereins-Anmeldung mehrere short_text + email + consent Felder auf einmal vorschlagen.',
|
||||
defaultPolicy: 'propose',
|
||||
parameters: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
description: 'Titel des Formulars (z.B. "Anmeldung Sommerfest")',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'string',
|
||||
description: 'Optionaler Beschreibungstext oben im Formular',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'fields',
|
||||
type: 'array',
|
||||
description:
|
||||
'Optionales Array von Feld-Definitionen. Jedes Feld: { type, label, required?, helpText?, options?: [{label}] }. Erlaubte type-Werte: short_text | long_text | single_choice | multi_choice | number | date | email | yes_no | rating | section | consent.',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_add_field',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Fuegt einem bestehenden Formular ein einzelnes Feld hinzu. Ans Ende der Feldliste angehaengt — Reorder ist nicht ueber dieses Tool moeglich (User macht das per Drag im Builder).',
|
||||
defaultPolicy: 'propose',
|
||||
parameters: [
|
||||
{ name: 'formId', type: 'string', description: 'ID des Formulars', required: true },
|
||||
{
|
||||
name: 'type',
|
||||
type: 'string',
|
||||
description: 'Feldtyp',
|
||||
required: true,
|
||||
enum: [
|
||||
'short_text',
|
||||
'long_text',
|
||||
'single_choice',
|
||||
'multi_choice',
|
||||
'number',
|
||||
'date',
|
||||
'email',
|
||||
'yes_no',
|
||||
'rating',
|
||||
'section',
|
||||
'consent',
|
||||
],
|
||||
},
|
||||
{ name: 'label', type: 'string', description: 'Label / Frage des Feldes', required: true },
|
||||
{ name: 'helpText', type: 'string', description: 'Hilfetext (optional)', required: false },
|
||||
{
|
||||
name: 'required',
|
||||
type: 'boolean',
|
||||
description: 'Pflichtfeld (Standard false)',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
type: 'array',
|
||||
description:
|
||||
'Bei single_choice / multi_choice: Array von { label: string } — IDs werden generiert.',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_publish',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Bewegt ein Formular von "draft" auf "published". Erst nach diesem Schritt kann der User die Sichtbarkeit auf "unlisted" setzen und einen Share-Link erzeugen. Wirft, wenn das Formular keine Antwortfelder hat (nur section/consent).',
|
||||
defaultPolicy: 'propose',
|
||||
parameters: [
|
||||
{ name: 'formId', type: 'string', description: 'ID des Formulars', required: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_close',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Setzt ein veroeffentlichtes Formular auf "closed" — keine neuen Antworten mehr. Existierende Antworten und der Share-Link bleiben erhalten; das Formular wird aber im SharedFormView nicht mehr submitbar gerendert.',
|
||||
defaultPolicy: 'propose',
|
||||
parameters: [
|
||||
{ name: 'formId', type: 'string', description: 'ID des Formulars', required: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_list',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Listet Formulare im aktiven Space (id, title, status, fieldCount, responseCount, visibility). Optional nach Status filterbar.',
|
||||
defaultPolicy: 'auto',
|
||||
parameters: [
|
||||
{
|
||||
name: 'status',
|
||||
type: 'string',
|
||||
description: 'Nur einen Status zeigen',
|
||||
required: false,
|
||||
enum: ['draft', 'published', 'closed'],
|
||||
},
|
||||
{
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
description: 'Maximale Anzahl (Standard 50)',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_get_responses',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Liefert Aggregate ueber die Antworten eines Formulars: responseCount pro Status, pro Choice-Feld eine Histogramm-Map (option-label → count), pro Text-Feld eine Liste der ersten N Antworten. Antworten werden client-side entschluesselt; vault-locked → leerer Antwort-Vector.',
|
||||
defaultPolicy: 'auto',
|
||||
parameters: [
|
||||
{ name: 'formId', type: 'string', description: 'ID des Formulars', required: true },
|
||||
{
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
description: 'Max. Text-Antworten pro Feld (Standard 50)',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'forms_summarize_responses',
|
||||
module: 'forms',
|
||||
description:
|
||||
'Sammelt rohe Text-Antworten + Choice-Histogramme eines Formulars und gibt sie als strukturierte Payload zurueck, damit der naechste Planner-Schritt thematisch clustern kann (Augur-style). Reine Daten-Extraktion — keine eigene LLM-Roundtrip. Ideal in einer Mission "Fasse die Pulse-Check-Antworten der Woche zusammen".',
|
||||
defaultPolicy: 'auto',
|
||||
parameters: [
|
||||
{ name: 'formId', type: 'string', description: 'ID des Formulars', required: true },
|
||||
{
|
||||
name: 'sinceDays',
|
||||
type: 'number',
|
||||
description: 'Nur Antworten der letzten N Tage einbeziehen (Standard: alle)',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue