Skip to Content
DocumentationBuilding with LoopstackοΈπŸ“„ DocumentsCreating Documents

Creating Documents

Documents are structured data containers in Loopstack that enable user input, data validation, and form rendering in the Loopstack Studio. They’re essential for capturing and displaying structured information within your workflows.

Creating a Document

A document is created by extending the DocumentBase class and decorating it with @BlockConfig and @WithArguments. Documents define their schema using Zod and optionally include UI configuration for form rendering.

Basic Document Definition

import { z } from 'zod'; import { DocumentBase } from '@loopstack/core'; import { BlockConfig, WithArguments } from '@loopstack/common'; import { Injectable } from '@nestjs/common'; export const TaskDocumentSchema = z.object({ title: z.string().min(1, "Title is required"), description: z.string().optional(), dueDate: z.string().datetime(), priority: z.enum(['low', 'medium', 'high']).default('medium'), assignees: z.array(z.string()).default([]), }); @Injectable() @BlockConfig({ configFile: __dirname + '/task.document.yaml', }) @WithArguments(TaskDocumentSchema) export class TaskDocument extends DocumentBase {}

Key Components

@Injectable() Decorator

  • Standard NestJS decorator that marks the class as injectable
  • Required for dependency injection within the framework

@BlockConfig Decorator

  • Links the document class to its YAML configuration via configFile
  • Defines metadata and configuration for the document

@WithArguments() Decorator

  • Defines the document schema and validation rules using a Zod schema
  • Replaces the inline properties definition from the previous version
  • Schema can be exported for reuse in workflows with @WithState

YAML Config

  • ui.form.order - Controls the display order of fields in the Studio
  • ui.form.properties - Defines how each field is rendered in the frontend
  • widget - Specifies the input type (text, textarea, select, date, etc.)
  • readonly - Makes fields display-only when set to true

Registering the Document

Documents are registered in workflows using the @Document() decorator and must be imported in your module.

import { z } from 'zod'; import { WorkflowBase } from '@loopstack/core'; import { BlockConfig, Document, Tool, WithArguments, WithState } from '@loopstack/common'; import { CreateDocument } from '@loopstack/core-ui-module'; import { TaskDocument, TaskDocumentSchema } from './documents/task.document'; import { Injectable } from '@nestjs/common'; @Injectable() @BlockConfig({ configFile: __dirname + '/task-workflow.yaml', }) @WithArguments(z.object({ userId: z.string(), })) @WithState(z.object({ task: TaskDocumentSchema, })) export class TaskWorkflow extends WorkflowBase { @Tool() createDocument: CreateDocument; @Document() taskDocument: TaskDocument; }

Using Documents in Workflows

Creating Document Instances

Use the createDocument tool to instantiate documents in your workflow:

title: "Task Management Workflow" description: A workflow for creating and managing tasks. transitions: - id: initialize_task from: start to: task_created call: - tool: createDocument args: id: task document: taskDocument update: content: title: "Review quarterly reports" description: "Analyze Q4 performance metrics" dueDate: "2025-12-31T23:59:59Z" priority: "high" assignees: ["alice@example.com", "bob@example.com"]

Using Template Variables

Documents can use workflow arguments and state variables with template syntax:

transitions: - id: create_personalized_task from: start to: task_created call: - tool: createDocument args: id: task document: taskDocument update: content: title: "Task for {{ args.userId }}" priority: "medium"

Storing Document Output in State

Use assign to store document data in workflow state for later use:

transitions: - id: generate_task from: start to: task_generated call: - tool: aiGenerateDocument args: llm: provider: openai model: gpt-4o response: document: taskDocument prompt: | Create a task for reviewing the quarterly report. assign: task: ${ result.data.content } - id: display_task from: task_generated to: end call: - tool: createDocument args: id: summary document: messageDocument update: content: role: assistant parts: - type: text text: | Created task: {{ task.title }} Due: {{ task.dueDate }}

Capturing User Input

Combine documents with manual transitions to collect user input through forms:

transitions: - id: display_form from: start to: awaiting_input call: - tool: createDocument args: id: taskForm document: taskDocument update: content: title: "" priority: "medium" - id: process_input from: awaiting_input to: task_saved when: manual call: - tool: createDocument args: id: savedTask document: taskDocument update: content: ${ transition.payload } assign: task: ${ result.data.content }

Complete Example

Here’s a full example showing a workflow that generates a code file using AI:

import { z } from 'zod'; import { DocumentBase } from '@loopstack/core'; import { BlockConfig, WithArguments } from '@loopstack/common'; import { Injectable } from '@nestjs/common'; export const FileDocumentSchema = z.object({ filename: z.string(), description: z.string().optional(), code: z.string(), }); @Injectable() @BlockConfig({ configFile: __dirname + '/file-document.yaml', }) @WithArguments(FileDocumentSchema) export class FileDocument extends DocumentBase {}

Available UI Widgets

Documents support various widget types for different data formats:

WidgetDescriptionBest For
textSingle-line text inputShort text, names, titles, email, url, numbers
textareaMulti-line text input with fixed heightDescriptions, notes, long text
textarea-expandMulti-line text input with expandable heightLong-form content that varies in length
selectDropdown selectionSingle choice from predefined options
radioRadio button groupSingle choice with visible options
checkboxBoolean checkboxYes/no, true/false values
switchToggle switchEnable/disable, on/off states
sliderNumeric sliderNumeric values within a defined range
code-viewCode display fieldRead-only code snippets or formatted text
Last updated on