@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.
- package/auto-enable.ts +24 -0
- package/dist/actions/restore.d.ts +25 -0
- package/dist/actions/restore.d.ts.map +1 -0
- package/dist/actions/restore.js +176 -0
- package/dist/actions/restore.js.map +1 -0
- package/dist/builder.d.ts +320 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +458 -0
- package/dist/builder.js.map +1 -0
- package/dist/builtins.d.ts +128 -0
- package/dist/builtins.d.ts.map +1 -0
- package/dist/builtins.js +233 -0
- package/dist/builtins.js.map +1 -0
- package/dist/defaults.d.ts +95 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +79 -0
- package/dist/defaults.js.map +1 -0
- package/dist/evaluators/extractor.d.ts +28 -0
- package/dist/evaluators/extractor.d.ts.map +1 -0
- package/dist/evaluators/extractor.js +247 -0
- package/dist/evaluators/extractor.js.map +1 -0
- package/dist/extraction.d.ts +55 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/extraction.js +331 -0
- package/dist/extraction.js.map +1 -0
- package/dist/index.d.ts +31 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -3284
- package/dist/index.js.map +1 -30
- package/dist/providers/context.d.ts +56 -0
- package/dist/providers/context.d.ts.map +1 -0
- package/dist/providers/context.js +206 -0
- package/dist/providers/context.js.map +1 -0
- package/dist/service.d.ts +402 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +1158 -0
- package/dist/service.js.map +1 -0
- package/dist/storage.d.ts +228 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +218 -0
- package/dist/storage.js.map +1 -0
- package/dist/template.d.ts +10 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +60 -0
- package/dist/template.js.map +1 -0
- package/dist/ttl.d.ts +144 -0
- package/dist/ttl.d.ts.map +1 -0
- package/dist/ttl.js +85 -0
- package/dist/ttl.js.map +1 -0
- package/dist/types.d.ts +1213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +39 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +156 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +289 -0
- package/dist/validation.js.map +1 -0
- package/package.json +39 -42
package/auto-enable.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Auto-enable check for @elizaos/plugin-form.
|
|
2
|
+
//
|
|
3
|
+
// Plugin manifest entry-point — referenced by package.json's
|
|
4
|
+
// `elizaos.plugin.autoEnableModule`. Keep this module light: env reads only,
|
|
5
|
+
// no service init, no transitive imports of the full plugin runtime. The
|
|
6
|
+
// auto-enable engine loads dozens of these per boot.
|
|
7
|
+
import type { PluginAutoEnableContext } from "@elizaos/core";
|
|
8
|
+
|
|
9
|
+
function isFeatureEnabled(
|
|
10
|
+
config: PluginAutoEnableContext["config"],
|
|
11
|
+
key: string,
|
|
12
|
+
): boolean {
|
|
13
|
+
const f = (config?.features as Record<string, unknown> | undefined)?.[key];
|
|
14
|
+
if (f === true) return true;
|
|
15
|
+
if (f && typeof f === "object" && f !== null) {
|
|
16
|
+
return (f as Record<string, unknown>).enabled !== false;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Enable when `config.features.form` is truthy / not explicitly disabled. */
|
|
22
|
+
export function shouldEnable(ctx: PluginAutoEnableContext): boolean {
|
|
23
|
+
return isFeatureEnabled(ctx.config, "form");
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module actions/restore
|
|
3
|
+
* @description Planner action for restoring stashed form sessions.
|
|
4
|
+
*
|
|
5
|
+
* Restore is a planner-driven Action (not part of the post-message form
|
|
6
|
+
* evaluator) because the restored form context must reach the provider
|
|
7
|
+
* BEFORE the agent generates its response. If the user has an active form
|
|
8
|
+
* in the current room, the action asks them to continue or stash the
|
|
9
|
+
* current one. Multiple stashed forms restore the most recent.
|
|
10
|
+
*/
|
|
11
|
+
import { type Action } from "@elizaos/core";
|
|
12
|
+
/**
|
|
13
|
+
* Form Restore Action
|
|
14
|
+
*
|
|
15
|
+
* Fast-path action for restoring stashed forms.
|
|
16
|
+
* Preempts REPLY to provide immediate restoration with summary.
|
|
17
|
+
*
|
|
18
|
+
* WHY action:
|
|
19
|
+
* - Needs to run BEFORE provider
|
|
20
|
+
* - Must generate immediate response
|
|
21
|
+
* - Context needed for next message
|
|
22
|
+
*/
|
|
23
|
+
export declare const formRestoreAction: Action;
|
|
24
|
+
export default formRestoreAction;
|
|
25
|
+
//# sourceMappingURL=restore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/actions/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,MAAM,EASZ,MAAM,eAAe,CAAC;AAYvB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,MA4L/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "@elizaos/core";
|
|
4
|
+
const RESTORE_FIELD_LIMIT = 12;
|
|
5
|
+
const RESTORE_RESPONSE_MAX_CHARS = 4e3;
|
|
6
|
+
function truncateRestoreResponse(text) {
|
|
7
|
+
return text.length <= RESTORE_RESPONSE_MAX_CHARS ? text : `${text.slice(0, RESTORE_RESPONSE_MAX_CHARS)}
|
|
8
|
+
|
|
9
|
+
[truncated restored form summary]`;
|
|
10
|
+
}
|
|
11
|
+
const formRestoreAction = {
|
|
12
|
+
name: "FORM_RESTORE",
|
|
13
|
+
contexts: ["tasks", "automation", "memory"],
|
|
14
|
+
contextGate: { anyOf: ["tasks", "automation", "memory"] },
|
|
15
|
+
roleGate: { minRole: "USER" },
|
|
16
|
+
similes: ["RESUME_FORM", "CONTINUE_FORM"],
|
|
17
|
+
description: "Restore a previously stashed form session",
|
|
18
|
+
descriptionCompressed: "Restore stashed form session.",
|
|
19
|
+
parameters: [
|
|
20
|
+
{
|
|
21
|
+
name: "sessionId",
|
|
22
|
+
description: "Optional stashed form session id to restore.",
|
|
23
|
+
required: false,
|
|
24
|
+
schema: { type: "string" }
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
/**
|
|
28
|
+
* Validate: action is selectable whenever the user has stashed sessions
|
|
29
|
+
* and no active form in the current room. The planner picks it via the
|
|
30
|
+
* action description/similes when the user actually wants to resume.
|
|
31
|
+
*/
|
|
32
|
+
validate: async (runtime, message, _state) => {
|
|
33
|
+
const formService = runtime.getService("FORM");
|
|
34
|
+
if (!formService) return false;
|
|
35
|
+
const entityId = message.entityId;
|
|
36
|
+
const roomId = message.roomId;
|
|
37
|
+
if (!entityId || !roomId) return false;
|
|
38
|
+
const stashed = await formService.getStashedSessions(entityId);
|
|
39
|
+
if (stashed.length === 0) return false;
|
|
40
|
+
const active = await formService.getActiveSession(entityId, roomId);
|
|
41
|
+
return active === null;
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Handler: Restore the most recent stashed session.
|
|
45
|
+
*
|
|
46
|
+
* 1. Check for conflicts (active session in room)
|
|
47
|
+
* 2. Restore the session
|
|
48
|
+
* 3. Generate summary response
|
|
49
|
+
*
|
|
50
|
+
* @returns ActionResult with success status and session data
|
|
51
|
+
*/
|
|
52
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
53
|
+
try {
|
|
54
|
+
const formService = runtime.getService("FORM");
|
|
55
|
+
if (!formService) {
|
|
56
|
+
await callback?.({
|
|
57
|
+
text: "Sorry, I couldn't find the form service."
|
|
58
|
+
});
|
|
59
|
+
return { success: false };
|
|
60
|
+
}
|
|
61
|
+
const entityId = message.entityId;
|
|
62
|
+
const roomId = message.roomId;
|
|
63
|
+
if (!entityId || !roomId) {
|
|
64
|
+
await callback?.({
|
|
65
|
+
text: "Sorry, I couldn't identify you."
|
|
66
|
+
});
|
|
67
|
+
return { success: false };
|
|
68
|
+
}
|
|
69
|
+
const existing = await formService.getActiveSession(entityId, roomId);
|
|
70
|
+
if (existing) {
|
|
71
|
+
const form2 = formService.getForm(existing.formId);
|
|
72
|
+
await callback?.({
|
|
73
|
+
text: `You already have an active form: "${form2?.name || existing.formId}". Would you like to continue with that one, or should I save it and restore your other form?`
|
|
74
|
+
});
|
|
75
|
+
return { success: false };
|
|
76
|
+
}
|
|
77
|
+
const stashed = await formService.getStashedSessions(entityId);
|
|
78
|
+
if (stashed.length === 0) {
|
|
79
|
+
await callback?.({
|
|
80
|
+
text: "You don't have any saved forms to resume."
|
|
81
|
+
});
|
|
82
|
+
return { success: false };
|
|
83
|
+
}
|
|
84
|
+
const sessionToRestore = stashed.sort(
|
|
85
|
+
(a, b) => b.updatedAt - a.updatedAt
|
|
86
|
+
)[0];
|
|
87
|
+
const session = await formService.restore(sessionToRestore.id, entityId);
|
|
88
|
+
const form = formService.getForm(session.formId);
|
|
89
|
+
const context = formService.getSessionContext(session);
|
|
90
|
+
let responseText = `I've restored your "${form?.name || session.formId}" form. `;
|
|
91
|
+
responseText += `You're ${context.progress}% complete. `;
|
|
92
|
+
if (context.filledFields.length > 0) {
|
|
93
|
+
responseText += `
|
|
94
|
+
|
|
95
|
+
Here's what I have so far:
|
|
96
|
+
`;
|
|
97
|
+
for (const field of context.filledFields.slice(0, RESTORE_FIELD_LIMIT)) {
|
|
98
|
+
responseText += `\u2022 ${field.label}: ${field.displayValue}
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (context.nextField) {
|
|
103
|
+
responseText += `
|
|
104
|
+
Let's continue with ${context.nextField.label}.`;
|
|
105
|
+
if (context.nextField.askPrompt) {
|
|
106
|
+
responseText += ` ${context.nextField.askPrompt}`;
|
|
107
|
+
}
|
|
108
|
+
} else if (context.status === "ready") {
|
|
109
|
+
responseText += `
|
|
110
|
+
Everything looks complete! Ready to submit?`;
|
|
111
|
+
}
|
|
112
|
+
await callback?.({
|
|
113
|
+
text: truncateRestoreResponse(responseText)
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
success: true,
|
|
117
|
+
data: {
|
|
118
|
+
sessionId: session.id,
|
|
119
|
+
formId: session.formId,
|
|
120
|
+
progress: context.progress
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
} catch (error) {
|
|
124
|
+
logger.error("[FormRestoreAction] Handler error:", String(error));
|
|
125
|
+
await callback?.({
|
|
126
|
+
text: "Sorry, I couldn't restore your form. Please try again."
|
|
127
|
+
});
|
|
128
|
+
return { success: false };
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
// Example conversations for training/documentation
|
|
132
|
+
examples: [
|
|
133
|
+
[
|
|
134
|
+
{
|
|
135
|
+
name: "{{user1}}",
|
|
136
|
+
content: { text: "Resume my form" }
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "{{agentName}}",
|
|
140
|
+
content: {
|
|
141
|
+
text: "I've restored your form. Let's continue where you left off."
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
[
|
|
146
|
+
{
|
|
147
|
+
name: "{{user1}}",
|
|
148
|
+
content: { text: "Continue with my registration" }
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: "{{agentName}}",
|
|
152
|
+
content: {
|
|
153
|
+
text: "I've restored your Registration form. You're 60% complete."
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
[
|
|
158
|
+
{
|
|
159
|
+
name: "{{user1}}",
|
|
160
|
+
content: { text: "Pick up where I left off" }
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "{{agentName}}",
|
|
164
|
+
content: {
|
|
165
|
+
text: "I've restored your form. Here's what you have so far..."
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
var restore_default = formRestoreAction;
|
|
172
|
+
export {
|
|
173
|
+
restore_default as default,
|
|
174
|
+
formRestoreAction
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=restore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/actions/restore.ts"],"sourcesContent":["/**\n * @module actions/restore\n * @description Planner action for restoring stashed form sessions.\n *\n * Restore is a planner-driven Action (not part of the post-message form\n * evaluator) because the restored form context must reach the provider\n * BEFORE the agent generates its response. If the user has an active form\n * in the current room, the action asks them to continue or stash the\n * current one. Multiple stashed forms restore the most recent.\n */\n\nimport {\n type Action,\n type ActionResult,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n logger,\n type Memory,\n type State,\n type UUID,\n} from \"@elizaos/core\";\nimport type { FormService } from \"../service\";\n\nconst RESTORE_FIELD_LIMIT = 12;\nconst RESTORE_RESPONSE_MAX_CHARS = 4_000;\n\nfunction truncateRestoreResponse(text: string): string {\n return text.length <= RESTORE_RESPONSE_MAX_CHARS\n ? text\n : `${text.slice(0, RESTORE_RESPONSE_MAX_CHARS)}\\n\\n[truncated restored form summary]`;\n}\n\n/**\n * Form Restore Action\n *\n * Fast-path action for restoring stashed forms.\n * Preempts REPLY to provide immediate restoration with summary.\n *\n * WHY action:\n * - Needs to run BEFORE provider\n * - Must generate immediate response\n * - Context needed for next message\n */\nexport const formRestoreAction: Action = {\n name: \"FORM_RESTORE\",\n contexts: [\"tasks\", \"automation\", \"memory\"],\n contextGate: { anyOf: [\"tasks\", \"automation\", \"memory\"] },\n roleGate: { minRole: \"USER\" },\n similes: [\"RESUME_FORM\", \"CONTINUE_FORM\"],\n description: \"Restore a previously stashed form session\",\n descriptionCompressed: \"Restore stashed form session.\",\n parameters: [\n {\n name: \"sessionId\",\n description: \"Optional stashed form session id to restore.\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n\n /**\n * Validate: action is selectable whenever the user has stashed sessions\n * and no active form in the current room. The planner picks it via the\n * action description/similes when the user actually wants to resume.\n */\n validate: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n const formService = runtime.getService(\"FORM\") as FormService;\n if (!formService) return false;\n\n const entityId = message.entityId as UUID;\n const roomId = message.roomId as UUID;\n if (!entityId || !roomId) return false;\n\n const stashed = await formService.getStashedSessions(entityId);\n if (stashed.length === 0) return false;\n\n const active = await formService.getActiveSession(entityId, roomId);\n return active === null;\n },\n\n /**\n * Handler: Restore the most recent stashed session.\n *\n * 1. Check for conflicts (active session in room)\n * 2. Restore the session\n * 3. Generate summary response\n *\n * @returns ActionResult with success status and session data\n */\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const formService = runtime.getService(\"FORM\") as FormService;\n if (!formService) {\n await callback?.({\n text: \"Sorry, I couldn't find the form service.\",\n });\n return { success: false };\n }\n\n const entityId = message.entityId as UUID;\n const roomId = message.roomId as UUID;\n\n if (!entityId || !roomId) {\n await callback?.({\n text: \"Sorry, I couldn't identify you.\",\n });\n return { success: false };\n }\n\n // Check for existing active session in this room\n // WHY check: Can't have two active sessions in same room\n const existing = await formService.getActiveSession(entityId, roomId);\n if (existing) {\n const form = formService.getForm(existing.formId);\n await callback?.({\n text: `You already have an active form: \"${form?.name || existing.formId}\". Would you like to continue with that one, or should I save it and restore your other form?`,\n });\n return { success: false };\n }\n\n // Get stashed sessions\n const stashed = await formService.getStashedSessions(entityId);\n\n if (stashed.length === 0) {\n await callback?.({\n text: \"You don't have any saved forms to resume.\",\n });\n return { success: false };\n }\n\n // Restore the most recent stashed session — the user likely wants what\n // they just stashed.\n const sessionToRestore = stashed.sort(\n (a, b) => b.updatedAt - a.updatedAt,\n )[0];\n const session = await formService.restore(sessionToRestore.id, entityId);\n\n const form = formService.getForm(session.formId);\n const context = formService.getSessionContext(session);\n\n // Generate response with restored context\n // WHY immediate response: User knows what happened\n let responseText = `I've restored your \"${form?.name || session.formId}\" form. `;\n responseText += `You're ${context.progress}% complete. `;\n\n if (context.filledFields.length > 0) {\n responseText += `\\n\\nHere's what I have so far:\\n`;\n for (const field of context.filledFields.slice(0, RESTORE_FIELD_LIMIT)) {\n responseText += `• ${field.label}: ${field.displayValue}\\n`;\n }\n }\n\n if (context.nextField) {\n responseText += `\\nLet's continue with ${context.nextField.label}.`;\n if (context.nextField.askPrompt) {\n responseText += ` ${context.nextField.askPrompt}`;\n }\n } else if (context.status === \"ready\") {\n responseText += `\\nEverything looks complete! Ready to submit?`;\n }\n\n await callback?.({\n text: truncateRestoreResponse(responseText),\n });\n\n return {\n success: true,\n data: {\n sessionId: session.id,\n formId: session.formId,\n progress: context.progress,\n },\n };\n } catch (error) {\n logger.error(\"[FormRestoreAction] Handler error:\", String(error));\n await callback?.({\n text: \"Sorry, I couldn't restore your form. Please try again.\",\n });\n return { success: false };\n }\n },\n\n // Example conversations for training/documentation\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Resume my form\" },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I've restored your form. Let's continue where you left off.\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Continue with my registration\" },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I've restored your Registration form. You're 60% complete.\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Pick up where I left off\" },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I've restored your form. Here's what you have so far...\",\n },\n },\n ],\n ],\n};\n\nexport default formRestoreAction;\n"],"mappings":"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","names":["form"]}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module builder
|
|
3
|
+
* @description Fluent builder API for defining forms and controls
|
|
4
|
+
*
|
|
5
|
+
* ## Why a Builder API
|
|
6
|
+
*
|
|
7
|
+
* Form definitions can be verbose with many optional fields. The builder
|
|
8
|
+
* API provides:
|
|
9
|
+
*
|
|
10
|
+
* 1. **Type Safety**: Method chaining with TypeScript gives autocomplete
|
|
11
|
+
* 2. **Readability**: Intent is clear from method names
|
|
12
|
+
* 3. **Defaults**: Builder applies sensible defaults
|
|
13
|
+
* 4. **Validation**: Build-time checks for common mistakes
|
|
14
|
+
*
|
|
15
|
+
* ## Usage Examples
|
|
16
|
+
*
|
|
17
|
+
* ### Simple Form
|
|
18
|
+
*
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const form = Form.create('contact')
|
|
21
|
+
* .name('Contact Form')
|
|
22
|
+
* .control(C.email('email').required())
|
|
23
|
+
* .control(C.text('message').required())
|
|
24
|
+
* .build();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ### Complex Form
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const registrationForm = Form.create('registration')
|
|
31
|
+
* .name('User Registration')
|
|
32
|
+
* .description('Create your account')
|
|
33
|
+
* .control(
|
|
34
|
+
* C.email('email')
|
|
35
|
+
* .required()
|
|
36
|
+
* .ask('What email should we use for your account?')
|
|
37
|
+
* .example('user@example.com')
|
|
38
|
+
* )
|
|
39
|
+
* .control(
|
|
40
|
+
* C.text('username')
|
|
41
|
+
* .required()
|
|
42
|
+
* .minLength(3)
|
|
43
|
+
* .maxLength(20)
|
|
44
|
+
* .pattern('^[a-z0-9_]+$')
|
|
45
|
+
* .ask('Choose a username (letters, numbers, underscore)')
|
|
46
|
+
* )
|
|
47
|
+
* .control(
|
|
48
|
+
* C.number('age')
|
|
49
|
+
* .min(13)
|
|
50
|
+
* .ask('How old are you?')
|
|
51
|
+
* )
|
|
52
|
+
* .onSubmit('handle_registration')
|
|
53
|
+
* .ttl({ minDays: 7, maxDays: 30 })
|
|
54
|
+
* .build();
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ### Custom Type
|
|
58
|
+
*
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // Register custom type first
|
|
61
|
+
* FormService.registerType('solana_address', {
|
|
62
|
+
* validate: (v) => ({
|
|
63
|
+
* valid: /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(String(v)),
|
|
64
|
+
* error: 'Invalid Solana address'
|
|
65
|
+
* }),
|
|
66
|
+
* extractionPrompt: 'a Solana wallet address (Base58 encoded)'
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* // Use in form
|
|
70
|
+
* const form = Form.create('wallet')
|
|
71
|
+
* .control(
|
|
72
|
+
* C.field('walletAddress')
|
|
73
|
+
* .type('solana_address')
|
|
74
|
+
* .required()
|
|
75
|
+
* .label('Wallet Address')
|
|
76
|
+
* .ask('What is your Solana wallet address?')
|
|
77
|
+
* )
|
|
78
|
+
* .build();
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* ## Shorthand Exports
|
|
82
|
+
*
|
|
83
|
+
* For convenience:
|
|
84
|
+
* - `Form` is an alias for `FormBuilder`
|
|
85
|
+
* - `C` is an alias for `ControlBuilder`
|
|
86
|
+
*
|
|
87
|
+
* This enables the concise syntax shown in examples.
|
|
88
|
+
*/
|
|
89
|
+
import type { JsonValue } from "@elizaos/core";
|
|
90
|
+
import type { FormControl, FormControlDependency, FormControlOption, FormDefinition, FormDefinitionHooks } from "./types";
|
|
91
|
+
/**
|
|
92
|
+
* Fluent builder for FormControl.
|
|
93
|
+
*
|
|
94
|
+
* Create controls with readable, chainable syntax:
|
|
95
|
+
*
|
|
96
|
+
* ```typescript
|
|
97
|
+
* ControlBuilder.email('email').required().ask('What is your email?')
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* All methods return `this` for chaining except `build()` which returns
|
|
101
|
+
* the final FormControl.
|
|
102
|
+
*/
|
|
103
|
+
export declare class ControlBuilder {
|
|
104
|
+
/** Partial control being built */
|
|
105
|
+
private control;
|
|
106
|
+
/**
|
|
107
|
+
* Create a new ControlBuilder.
|
|
108
|
+
*
|
|
109
|
+
* @param key - The unique key for this control
|
|
110
|
+
*/
|
|
111
|
+
constructor(key: string);
|
|
112
|
+
/** Create a generic field builder */
|
|
113
|
+
static field(key: string): ControlBuilder;
|
|
114
|
+
/** Create a text field */
|
|
115
|
+
static text(key: string): ControlBuilder;
|
|
116
|
+
/** Create an email field */
|
|
117
|
+
static email(key: string): ControlBuilder;
|
|
118
|
+
/** Create a number field */
|
|
119
|
+
static number(key: string): ControlBuilder;
|
|
120
|
+
/** Create a boolean (yes/no) field */
|
|
121
|
+
static boolean(key: string): ControlBuilder;
|
|
122
|
+
/** Create a select field with options */
|
|
123
|
+
static select(key: string, options: FormControlOption[]): ControlBuilder;
|
|
124
|
+
/** Create a date field */
|
|
125
|
+
static date(key: string): ControlBuilder;
|
|
126
|
+
/** Create a file upload field */
|
|
127
|
+
static file(key: string): ControlBuilder;
|
|
128
|
+
/** Set the field type */
|
|
129
|
+
type(type: string): this;
|
|
130
|
+
/** Mark field as required */
|
|
131
|
+
required(): this;
|
|
132
|
+
/** Mark field as optional (default) */
|
|
133
|
+
optional(): this;
|
|
134
|
+
/** Mark field as hidden (extract silently, never ask) */
|
|
135
|
+
hidden(): this;
|
|
136
|
+
/** Mark field as sensitive (don't echo value back) */
|
|
137
|
+
sensitive(): this;
|
|
138
|
+
/** Mark field as readonly (can't change after set) */
|
|
139
|
+
readonly(): this;
|
|
140
|
+
/** Mark field as accepting multiple values */
|
|
141
|
+
multiple(): this;
|
|
142
|
+
/** Set regex pattern for validation */
|
|
143
|
+
pattern(regex: string): this;
|
|
144
|
+
/** Set minimum value (for numbers) or minimum length (via minLength) */
|
|
145
|
+
min(n: number): this;
|
|
146
|
+
/** Set maximum value (for numbers) or maximum length (via maxLength) */
|
|
147
|
+
max(n: number): this;
|
|
148
|
+
/** Set minimum string length */
|
|
149
|
+
minLength(n: number): this;
|
|
150
|
+
/** Set maximum string length */
|
|
151
|
+
maxLength(n: number): this;
|
|
152
|
+
/** Set allowed values (enum) */
|
|
153
|
+
enum(values: string[]): this;
|
|
154
|
+
/** Set select options */
|
|
155
|
+
options(opts: FormControlOption[]): this;
|
|
156
|
+
/** Set human-readable label */
|
|
157
|
+
label(label: string): this;
|
|
158
|
+
/** Set custom prompt for asking this field */
|
|
159
|
+
ask(prompt: string): this;
|
|
160
|
+
/** Set description for LLM context */
|
|
161
|
+
description(desc: string): this;
|
|
162
|
+
/** Add extraction hints (keywords to look for) */
|
|
163
|
+
hint(...hints: string[]): this;
|
|
164
|
+
/** Set example value for "give me an example" */
|
|
165
|
+
example(value: string): this;
|
|
166
|
+
/** Set confidence threshold for auto-acceptance */
|
|
167
|
+
confirmThreshold(n: number): this;
|
|
168
|
+
/** Set accepted MIME types for file upload */
|
|
169
|
+
accept(mimeTypes: string[]): this;
|
|
170
|
+
/** Set maximum file size in bytes */
|
|
171
|
+
maxSize(bytes: number): this;
|
|
172
|
+
/** Set maximum number of files */
|
|
173
|
+
maxFiles(n: number): this;
|
|
174
|
+
/** Set roles that can see/fill this field */
|
|
175
|
+
roles(...roles: string[]): this;
|
|
176
|
+
/** Set default value */
|
|
177
|
+
default(value: JsonValue): this;
|
|
178
|
+
/** Set dependency on another field */
|
|
179
|
+
dependsOn(field: string, condition?: FormControlDependency["condition"], value?: JsonValue): this;
|
|
180
|
+
/** Set database column name (defaults to key) */
|
|
181
|
+
dbbind(columnName: string): this;
|
|
182
|
+
/** Set section name for grouping */
|
|
183
|
+
section(name: string): this;
|
|
184
|
+
/** Set display order within section */
|
|
185
|
+
order(n: number): this;
|
|
186
|
+
/** Set placeholder text */
|
|
187
|
+
placeholder(text: string): this;
|
|
188
|
+
/** Set help text */
|
|
189
|
+
helpText(text: string): this;
|
|
190
|
+
/** Set custom widget type */
|
|
191
|
+
widget(type: string): this;
|
|
192
|
+
/** Add localized text for a locale */
|
|
193
|
+
i18n(locale: string, translations: {
|
|
194
|
+
label?: string;
|
|
195
|
+
description?: string;
|
|
196
|
+
askPrompt?: string;
|
|
197
|
+
helpText?: string;
|
|
198
|
+
}): this;
|
|
199
|
+
/** Add custom metadata */
|
|
200
|
+
meta(key: string, value: JsonValue): this;
|
|
201
|
+
/**
|
|
202
|
+
* Build the final FormControl.
|
|
203
|
+
*
|
|
204
|
+
* Applies defaults and validates the control.
|
|
205
|
+
*
|
|
206
|
+
* @returns Complete FormControl object
|
|
207
|
+
*/
|
|
208
|
+
build(): FormControl;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Fluent builder for FormDefinition.
|
|
212
|
+
*
|
|
213
|
+
* Create forms with readable, chainable syntax:
|
|
214
|
+
*
|
|
215
|
+
* ```typescript
|
|
216
|
+
* Form.create('contact')
|
|
217
|
+
* .name('Contact Form')
|
|
218
|
+
* .control(C.email('email').required())
|
|
219
|
+
* .onSubmit('handle_contact')
|
|
220
|
+
* .build();
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export declare class FormBuilder {
|
|
224
|
+
/** Partial form being built */
|
|
225
|
+
private form;
|
|
226
|
+
/**
|
|
227
|
+
* Create a new FormBuilder.
|
|
228
|
+
*
|
|
229
|
+
* @param id - Unique form identifier
|
|
230
|
+
*/
|
|
231
|
+
constructor(id: string);
|
|
232
|
+
/** Create a new form builder */
|
|
233
|
+
static create(id: string): FormBuilder;
|
|
234
|
+
/** Set form name */
|
|
235
|
+
name(name: string): this;
|
|
236
|
+
/** Set form description */
|
|
237
|
+
description(desc: string): this;
|
|
238
|
+
/** Set form version */
|
|
239
|
+
version(v: number): this;
|
|
240
|
+
/**
|
|
241
|
+
* Add a control to the form.
|
|
242
|
+
*
|
|
243
|
+
* Accepts either a ControlBuilder (calls .build()) or a FormControl.
|
|
244
|
+
*/
|
|
245
|
+
control(builder: ControlBuilder | FormControl): this;
|
|
246
|
+
/** Add multiple controls */
|
|
247
|
+
controls(...builders: (ControlBuilder | FormControl)[]): this;
|
|
248
|
+
/** Add required text fields */
|
|
249
|
+
required(...keys: string[]): this;
|
|
250
|
+
/** Add optional text fields */
|
|
251
|
+
optional(...keys: string[]): this;
|
|
252
|
+
/** Set roles that can start this form */
|
|
253
|
+
roles(...roles: string[]): this;
|
|
254
|
+
/** Allow multiple submissions per user */
|
|
255
|
+
allowMultiple(): this;
|
|
256
|
+
/** Disable undo functionality */
|
|
257
|
+
noUndo(): this;
|
|
258
|
+
/** Disable skip functionality */
|
|
259
|
+
noSkip(): this;
|
|
260
|
+
/** Disable autofill */
|
|
261
|
+
noAutofill(): this;
|
|
262
|
+
/** Set maximum undo steps */
|
|
263
|
+
maxUndoSteps(n: number): this;
|
|
264
|
+
/** Configure TTL (time-to-live) settings */
|
|
265
|
+
ttl(config: {
|
|
266
|
+
minDays?: number;
|
|
267
|
+
maxDays?: number;
|
|
268
|
+
effortMultiplier?: number;
|
|
269
|
+
}): this;
|
|
270
|
+
/** Disable nudge messages */
|
|
271
|
+
noNudge(): this;
|
|
272
|
+
/** Set inactivity hours before nudge */
|
|
273
|
+
nudgeAfter(hours: number): this;
|
|
274
|
+
/** Set custom nudge message */
|
|
275
|
+
nudgeMessage(message: string): this;
|
|
276
|
+
/** Set task worker to call on session start */
|
|
277
|
+
onStart(workerName: string): this;
|
|
278
|
+
/** Set task worker to call on field change */
|
|
279
|
+
onFieldChange(workerName: string): this;
|
|
280
|
+
/** Set task worker to call when form is ready to submit */
|
|
281
|
+
onReady(workerName: string): this;
|
|
282
|
+
/** Set task worker to call on submission */
|
|
283
|
+
onSubmit(workerName: string): this;
|
|
284
|
+
/** Set task worker to call on cancellation */
|
|
285
|
+
onCancel(workerName: string): this;
|
|
286
|
+
/** Set task worker to call on expiration */
|
|
287
|
+
onExpire(workerName: string): this;
|
|
288
|
+
/** Set multiple hooks at once */
|
|
289
|
+
hooks(hooks: FormDefinitionHooks): this;
|
|
290
|
+
/** Enable debug mode (logs extraction reasoning) */
|
|
291
|
+
debug(): this;
|
|
292
|
+
/** Add localized form text */
|
|
293
|
+
i18n(locale: string, translations: {
|
|
294
|
+
name?: string;
|
|
295
|
+
description?: string;
|
|
296
|
+
}): this;
|
|
297
|
+
/** Add custom metadata */
|
|
298
|
+
meta(key: string, value: JsonValue): this;
|
|
299
|
+
/**
|
|
300
|
+
* Build the final FormDefinition.
|
|
301
|
+
*
|
|
302
|
+
* Applies defaults and validates the form.
|
|
303
|
+
*
|
|
304
|
+
* @returns Complete FormDefinition object
|
|
305
|
+
*/
|
|
306
|
+
build(): FormDefinition;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Shorthand for FormBuilder.create
|
|
310
|
+
*
|
|
311
|
+
* Usage: `Form.create('myForm')...`
|
|
312
|
+
*/
|
|
313
|
+
export declare const Form: typeof FormBuilder;
|
|
314
|
+
/**
|
|
315
|
+
* Shorthand for ControlBuilder factories
|
|
316
|
+
*
|
|
317
|
+
* Usage: `C.email('email').required()`
|
|
318
|
+
*/
|
|
319
|
+
export declare const C: typeof ControlBuilder;
|
|
320
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|