426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
135 lines
6.1 KiB
Markdown
135 lines
6.1 KiB
Markdown
# @elizaos/plugin-form
|
||
|
||
Conversational forms for Eliza agents. Define structured data-collection workflows; the agent extracts values from natural conversation, tracks completion, and delivers a typed `FormSubmission` when all required fields are filled.
|
||
|
||
## What it does
|
||
|
||
- **Defines forms** — a `FormDefinition` describes the fields to collect (`FormControl[]`), lifecycle hooks, TTL settings, and UX rules (undo, skip, autofill).
|
||
- **Tracks sessions** — one `FormSession` per user per room. Sessions survive topic changes and can be stashed and resumed later.
|
||
- **Extracts field values via LLM** — the post-turn evaluator detects user intent and pulls values from conversational messages, handling uncertain extractions with a confirm step.
|
||
- **Supports composite and external control types** — composite types (e.g. address) have subfields that must all fill before the parent is complete; external types (e.g. payment) await asynchronous confirmation from another service before marking the field filled.
|
||
- **Effort-aware retention** — session TTL scales with how long the user has invested (default 14–90 days).
|
||
|
||
## Capabilities added to an Eliza agent
|
||
|
||
| Capability | How |
|
||
|---|---|
|
||
| FORM\_CONTEXT provider | Injects current form progress into every agent turn — filled/missing fields, uncertain extractions, pending external fields, and a single action directive |
|
||
| FORM action | `action=restore` rehydrates the most recent stashed form before the agent responds. **Not auto-registered** — import `formAction` from `@elizaos/plugin-form` and add it to your consuming plugin's `actions` array to activate it. |
|
||
| Form evaluator | Post-turn: detects submit / stash / cancel / undo / skip / autofill / fill\_form intents and updates session state |
|
||
| FormService | Singleton service: register forms and custom control types, start/manage sessions, submit, stash, restore |
|
||
|
||
## Installation
|
||
|
||
Add the plugin to your agent character config:
|
||
|
||
```json
|
||
{
|
||
"plugins": ["@elizaos/plugin-form"],
|
||
"features": {
|
||
"form": true
|
||
}
|
||
}
|
||
```
|
||
|
||
The plugin auto-enables when `config.features.form` is truthy (`true`, or an object whose `enabled` is not `false`). No environment variables are required.
|
||
|
||
## Built-in field types
|
||
|
||
`text`, `number`, `email`, `boolean`, `select`, `date`, `file`
|
||
|
||
Custom types are registered at runtime via `FormService.registerControlType()`.
|
||
|
||
## Registering a form (consuming plugin example)
|
||
|
||
```typescript
|
||
import type { FormDefinition } from '@elizaos/plugin-form';
|
||
|
||
const onboardingForm: FormDefinition = {
|
||
id: 'onboard',
|
||
name: 'Onboarding',
|
||
controls: [
|
||
{ key: 'name', label: 'Full Name', type: 'text', required: true },
|
||
{ key: 'email', label: 'Email', type: 'email', required: true },
|
||
{ key: 'role', label: 'Role', type: 'select', required: false,
|
||
options: [{ value: 'dev', label: 'Developer' }, { value: 'pm', label: 'Product' }] },
|
||
],
|
||
hooks: { onSubmit: 'handle_onboarding_submission' },
|
||
};
|
||
|
||
// In your plugin's start() or action handler:
|
||
const formService = runtime.getService('FORM');
|
||
formService.registerForm(onboardingForm);
|
||
await formService.startSession('onboard', entityId, roomId);
|
||
```
|
||
|
||
Register a task worker to handle the submission:
|
||
|
||
```typescript
|
||
runtime.registerTaskWorker({
|
||
name: 'handle_onboarding_submission',
|
||
execute: async (runtime, { submission }) => {
|
||
// submission.values, submission.mappedValues, submission.entityId, etc.
|
||
},
|
||
});
|
||
```
|
||
|
||
## Registering a custom control type
|
||
|
||
```typescript
|
||
// Simple type
|
||
formService.registerControlType({
|
||
id: 'phone',
|
||
validate: (v) => ({ valid: /^\+?[\d\s-]{10,}$/.test(String(v)) }),
|
||
extractionPrompt: 'a phone number with country code',
|
||
});
|
||
|
||
// External type (async confirmation required)
|
||
formService.registerControlType({
|
||
id: 'payment',
|
||
getSubControls: () => [
|
||
{ key: 'amount', type: 'number', label: 'Amount', required: true },
|
||
{ key: 'currency', type: 'select', label: 'Currency', required: true,
|
||
options: [{ value: 'SOL', label: 'SOL' }, { value: 'USDC', label: 'USDC' }] },
|
||
],
|
||
activate: async (ctx) => {
|
||
// Return instructions and a reference for matching the external event
|
||
return { instructions: 'Send funds to ...', reference: 'memo-xyz', address: '...' };
|
||
},
|
||
});
|
||
```
|
||
|
||
When all subfields are filled the evaluator automatically calls `activateExternalField()`. Your service calls `formService.confirmExternalField(sessionId, entityId, field, value, externalData)` when confirmation arrives.
|
||
|
||
## FormDefinition reference (key fields)
|
||
|
||
| Field | Type | Default | Description |
|
||
|---|---|---|---|
|
||
| `id` | string | required | Unique form identifier |
|
||
| `name` | string | required | Human-readable name |
|
||
| `controls` | FormControl[] | required | Fields to collect |
|
||
| `status` | `draft\|active\|deprecated` | `active` | Draft forms cannot be started |
|
||
| `allowMultiple` | boolean | `false` | Allow multiple submissions per user |
|
||
| `hooks.onStart/onSubmit/onCancel/onReady/onFieldChange/onExpire` | string | — | Task worker names |
|
||
| `ttl.minDays` / `ttl.maxDays` | number | 14 / 90 | Retention bounds |
|
||
| `ttl.effortMultiplier` | number | 0.5 | Extra days per minute of interaction |
|
||
| `ux.allowUndo` / `allowSkip` / `allowAutofill` | boolean | all `true` | UX feature flags |
|
||
| `nudge.afterInactiveHours` / `maxNudges` | number | 48 / 3 | Stale-session nudge config |
|
||
|
||
## FormControl reference (key fields)
|
||
|
||
| Field | Type | Description |
|
||
|---|---|---|
|
||
| `key` | string | Unique within form; used in `values` map |
|
||
| `label` | string | Human-readable name |
|
||
| `type` | string | `text`, `number`, `email`, `boolean`, `select`, `date`, `file`, or custom |
|
||
| `required` | boolean | Form cannot submit without this field |
|
||
| `sensitive` | boolean | Value masked in agent context |
|
||
| `hidden` | boolean | Extract silently, never ask directly |
|
||
| `askPrompt` | string | Custom agent prompt for this field |
|
||
| `extractHints` | string[] | Keywords to improve LLM extraction accuracy |
|
||
| `confirmThreshold` | number | Confidence below this triggers confirmation (default 0.8) |
|
||
| `dependsOn` | FormControlDependency | Conditional display based on another field's value |
|
||
| `dbbind` | string | Column name for `mappedValues` in submission |
|
||
| `options` | FormControlOption[] | For `select` type |
|