@elizaos/plugin-form 2.0.0-beta.1 → 2.0.3-beta.3
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/LICENSE +21 -0
- package/README.md +134 -0
- package/package.json +22 -4
- package/registry-entry.json +26 -0
- package/dist/actions/restore.d.ts +0 -25
- package/dist/actions/restore.d.ts.map +0 -1
- package/dist/actions/restore.js +0 -176
- package/dist/actions/restore.js.map +0 -1
- package/dist/builder.d.ts +0 -320
- package/dist/builder.d.ts.map +0 -1
- package/dist/builder.js +0 -458
- package/dist/builder.js.map +0 -1
- package/dist/builtins.d.ts +0 -128
- package/dist/builtins.d.ts.map +0 -1
- package/dist/builtins.js +0 -233
- package/dist/builtins.js.map +0 -1
- package/dist/defaults.d.ts +0 -95
- package/dist/defaults.d.ts.map +0 -1
- package/dist/defaults.js +0 -79
- package/dist/defaults.js.map +0 -1
- package/dist/evaluators/extractor.d.ts +0 -28
- package/dist/evaluators/extractor.d.ts.map +0 -1
- package/dist/evaluators/extractor.js +0 -247
- package/dist/evaluators/extractor.js.map +0 -1
- package/dist/extraction.d.ts +0 -55
- package/dist/extraction.d.ts.map +0 -1
- package/dist/extraction.js +0 -331
- package/dist/extraction.js.map +0 -1
- package/dist/index.d.ts +0 -31
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -144
- package/dist/index.js.map +0 -1
- package/dist/providers/context.d.ts +0 -56
- package/dist/providers/context.d.ts.map +0 -1
- package/dist/providers/context.js +0 -206
- package/dist/providers/context.js.map +0 -1
- package/dist/service.d.ts +0 -402
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -1158
- package/dist/service.js.map +0 -1
- package/dist/storage.d.ts +0 -228
- package/dist/storage.d.ts.map +0 -1
- package/dist/storage.js +0 -218
- package/dist/storage.js.map +0 -1
- package/dist/template.d.ts +0 -10
- package/dist/template.d.ts.map +0 -1
- package/dist/template.js +0 -60
- package/dist/template.js.map +0 -1
- package/dist/ttl.d.ts +0 -144
- package/dist/ttl.d.ts.map +0 -1
- package/dist/ttl.js +0 -85
- package/dist/ttl.js.map +0 -1
- package/dist/types.d.ts +0 -1213
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -39
- package/dist/types.js.map +0 -1
- package/dist/validation.d.ts +0 -156
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -289
- package/dist/validation.js.map +0 -1
package/dist/extraction.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/extraction.ts"],"sourcesContent":["/**\n * @module extraction\n * @description LLM-based field extraction from natural language.\n *\n * Exposes prompt/schema/parse helpers consumed by the form Evaluator and\n * runs the LLM call directly only for the targeted single-field and\n * correction-detection helpers.\n */\n\nimport type { IAgentRuntime, JSONSchema, JsonValue } from \"@elizaos/core\";\nimport { ModelType } from \"@elizaos/core\";\nimport type { TemplateValues } from \"./template\";\nimport { resolveControlTemplates } from \"./template\";\nimport type {\n ExtractionResult,\n FormControl,\n FormDefinition,\n FormIntent,\n IntentResult,\n} from \"./types\";\nimport { getTypeHandler, parseValue, validateField } from \"./validation\";\n\nconst FORM_INTENTS: FormIntent[] = [\n \"fill_form\",\n \"submit\",\n \"stash\",\n \"restore\",\n \"cancel\",\n \"undo\",\n \"skip\",\n \"explain\",\n \"example\",\n \"progress\",\n \"autofill\",\n \"other\",\n];\n\nconst INTENT_MEANINGS: Record<FormIntent, string> = {\n fill_form: \"user is providing field values\",\n submit: \"user wants to submit or finish the form\",\n stash: \"user wants to save or pause the form for later\",\n restore: \"user wants to resume a saved form\",\n cancel: \"user wants to cancel or abandon the form\",\n undo: \"user wants to undo the last change\",\n skip: \"user wants to skip the current field\",\n explain: \"user wants an explanation\",\n example: \"user wants an example value\",\n progress: \"user wants a progress update\",\n autofill: \"user wants to use saved values\",\n other: \"none of the above\",\n};\n\ntype SingleFieldJsonResponse = {\n found?: string | boolean;\n value?: JsonValue;\n confidence?: string | number;\n reasoning?: string;\n};\n\ntype CorrectionJsonField = {\n field?: string;\n old_value?: JsonValue;\n new_value?: JsonValue;\n confidence?: string | number;\n};\n\ntype CorrectionJsonResponse = {\n has_correction?: string | boolean;\n corrections?: CorrectionJsonField[];\n};\n\nfunction parseJsonObjectResponse<T>(response: string): T | null {\n try {\n const trimmed = response.trim();\n const fenced = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n const candidate = (fenced?.[1] ?? trimmed).trim();\n const firstBrace = candidate.indexOf(\"{\");\n const lastBrace = candidate.lastIndexOf(\"}\");\n if (firstBrace < 0 || lastBrace <= firstBrace) return null;\n const parsed = JSON.parse(candidate.slice(firstBrace, lastBrace + 1));\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n return parsed as T;\n } catch {\n return null;\n }\n}\n\nfunction parseBoolean(value: unknown): boolean {\n return (\n String(value ?? \"\")\n .trim()\n .toLowerCase() === \"true\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isValidIntent(str: string): str is FormIntent {\n return (FORM_INTENTS as string[]).includes(str);\n}\n\n// ============================================================================\n// EVALUATOR HELPERS — schema, prompt, parse for the unified evaluator pass\n// ============================================================================\n\n/**\n * Build the JSON Schema fragment for the form-extractor evaluator section.\n *\n * Returned shape:\n * { formIntent: <enum>, formExtractions: [{ field, value, confidence, isCorrection }] }\n */\nexport function buildFormExtractorSchema(): JSONSchema {\n return {\n type: \"object\",\n properties: {\n formIntent: {\n type: \"string\",\n enum: [...FORM_INTENTS],\n },\n formExtractions: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n field: { type: \"string\" },\n value: {},\n confidence: { type: \"number\" },\n isCorrection: { type: \"boolean\" },\n reasoning: { type: \"string\" },\n },\n required: [\"field\", \"confidence\"],\n additionalProperties: false,\n },\n },\n },\n required: [\"formIntent\", \"formExtractions\"],\n additionalProperties: false,\n };\n}\n\n/**\n * Build the prompt section for the form-extractor evaluator.\n *\n * The unified evaluator prompt inlines this string and asks the model to\n * populate `{ formIntent, formExtractions }` for the active form.\n */\nexport function buildFormExtractorPromptSection(params: {\n text: string;\n form: FormDefinition;\n controls: FormControl[];\n templateValues?: TemplateValues;\n}): string {\n const { text, form, controls, templateValues } = params;\n\n const resolvedControls = templateValues\n ? controls.map((control) =>\n resolveControlTemplates(control, templateValues),\n )\n : controls;\n\n const visibleControls = resolvedControls.filter((c) => !c.hidden);\n const fieldsDescription = visibleControls.map((c) => {\n const handler = getTypeHandler(c.type);\n const typeHint = handler?.extractionPrompt || c.type;\n return {\n key: c.key,\n label: c.label,\n type: typeHint,\n description: c.description || typeHint,\n hints: c.extractHints ?? [],\n options: c.options?.map((o) => o.value) ?? [],\n };\n });\n\n return `Extract form intent and field values for the active form session.\n\nContext JSON:\n${JSON.stringify(\n {\n form: {\n name: form.name,\n description: form.description,\n },\n fields: fieldsDescription,\n user_message: text,\n intent_options: FORM_INTENTS,\n intent_meanings: INTENT_MEANINGS,\n },\n null,\n 2,\n)}\n\nPopulate this evaluator's section as:\n{\n \"formIntent\": \"one of intent_options\",\n \"formExtractions\": [\n { \"field\": \"<key>\", \"value\": <extracted>, \"confidence\": 0.0-1.0, \"isCorrection\": false, \"reasoning\": \"brief\" }\n ]\n}\n\nRules:\n- Choose exactly one intent.\n- For fill_form, extract every mentioned field value.\n- Use an empty formExtractions array when no fields were extracted.\n- Confidence is a number from 0.0 to 1.0.`;\n}\n\n/**\n * Parse the raw `{ formIntent, formExtractions }` object produced by the\n * unified evaluator pass into a typed `IntentResult`. Type coercion and\n * validation against control rules happen later (in the processor) where\n * the form definition is in scope.\n */\nexport function parseFormExtractorOutput(raw: unknown): IntentResult | null {\n if (!isRecord(raw)) return null;\n\n const intentStr =\n typeof raw.formIntent === \"string\"\n ? raw.formIntent.toLowerCase()\n : \"other\";\n const intent: FormIntent = isValidIntent(intentStr) ? intentStr : \"other\";\n\n const rawExtractions = Array.isArray(raw.formExtractions)\n ? raw.formExtractions\n : [];\n\n const extractions: ExtractionResult[] = [];\n const seen = new Set<string>();\n\n for (const entry of rawExtractions) {\n if (!isRecord(entry)) continue;\n const fieldKey = typeof entry.field === \"string\" ? entry.field : \"\";\n if (!fieldKey) continue;\n\n const dedupeKey = `${fieldKey}\\0${String(entry.value ?? \"\")}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n\n const value: JsonValue =\n (entry.value as JsonValue | undefined) ?? null;\n\n let confidence =\n typeof entry.confidence === \"number\"\n ? entry.confidence\n : parseFloat(String(entry.confidence ?? \"\"));\n if (!Number.isFinite(confidence)) confidence = 0.5;\n\n const reasoning =\n typeof entry.reasoning === \"string\" ? entry.reasoning : undefined;\n\n extractions.push({\n field: fieldKey,\n value,\n confidence,\n reasoning,\n isCorrection: parseBoolean(entry.isCorrection),\n });\n }\n\n return { intent, extractions };\n}\n\n/**\n * Apply type coercion + validation to a parsed extractions list against the\n * resolved form controls. Lowers confidence to 0.3 when a value fails the\n * control's validator (so downstream confirmation flow kicks in).\n */\nexport function coerceExtractionsAgainstControls(\n extractions: ExtractionResult[],\n controls: FormControl[],\n templateValues?: TemplateValues,\n): ExtractionResult[] {\n const resolvedControls = templateValues\n ? controls.map((control) =>\n resolveControlTemplates(control, templateValues),\n )\n : controls;\n\n return extractions.map((extraction) => {\n if (extraction.field.includes(\".\")) return extraction;\n\n const control = resolvedControls.find((c) => c.key === extraction.field);\n if (!control) return extraction;\n\n let value = extraction.value;\n if (typeof value === \"string\") {\n value = parseValue(value, control);\n }\n\n const validation = validateField(value, control);\n if (!validation.valid) {\n const reasoning = `${extraction.reasoning ?? \"\"} (Validation failed: ${validation.error})`.trim();\n return {\n ...extraction,\n value,\n confidence: Math.min(extraction.confidence, 0.3),\n reasoning,\n };\n }\n\n return { ...extraction, value };\n });\n}\n\n// ============================================================================\n// SINGLE-FIELD EXTRACTION (still owns its LLM call — narrow targeted use)\n// ============================================================================\n\n/**\n * Extract a specific field value from a user message with a focused prompt.\n *\n * Used when the agent has just asked for a specific field and expects a\n * direct answer. Independent of the unified evaluator pass.\n */\nexport async function extractSingleField(\n runtime: IAgentRuntime,\n text: string,\n control: FormControl,\n debug?: boolean,\n templateValues?: TemplateValues,\n): Promise<ExtractionResult | null> {\n const resolvedControl = templateValues\n ? resolveControlTemplates(control, templateValues)\n : control;\n const handler = getTypeHandler(resolvedControl.type);\n const typeHint = handler?.extractionPrompt || resolvedControl.type;\n\n const prompt = `Extract a single form field value from the user message.\n\nContext JSON:\n${JSON.stringify(\n {\n field: {\n key: resolvedControl.key,\n label: resolvedControl.label,\n type: typeHint,\n description: resolvedControl.description,\n hints: resolvedControl.extractHints ?? [],\n options: resolvedControl.options?.map((o) => o.value) ?? [],\n example: resolvedControl.example,\n },\n user_message: text,\n },\n null,\n 2,\n)}\n\nReturn only a valid JSON object with this schema:\n{\n \"found\": true,\n \"value\": \"extracted value or null if not found\",\n \"confidence\": 0.95,\n \"reasoning\": \"brief explanation\"\n}`;\n\n const runModel = runtime.useModel.bind(runtime);\n const response = await runModel(ModelType.TEXT_SMALL, {\n prompt,\n temperature: 0.1,\n });\n\n const parsed = parseJsonObjectResponse<SingleFieldJsonResponse>(response);\n const found = parsed?.found === true || parsed?.found === \"true\";\n if (!found || !parsed) return null;\n\n let value = parsed.value;\n if (typeof value === \"string\") {\n value = parseValue(value, resolvedControl);\n }\n\n const confidence =\n typeof parsed.confidence === \"number\"\n ? parsed.confidence\n : parseFloat(String(parsed.confidence ?? \"\"));\n\n const result: ExtractionResult = {\n field: resolvedControl.key,\n value: value ?? null,\n confidence: Number.isFinite(confidence) ? confidence : 0.5,\n reasoning: parsed.reasoning ? String(parsed.reasoning) : undefined,\n };\n\n if (debug) {\n runtime.logger.debug(\n \"[FormExtraction] Single field extraction:\",\n JSON.stringify(result),\n );\n }\n\n return result;\n}\n\n// ============================================================================\n// CORRECTION DETECTION (still owns its LLM call — narrow targeted use)\n// ============================================================================\n\n/**\n * Detect whether the user is correcting a previously filled value.\n */\nexport async function detectCorrection(\n runtime: IAgentRuntime,\n text: string,\n currentValues: Record<string, JsonValue>,\n controls: FormControl[],\n templateValues?: TemplateValues,\n): Promise<ExtractionResult[]> {\n const resolvedControls = templateValues\n ? controls.map((control) =>\n resolveControlTemplates(control, templateValues),\n )\n : controls;\n\n const currentValueEntries = resolvedControls.filter(\n (c) => currentValues[c.key] !== undefined,\n );\n if (currentValueEntries.length === 0) return [];\n\n const currentValueRows = currentValueEntries.map((c) => ({\n key: c.key,\n label: c.label,\n value: currentValues[c.key],\n }));\n\n const prompt = `Detect whether the user is correcting a previous form value.\n\nContext JSON:\n${JSON.stringify(\n {\n current_values: currentValueRows,\n user_message: text,\n },\n null,\n 2,\n)}\n\nReturn only a valid JSON object with this schema:\n{\n \"has_correction\": true,\n \"corrections\": [\n {\n \"field\": \"email\",\n \"old_value\": \"old@example.com\",\n \"new_value\": \"new@example.com\",\n \"confidence\": 0.9\n }\n ]\n}\n\nRules:\n- Decide whether the user is correcting a previous value.\n- When correcting, extract the replacement value.\n- Use an empty corrections array when no corrections were found.`;\n\n const runModel = runtime.useModel.bind(runtime);\n const response = await runModel(ModelType.TEXT_SMALL, {\n prompt,\n temperature: 0.1,\n });\n\n const parsed = parseJsonObjectResponse<CorrectionJsonResponse>(response);\n const hasCorrection =\n parsed?.has_correction === true || parsed?.has_correction === \"true\";\n if (!parsed || !hasCorrection || !parsed.corrections) return [];\n\n const corrections: ExtractionResult[] = [];\n const correctionList = Array.isArray(parsed.corrections)\n ? parsed.corrections\n : [];\n const seen = new Set<string>();\n\n for (const correction of correctionList) {\n const fieldName = correction.field ? String(correction.field) : \"\";\n const control = resolvedControls.find(\n (c) =>\n c.label.toLowerCase() === fieldName.toLowerCase() ||\n c.key.toLowerCase() === fieldName.toLowerCase(),\n );\n if (!control) continue;\n\n const dedupeKey = `${control.key}\\0${String(correction.new_value ?? \"\")}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n\n let value = correction.new_value;\n if (typeof value === \"string\") {\n value = parseValue(value, control);\n }\n\n const confidence =\n typeof correction.confidence === \"number\"\n ? correction.confidence\n : parseFloat(String(correction.confidence ?? \"\"));\n\n corrections.push({\n field: control.key,\n value: value ?? null,\n confidence: Number.isFinite(confidence) ? confidence : 0.8,\n isCorrection: true,\n });\n }\n\n return corrections;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @elizaos/plugin-form
|
|
3
|
-
* @description Guardrails for agent-guided user journeys
|
|
4
|
-
*
|
|
5
|
-
* @author Odilitime
|
|
6
|
-
* @copyright 2025 Odilitime
|
|
7
|
-
* @license MIT
|
|
8
|
-
*/
|
|
9
|
-
import type { Plugin } from "@elizaos/core";
|
|
10
|
-
export * from "./types";
|
|
11
|
-
export { BUILTIN_TYPE_MAP, BUILTIN_TYPES, getBuiltinType, isBuiltinType, registerBuiltinTypes, } from "./builtins";
|
|
12
|
-
export { clearTypeHandlers, formatValue, getTypeHandler, matchesMimeType, parseValue, registerTypeHandler, validateField, } from "./validation";
|
|
13
|
-
export { deleteSession, getActiveSession, getAllActiveSessions, getAutofillData, getStashedSessions, getSubmissions, saveAutofillData, saveSession, saveSubmission, } from "./storage";
|
|
14
|
-
export { buildFormExtractorPromptSection, buildFormExtractorSchema, coerceExtractionsAgainstControls, detectCorrection, extractSingleField, parseFormExtractorOutput, } from "./extraction";
|
|
15
|
-
export { calculateTTL, formatEffort, formatTimeRemaining, isExpired, isExpiringSoon, shouldConfirmCancel, shouldNudge, } from "./ttl";
|
|
16
|
-
export { applyControlDefaults, applyFormDefaults, prettify } from "./defaults";
|
|
17
|
-
export { C, ControlBuilder, Form, FormBuilder } from "./builder";
|
|
18
|
-
export { FormService } from "./service";
|
|
19
|
-
export { formRestoreAction } from "./actions/restore";
|
|
20
|
-
export { formEvaluator } from "./evaluators/extractor";
|
|
21
|
-
export { formContextProvider } from "./providers/context";
|
|
22
|
-
/**
|
|
23
|
-
* Form Plugin
|
|
24
|
-
*
|
|
25
|
-
* Infrastructure plugin for collecting structured data through natural conversation.
|
|
26
|
-
*/
|
|
27
|
-
export declare const formPlugin: Plugin & {
|
|
28
|
-
descriptionCompressed?: string;
|
|
29
|
-
};
|
|
30
|
-
export default formPlugin;
|
|
31
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAEV,MAAM,EAEP,MAAM,eAAe,CAAC;AAGvB,cAAc,SAAS,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,+BAA+B,EAC/B,wBAAwB,EACxB,gCAAgC,EAChC,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,WAAW,GACZ,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE/E,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,UAAU,EA4ClB,MAAM,GAAG;IAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,eAAe,UAAU,CAAC"}
|
package/dist/index.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @elizaos/plugin-form
|
|
3
|
-
* @description Guardrails for agent-guided user journeys
|
|
4
|
-
*
|
|
5
|
-
* @author Odilitime
|
|
6
|
-
* @copyright 2025 Odilitime
|
|
7
|
-
* @license MIT
|
|
8
|
-
*/
|
|
9
|
-
import { formEvaluator } from "./evaluators/extractor";
|
|
10
|
-
export * from "./types";
|
|
11
|
-
import {
|
|
12
|
-
BUILTIN_TYPE_MAP,
|
|
13
|
-
BUILTIN_TYPES,
|
|
14
|
-
getBuiltinType,
|
|
15
|
-
isBuiltinType,
|
|
16
|
-
registerBuiltinTypes
|
|
17
|
-
} from "./builtins";
|
|
18
|
-
import {
|
|
19
|
-
clearTypeHandlers,
|
|
20
|
-
formatValue,
|
|
21
|
-
getTypeHandler,
|
|
22
|
-
matchesMimeType,
|
|
23
|
-
parseValue,
|
|
24
|
-
registerTypeHandler,
|
|
25
|
-
validateField
|
|
26
|
-
} from "./validation";
|
|
27
|
-
import {
|
|
28
|
-
deleteSession,
|
|
29
|
-
getActiveSession,
|
|
30
|
-
getAllActiveSessions,
|
|
31
|
-
getAutofillData,
|
|
32
|
-
getStashedSessions,
|
|
33
|
-
getSubmissions,
|
|
34
|
-
saveAutofillData,
|
|
35
|
-
saveSession,
|
|
36
|
-
saveSubmission
|
|
37
|
-
} from "./storage";
|
|
38
|
-
import {
|
|
39
|
-
buildFormExtractorPromptSection,
|
|
40
|
-
buildFormExtractorSchema,
|
|
41
|
-
coerceExtractionsAgainstControls,
|
|
42
|
-
detectCorrection,
|
|
43
|
-
extractSingleField,
|
|
44
|
-
parseFormExtractorOutput
|
|
45
|
-
} from "./extraction";
|
|
46
|
-
import {
|
|
47
|
-
calculateTTL,
|
|
48
|
-
formatEffort,
|
|
49
|
-
formatTimeRemaining,
|
|
50
|
-
isExpired,
|
|
51
|
-
isExpiringSoon,
|
|
52
|
-
shouldConfirmCancel,
|
|
53
|
-
shouldNudge
|
|
54
|
-
} from "./ttl";
|
|
55
|
-
import { applyControlDefaults, applyFormDefaults, prettify } from "./defaults";
|
|
56
|
-
import { C, ControlBuilder, Form, FormBuilder } from "./builder";
|
|
57
|
-
import { FormService } from "./service";
|
|
58
|
-
import { formRestoreAction } from "./actions/restore";
|
|
59
|
-
import { formEvaluator as formEvaluator2 } from "./evaluators/extractor";
|
|
60
|
-
import { formContextProvider } from "./providers/context";
|
|
61
|
-
const formPlugin = {
|
|
62
|
-
name: "form",
|
|
63
|
-
description: "Agent-native conversational forms for data collection",
|
|
64
|
-
descriptionCompressed: "Conversational forms for structured data collection.",
|
|
65
|
-
autoEnable: {
|
|
66
|
-
shouldEnable: (_env, config) => {
|
|
67
|
-
const f = config?.features?.form;
|
|
68
|
-
return f === true || typeof f === "object" && f !== null && f.enabled !== false;
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
services: [
|
|
72
|
-
{
|
|
73
|
-
serviceType: "FORM",
|
|
74
|
-
start: async (runtime) => {
|
|
75
|
-
const { FormService: FormService2 } = await import("./service");
|
|
76
|
-
return FormService2.start(runtime);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
],
|
|
80
|
-
providers: [
|
|
81
|
-
{
|
|
82
|
-
name: "FORM_CONTEXT",
|
|
83
|
-
description: "Provides context about active form sessions",
|
|
84
|
-
descriptionCompressed: "Active form session context.",
|
|
85
|
-
get: async (runtime, message, state) => {
|
|
86
|
-
const { formContextProvider: formContextProvider2 } = await import("./providers/context");
|
|
87
|
-
return formContextProvider2.get(runtime, message, state);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
],
|
|
91
|
-
actions: [],
|
|
92
|
-
evaluators: [formEvaluator]
|
|
93
|
-
};
|
|
94
|
-
var index_default = formPlugin;
|
|
95
|
-
export {
|
|
96
|
-
BUILTIN_TYPES,
|
|
97
|
-
BUILTIN_TYPE_MAP,
|
|
98
|
-
C,
|
|
99
|
-
ControlBuilder,
|
|
100
|
-
Form,
|
|
101
|
-
FormBuilder,
|
|
102
|
-
FormService,
|
|
103
|
-
applyControlDefaults,
|
|
104
|
-
applyFormDefaults,
|
|
105
|
-
buildFormExtractorPromptSection,
|
|
106
|
-
buildFormExtractorSchema,
|
|
107
|
-
calculateTTL,
|
|
108
|
-
clearTypeHandlers,
|
|
109
|
-
coerceExtractionsAgainstControls,
|
|
110
|
-
index_default as default,
|
|
111
|
-
deleteSession,
|
|
112
|
-
detectCorrection,
|
|
113
|
-
extractSingleField,
|
|
114
|
-
formContextProvider,
|
|
115
|
-
formEvaluator2 as formEvaluator,
|
|
116
|
-
formPlugin,
|
|
117
|
-
formRestoreAction,
|
|
118
|
-
formatEffort,
|
|
119
|
-
formatTimeRemaining,
|
|
120
|
-
formatValue,
|
|
121
|
-
getActiveSession,
|
|
122
|
-
getAllActiveSessions,
|
|
123
|
-
getAutofillData,
|
|
124
|
-
getBuiltinType,
|
|
125
|
-
getStashedSessions,
|
|
126
|
-
getSubmissions,
|
|
127
|
-
getTypeHandler,
|
|
128
|
-
isBuiltinType,
|
|
129
|
-
isExpired,
|
|
130
|
-
isExpiringSoon,
|
|
131
|
-
matchesMimeType,
|
|
132
|
-
parseFormExtractorOutput,
|
|
133
|
-
parseValue,
|
|
134
|
-
prettify,
|
|
135
|
-
registerBuiltinTypes,
|
|
136
|
-
registerTypeHandler,
|
|
137
|
-
saveAutofillData,
|
|
138
|
-
saveSession,
|
|
139
|
-
saveSubmission,
|
|
140
|
-
shouldConfirmCancel,
|
|
141
|
-
shouldNudge,
|
|
142
|
-
validateField
|
|
143
|
-
};
|
|
144
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @module @elizaos/plugin-form\n * @description Guardrails for agent-guided user journeys\n *\n * @author Odilitime\n * @copyright 2025 Odilitime\n * @license MIT\n */\n\nimport type {\n IAgentRuntime,\n Plugin,\n ServiceClass,\n} from \"@elizaos/core\";\nimport { formEvaluator } from \"./evaluators/extractor\";\n\nexport * from \"./types\";\n\nexport {\n BUILTIN_TYPE_MAP,\n BUILTIN_TYPES,\n getBuiltinType,\n isBuiltinType,\n registerBuiltinTypes,\n} from \"./builtins\";\n\nexport {\n clearTypeHandlers,\n formatValue,\n getTypeHandler,\n matchesMimeType,\n parseValue,\n registerTypeHandler,\n validateField,\n} from \"./validation\";\n\nexport {\n deleteSession,\n getActiveSession,\n getAllActiveSessions,\n getAutofillData,\n getStashedSessions,\n getSubmissions,\n saveAutofillData,\n saveSession,\n saveSubmission,\n} from \"./storage\";\n\nexport {\n buildFormExtractorPromptSection,\n buildFormExtractorSchema,\n coerceExtractionsAgainstControls,\n detectCorrection,\n extractSingleField,\n parseFormExtractorOutput,\n} from \"./extraction\";\n\nexport {\n calculateTTL,\n formatEffort,\n formatTimeRemaining,\n isExpired,\n isExpiringSoon,\n shouldConfirmCancel,\n shouldNudge,\n} from \"./ttl\";\n\nexport { applyControlDefaults, applyFormDefaults, prettify } from \"./defaults\";\n\nexport { C, ControlBuilder, Form, FormBuilder } from \"./builder\";\n\nexport { FormService } from \"./service\";\n\nexport { formRestoreAction } from \"./actions/restore\";\nexport { formEvaluator } from \"./evaluators/extractor\";\nexport { formContextProvider } from \"./providers/context\";\n\n/**\n * Form Plugin\n *\n * Infrastructure plugin for collecting structured data through natural conversation.\n */\nexport const formPlugin = {\n name: \"form\",\n description: \"Agent-native conversational forms for data collection\",\n descriptionCompressed: \"Conversational forms for structured data collection.\",\n\n autoEnable: {\n shouldEnable: (\n _env: Record<string, string | undefined>,\n config: Record<string, unknown>,\n ) => {\n const f = (config?.features as Record<string, unknown> | undefined)?.form;\n return (\n f === true ||\n (typeof f === \"object\" &&\n f !== null &&\n (f as { enabled?: unknown }).enabled !== false)\n );\n },\n },\n\n services: [\n {\n serviceType: \"FORM\",\n start: async (runtime: IAgentRuntime) => {\n const { FormService } = await import(\"./service\");\n return FormService.start(runtime);\n },\n } as ServiceClass,\n ],\n\n providers: [\n {\n name: \"FORM_CONTEXT\",\n description: \"Provides context about active form sessions\",\n descriptionCompressed: \"Active form session context.\",\n get: async (runtime, message, state) => {\n const { formContextProvider } = await import(\"./providers/context\");\n return formContextProvider.get(runtime, message, state);\n },\n },\n ],\n\n actions: [],\n evaluators: [formEvaluator],\n} as Plugin & { descriptionCompressed?: string };\n\nexport default formPlugin;\n"],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,SAAS,qBAAqB;AAE9B,cAAc;AAEd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,sBAAsB,mBAAmB,gBAAgB;AAElE,SAAS,GAAG,gBAAgB,MAAM,mBAAmB;AAErD,SAAS,mBAAmB;AAE5B,SAAS,yBAAyB;AAClC,SAAS,iBAAAA,sBAAqB;AAC9B,SAAS,2BAA2B;AAO7B,MAAM,aAAa;AAAA,EACxB,MAAM;AAAA,EACN,aAAa;AAAA,EACb,uBAAuB;AAAA,EAEvB,YAAY;AAAA,IACV,cAAc,CACZ,MACA,WACG;AACH,YAAM,IAAK,QAAQ,UAAkD;AACrE,aACE,MAAM,QACL,OAAO,MAAM,YACZ,MAAM,QACL,EAA4B,YAAY;AAAA,IAE/C;AAAA,EACF;AAAA,EAEA,UAAU;AAAA,IACR;AAAA,MACE,aAAa;AAAA,MACb,OAAO,OAAO,YAA2B;AACvC,cAAM,EAAE,aAAAC,aAAY,IAAI,MAAM,OAAO,WAAW;AAChD,eAAOA,aAAY,MAAM,OAAO;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW;AAAA,IACT;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,uBAAuB;AAAA,MACvB,KAAK,OAAO,SAAS,SAAS,UAAU;AACtC,cAAM,EAAE,qBAAAC,qBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,eAAOA,qBAAoB,IAAI,SAAS,SAAS,KAAK;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS,CAAC;AAAA,EACV,YAAY,CAAC,aAAa;AAC5B;AAEA,IAAO,gBAAQ;","names":["formEvaluator","FormService","formContextProvider"]}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module providers/context
|
|
3
|
-
* @description Form context provider for agent awareness
|
|
4
|
-
*
|
|
5
|
-
* ## Purpose
|
|
6
|
-
*
|
|
7
|
-
* This provider injects form state into the agent's context BEFORE
|
|
8
|
-
* the agent generates a response. This allows the agent to:
|
|
9
|
-
*
|
|
10
|
-
* 1. Know if a form is active
|
|
11
|
-
* 2. Know what required/optional fields we have vs don't have
|
|
12
|
-
* 3. Know what needs confirmation (low-confidence extractions)
|
|
13
|
-
* 4. Know what external actions are pending (payments, signatures, etc.)
|
|
14
|
-
* 5. Get a single, coherent instruction (nudge for required, confirm, or submit)
|
|
15
|
-
*
|
|
16
|
-
* ## Output layout
|
|
17
|
-
*
|
|
18
|
-
* The text output uses a required/optional × have/don't-have layout so the
|
|
19
|
-
* agent sees the full picture at a glance and can ask for one or several
|
|
20
|
-
* missing fields in a single message (the form extracts and saves each).
|
|
21
|
-
*
|
|
22
|
-
* ## Context Output
|
|
23
|
-
*
|
|
24
|
-
* - `data`: Full FormContextState (programmatic access; e.g. restore action uses nextField)
|
|
25
|
-
* - `values`: String values for template substitution (formContext, formProgress, etc.)
|
|
26
|
-
* - `text`: Human-readable summary injected into the agent prompt
|
|
27
|
-
*
|
|
28
|
-
* ## How It Works
|
|
29
|
-
*
|
|
30
|
-
* ```
|
|
31
|
-
* User Message → Provider Runs → Agent Gets Context → Agent Responds
|
|
32
|
-
* ↓
|
|
33
|
-
* FormContextState
|
|
34
|
-
* ↓
|
|
35
|
-
* - hasActiveForm, progress
|
|
36
|
-
* - required/optional × have/don't have
|
|
37
|
-
* - uncertainFields, pendingExternalFields
|
|
38
|
-
* - single Instruction line
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* ## Stashed Forms
|
|
42
|
-
*
|
|
43
|
-
* If the user has stashed forms, the provider appends a reminder so the
|
|
44
|
-
* agent can tell the user they have unfinished work and can say "resume".
|
|
45
|
-
*/
|
|
46
|
-
import type { Provider } from "@elizaos/core";
|
|
47
|
-
/**
|
|
48
|
-
* Form Context Provider
|
|
49
|
-
*
|
|
50
|
-
* Injects the current form state into the agent's context,
|
|
51
|
-
* allowing the agent to respond naturally about form progress
|
|
52
|
-
* and nudge for missing fields (one or several at once).
|
|
53
|
-
*/
|
|
54
|
-
export declare const formContextProvider: Provider;
|
|
55
|
-
export default formContextProvider;
|
|
56
|
-
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/providers/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EAIV,QAAQ,EAIT,MAAM,eAAe,CAAC;AAiBvB;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAuPjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import { logger } from "@elizaos/core";
|
|
2
|
-
import {
|
|
3
|
-
buildTemplateValues,
|
|
4
|
-
renderTemplate,
|
|
5
|
-
resolveControlTemplates
|
|
6
|
-
} from "../template";
|
|
7
|
-
function compactJson(value) {
|
|
8
|
-
return JSON.stringify(value, null, 2);
|
|
9
|
-
}
|
|
10
|
-
const MAX_CONTEXT_FIELDS = 20;
|
|
11
|
-
const MAX_STASHED_FOR_CONTEXT = 10;
|
|
12
|
-
const formContextProvider = {
|
|
13
|
-
name: "FORM_CONTEXT",
|
|
14
|
-
description: "Provides context about active form sessions",
|
|
15
|
-
descriptionCompressed: "Active form session context.",
|
|
16
|
-
contexts: ["automation", "knowledge"],
|
|
17
|
-
contextGate: { anyOf: ["automation", "knowledge"] },
|
|
18
|
-
cacheStable: false,
|
|
19
|
-
cacheScope: "turn",
|
|
20
|
-
/**
|
|
21
|
-
* Get form context for the current message.
|
|
22
|
-
*
|
|
23
|
-
* @param runtime - Agent runtime for service access
|
|
24
|
-
* @param message - The user message being processed
|
|
25
|
-
* @param _state - Current agent state (unused)
|
|
26
|
-
* @returns Provider result with form context (data, values, text)
|
|
27
|
-
*/
|
|
28
|
-
get: async (runtime, message, _state) => {
|
|
29
|
-
try {
|
|
30
|
-
const formService = runtime.getService("FORM");
|
|
31
|
-
if (!formService) {
|
|
32
|
-
return {
|
|
33
|
-
data: { hasActiveForm: false },
|
|
34
|
-
values: { formContext: "" },
|
|
35
|
-
text: ""
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
const entityId = message.entityId;
|
|
39
|
-
const roomId = message.roomId;
|
|
40
|
-
if (!entityId || !roomId) {
|
|
41
|
-
return {
|
|
42
|
-
data: { hasActiveForm: false },
|
|
43
|
-
values: { formContext: "" },
|
|
44
|
-
text: ""
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const session = await formService.getActiveSession(entityId, roomId);
|
|
48
|
-
const stashed = await formService.getStashedSessions(entityId);
|
|
49
|
-
if (!session && stashed.length === 0) {
|
|
50
|
-
return {
|
|
51
|
-
data: { hasActiveForm: false, stashedCount: 0 },
|
|
52
|
-
values: { formContext: "" },
|
|
53
|
-
text: ""
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
let contextText = "";
|
|
57
|
-
let contextState;
|
|
58
|
-
let stashedRows = [];
|
|
59
|
-
if (session) {
|
|
60
|
-
contextState = formService.getSessionContext(session);
|
|
61
|
-
const form = formService.getForm(session.formId);
|
|
62
|
-
const templateValues = buildTemplateValues(session);
|
|
63
|
-
const resolve = (v) => renderTemplate(v, templateValues);
|
|
64
|
-
contextState = {
|
|
65
|
-
...contextState,
|
|
66
|
-
filledFields: contextState.filledFields.map((f) => ({
|
|
67
|
-
...f,
|
|
68
|
-
label: resolve(f.label) ?? f.label
|
|
69
|
-
})),
|
|
70
|
-
missingRequired: contextState.missingRequired.map((f) => ({
|
|
71
|
-
...f,
|
|
72
|
-
label: resolve(f.label) ?? f.label,
|
|
73
|
-
description: resolve(f.description),
|
|
74
|
-
askPrompt: resolve(f.askPrompt)
|
|
75
|
-
})),
|
|
76
|
-
uncertainFields: contextState.uncertainFields.map((f) => ({
|
|
77
|
-
...f,
|
|
78
|
-
label: resolve(f.label) ?? f.label
|
|
79
|
-
})),
|
|
80
|
-
nextField: contextState.nextField ? resolveControlTemplates(contextState.nextField, templateValues) : null
|
|
81
|
-
};
|
|
82
|
-
const controls = form?.controls ?? [];
|
|
83
|
-
const filledKeys = new Set(contextState.filledFields.map((f) => f.key));
|
|
84
|
-
const controlByKey = new Map(controls.map((c) => [c.key, c]));
|
|
85
|
-
const requiredFilled = contextState.filledFields.filter(
|
|
86
|
-
(f) => controlByKey.get(f.key)?.required
|
|
87
|
-
);
|
|
88
|
-
const optionalFilled = contextState.filledFields.filter(
|
|
89
|
-
(f) => !controlByKey.get(f.key)?.required
|
|
90
|
-
);
|
|
91
|
-
const optionalMissing = controls.filter((c) => !c.hidden && !c.required && !filledKeys.has(c.key)).map((c) => resolveControlTemplates(c, templateValues));
|
|
92
|
-
let instruction = "";
|
|
93
|
-
if (contextState.pendingExternalFields.length > 0) {
|
|
94
|
-
const p = contextState.pendingExternalFields[0];
|
|
95
|
-
instruction = `Waiting for external action. Remind user: "${p.instructions}"`;
|
|
96
|
-
} else if (contextState.pendingCancelConfirmation) {
|
|
97
|
-
instruction = "User is trying to cancel. Confirm they really want to lose progress.";
|
|
98
|
-
} else if (contextState.uncertainFields.length > 0) {
|
|
99
|
-
const u = contextState.uncertainFields[0];
|
|
100
|
-
instruction = `Ask user to confirm "${u.label}" = "${u.value}".`;
|
|
101
|
-
} else if (contextState.missingRequired.length > 0) {
|
|
102
|
-
instruction = "Nudge the user into helping complete required fields. The user can provide one or several answers in a single message.";
|
|
103
|
-
} else if (contextState.status === "ready") {
|
|
104
|
-
instruction = "All required fields collected. Nudge user to submit.";
|
|
105
|
-
} else if (optionalMissing.length > 0) {
|
|
106
|
-
instruction = "Required fields are done. Optionally nudge for remaining optional fields, or nudge to submit.";
|
|
107
|
-
}
|
|
108
|
-
contextText = `form_context_json:
|
|
109
|
-
${compactJson({
|
|
110
|
-
active: true,
|
|
111
|
-
form_id: session.formId,
|
|
112
|
-
form_name: form?.name || session.formId,
|
|
113
|
-
progress: contextState.progress,
|
|
114
|
-
status: contextState.status,
|
|
115
|
-
required_missing: contextState.missingRequired.slice(
|
|
116
|
-
0,
|
|
117
|
-
MAX_CONTEXT_FIELDS
|
|
118
|
-
),
|
|
119
|
-
required_filled: requiredFilled.map((field) => ({
|
|
120
|
-
...field,
|
|
121
|
-
value: field.displayValue
|
|
122
|
-
})).slice(0, MAX_CONTEXT_FIELDS),
|
|
123
|
-
optional_missing: optionalMissing.slice(0, MAX_CONTEXT_FIELDS),
|
|
124
|
-
optional_filled: optionalFilled.map((field) => ({
|
|
125
|
-
...field,
|
|
126
|
-
value: field.displayValue
|
|
127
|
-
})).slice(0, MAX_CONTEXT_FIELDS),
|
|
128
|
-
uncertain_fields: contextState.uncertainFields.slice(0, MAX_CONTEXT_FIELDS).map((field) => ({
|
|
129
|
-
...field,
|
|
130
|
-
confidence: Math.round(field.confidence * 100) / 100
|
|
131
|
-
})),
|
|
132
|
-
pending_external_fields: contextState.pendingExternalFields.map(
|
|
133
|
-
(field) => ({
|
|
134
|
-
...field,
|
|
135
|
-
age_minutes: Math.max(
|
|
136
|
-
0,
|
|
137
|
-
Math.floor((Date.now() - field.activatedAt) / 6e4)
|
|
138
|
-
)
|
|
139
|
-
})
|
|
140
|
-
).slice(0, MAX_CONTEXT_FIELDS),
|
|
141
|
-
instruction
|
|
142
|
-
})}`;
|
|
143
|
-
} else {
|
|
144
|
-
contextState = {
|
|
145
|
-
hasActiveForm: false,
|
|
146
|
-
progress: 0,
|
|
147
|
-
filledFields: [],
|
|
148
|
-
missingRequired: [],
|
|
149
|
-
uncertainFields: [],
|
|
150
|
-
nextField: null,
|
|
151
|
-
stashedCount: stashed.length,
|
|
152
|
-
pendingExternalFields: []
|
|
153
|
-
};
|
|
154
|
-
contextText = `form_context_json:
|
|
155
|
-
${compactJson({
|
|
156
|
-
active: false,
|
|
157
|
-
progress: 0,
|
|
158
|
-
stashed_count: stashed.length
|
|
159
|
-
})}`;
|
|
160
|
-
}
|
|
161
|
-
if (stashed.length > 0) {
|
|
162
|
-
stashedRows = stashed.slice(0, MAX_STASHED_FOR_CONTEXT).map((s) => {
|
|
163
|
-
const f = formService.getForm(s.formId);
|
|
164
|
-
const ctx = formService.getSessionContext(s);
|
|
165
|
-
return {
|
|
166
|
-
form_id: s.formId,
|
|
167
|
-
form_name: f?.name || s.formId,
|
|
168
|
-
progress: ctx.progress
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
contextText += `
|
|
172
|
-
stashed_forms_json:
|
|
173
|
-
${compactJson(stashedRows)}`;
|
|
174
|
-
contextText += "\nstashed_instruction: User can say resume to restore one.";
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
// Full context object for programmatic access
|
|
178
|
-
// WHY: Restore action and others read data.nextField, data.filledFields, etc.
|
|
179
|
-
data: JSON.parse(JSON.stringify(contextState)),
|
|
180
|
-
// String values for template substitution (e.g. in prompts: formContext, formProgress, formStatus)
|
|
181
|
-
values: {
|
|
182
|
-
formContext: contextText,
|
|
183
|
-
hasActiveForm: String(contextState.hasActiveForm),
|
|
184
|
-
formProgress: String(contextState.progress),
|
|
185
|
-
formStatus: contextState.status || "",
|
|
186
|
-
stashedCount: String(stashed.length)
|
|
187
|
-
},
|
|
188
|
-
// Human-readable text for agent (injected into prompt)
|
|
189
|
-
text: contextText
|
|
190
|
-
};
|
|
191
|
-
} catch (error) {
|
|
192
|
-
logger.error("[FormContextProvider] Error:", String(error));
|
|
193
|
-
return {
|
|
194
|
-
data: { hasActiveForm: false, error: true },
|
|
195
|
-
values: { formContext: 'form_context_json:\n{"error":true}' },
|
|
196
|
-
text: 'form_context_json:\n{"error":true}'
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
var context_default = formContextProvider;
|
|
202
|
-
export {
|
|
203
|
-
context_default as default,
|
|
204
|
-
formContextProvider
|
|
205
|
-
};
|
|
206
|
-
//# sourceMappingURL=context.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/context.ts"],"sourcesContent":["/**\n * @module providers/context\n * @description Form context provider for agent awareness\n *\n * ## Purpose\n *\n * This provider injects form state into the agent's context BEFORE\n * the agent generates a response. This allows the agent to:\n *\n * 1. Know if a form is active\n * 2. Know what required/optional fields we have vs don't have\n * 3. Know what needs confirmation (low-confidence extractions)\n * 4. Know what external actions are pending (payments, signatures, etc.)\n * 5. Get a single, coherent instruction (nudge for required, confirm, or submit)\n *\n * ## Output layout\n *\n * The text output uses a required/optional × have/don't-have layout so the\n * agent sees the full picture at a glance and can ask for one or several\n * missing fields in a single message (the form extracts and saves each).\n *\n * ## Context Output\n *\n * - `data`: Full FormContextState (programmatic access; e.g. restore action uses nextField)\n * - `values`: String values for template substitution (formContext, formProgress, etc.)\n * - `text`: Human-readable summary injected into the agent prompt\n *\n * ## How It Works\n *\n * ```\n * User Message → Provider Runs → Agent Gets Context → Agent Responds\n * ↓\n * FormContextState\n * ↓\n * - hasActiveForm, progress\n * - required/optional × have/don't have\n * - uncertainFields, pendingExternalFields\n * - single Instruction line\n * ```\n *\n * ## Stashed Forms\n *\n * If the user has stashed forms, the provider appends a reminder so the\n * agent can tell the user they have unfinished work and can say \"resume\".\n */\n\nimport type {\n IAgentRuntime,\n JsonValue,\n Memory,\n Provider,\n ProviderResult,\n State,\n UUID,\n} from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\nimport type { FormService } from \"../service\";\nimport {\n buildTemplateValues,\n renderTemplate,\n resolveControlTemplates,\n} from \"../template\";\nimport type { FormContextState } from \"../types\";\n\nfunction compactJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nconst MAX_CONTEXT_FIELDS = 20;\nconst MAX_STASHED_FOR_CONTEXT = 10;\n\n/**\n * Form Context Provider\n *\n * Injects the current form state into the agent's context,\n * allowing the agent to respond naturally about form progress\n * and nudge for missing fields (one or several at once).\n */\nexport const formContextProvider: Provider = {\n name: \"FORM_CONTEXT\",\n description: \"Provides context about active form sessions\",\n descriptionCompressed: \"Active form session context.\",\n contexts: [\"automation\", \"knowledge\"],\n contextGate: { anyOf: [\"automation\", \"knowledge\"] },\n cacheStable: false,\n cacheScope: \"turn\",\n\n /**\n * Get form context for the current message.\n *\n * @param runtime - Agent runtime for service access\n * @param message - The user message being processed\n * @param _state - Current agent state (unused)\n * @returns Provider result with form context (data, values, text)\n */\n get: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state: State,\n ): Promise<ProviderResult> => {\n try {\n // Get form service\n // WHY type cast: Runtime returns unknown, we know it's FormService\n const formService = runtime.getService(\"FORM\") as FormService;\n if (!formService) {\n // WHY early return: No form plugin registered or FORM service not available\n return {\n data: { hasActiveForm: false },\n values: { formContext: \"\" },\n text: \"\",\n };\n }\n\n // Get entity and room IDs\n // WHY UUID cast: Memory has these as unknown, we need proper typing for storage lookups\n const entityId = message.entityId as UUID;\n const roomId = message.roomId as UUID;\n if (!entityId || !roomId) {\n // WHY early return: Cannot look up session without identity and room\n return {\n data: { hasActiveForm: false },\n values: { formContext: \"\" },\n text: \"\",\n };\n }\n\n // Get active session for this room\n const session = await formService.getActiveSession(entityId, roomId);\n // Get stashed sessions (for \"you have saved forms\" prompt)\n const stashed = await formService.getStashedSessions(entityId);\n\n // If no active session and no stashed, nothing to provide\n if (!session && stashed.length === 0) {\n return {\n data: { hasActiveForm: false, stashedCount: 0 },\n values: { formContext: \"\" },\n text: \"\",\n };\n }\n\n let contextText = \"\";\n let contextState: FormContextState;\n let stashedRows: Array<Record<string, unknown>> = [];\n\n if (session) {\n // Build context for active session\n // Get session context from service\n // WHY: Service computes filledFields, missingRequired, uncertainFields, nextField from session + form definition\n contextState = formService.getSessionContext(session);\n const form = formService.getForm(session.formId);\n // Build template values from session (for {{placeholders}} in labels, askPrompt, etc.)\n const templateValues = buildTemplateValues(session);\n // WHY resolve: Form definitions may use {{variable}} in label, description, askPrompt; renderTemplate substitutes from session\n const resolve = (v?: string): string | undefined =>\n renderTemplate(v, templateValues);\n\n // Apply template resolution to all user-facing strings\n // WHY: Agent and user see resolved labels (e.g. \"{{discoveryQuestion1Text}}\" → actual question text)\n contextState = {\n ...contextState,\n filledFields: contextState.filledFields.map((f) => ({\n ...f,\n label: resolve(f.label) ?? f.label,\n })),\n missingRequired: contextState.missingRequired.map((f) => ({\n ...f,\n label: resolve(f.label) ?? f.label,\n description: resolve(f.description),\n askPrompt: resolve(f.askPrompt),\n })),\n uncertainFields: contextState.uncertainFields.map((f) => ({\n ...f,\n label: resolve(f.label) ?? f.label,\n })),\n nextField: contextState.nextField\n ? resolveControlTemplates(contextState.nextField, templateValues)\n : null,\n };\n // WHY nextField in data: Restore action reads contextState.nextField for \"Let's continue with X\"\n\n // Partition controls into required/optional × filled/missing\n // WHY four buckets: Agent needs full picture at a glance; can nudge for required and optionally for optional; can ask for one or bundle several\n const controls = form?.controls ?? [];\n const filledKeys = new Set(contextState.filledFields.map((f) => f.key));\n const controlByKey = new Map(controls.map((c) => [c.key, c]));\n\n const requiredFilled = contextState.filledFields.filter(\n (f) => controlByKey.get(f.key)?.required,\n );\n const optionalFilled = contextState.filledFields.filter(\n (f) => !controlByKey.get(f.key)?.required,\n );\n const optionalMissing = controls\n .filter((c) => !c.hidden && !c.required && !filledKeys.has(c.key))\n .map((c) => resolveControlTemplates(c, templateValues));\n\n let instruction = \"\";\n // Explicit agent guidance — single instruction field\n // WHY one instruction: Avoids conflicting guidance (e.g. \"ask next\" vs \"confirm\"); priority order matches UX\n if (contextState.pendingExternalFields.length > 0) {\n // We're waiting for external confirmation (payment, signature, etc.)\n const p = contextState.pendingExternalFields[0];\n instruction = `Waiting for external action. Remind user: \"${p.instructions}\"`;\n } else if (contextState.pendingCancelConfirmation) {\n // User wants to cancel a high-effort form; confirm before losing progress\n instruction =\n \"User is trying to cancel. Confirm they really want to lose progress.\";\n } else if (contextState.uncertainFields.length > 0) {\n // Need to confirm an uncertain value before we commit it\n const u = contextState.uncertainFields[0];\n instruction = `Ask user to confirm \"${u.label}\" = \"${u.value}\".`;\n } else if (contextState.missingRequired.length > 0) {\n // Nudge for required; user can give one or several answers in one message\n instruction =\n \"Nudge the user into helping complete required fields. The user can provide one or several answers in a single message.\";\n } else if (contextState.status === \"ready\") {\n // All required fields done; suggest submit\n instruction = \"All required fields collected. Nudge user to submit.\";\n } else if (optionalMissing.length > 0) {\n // Required done; optionally nudge for optional or submit\n instruction =\n \"Required fields are done. Optionally nudge for remaining optional fields, or nudge to submit.\";\n }\n\n contextText = `form_context_json:\\n${compactJson({\n active: true,\n form_id: session.formId,\n form_name: form?.name || session.formId,\n progress: contextState.progress,\n status: contextState.status,\n required_missing: contextState.missingRequired.slice(\n 0,\n MAX_CONTEXT_FIELDS,\n ),\n required_filled: requiredFilled.map((field) => ({\n ...field,\n value: field.displayValue,\n })).slice(0, MAX_CONTEXT_FIELDS),\n optional_missing: optionalMissing.slice(0, MAX_CONTEXT_FIELDS),\n optional_filled: optionalFilled.map((field) => ({\n ...field,\n value: field.displayValue,\n })).slice(0, MAX_CONTEXT_FIELDS),\n uncertain_fields: contextState.uncertainFields\n .slice(0, MAX_CONTEXT_FIELDS)\n .map((field) => ({\n ...field,\n confidence: Math.round(field.confidence * 100) / 100,\n })),\n pending_external_fields: contextState.pendingExternalFields.map(\n (field) => ({\n ...field,\n age_minutes: Math.max(\n 0,\n Math.floor((Date.now() - field.activatedAt) / 60000),\n ),\n }),\n ).slice(0, MAX_CONTEXT_FIELDS),\n instruction,\n })}`;\n } else {\n // No active session — only stashed forms exist\n // WHY build contextState anyway: Return shape is consistent; callers get hasActiveForm: false, stashedCount; stashed list goes in text below\n contextState = {\n hasActiveForm: false,\n progress: 0,\n filledFields: [],\n missingRequired: [],\n uncertainFields: [],\n nextField: null,\n stashedCount: stashed.length,\n pendingExternalFields: [],\n };\n contextText = `form_context_json:\\n${compactJson({\n active: false,\n progress: 0,\n stashed_count: stashed.length,\n })}`;\n }\n\n // Stashed forms reminder\n // WHY: User might have forgotten about saved forms; agent can say \"You have a saved form, say resume to continue\"\n if (stashed.length > 0) {\n stashedRows = stashed.slice(0, MAX_STASHED_FOR_CONTEXT).map((s) => {\n const f = formService.getForm(s.formId);\n const ctx = formService.getSessionContext(s);\n return {\n form_id: s.formId,\n form_name: f?.name || s.formId,\n progress: ctx.progress,\n };\n });\n contextText += `\\nstashed_forms_json:\\n${compactJson(stashedRows)}`;\n contextText +=\n \"\\nstashed_instruction: User can say resume to restore one.\";\n }\n\n return {\n // Full context object for programmatic access\n // WHY: Restore action and others read data.nextField, data.filledFields, etc.\n data: JSON.parse(JSON.stringify(contextState)) as Record<\n string,\n JsonValue\n >,\n // String values for template substitution (e.g. in prompts: formContext, formProgress, formStatus)\n values: {\n formContext: contextText,\n hasActiveForm: String(contextState.hasActiveForm),\n formProgress: String(contextState.progress),\n formStatus: contextState.status || \"\",\n stashedCount: String(stashed.length),\n },\n // Human-readable text for agent (injected into prompt)\n text: contextText,\n };\n } catch (error) {\n logger.error(\"[FormContextProvider] Error:\", String(error));\n // WHY return safe fallback: Provider failure should not break response generation; agent gets empty form context\n return {\n data: { hasActiveForm: false, error: true },\n values: { formContext: 'form_context_json:\\n{\"error\":true}' },\n text: 'form_context_json:\\n{\"error\":true}',\n };\n }\n },\n};\n\nexport default formContextProvider;\n"],"mappings":"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","names":[]}
|