@elizaos/plugin-form 2.0.0-alpha.9 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/auto-enable.ts +24 -0
  2. package/dist/actions/restore.d.ts +25 -0
  3. package/dist/actions/restore.d.ts.map +1 -0
  4. package/dist/actions/restore.js +176 -0
  5. package/dist/actions/restore.js.map +1 -0
  6. package/dist/builder.d.ts +320 -0
  7. package/dist/builder.d.ts.map +1 -0
  8. package/dist/builder.js +458 -0
  9. package/dist/builder.js.map +1 -0
  10. package/dist/builtins.d.ts +128 -0
  11. package/dist/builtins.d.ts.map +1 -0
  12. package/dist/builtins.js +233 -0
  13. package/dist/builtins.js.map +1 -0
  14. package/dist/defaults.d.ts +95 -0
  15. package/dist/defaults.d.ts.map +1 -0
  16. package/dist/defaults.js +79 -0
  17. package/dist/defaults.js.map +1 -0
  18. package/dist/evaluators/extractor.d.ts +28 -0
  19. package/dist/evaluators/extractor.d.ts.map +1 -0
  20. package/dist/evaluators/extractor.js +247 -0
  21. package/dist/evaluators/extractor.js.map +1 -0
  22. package/dist/extraction.d.ts +55 -0
  23. package/dist/extraction.d.ts.map +1 -0
  24. package/dist/extraction.js +331 -0
  25. package/dist/extraction.js.map +1 -0
  26. package/dist/index.d.ts +31 -2
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +119 -3284
  29. package/dist/index.js.map +1 -30
  30. package/dist/providers/context.d.ts +56 -0
  31. package/dist/providers/context.d.ts.map +1 -0
  32. package/dist/providers/context.js +206 -0
  33. package/dist/providers/context.js.map +1 -0
  34. package/dist/service.d.ts +402 -0
  35. package/dist/service.d.ts.map +1 -0
  36. package/dist/service.js +1158 -0
  37. package/dist/service.js.map +1 -0
  38. package/dist/storage.d.ts +228 -0
  39. package/dist/storage.d.ts.map +1 -0
  40. package/dist/storage.js +218 -0
  41. package/dist/storage.js.map +1 -0
  42. package/dist/template.d.ts +10 -0
  43. package/dist/template.d.ts.map +1 -0
  44. package/dist/template.js +60 -0
  45. package/dist/template.js.map +1 -0
  46. package/dist/ttl.d.ts +144 -0
  47. package/dist/ttl.d.ts.map +1 -0
  48. package/dist/ttl.js +85 -0
  49. package/dist/ttl.js.map +1 -0
  50. package/dist/types.d.ts +1213 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +39 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/validation.d.ts +156 -0
  55. package/dist/validation.d.ts.map +1 -0
  56. package/dist/validation.js +289 -0
  57. package/dist/validation.js.map +1 -0
  58. package/package.json +39 -42
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,39 @@
1
+ const FORM_CONTROL_DEFAULTS = {
2
+ type: "text",
3
+ required: false,
4
+ confirmThreshold: 0.8
5
+ };
6
+ const FORM_DEFINITION_DEFAULTS = {
7
+ version: 1,
8
+ status: "active",
9
+ ux: {
10
+ allowUndo: true,
11
+ allowSkip: true,
12
+ maxUndoSteps: 5,
13
+ showExamples: true,
14
+ showExplanations: true,
15
+ allowAutofill: true
16
+ },
17
+ ttl: {
18
+ minDays: 14,
19
+ maxDays: 90,
20
+ effortMultiplier: 0.5
21
+ },
22
+ nudge: {
23
+ enabled: true,
24
+ afterInactiveHours: 48,
25
+ maxNudges: 3
26
+ },
27
+ debug: false
28
+ };
29
+ const FORM_SESSION_COMPONENT = "form_session";
30
+ const FORM_SUBMISSION_COMPONENT = "form_submission";
31
+ const FORM_AUTOFILL_COMPONENT = "form_autofill";
32
+ export {
33
+ FORM_AUTOFILL_COMPONENT,
34
+ FORM_CONTROL_DEFAULTS,
35
+ FORM_DEFINITION_DEFAULTS,
36
+ FORM_SESSION_COMPONENT,
37
+ FORM_SUBMISSION_COMPONENT
38
+ };
39
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * @module types\n * @description Core type definitions for the Form Plugin\n *\n * ## The Core Insight\n *\n * Forms are **guardrails for agent-guided user journeys**.\n *\n * Without structure, agents wander. They forget what they're collecting,\n * miss required information, and can't reliably guide users to outcomes.\n * These types define the rails that keep agents on track.\n *\n * - **FormDefinition** = The journey map (what stops are required)\n * - **FormControl** = A stop on the journey (what info to collect)\n * - **FormSession** = Progress through the journey (where we are)\n * - **FormSubmission** = Journey complete (the outcome)\n *\n * ## Design Principles\n *\n * 1. **Agent-Native**: Designed for conversational, asynchronous interactions.\n * No form UI - the agent extracts data and guides the conversation.\n *\n * 2. **Future-Compatible**: Many fields are optional with sensible defaults.\n * The `meta` field on most interfaces allows arbitrary extension.\n *\n * 3. **Scoped Sessions**: Sessions are keyed by (entityId + roomId) because\n * a user might be on different journeys in different rooms.\n *\n * 4. **Effort-Aware**: Form data is retained based on user effort invested.\n * Someone who spent 2 hours deserves longer retention than 2 minutes.\n *\n * 5. **TypeScript-First**: Types use discriminated unions, generics, and\n * template literals for excellent IDE support and type safety.\n */\n\nimport type { JsonValue, UUID } from \"@elizaos/core\";\n\n// ============================================================================\n// FORM CONTROL - Individual field definition\n// ============================================================================\n\n/**\n * Select/choice option for select-type fields.\n *\n * WHY separate from simple string[]:\n * - Labels can differ from values (display \"United States\", submit \"US\")\n * - Optional description enables rich select UIs in future\n * - Allows localization of labels without changing values\n */\nexport interface FormControlOption {\n value: string;\n label: string;\n description?: string;\n}\n\n/**\n * File upload configuration.\n *\n * WHY separate interface:\n * - File uploads have unique concerns (size, type, count)\n * - Not all controls need these options\n * - Allows file-specific validation without polluting base control\n */\nexport interface FormControlFileOptions {\n /** MIME type patterns, e.g., ['image/*', 'application/pdf'] */\n accept?: string[];\n /** Maximum file size in bytes */\n maxSize?: number;\n /** Maximum number of files (for multiple uploads) */\n maxFiles?: number;\n}\n\n/**\n * Conditional field dependency.\n *\n * WHY this exists:\n * - Some fields only make sense if another field has a value\n * - Example: \"State\" only relevant if \"Country\" is \"US\"\n * - The agent should skip asking about dependent fields until parent is filled\n */\nexport interface FormControlDependency {\n /** Key of the field this one depends on */\n field: string;\n /** When should this field be shown/asked */\n condition: \"exists\" | \"equals\" | \"not_equals\";\n /** Value to compare against for equals/not_equals */\n value?: JsonValue;\n}\n\n/**\n * UI hints for future frontends.\n *\n * WHY include UI hints in an agent-native form:\n * - Forms may eventually render in GUI\n * - Provides grouping hints to the agent for logical conversation flow\n * - Widget hints allow custom input components\n */\nexport interface FormControlUI {\n /** Section name for grouping fields */\n section?: string;\n /** Display order within section */\n order?: number;\n /** Placeholder text for input fields */\n placeholder?: string;\n /** Help text shown below input */\n helpText?: string;\n /** Custom widget type identifier */\n widget?: string;\n}\n\n/**\n * Localization for a field.\n *\n * WHY per-field i18n:\n * - Allows gradual localization (not all-or-nothing)\n * - Agent prompts need localized versions too\n * - Keeps localization close to the field it affects\n */\nexport interface FormControlI18n {\n label?: string;\n description?: string;\n askPrompt?: string;\n helpText?: string;\n}\n\n/**\n * FormControl - The central field abstraction\n *\n * This is the heart of the form system. Each FormControl defines:\n * - What data to collect (key, type)\n * - How to validate it (pattern, min/max, required)\n * - How the agent should ask for it (askPrompt, extractHints)\n * - How to store it (dbbind)\n *\n * WHY such a rich interface:\n * - Agent needs context to extract values intelligently\n * - Validation needs to happen at extraction time, not just submission\n * - Multiple systems (agent, storage, UI) need different views of the same field\n *\n * WHY `type` is a string, not an enum:\n * - Allows custom types without changing core code\n * - Plugins can register handlers for domain-specific types\n * - Example: 'solana_address', 'evm_address', 'phone'\n */\nexport interface FormControl {\n // ═══ IDENTITY ═══\n /** Unique key within the form. Used in values object. */\n key: string;\n /** Human-readable label. Shown to user if not using askPrompt. */\n label: string;\n /**\n * Field type. Built-in types: 'text', 'number', 'email', 'boolean', 'select', 'date', 'file'.\n * Custom types can be registered via FormService.registerType().\n */\n type: string;\n\n // ═══ BEHAVIOR ═══\n /** If true, form cannot be submitted without this field. Default: false */\n required?: boolean;\n /** If true, accepts array of values. Default: false */\n multiple?: boolean;\n /** If true, value cannot be changed after initial set. Default: false */\n readonly?: boolean;\n /** If true, extract silently but never ask directly. Default: false */\n hidden?: boolean;\n /** If true, agent should not echo value back (passwords, tokens). Default: false */\n sensitive?: boolean;\n\n // ═══ DATABASE BINDING ═══\n /**\n * Database column name. Defaults to key if not specified.\n *\n * WHY this exists:\n * - Form field names can be user-friendly (\"Email Address\")\n * - Database columns often have conventions (\"email_address\")\n * - Consuming plugins use this for mapping\n */\n dbbind?: string;\n\n // ═══ VALIDATION ═══\n /** Regex pattern for validation. Applied to string representation. */\n pattern?: string;\n /** Minimum value (for numbers) or minimum length (for strings) */\n min?: number;\n /** Maximum value (for numbers) or maximum length (for strings) */\n max?: number;\n /** Minimum string length (explicit, for when min is used for value) */\n minLength?: number;\n /** Maximum string length (explicit, for when max is used for value) */\n maxLength?: number;\n /** Allowed values (for string enums without select options) */\n enum?: string[];\n\n // ═══ SELECT OPTIONS ═══\n /** Options for 'select' type fields */\n options?: FormControlOption[];\n\n // ═══ FILE OPTIONS ═══\n /** Configuration for 'file' type fields */\n file?: FormControlFileOptions;\n\n // ═══ DEFAULTS & CONDITIONS ═══\n /** Default value if user doesn't provide one */\n defaultValue?: JsonValue;\n /** Conditional display/requirement based on another field */\n dependsOn?: FormControlDependency;\n\n // ═══ ACCESS CONTROL ═══\n /**\n * Role names that can see/fill this field.\n *\n * WHY field-level access:\n * - Some fields only admins should fill\n * - User shouldn't even know certain fields exist\n * - Example: \"discount_code\" only for \"sales\" role\n */\n roles?: string[];\n\n // ═══ AGENT HINTS ═══\n /**\n * Context description for LLM extraction.\n *\n * WHY this matters:\n * - LLM needs context to correctly interpret user messages\n * - \"Enter your order\" could be order number or food order\n * - Description clarifies intent\n */\n description?: string;\n /**\n * Custom prompt template when agent asks for this field.\n *\n * WHY custom prompts:\n * - \"What's your email?\" vs \"Where should we send the confirmation?\"\n * - Allows personality and context-appropriate phrasing\n */\n askPrompt?: string;\n /**\n * Keywords to help LLM extraction.\n *\n * WHY extraction hints:\n * - LLM might not know domain-specific patterns\n * - \"wallet address\" helps identify Base58 strings as Solana addresses\n */\n extractHints?: string[];\n /**\n * Confidence threshold for automatic acceptance. Default: 0.8.\n *\n * WHY configurable threshold:\n * - High-stakes fields (payment amount) need high confidence\n * - Low-stakes fields (nickname) can be more lenient\n */\n confirmThreshold?: number;\n /** Example value for \"give me an example\" request */\n example?: string;\n\n // ═══ UI HINTS ═══\n /** Hints for future GUI rendering */\n ui?: FormControlUI;\n\n // ═══ I18N ═══\n /** Localized versions of label, description, askPrompt */\n i18n?: Record<string, FormControlI18n>;\n\n // ═══ NESTED FIELDS ═══\n /**\n * Child fields for object/array types.\n *\n * WHY nested fields:\n * - Complex data like address (street, city, zip)\n * - Agent can collect as one logical unit\n * - Stored as nested object\n */\n fields?: FormControl[];\n\n // ═══ EXTENSION ═══\n /**\n * Arbitrary metadata for plugins.\n *\n * WHY meta field:\n * - Plugins may need custom data we didn't anticipate\n * - Avoids modifying core types\n * - Example: trading plugin adds 'slippage_tolerance'\n */\n meta?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// FORM DEFINITION - The container for controls\n// ============================================================================\n\n/**\n * UX options for the form.\n *\n * WHY form-level UX options:\n * - Different forms have different requirements\n * - Legal forms might disable undo\n * - Quick forms might disable autofill\n */\nexport interface FormDefinitionUX {\n /** Allow \"undo\" to revert last change. Default: true */\n allowUndo?: boolean;\n /** Allow \"skip\" for optional fields. Default: true */\n allowSkip?: boolean;\n /** Maximum undo history size. Default: 5 */\n maxUndoSteps?: number;\n /** Show examples when user asks. Default: true */\n showExamples?: boolean;\n /** Show explanations when user asks. Default: true */\n showExplanations?: boolean;\n /** Allow autofill from previous submissions. Default: true */\n allowAutofill?: boolean;\n}\n\n/**\n * Smart TTL configuration.\n *\n * WHY effort-based TTL:\n * - User spending 2 hours on a form deserves weeks of retention\n * - User who started and abandoned deserves quick cleanup\n * - Respects user effort while managing storage\n */\nexport interface FormDefinitionTTL {\n /** Minimum retention in days, even with no effort. Default: 14 */\n minDays?: number;\n /** Maximum retention in days, regardless of effort. Default: 90 */\n maxDays?: number;\n /**\n * Days added per minute of user effort. Default: 0.5.\n * Example: 10 min work = 5 extra days retention.\n */\n effortMultiplier?: number;\n}\n\n/**\n * Nudge configuration for stale sessions.\n *\n * WHY nudge system:\n * - Users forget about forms they started\n * - Gentle reminders increase completion rates\n * - But too many nudges are spammy\n */\nexport interface FormDefinitionNudge {\n /** Enable nudge messages. Default: true */\n enabled?: boolean;\n /** Hours of inactivity before first nudge. Default: 48 */\n afterInactiveHours?: number;\n /** Maximum nudge messages to send. Default: 3 */\n maxNudges?: number;\n /** Custom nudge message template */\n message?: string;\n}\n\n/**\n * Hook configuration (task worker names).\n *\n * WHY hooks as task worker names:\n * - Consuming plugins define their own logic\n * - Hooks are async and can do anything\n * - Decouples form system from business logic\n */\nexport interface FormDefinitionHooks {\n /** Called when session starts */\n onStart?: string;\n /** Called when any field changes */\n onFieldChange?: string;\n /** Called when all required fields are filled */\n onReady?: string;\n /** Called on successful submission */\n onSubmit?: string;\n /** Called when user cancels */\n onCancel?: string;\n /** Called when session expires */\n onExpire?: string;\n}\n\n/**\n * Localization for the form.\n */\nexport interface FormDefinitionI18n {\n name?: string;\n description?: string;\n}\n\n/**\n * FormDefinition - The form container\n *\n * Defines a complete form including all its fields, lifecycle settings,\n * permissions, and hooks for consuming plugins.\n *\n * WHY separate from controls:\n * - Form-level settings affect all controls\n * - Hooks need form context\n * - Permissions apply to entire form\n */\nexport interface FormDefinition {\n // ═══ IDENTITY ═══\n /** Unique identifier for this form definition */\n id: string;\n /** Human-readable name shown in UI and agent responses */\n name: string;\n /** Description of what this form collects */\n description?: string;\n /**\n * Schema version for migrations. Default: 1.\n *\n * WHY version:\n * - Forms evolve over time\n * - Old sessions might use old schema\n * - Version helps handle migrations\n */\n version?: number;\n\n // ═══ CONTROLS ═══\n /** Array of field definitions */\n controls: FormControl[];\n\n // ═══ LIFECYCLE ═══\n /**\n * Form status. Draft forms aren't startable.\n *\n * WHY status:\n * - Forms can be prepared but not yet active\n * - Deprecated forms shouldn't start new sessions\n * - Existing sessions on deprecated forms continue\n */\n status?: \"draft\" | \"active\" | \"deprecated\";\n\n // ═══ PERMISSIONS ═══\n /**\n * Roles that can start this form.\n *\n * WHY form-level roles:\n * - Some forms only for admins\n * - Prevents unauthorized data collection\n */\n roles?: string[];\n\n // ═══ BEHAVIOR ═══\n /**\n * Allow multiple submissions per user.\n *\n * WHY this flag:\n * - Registration forms: one per user\n * - Order forms: unlimited submissions\n * - Feedback forms: maybe one per session\n */\n allowMultiple?: boolean;\n\n // ═══ UX OPTIONS ═══\n ux?: FormDefinitionUX;\n\n // ═══ TTL (Smart Retention) ═══\n ttl?: FormDefinitionTTL;\n\n // ═══ NUDGE ═══\n nudge?: FormDefinitionNudge;\n\n // ═══ HOOKS ═══\n hooks?: FormDefinitionHooks;\n\n // ═══ DEBUG ═══\n /**\n * Enable debug logging for extraction.\n *\n * WHY debug flag:\n * - Extraction is LLM-based and can fail mysteriously\n * - Debug logs show LLM reasoning\n * - Off by default for performance\n */\n debug?: boolean;\n\n // ═══ I18N ═══\n i18n?: Record<string, FormDefinitionI18n>;\n\n // ═══ EXTENSION ═══\n meta?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// FIELD STATE - Runtime state of a single field\n// ============================================================================\n\n/**\n * File attachment metadata.\n *\n * WHY separate from value:\n * - Files need special handling (storage, URLs)\n * - Metadata is safe to serialize, file content isn't\n * - URL might be temporary/signed\n */\nexport interface FieldFile {\n /** Unique identifier for the file */\n id: string;\n /** Original filename */\n name: string;\n /** MIME type */\n mimeType: string;\n /** Size in bytes */\n size: number;\n /** URL to access the file */\n url: string;\n}\n\n/**\n * FieldState - Runtime state of a field\n *\n * Tracks the current value, validation status, confidence level,\n * and audit trail for a single field in an active form session.\n *\n * WHY this complexity:\n * - Agent extractions have confidence levels\n * - Users correct mistakes (\"no, I meant...\")\n * - Undo needs history\n * - Validation happens at extraction, not just submission\n */\nexport interface FieldState {\n // ═══ STATUS ═══\n /**\n * Current status of this field.\n *\n * WHY multiple statuses:\n * - 'empty': Not yet provided\n * - 'filled': Value accepted\n * - 'uncertain': LLM not confident, needs confirmation\n * - 'invalid': Value failed validation\n * - 'skipped': User explicitly skipped optional field\n * - 'pending': External type activated, waiting for confirmation\n */\n status: \"empty\" | \"filled\" | \"uncertain\" | \"invalid\" | \"skipped\" | \"pending\";\n\n // ═══ VALUE ═══\n /** The current value (undefined if empty/skipped) */\n value?: JsonValue;\n\n // ═══ CONFIDENCE ═══\n /**\n * LLM confidence in extraction. 0-1.\n *\n * WHY track confidence:\n * - Low confidence triggers confirmation\n * - High confidence allows auto-acceptance\n * - Useful for debugging extraction issues\n */\n confidence?: number;\n /** Other possible interpretations of user message */\n alternatives?: JsonValue[];\n\n // ═══ VALIDATION ═══\n /** Validation error message if status is 'invalid' */\n error?: string;\n\n // ═══ FILES ═══\n /** File metadata for file-type fields */\n files?: FieldFile[];\n\n // ═══ AUDIT TRAIL ═══\n /**\n * How this value was obtained.\n *\n * WHY track source:\n * - Autofilled values might need re-confirmation\n * - Corrections show user engagement\n * - Useful for analytics\n */\n source?:\n | \"extraction\"\n | \"autofill\"\n | \"default\"\n | \"manual\"\n | \"correction\"\n | \"external\";\n /** ID of message that provided this value */\n messageId?: string;\n /** When the value was last updated */\n updatedAt?: number;\n /** When user confirmed an uncertain value */\n confirmedAt?: number;\n\n // ═══ COMPOSITE TYPES ═══\n /**\n * Subfield states for composite control types.\n *\n * WHY subFields:\n * - Composite types (address, payment) have multiple parts\n * - Each part has its own state (filled, uncertain, etc.)\n * - Parent field is \"filled\" when all required subfields are filled\n *\n * Keyed by subcontrol key (e.g., \"amount\", \"currency\" for payment).\n */\n subFields?: Record<string, FieldState>;\n\n // ═══ EXTERNAL TYPES ═══\n /**\n * State for external/async control types.\n *\n * WHY externalState:\n * - External types (payment, signature) have async lifecycle\n * - Need to track activation status, reference, instructions\n * - Separate from main status because field can be \"pending\" while\n * we wait for external confirmation\n *\n * @see ExternalFieldState for full interface\n */\n externalState?: {\n /** Current status of the external interaction */\n status: \"pending\" | \"confirmed\" | \"failed\" | \"expired\";\n /** Reference used to match external events */\n reference?: string;\n /** Instructions shown to user (cached from activation) */\n instructions?: string;\n /** Address shown to user (cached from activation) */\n address?: string;\n /** When the external process was activated */\n activatedAt?: number;\n /** When the external process was confirmed */\n confirmedAt?: number;\n /** Data from the external confirmation (txId, signature, etc.) */\n externalData?: Record<string, JsonValue>;\n };\n\n // ═══ EXTENSION ═══\n meta?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// FORM SESSION - Active form being filled\n// ============================================================================\n\n/**\n * History entry for undo functionality.\n *\n * WHY track history:\n * - \"Undo\" is natural in conversation (\"wait, go back\")\n * - Need to know what to restore\n * - Limited history prevents memory bloat\n */\nexport interface FieldHistoryEntry {\n /** Which field was changed */\n field: string;\n /** Previous value (to restore) */\n oldValue: JsonValue;\n /** New value (for audit) */\n newValue: JsonValue;\n /** When the change happened */\n timestamp: number;\n}\n\n/**\n * Effort tracking for smart TTL.\n *\n * WHY track effort:\n * - Forms abandoned quickly should expire quickly\n * - Forms worked on for hours deserve long retention\n * - Interaction count shows engagement even if time is short\n */\nexport interface SessionEffort {\n /** Number of messages processed for this form */\n interactionCount: number;\n /** Total time from first to last interaction */\n timeSpentMs: number;\n /** When user first interacted with this form */\n firstInteractionAt: number;\n /** When user last interacted with this form */\n lastInteractionAt: number;\n}\n\n/**\n * FormSession - Active form state\n *\n * Represents an active form being filled by a user. This is the runtime\n * state that changes as the conversation progresses.\n *\n * WHY scoped to (entityId + roomId):\n * - Same user might fill different forms in different rooms\n * - Each room conversation has its own context\n * - User in Discord DM vs Telegram should have separate sessions\n *\n * WHY not just store values directly:\n * - Need to track status of each field\n * - Need confidence levels for confirmation\n * - Need history for undo\n * - Need metadata for analytics\n */\nexport interface FormSession {\n // ═══ IDENTITY ═══\n /** Unique session ID */\n id: string;\n /** Reference to FormDefinition.id */\n formId: string;\n /** Form version at session start (for migration handling) */\n formVersion?: number;\n\n // ═══ SCOPING (user + room) ═══\n /** The user filling the form */\n entityId: UUID;\n /** The room where conversation is happening */\n roomId: UUID;\n\n // ═══ STATUS ═══\n /**\n * Session lifecycle status.\n *\n * WHY multiple statuses:\n * - 'active': Currently being filled\n * - 'ready': All required fields done, can submit\n * - 'submitted': Successfully submitted\n * - 'stashed': Saved for later\n * - 'cancelled': User abandoned\n * - 'expired': TTL exceeded\n */\n status:\n | \"active\"\n | \"ready\"\n | \"submitted\"\n | \"stashed\"\n | \"cancelled\"\n | \"expired\";\n\n // ═══ FIELD DATA ═══\n /** Current state of each field, keyed by control.key */\n fields: Record<string, FieldState>;\n\n // ═══ HISTORY (for undo) ═══\n /** Recent changes for undo functionality */\n history: FieldHistoryEntry[];\n\n // ═══ HIERARCHY ═══\n /**\n * Parent session ID for subforms.\n *\n * WHY parent reference:\n * - Complex forms might have nested sections\n * - Subform completion triggers parent update\n * - Not yet implemented but structure is ready\n */\n parentSessionId?: string;\n\n // ═══ CONTEXT ═══\n /**\n * Arbitrary context from consuming plugin.\n *\n * WHY context field:\n * - Consuming plugin might pass order ID, user tier, etc.\n * - Affects how form behaves or what values are valid\n * - Stored with session for hook access\n */\n context?: Record<string, JsonValue>;\n /** User's locale for i18n */\n locale?: string;\n\n // ═══ TRACKING ═══\n /** Last field agent asked about (for skip functionality) */\n lastAskedField?: string;\n /** Last message processed (for deduplication) */\n lastMessageId?: string;\n /** True if we asked \"are you sure you want to cancel?\" */\n cancelConfirmationAsked?: boolean;\n\n // ═══ EFFORT (for smart TTL) ═══\n effort: SessionEffort;\n\n // ═══ TTL ═══\n /** When this session expires (timestamp) */\n expiresAt: number;\n /** True if we already warned about expiration */\n expirationWarned?: boolean;\n /** Number of nudge messages sent */\n nudgeCount?: number;\n /** When we last sent a nudge */\n lastNudgeAt?: number;\n\n // ═══ TIMESTAMPS ═══\n /** When session was created */\n createdAt: number;\n /** When session was last modified */\n updatedAt: number;\n /** When session was submitted (if status is 'submitted') */\n submittedAt?: number;\n\n // ═══ EXTENSION ═══\n meta?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// FORM SUBMISSION - Completed form data\n// ============================================================================\n\n/**\n * FormSubmission - Completed form record\n *\n * The permanent record of a submitted form. This is what consuming\n * plugins use to create accounts, process orders, etc.\n *\n * WHY separate from session:\n * - Sessions are mutable, submissions are immutable\n * - Submissions don't need undo history, TTL, etc.\n * - Submissions are the \"official record\"\n */\nexport interface FormSubmission {\n /** Unique submission ID */\n id: string;\n /** Which form definition this is for */\n formId: string;\n /** Form version at submission time */\n formVersion?: number;\n /** The session that produced this submission */\n sessionId: string;\n /** Who submitted */\n entityId: UUID;\n\n /** Field values keyed by control.key */\n values: Record<string, JsonValue>;\n /**\n * Same values but keyed by dbbind.\n *\n * WHY mappedValues:\n * - Convenience for consuming plugins\n * - No need to look up dbbind for each field\n * - Direct database insertion ready\n */\n mappedValues?: Record<string, JsonValue>;\n /** File attachments keyed by control.key */\n files?: Record<string, FieldFile[]>;\n\n /** When the form was submitted */\n submittedAt: number;\n\n meta?: Record<string, JsonValue>;\n}\n\n// ============================================================================\n// TYPE HANDLER - Custom type validation & formatting\n// ============================================================================\n\n/**\n * TypeHandler - Custom type behavior.\n *\n * Allows registering custom field types with their own validation,\n * parsing, formatting, and extraction hints. Used by the validation\n * pipeline for simple single-value types. For composite or external\n * types, use ControlType instead.\n */\nexport interface TypeHandler {\n /** Validate a value. Return { valid: true } or { valid: false, error: '...' } */\n validate?: (\n value: JsonValue,\n control: FormControl,\n ) => { valid: boolean; error?: string };\n /** Parse string input to appropriate type */\n parse?: (value: string) => JsonValue;\n /** Format value for display */\n format?: (value: JsonValue) => string;\n /**\n * Description for LLM extraction.\n *\n * WHY extraction prompt:\n * - Helps LLM understand what to look for\n * - \"a US phone number (10 digits)\" vs just \"phone\"\n */\n extractionPrompt?: string;\n}\n\n// ============================================================================\n// CONTROL TYPE - widget/type registry\n// ============================================================================\n\n/**\n * ValidationResult - Standardized validation output\n *\n * WHY this structure:\n * - Consistent validation across all control types\n * - Error messages can be shown to users\n * - Simple boolean + optional error pattern\n */\nexport interface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * ActivationContext - Context passed to external control types\n *\n * WHY this exists:\n * - External types (payment, signature) need runtime access\n * - They need the session and control for context\n * - They need subfield values to know what to activate\n *\n * Example: Payment widget needs amount, currency, method from subcontrols\n * to generate the correct payment address and instructions.\n */\nexport interface ActivationContext {\n /** Runtime for accessing services */\n runtime: import(\"@elizaos/core\").IAgentRuntime;\n /** The current form session */\n session: FormSession;\n /** The control being activated */\n control: FormControl;\n /** Filled subcontrol values, keyed by subcontrol key */\n subValues: Record<string, JsonValue>;\n}\n\n/**\n * ExternalActivation - Result of activating an external control type\n *\n * WHY this structure:\n * - Instructions tell user what to do (\"Send 0.5 SOL to xyz...\")\n * - Reference uniquely identifies this activation for matching events\n * - Address is optional but common (payment address, signing target)\n * - ExpiresAt allows time-limited activations\n *\n * The reference is critical: when a blockchain event comes in,\n * we match it to the pending activation via this reference.\n */\nexport interface ExternalActivation {\n /** Human-readable instructions for the user */\n instructions: string;\n /** Unique reference to match external events (e.g., memo, tx reference) */\n reference: string;\n /** Optional address (payment address, signing endpoint, etc.) */\n address?: string;\n /** When this activation expires (timestamp) */\n expiresAt?: number;\n /** Arbitrary metadata from the widget */\n meta?: Record<string, JsonValue>;\n}\n\n/**\n * ExternalFieldState - State tracking for external/async control types\n *\n * WHY this exists:\n * - External types have async lifecycles (pending → confirmed/failed)\n * - Need to store instructions for agent to communicate\n * - Need reference for matching events\n * - Need to track when things happened for debugging/TTL\n *\n * Stored within FieldState.externalState for fields using external types.\n */\nexport interface ExternalFieldState {\n /** Current status of the external interaction */\n status: \"pending\" | \"confirmed\" | \"failed\" | \"expired\";\n /** Reference used to match external events */\n reference?: string;\n /** Instructions shown to user (cached from activation) */\n instructions?: string;\n /** Address shown to user (cached from activation) */\n address?: string;\n /** When the external process was activated */\n activatedAt?: number;\n /** When the external process was confirmed */\n confirmedAt?: number;\n /** Data from the external confirmation (txId, signature, etc.) */\n externalData?: Record<string, JsonValue>;\n}\n\n/**\n * ControlType - widget/type registry entry\n *\n * This is the evolution of TypeHandler into a full widget system.\n * ControlType handles three patterns:\n *\n * 1. **Simple types** (text, number, email)\n * - Just validate/parse/format\n * - No subcontrols, no activation\n *\n * 2. **Composite types** (address, payment setup)\n * - Have subcontrols (getSubControls)\n * - Parent field is \"filled\" when all subcontrols filled\n * - No external activation\n *\n * 3. **External types** (payment, signature, file upload)\n * - May have subcontrols\n * - Have activate() for starting async process\n * - Confirmation comes from external event\n *\n * WHY shared interface:\n * - Plugins register one type of thing (ControlType)\n * - FormService treats all types uniformly\n * - Progressive capability: simple types just use validate()\n *\n * WHY builtin flag:\n * - Protects standard types from accidental override\n * - Allows intentional override with allowOverride option\n * - Logs warning when override happens\n *\n * Example registrations:\n *\n * ```typescript\n * // Simple type\n * formService.registerControlType({\n * id: 'phone',\n * builtin: false,\n * validate: (v) => ({ valid: /^\\+?[\\d\\s-]{10,}$/.test(String(v)) }),\n * extractionPrompt: 'a phone number with country code',\n * });\n *\n * // Composite type\n * formService.registerControlType({\n * id: 'address',\n * getSubControls: () => [\n * { key: 'street', type: 'text', label: 'Street', required: true },\n * { key: 'city', type: 'text', label: 'City', required: true },\n * { key: 'zip', type: 'text', label: 'ZIP', required: true },\n * ],\n * });\n *\n * // External type (payment)\n * formService.registerControlType({\n * id: 'payment',\n * getSubControls: () => [\n * { key: 'amount', type: 'number', label: 'Amount', required: true },\n * { key: 'currency', type: 'select', label: 'Currency', required: true },\n * ],\n * activate: async (ctx) => {\n * const paymentService = ctx.runtime.getService('PAYMENT');\n * return paymentService.createPendingPayment(ctx.subValues);\n * },\n * deactivate: async (ctx) => {\n * const ref = ctx.session.fields[ctx.control.key]?.externalState?.reference;\n * if (ref) await paymentService.cancelPending(ref);\n * },\n * });\n * ```\n */\nexport interface ControlType {\n /** Unique identifier for this control type */\n id: string;\n\n /**\n * If true, this is a built-in type that should warn on override.\n * Built-in types: text, number, email, boolean, select, date, file\n */\n builtin?: boolean;\n\n // ═══ SIMPLE TYPE METHODS ═══\n\n /**\n * Validate a value for this type.\n * Called during extraction and before submission.\n */\n validate?: (value: JsonValue, control: FormControl) => ValidationResult;\n\n /**\n * Parse string input to the appropriate type.\n * Called when processing extracted values.\n */\n parse?: (value: string) => JsonValue;\n\n /**\n * Format value for display to user.\n * Called when showing field values in context.\n */\n format?: (value: JsonValue) => string;\n\n /**\n * Description for LLM extraction.\n * Helps the LLM understand what to look for in user messages.\n */\n extractionPrompt?: string;\n\n // ═══ COMPOSITE TYPE METHODS ═══\n\n /**\n * Return subcontrols that must be filled before parent is complete.\n *\n * WHY runtime parameter:\n * - Subcontrols might depend on available services\n * - e.g., payment methods depend on what payment plugins are loaded\n *\n * Called by evaluator to understand the field structure.\n */\n getSubControls?: (\n control: FormControl,\n runtime: import(\"@elizaos/core\").IAgentRuntime,\n ) => FormControl[];\n\n // ═══ EXTERNAL TYPE METHODS ═══\n\n /**\n * Activate the external process.\n *\n * Called when all subcontrols are filled (or immediately for\n * external types without subcontrols).\n *\n * Returns activation info including instructions and reference.\n * The reference is used to match incoming external events.\n */\n activate?: (context: ActivationContext) => Promise<ExternalActivation>;\n\n /**\n * Deactivate/cancel a pending external process.\n *\n * Called when user cancels form or field is reset.\n * Should clean up any pending listeners/watchers.\n */\n deactivate?: (context: ActivationContext) => Promise<void>;\n}\n\n// ============================================================================\n// FORM WIDGET EVENTS - Events emitted by evaluator\n// ============================================================================\n\n/**\n * Form widget event types\n *\n * WHY events:\n * - Widgets don't parse messages, evaluator does\n * - Widgets react to these standardized events\n * - Single source of truth for extraction\n * - Plugins can listen for analytics/logging\n *\n * The evaluator emits these as it processes messages.\n */\nexport type FormWidgetEventType =\n | \"FORM_FIELD_EXTRACTED\" // Value extracted for any field\n | \"FORM_SUBFIELD_UPDATED\" // Subcontrol value updated\n | \"FORM_SUBCONTROLS_FILLED\" // All subcontrols of composite type filled\n | \"FORM_EXTERNAL_ACTIVATED\" // External type activated\n | \"FORM_FIELD_CONFIRMED\" // External field confirmed\n | \"FORM_FIELD_CANCELLED\"; // External field cancelled/expired\n\n/**\n * Payload for FORM_FIELD_EXTRACTED event\n */\nexport interface FormFieldExtractedEvent {\n type: \"FORM_FIELD_EXTRACTED\";\n sessionId: string;\n field: string;\n value: JsonValue;\n confidence: number;\n}\n\n/**\n * Payload for FORM_SUBFIELD_UPDATED event\n */\nexport interface FormSubfieldUpdatedEvent {\n type: \"FORM_SUBFIELD_UPDATED\";\n sessionId: string;\n parentField: string;\n subField: string;\n value: JsonValue;\n confidence: number;\n}\n\n/**\n * Payload for FORM_SUBCONTROLS_FILLED event\n */\nexport interface FormSubcontrolsFilledEvent {\n type: \"FORM_SUBCONTROLS_FILLED\";\n sessionId: string;\n field: string;\n subValues: Record<string, JsonValue>;\n}\n\n/**\n * Payload for FORM_EXTERNAL_ACTIVATED event\n */\nexport interface FormExternalActivatedEvent {\n type: \"FORM_EXTERNAL_ACTIVATED\";\n sessionId: string;\n field: string;\n activation: ExternalActivation;\n}\n\n/**\n * Payload for FORM_FIELD_CONFIRMED event\n */\nexport interface FormFieldConfirmedEvent {\n type: \"FORM_FIELD_CONFIRMED\";\n sessionId: string;\n field: string;\n value: JsonValue;\n externalData?: Record<string, JsonValue>;\n}\n\n/**\n * Payload for FORM_FIELD_CANCELLED event\n */\nexport interface FormFieldCancelledEvent {\n type: \"FORM_FIELD_CANCELLED\";\n sessionId: string;\n field: string;\n reason: string;\n}\n\n/**\n * Union of all form widget events\n */\nexport type FormWidgetEvent =\n | FormFieldExtractedEvent\n | FormSubfieldUpdatedEvent\n | FormSubcontrolsFilledEvent\n | FormExternalActivatedEvent\n | FormFieldConfirmedEvent\n | FormFieldCancelledEvent;\n\n// ============================================================================\n// FORM CONTEXT STATE - Provider output\n// ============================================================================\n\n/**\n * Filled field summary for context.\n */\nexport interface FilledFieldSummary {\n key: string;\n label: string;\n /** Formatted value safe to show user (respects sensitive flag) */\n displayValue: string;\n}\n\n/**\n * Missing field summary for context.\n */\nexport interface MissingFieldSummary {\n key: string;\n label: string;\n description?: string;\n /** How agent should ask for this field */\n askPrompt?: string;\n}\n\n/**\n * Uncertain field summary for confirmation.\n */\nexport interface UncertainFieldSummary {\n key: string;\n label: string;\n /** The uncertain value */\n value: JsonValue;\n /** How confident the LLM was */\n confidence: number;\n}\n\n/**\n * FormContextState - Provider output for agent\n *\n * The context injected into the agent's state, giving it awareness\n * of the current form progress and what to do next.\n *\n * WHY this structure:\n * - Agent needs to know what's filled (for progress updates)\n * - Agent needs to know what's missing (to ask)\n * - Agent needs to know what's uncertain (to confirm)\n * - Agent needs suggested actions (what to do next)\n */\n/**\n * Summary of a pending external field for agent context.\n */\nexport interface PendingExternalFieldSummary {\n /** Field key */\n key: string;\n /** Field label for display */\n label: string;\n /** Instructions for the user (e.g., \"Send 0.5 SOL to xyz...\") */\n instructions: string;\n /** Reference for matching (may be shown to user) */\n reference: string;\n /** When the external process was activated */\n activatedAt: number;\n /** Optional address (payment address, etc.) */\n address?: string;\n}\n\nexport interface FormContextState {\n /** True if there's an active form in this room */\n hasActiveForm: boolean;\n /** Current form ID */\n formId?: string;\n /** Current form name */\n formName?: string;\n /** Completion percentage (0-100) */\n progress: number;\n /** Fields that have been filled */\n filledFields: FilledFieldSummary[];\n /** Required fields still needed */\n missingRequired: MissingFieldSummary[];\n /** Fields needing user confirmation */\n uncertainFields: UncertainFieldSummary[];\n /** Next field to ask about */\n nextField: FormControl | null;\n /** Current session status */\n status?: FormSession[\"status\"];\n /** Number of stashed forms (for \"you have saved forms\" prompt) */\n stashedCount?: number;\n /** True if we asked \"are you sure you want to cancel?\" */\n pendingCancelConfirmation?: boolean;\n\n /**\n * External fields waiting for confirmation.\n *\n * WHY this exists:\n * - Agent needs to remind user about pending payments/signatures\n * - Shows instructions and reference for user to act on\n * - Allows agent to check \"still waiting for your payment...\"\n */\n pendingExternalFields: PendingExternalFieldSummary[];\n}\n\n// ============================================================================\n// INTENT SYSTEM\n// ============================================================================\n\n/**\n * All supported user intents.\n *\n * WHY explicit intent types:\n * - Type safety for intent handling\n * - Clear documentation of what's supported\n * - Easy to add new intents\n */\nexport type FormIntent =\n // Lifecycle - affects session state\n | \"fill_form\" // Providing field values\n | \"submit\" // Ready to submit\n | \"stash\" // Save for later\n | \"restore\" // Resume saved form\n | \"cancel\" // Abandon form\n\n // UX Magic - helper actions\n | \"undo\" // Revert last change\n | \"skip\" // Skip optional field\n | \"explain\" // \"Why do you need this?\"\n | \"example\" // \"Give me an example\"\n | \"progress\" // \"How far am I?\"\n | \"autofill\" // \"Use my usual values\"\n\n // Fallback\n | \"other\"; // Unknown intent\n\n/**\n * Extraction result for a single field.\n *\n * WHY this structure:\n * - Need value and confidence together\n * - Need to know if this is correcting a previous value\n * - Need reasoning for debugging\n */\nexport interface ExtractionResult {\n /** Which field this is for */\n field: string;\n /** Extracted value */\n value: JsonValue;\n /** LLM confidence (0-1) */\n confidence: number;\n /** LLM reasoning (for debug mode) */\n reasoning?: string;\n /** Other possible values if uncertain */\n alternatives?: JsonValue[];\n /** True if user is correcting previous value */\n isCorrection?: boolean;\n}\n\n/**\n * Combined intent and extraction result.\n *\n * WHY combined:\n * - Single LLM call extracts both intent and values\n * - Reduces latency\n * - Context helps with both\n */\nexport interface IntentResult {\n /** What the user wants to do */\n intent: FormIntent;\n /** Extracted field values (for fill_form intent) */\n extractions: ExtractionResult[];\n /** Target form ID for restore if multiple stashed */\n targetFormId?: string;\n}\n\n// ============================================================================\n// DEFAULTS\n// ============================================================================\n\n/**\n * Default values for FormControl.\n *\n * WHY explicit defaults:\n * - Clear documentation of behavior\n * - Used by applyControlDefaults()\n * - Can be overridden per-control\n */\nexport const FORM_CONTROL_DEFAULTS = {\n type: \"text\",\n required: false,\n confirmThreshold: 0.8,\n} as const;\n\n/**\n * Default values for FormDefinition.\n *\n * WHY these specific defaults:\n * - 14 days min TTL: Long enough for user to return\n * - 90 days max TTL: Not forever, but generous\n * - 0.5 effort multiplier: 10 min work = 5 extra days\n * - 48h nudge: Not too aggressive\n * - 3 max nudges: Helpful but not spammy\n */\nexport const FORM_DEFINITION_DEFAULTS = {\n version: 1,\n status: \"active\" as const,\n ux: {\n allowUndo: true,\n allowSkip: true,\n maxUndoSteps: 5,\n showExamples: true,\n showExplanations: true,\n allowAutofill: true,\n },\n ttl: {\n minDays: 14,\n maxDays: 90,\n effortMultiplier: 0.5,\n },\n nudge: {\n enabled: true,\n afterInactiveHours: 48,\n maxNudges: 3,\n },\n debug: false,\n} as const;\n\n// ============================================================================\n// COMPONENT TYPES - For storage\n// ============================================================================\n\n/**\n * Component type prefix for form sessions.\n *\n * WHY component-based storage:\n * - Components are elizaOS's entity data storage\n * - Scoped to entity, can include room in type\n * - Automatic CRUD via runtime\n */\nexport const FORM_SESSION_COMPONENT = \"form_session\";\n\n/**\n * Component type prefix for form submissions.\n */\nexport const FORM_SUBMISSION_COMPONENT = \"form_submission\";\n\n/**\n * Component type prefix for autofill data.\n */\nexport const FORM_AUTOFILL_COMPONENT = \"form_autofill\";\n\n/**\n * Autofill data stored per user per form.\n *\n * WHY store autofill:\n * - Users filling repeat forms want saved values\n * - Stored per user per form (not global)\n * - Updated on each submission\n */\nexport interface FormAutofillData {\n formId: string;\n values: Record<string, JsonValue>;\n updatedAt: number;\n}\n"],"mappings":"AAo2CO,MAAM,wBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,kBAAkB;AACpB;AAYO,MAAM,2BAA2B;AAAA,EACtC,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,IAAI;AAAA,IACF,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,SAAS;AAAA,IACT,kBAAkB;AAAA,EACpB;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,oBAAoB;AAAA,IACpB,WAAW;AAAA,EACb;AAAA,EACA,OAAO;AACT;AAcO,MAAM,yBAAyB;AAK/B,MAAM,4BAA4B;AAKlC,MAAM,0BAA0B;","names":[]}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @module validation
3
+ * @description Field validation utilities for the Form Plugin
4
+ *
5
+ * ## Design Rationale
6
+ *
7
+ * Validation happens at two points in the form lifecycle:
8
+ *
9
+ * 1. **At Extraction**: When the LLM extracts a value from user message,
10
+ * we immediately validate it. Invalid values get status 'invalid' and
11
+ * the agent asks again. This provides instant feedback.
12
+ *
13
+ * 2. **At Submission**: Final validation before submission ensures no
14
+ * invalid values slipped through. This is the safety net.
15
+ *
16
+ * ## Type Handler Registry (Legacy) vs ControlType
17
+ *
18
+ * There are two ways to register custom types:
19
+ *
20
+ * 1. **TypeHandler (Legacy)**: Simple validate/parse/format functions.
21
+ * Registered via registerTypeHandler(). Still supported for backwards
22
+ * compatibility.
23
+ *
24
+ * 2. **ControlType (New)**: Full widget system with subcontrols and
25
+ * external activation. Registered via FormService.registerControlType().
26
+ * Use this for new code.
27
+ *
28
+ * This validation module still uses TypeHandler for backwards compatibility.
29
+ * The FormService.getControlType() method should be preferred for new code.
30
+ *
31
+ * ## Custom Type Examples
32
+ *
33
+ * - Blockchain addresses (Solana, EVM)
34
+ * - Phone numbers (with country-specific rules)
35
+ * - Custom business identifiers (order numbers, employee IDs)
36
+ *
37
+ * Custom handlers are checked FIRST, before built-in type validation.
38
+ * This allows overriding built-in types if needed.
39
+ *
40
+ * ## Why String-Based Types
41
+ *
42
+ * Form control types are strings, not enums, because:
43
+ * - Plugins can add new types without modifying core
44
+ * - Type handlers provide runtime extensibility
45
+ * - No need to maintain exhaustive type lists
46
+ */
47
+ import type { JsonValue } from "@elizaos/core";
48
+ import type { FormControl, TypeHandler } from "./types";
49
+ /**
50
+ * Validation result.
51
+ *
52
+ * WHY simple structure:
53
+ * - Just need to know valid/invalid
54
+ * - Error message for user feedback
55
+ * - Easy to compose multiple validations
56
+ */
57
+ export interface ValidationResult {
58
+ valid: boolean;
59
+ error?: string;
60
+ }
61
+ /**
62
+ * Register a custom type handler.
63
+ *
64
+ * WHY this API:
65
+ * - Simple key-value registration
66
+ * - Called at plugin initialization
67
+ * - Overwrites existing handlers (allows hot-reload)
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * registerTypeHandler('solana_address', {
72
+ * validate: (value) => {
73
+ * const valid = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(String(value));
74
+ * return { valid, error: valid ? undefined : 'Invalid Solana address' };
75
+ * },
76
+ * extractionPrompt: 'a Solana wallet address (Base58 encoded)',
77
+ * });
78
+ * ```
79
+ */
80
+ export declare function registerTypeHandler(type: string, handler: TypeHandler): void;
81
+ /**
82
+ * Get a type handler.
83
+ *
84
+ * @returns The handler or undefined if not registered
85
+ */
86
+ export declare function getTypeHandler(type: string): TypeHandler | undefined;
87
+ /**
88
+ * Clear all type handlers.
89
+ *
90
+ * WHY this exists:
91
+ * - Test isolation
92
+ * - Hot-reload scenarios
93
+ * - Should not be called in production
94
+ */
95
+ export declare function clearTypeHandlers(): void;
96
+ /**
97
+ * Validate a value against a control's validation rules.
98
+ *
99
+ * Validation order (first failure returns):
100
+ * 1. Required check
101
+ * 2. Custom type handler (if registered)
102
+ * 3. Built-in type validation
103
+ * 4. Pattern, min/max, etc.
104
+ *
105
+ * WHY this order:
106
+ * - Required is fastest check
107
+ * - Custom handlers may have special logic
108
+ * - Built-in types provide fallback
109
+ * - Pattern/limits are additional constraints
110
+ *
111
+ * @param value - The value to validate
112
+ * @param control - The field definition with validation rules
113
+ * @returns Validation result with error message if invalid
114
+ */
115
+ export declare function validateField(value: JsonValue, control: FormControl): ValidationResult;
116
+ /**
117
+ * Check if a MIME type matches a pattern.
118
+ *
119
+ * Supports:
120
+ * - Exact match: "image/png"
121
+ * - Wildcard: "image/*"
122
+ * - Universal: "*\/*"
123
+ *
124
+ * @example
125
+ * matchesMimeType('image/png', 'image/*') // true
126
+ * matchesMimeType('application/pdf', 'image/*') // false
127
+ */
128
+ export declare function matchesMimeType(mimeType: string, pattern: string): boolean;
129
+ /**
130
+ * Parse a string value to the appropriate type based on control type.
131
+ *
132
+ * WHY parsing:
133
+ * - LLM extraction returns strings
134
+ * - We need proper types for validation and storage
135
+ * - Custom handlers can define custom parsing
136
+ *
137
+ * @param value - String value from extraction
138
+ * @param control - Field definition to determine type
139
+ * @returns Parsed value of appropriate type
140
+ */
141
+ export declare function parseValue(value: string, control: FormControl): JsonValue;
142
+ /**
143
+ * Format a value for display.
144
+ *
145
+ * WHY formatting:
146
+ * - Numbers should have locale formatting
147
+ * - Booleans should be "Yes"/"No" not "true"/"false"
148
+ * - Sensitive values should be masked
149
+ * - Select values should show label not value
150
+ *
151
+ * @param value - The value to format
152
+ * @param control - Field definition with display hints
153
+ * @returns Human-readable string representation
154
+ */
155
+ export declare function formatValue(value: JsonValue, control: FormControl): string;
156
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAExD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,gBAAgB,CA+ClB;AA2SD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAO1E;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,CA4BzE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAuD1E"}
@@ -0,0 +1,289 @@
1
+ const typeHandlers = /* @__PURE__ */ new Map();
2
+ function registerTypeHandler(type, handler) {
3
+ typeHandlers.set(type, handler);
4
+ }
5
+ function getTypeHandler(type) {
6
+ return typeHandlers.get(type);
7
+ }
8
+ function clearTypeHandlers() {
9
+ typeHandlers.clear();
10
+ }
11
+ function validateField(value, control) {
12
+ if (control.required) {
13
+ if (value === void 0 || value === null || value === "") {
14
+ return {
15
+ valid: false,
16
+ error: `${control.label || control.key} is required`
17
+ };
18
+ }
19
+ }
20
+ if (value === void 0 || value === null || value === "") {
21
+ return { valid: true };
22
+ }
23
+ const handler = typeHandlers.get(control.type);
24
+ if (handler?.validate) {
25
+ const result = handler.validate(value, control);
26
+ if (!result.valid) {
27
+ return result;
28
+ }
29
+ }
30
+ switch (control.type) {
31
+ case "email":
32
+ return validateEmail(value, control);
33
+ case "number":
34
+ return validateNumber(value, control);
35
+ case "boolean":
36
+ return validateBoolean(value, control);
37
+ case "date":
38
+ return validateDate(value, control);
39
+ case "select":
40
+ return validateSelect(value, control);
41
+ case "file":
42
+ return validateFile(value, control);
43
+ default:
44
+ return validateText(value, control);
45
+ }
46
+ }
47
+ function validateText(value, control) {
48
+ const strValue = String(value);
49
+ if (control.pattern) {
50
+ const regex = new RegExp(control.pattern);
51
+ if (!regex.test(strValue)) {
52
+ return {
53
+ valid: false,
54
+ error: `${control.label || control.key} has invalid format`
55
+ };
56
+ }
57
+ }
58
+ if (control.minLength !== void 0 && strValue.length < control.minLength) {
59
+ return {
60
+ valid: false,
61
+ error: `${control.label || control.key} must be at least ${control.minLength} characters`
62
+ };
63
+ }
64
+ if (control.maxLength !== void 0 && strValue.length > control.maxLength) {
65
+ return {
66
+ valid: false,
67
+ error: `${control.label || control.key} must be at most ${control.maxLength} characters`
68
+ };
69
+ }
70
+ if (control.enum && control.enum.length > 0) {
71
+ if (!control.enum.includes(strValue)) {
72
+ return {
73
+ valid: false,
74
+ error: `${control.label || control.key} must be one of: ${control.enum.join(", ")}`
75
+ };
76
+ }
77
+ }
78
+ return { valid: true };
79
+ }
80
+ function validateEmail(value, control) {
81
+ const rawValue = String(value);
82
+ const strValue = rawValue.length > 320 ? rawValue.slice(0, 320) : rawValue;
83
+ const emailRegex = /^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/;
84
+ if (!emailRegex.test(strValue)) {
85
+ return {
86
+ valid: false,
87
+ error: `${control.label || control.key} must be a valid email address`
88
+ };
89
+ }
90
+ return validateText(value, control);
91
+ }
92
+ function validateNumber(value, control) {
93
+ const numValue = typeof value === "number" ? value : parseFloat(String(value).replace(/[,$]/g, ""));
94
+ if (Number.isNaN(numValue)) {
95
+ return {
96
+ valid: false,
97
+ error: `${control.label || control.key} must be a number`
98
+ };
99
+ }
100
+ if (control.min !== void 0 && numValue < control.min) {
101
+ return {
102
+ valid: false,
103
+ error: `${control.label || control.key} must be at least ${control.min}`
104
+ };
105
+ }
106
+ if (control.max !== void 0 && numValue > control.max) {
107
+ return {
108
+ valid: false,
109
+ error: `${control.label || control.key} must be at most ${control.max}`
110
+ };
111
+ }
112
+ return { valid: true };
113
+ }
114
+ function validateBoolean(value, _control) {
115
+ if (typeof value === "boolean") {
116
+ return { valid: true };
117
+ }
118
+ const strValue = String(value).toLowerCase();
119
+ const truthy = ["true", "yes", "1", "on"];
120
+ const falsy = ["false", "no", "0", "off"];
121
+ if (truthy.includes(strValue) || falsy.includes(strValue)) {
122
+ return { valid: true };
123
+ }
124
+ return { valid: false, error: "Must be true or false" };
125
+ }
126
+ function validateDate(value, control) {
127
+ let dateValue;
128
+ if (value instanceof Date) {
129
+ dateValue = value;
130
+ } else if (typeof value === "string" || typeof value === "number") {
131
+ dateValue = new Date(value);
132
+ } else {
133
+ return {
134
+ valid: false,
135
+ error: `${control.label || control.key} must be a valid date`
136
+ };
137
+ }
138
+ if (Number.isNaN(dateValue.getTime())) {
139
+ return {
140
+ valid: false,
141
+ error: `${control.label || control.key} must be a valid date`
142
+ };
143
+ }
144
+ if (control.min !== void 0 && dateValue.getTime() < control.min) {
145
+ return {
146
+ valid: false,
147
+ error: `${control.label || control.key} is too early`
148
+ };
149
+ }
150
+ if (control.max !== void 0 && dateValue.getTime() > control.max) {
151
+ return {
152
+ valid: false,
153
+ error: `${control.label || control.key} is too late`
154
+ };
155
+ }
156
+ return { valid: true };
157
+ }
158
+ function validateSelect(value, control) {
159
+ const options = control.options ?? [];
160
+ if (options.length === 0) {
161
+ return { valid: true };
162
+ }
163
+ const strValue = String(value);
164
+ const validValues = options.map((opt) => opt.value);
165
+ if (!validValues.includes(strValue)) {
166
+ return {
167
+ valid: false,
168
+ error: `${control.label || control.key} must be one of the available options`
169
+ };
170
+ }
171
+ return { valid: true };
172
+ }
173
+ function validateFile(value, control) {
174
+ if (!control.file) {
175
+ return { valid: true };
176
+ }
177
+ const files = Array.isArray(value) ? value : [value];
178
+ if (control.file.maxFiles && files.length > control.file.maxFiles) {
179
+ return {
180
+ valid: false,
181
+ error: `Maximum ${control.file.maxFiles} files allowed`
182
+ };
183
+ }
184
+ for (const file of files) {
185
+ if (!file || typeof file !== "object") continue;
186
+ const fileObj = file;
187
+ if (control.file.maxSize && fileObj.size && fileObj.size > control.file.maxSize) {
188
+ return {
189
+ valid: false,
190
+ error: `File size exceeds maximum of ${formatBytes(control.file.maxSize)}`
191
+ };
192
+ }
193
+ if (control.file.accept && fileObj.mimeType) {
194
+ const { mimeType } = fileObj;
195
+ const accepted = control.file.accept.some(
196
+ (pattern) => matchesMimeType(mimeType, pattern)
197
+ );
198
+ if (!accepted) {
199
+ return {
200
+ valid: false,
201
+ error: `File type ${mimeType} is not accepted`
202
+ };
203
+ }
204
+ }
205
+ }
206
+ return { valid: true };
207
+ }
208
+ function matchesMimeType(mimeType, pattern) {
209
+ if (pattern === "*/*") return true;
210
+ if (pattern.endsWith("/*")) {
211
+ const prefix = pattern.slice(0, -1);
212
+ return mimeType.startsWith(prefix);
213
+ }
214
+ return mimeType === pattern;
215
+ }
216
+ function formatBytes(bytes) {
217
+ if (bytes < 1024) return `${bytes} B`;
218
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
219
+ if (bytes < 1024 * 1024 * 1024)
220
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
221
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
222
+ }
223
+ function parseValue(value, control) {
224
+ const handler = typeHandlers.get(control.type);
225
+ if (handler?.parse) {
226
+ return handler.parse(value);
227
+ }
228
+ switch (control.type) {
229
+ case "number":
230
+ return parseFloat(value.replace(/[,$]/g, ""));
231
+ case "boolean": {
232
+ const lower = value.toLowerCase();
233
+ return ["true", "yes", "1", "on"].includes(lower);
234
+ }
235
+ case "date": {
236
+ const timestamp = Date.parse(value);
237
+ return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : value;
238
+ }
239
+ default:
240
+ return value;
241
+ }
242
+ }
243
+ function formatValue(value, control) {
244
+ if (value === void 0 || value === null) return "";
245
+ const handler = typeHandlers.get(control.type);
246
+ if (handler?.format) {
247
+ return handler.format(value);
248
+ }
249
+ if (control.sensitive) {
250
+ const strVal = String(value);
251
+ if (strVal.length > 8) {
252
+ return `${strVal.slice(0, 4)}...${strVal.slice(-4)}`;
253
+ }
254
+ return "****";
255
+ }
256
+ switch (control.type) {
257
+ case "number":
258
+ return typeof value === "number" ? value.toLocaleString() : String(value);
259
+ case "boolean":
260
+ return value ? "Yes" : "No";
261
+ case "date":
262
+ return value instanceof Date ? value.toLocaleDateString() : String(value);
263
+ case "select":
264
+ if (control.options) {
265
+ const option = control.options.find(
266
+ (opt) => opt.value === String(value)
267
+ );
268
+ if (option) return option.label;
269
+ }
270
+ return String(value);
271
+ case "file":
272
+ if (Array.isArray(value)) {
273
+ return value.map((f) => f.name || "file").join(", ");
274
+ }
275
+ return value.name || "file";
276
+ default:
277
+ return String(value);
278
+ }
279
+ }
280
+ export {
281
+ clearTypeHandlers,
282
+ formatValue,
283
+ getTypeHandler,
284
+ matchesMimeType,
285
+ parseValue,
286
+ registerTypeHandler,
287
+ validateField
288
+ };
289
+ //# sourceMappingURL=validation.js.map