Skip to main content

Form Submit

Workflow Type: Form Submit AI Workflow​

Form Submit workflows are triggered when users fill out a form. Perfect for content generation, data processing, and user-initiated tasks.

Use Case: Story Generator​

Users submit a genre, description, and optional inspiration document, and the workflow generates a complete story in a Word document.

Here is how a Form Submit AI workflow looks like:

Form Submit Agent

Step 1: Create the Story Generator Function​

This function accepts form inputs and generates a story document.


from abacusai import (
ApiClient,
AgentInterface,
AgentResponse,
WorkflowGraph,
WorkflowGraphNode,
WorkflowNodeInputMapping,
WorkflowNodeInputSchema,
WorkflowNodeInputType,
WorkflowNodeOutputMapping,
WorkflowNodeOutputSchema,
WorkflowNodeOutputType,
)

def story_generator(genre_type, description, inspiration=None):
"""
Generates a story based on inspiration document, genre, and description.

Args:
genre_type (str): Selected genre for the story
description (str): Description of the story to be generated
inspiration (Blob, optional): Uploaded document containing inspiration material

Returns:
AgentResponse: Contains the generated story as a Word document
"""
# ALL imports inside the function
from abacusai import AgentResponse, ApiClient, Blob
from docx import Document
import io

client = ApiClient()

# Notify user of progress (streaming messages)
client.stream_message("Processing inspiration document...")

# Extract text from uploaded document (if provided)
inspiration_text = ""
if inspiration:
try:
# Try advanced extraction with OCR
extracted_doc_data = client.extract_document_data(
inspiration.contents,
document_processing_config={
"extract_bounding_boxes": False,
"ocr_mode": "AUTO",
"use_full_ocr": True,
},
)
inspiration_text = extracted_doc_data.extracted_text
except:
# Fallback to basic extraction
extracted_doc_data = client.extract_document_data(inspiration.contents)
inspiration_text = extracted_doc_data.embedded_text

client.stream_message("Generating story based on your inputs...")

# Create detailed prompt for story generation
prompt = f"""
Create an engaging and well-structured story based on the following inputs:

GENRE: {genre_type}
DESCRIPTION: {description}
INSPIRATION MATERIAL: {(inspiration_text[:5000] if inspiration_text else 'No inspiration material provided')}

Please write a complete story that:
- Follows the conventions of the {genre_type} genre
- Incorporates elements from the description provided
- Draws inspiration from the provided material (if any)
- Has a clear beginning, middle, and end
- Is approximately 1500-2500 words
- Includes engaging dialogue and descriptive scenes
"""

system_message = f"""You are a professional creative writer specializing in {genre_type} stories.
Create an original, captivating story that incorporates the user's requirements while maintaining
high literary quality. Use vivid descriptions, compelling characters, and engaging plot development
appropriate for the {genre_type} genre."""

# Generate story using LLM
story_response = client.evaluate_prompt(
prompt=prompt,
system_message=system_message,
llm_name="CLAUDE_V3_5_SONNET" # High-quality creative writing model
)
generated_story = story_response.content

client.stream_message("Creating Word document...")

# Create Word document
doc = Document()

# Add title
title = doc.add_heading(f"Generated {genre_type} Story", 0)

# Add metadata
doc.add_heading("Story Details", level=1)
doc.add_paragraph(f"Genre: {genre_type}")
doc.add_paragraph(f"Description: {description}")
doc.add_paragraph("")

# Add story content
doc.add_heading("Story", level=1)
story_paragraphs = generated_story.split("\n\n")
for paragraph in story_paragraphs:
if paragraph.strip():
doc.add_paragraph(paragraph.strip())

# Save document to bytes
doc_buffer = io.BytesIO()
doc.save(doc_buffer)
doc_bytes = doc_buffer.getvalue()

# Return as Blob (file download)
return AgentResponse(
story_document=Blob(
doc_bytes,
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
filename=f"{genre_type.lower().replace(' ', '_')}_story.docx",
)
)

Key Concepts:

  • client.stream_message(): Send real-time updates to the user
  • Blob: Wrapper for file data (documents, images, etc.)
  • extract_document_data(): OCR and text extraction from PDFs/Word docs

Step 2: Create Node with Input Schema​

For form-based workflows, you define an input_schema to create the user interface.

from abacusai import WorkflowNodeInputSchema, WorkflowNodeOutputSchema

story_generator_node = WorkflowGraphNode(
"Story Generator",
story_generator,

# Define the input form
input_schema=WorkflowNodeInputSchema(
json_schema={
"type": "object",
"title": "Story Generator Inputs",
"required": ["genre_type", "description"], # Required fields
"properties": {
"genre_type": {
"enum": [ # Dropdown options
"Fantasy",
"Science Fiction",
"Mystery",
"Romance",
"Horror",
"Thriller",
"Adventure",
"Historical Fiction",
"Contemporary Fiction",
"Young Adult",
"Comedy",
"Drama",
],
"type": "string",
"title": "Story Genre",
"description": "Select the genre for your story",
},
"description": {
"type": "string",
"title": "Story Description",
"description": "Provide a brief description of the story you want to generate",
},
"inspiration": {
"type": "string",
"title": "Inspiration Document",
"format": "data-url", # File upload
"description": "Upload a PDF or Word document for inspiration (optional)",
},
},
},

# Define UI widgets
ui_schema={
"genre_type": {"ui:widget": "select"}, # Dropdown
"description": {"ui:widget": "textarea"}, # Multi-line text
"inspiration": {"ui:widget": "file"}, # File uploader
},
),

output_mappings=["story_document"],

# Define the output display
output_schema=WorkflowNodeOutputSchema(
json_schema={
"type": "object",
"title": "Generated Story",
"properties": {
"story_document": {
"type": "string",
"title": "Story Document",
"format": "data-url", # File download
"description": "Download your generated story",
}
},
}
),
)

Input Schema Breakdown:

PropertyTypeWidgetPurpose
genre_typestring (enum)selectDropdown menu
descriptionstringtextareaMulti-line input
inspirationstring (data-url)fileFile upload

Output Schema:

  • story_document: File download with format: "data-url"

Step 3: Build Workflow Graph​

agent_interface = AgentInterface.DEFAULT

workflow_graph = WorkflowGraph(
nodes=[story_generator_node],
specification_type="data_flow"
)

Note: Form submit workflows often have a single node since user input directly triggers the function.


Step 4: Register the Agent​

from abacusai import ApiClient

client = ApiClient()

agent = client.create_agent(
project_id='your_project_id',
workflow_graph=workflow_graph,
agent_interface=agent_interface,
description="AI-powered story generator with genre selection and document inspiration",
package_requirements=["python-docx"], # Required for Word document creation
)

agent.wait_for_publish()
print(f"Story generator agent created: {agent.agent_id}")

Key Differences:

  • agent_interface=AgentInterface.DEFAULT
  • package_requirements: Include python-docx for Word document generation
  • No connectors needed for this workflow