Formulaires et confirmations

Les workflows conversationnels peuvent demander à l'utilisateur une entrée structurée : champs typés avec validation, choix unique ou multiple, téléchargement de fichiers, confirmations accepter/refuser. Utilisez FormInput pour les formulaires complets et ConfirmationInput / AcceptDeclineConfirmation pour les invites en un clic.

Entrées de formulaire structurées

Entrées de formulaire structurées

Pour les workflows nécessitant une entrée structurée avec champs typés, validation et rendu d'UI personnalisé, utilisez FormInput plutôt que ChatInput :

from datetime import date, datetime

import mistralai.workflows as workflows
import mistralai.workflows.plugins.mistralai as workflows_mistralai
from mistralai.workflows.conversational import (
    FormInput,
    TextField,
    NumberField,
    DateField,
    DateTimeField,
    SingleChoice,
)


class ExpenseForm(FormInput):
    """Structured form for expense submission."""

    description: str = TextField(description="Expense description")
    amount: float = NumberField(
        description="Amount in USD",
        minimum=0,
        maximum=10000,
    )
    category: str = SingleChoice(
        options=[
            ("travel", "Travel"),
            ("equipment", "Equipment"),
            ("software", "Software"),
        ],
        description="Expense category",
    )
    expense_date: date = DateField(description="Date of expense")
    due_date: datetime = DateTimeField(description="Reimbursement due date")
    receipt_id: str = TextField(
        description="Receipt ID",
        pattern=r"^RCP-\d{6}$",
    )


@workflows.workflow.define(
    name="expense-submission-workflow",
    workflow_display_name="Expense Submission",
    workflow_description="Submit an expense with structured form",
)
class ExpenseSubmissionWorkflow(workflows.InteractiveWorkflow):
    @workflows.workflow.entrypoint
    async def run(self) -> workflows_mistralai.ChatAssistantWorkflowOutput:
        expense = await self.wait_for_input(
            ExpenseForm,
            label="Submit Expense",
        )

        result = f"""Expense submitted:
- Description: {expense.description}
- Amount: ${expense.amount:.2f}
- Category: {expense.category}
- Date: {expense.expense_date.isoformat()}
- Due date: {expense.due_date.isoformat()}
- Receipt: {expense.receipt_id}"""

        return workflows_mistralai.ChatAssistantWorkflowOutput(
            content=[workflows_mistralai.TextOutput(text=result)]
        )
Un champ de formulaire structuré affiché dans Vibe Work.
Un champ de formulaire structuré affiché dans Vibe Work.
Types de champs

Types de champs

Type de champDescriptionPropriétés
TextFieldChamp textedescription, pattern (regex optionnelle), prefilled_value
NumberFieldChamp numériquedescription, minimum, maximum, exclusive_minimum, exclusive_maximum, prefilled_value
DateTimeFieldSélecteur de date/heuredescription, prefilled_value (chaîne de date/heure au format ISO 8601)
DateFieldSélecteur de datedescription, prefilled_value (chaîne de date au format ISO 8601)
SingleChoiceListe déroulante/unique choixoptions (liste de tuples ou chaînes), description, prefilled_value
MultiChoiceChoix multiplesoptions (liste de tuples ou chaînes), description, prefilled_value
FileFieldTéléchargement de fichierdescription, multiple (par défaut False), include_metadata (par défaut False)

Tous les types de champs (sauf FileField) prennent en charge un paramètre optionnel prefilled_value. Il s'agit uniquement d'une indication UI : il préremplit le champ de formulaire mais ne le rend pas optionnel. La valeur doit toujours être explicitement soumise par l'utilisateur. Les valeurs préremplies non valides (hors limites, motif non correspondant, option inconnue) sont ignorées silencieusement.

TextField

TextField

name: str = TextField(description="Your name", prefilled_value="John Doe")
email: str = TextField(
    description="Email address",
    pattern=r"^[\w.-]+@[\w.-]+\.\w+$",  # Optional regex validation
)
Un champ texte affiché dans Vibe Work.
Champ texte dans Vibe Work.
NumberField

NumberField

amount: float = NumberField(
    description="Amount",
    minimum=0,           # Inclusive minimum
    maximum=10000,       # Inclusive maximum
    prefilled_value=100,   # Pre-filled value
)
price: float = NumberField(
    description="Price",
    exclusive_minimum=0,   # Must be greater than 0
    exclusive_maximum=100, # Must be less than 100
)
Un champ numérique affiché dans Vibe Work.
Champ numérique dans Vibe Work.
DateTimeField

DateTimeField

from datetime import datetime

scheduled_at: datetime = DateTimeField(
    description="Schedule date and time",
    prefilled_value="2025-01-15T10:00:00Z",  # ISO 8601 datetime string
)
Un champ de sélection de date/heure affiché dans Vibe Work.
Champ date/heure dans Vibe Work.
DateField

DateField

from datetime import date

scheduled_at: date = DateField(
    description="Schedule date",
    prefilled_value="2025-01-15",  # ISO 8601 date string
)
Un champ de sélection de date affiché dans Vibe Work.
Champ date dans Vibe Work.
SingleChoice

SingleChoice

# With labels (value, display_label)
priority: str = SingleChoice(
    options=[
        ("low", "Low Priority"),
        ("medium", "Medium Priority"),
        ("high", "High Priority"),
    ],
    description="Select priority",
    prefilled_value="medium",  # Pre-selected option
)

# Simple string options (value = label)
status: str = SingleChoice(
    options=["pending", "approved", "rejected"],
    description="Status",
)
Une liste déroulante à choix unique affichée dans Vibe Work, avec des options de priorité.
Une liste déroulante à choix unique affichée dans Vibe Work, avec des options de statut.
Champ à choix unique dans Vibe Work.
MultiChoice

MultiChoice

# With labels (value, display_label)
tags: list[str] = MultiChoice(
    options=[
        ("frontend", "Frontend"),
        ("backend", "Backend"),
        ("infra", "Infrastructure"),
    ],
    description="Select applicable tags",
    prefilled_value=["frontend"],  # Pre-selected options
)

# Simple string options (value = label)
colors: list[str] = MultiChoice(
    options=["red", "green", "blue"],
    description="Pick colors",
)
Un champ à choix multiples affiché dans Vibe Work, avec des options de tags.
Un champ à choix multiples affiché dans Vibe Work, avec des options de couleurs.
Champ à choix multiples dans Vibe Work.
FileField

FileField

from mistralai.workflows.conversational import FileField, FileWithMetadataValue

# Single file upload (plain URL)
document: str = FileField(description="Upload a document")

# Multiple file uploads (plain URLs)
attachments: list[str] = FileField(description="Upload files", multiple=True)

# Single file upload with metadata
document: FileWithMetadataValue = FileField(description="Upload a document", include_metadata=True)

# Multiple file uploads with metadata
attachments: list[FileWithMetadataValue] = FileField(
    description="Upload files", multiple=True, include_metadata=True
)
Un champ de téléchargement de fichier unique affiché dans Vibe Work.
Un champ de téléchargement de fichiers multiples affiché dans Vibe Work, avec les fichiers joints.
Champ de téléchargement de fichier dans Vibe Work.

Par défaut, le workflow reçoit des URL (chaînes) pointant vers les fichiers téléchargés par l'utilisateur. Avec include_metadata=True, il reçoit des objets FileWithMetadataValue à la place :

ChampTypeObligatoireDescription
filenamestrOuiNom de fichier original
urlstrOuiURL signée pour télécharger le fichier
content_typestrOuiType MIME du fichier

Ces URL peuvent expirer : si votre workflow a besoin d’un accès à long terme aux fichiers, il est responsable de leur stockage ailleurs.

Entrées de confirmation

Entrées de confirmation

Pour les workflows nécessitant une confirmation simple par choix unique avec validation directe, utilisez ConfirmationInput ou AcceptDeclineConfirmation. Ces aides créent un formulaire à un seul champ où la sélection d’une option soumet immédiatement le formulaire.

ConfirmationInput

ConfirmationInput

ConfirmationInput propose une liste d’options devant être affichées sous forme de boutons. La sélection d’une option doit soumettre immédiatement le formulaire :

import mistralai.workflows as workflows
import mistralai.workflows.plugins.mistralai as workflows_mistralai


@workflows.workflow.define(
    name="type-selection-workflow",
    workflow_display_name="Type Selection",
    workflow_description="Select your favorite type",
)
class TypeSelectionWorkflow(workflows.InteractiveWorkflow):
    @workflows.workflow.entrypoint
    async def run(self) -> workflows_mistralai.ChatAssistantWorkflowOutput:
        await workflows_mistralai.send_assistant_message("Let's find out your type preference!")

        selection = await self.wait_for_input(
            workflows_mistralai.ConfirmationInput(
                options=[
                    ("fire", "Fire"),
                    ("water", "Water"),
                    ("grass", "Grass"),
                    ("electric", "Electric"),
                ],
                description="What is your favorite type?",
            )
        )

        selected_type = selection.choice  # Returns the value, e.g., "fire"
        return workflows_mistralai.ChatAssistantWorkflowOutput(
            content=[workflows_mistralai.TextOutput(text=f"You selected {selected_type}!")]
        )
Une entrée de confirmation affichée dans Vibe Work, avec des boutons pour chaque option.
Entrée de confirmation dans Vibe Work.
PropriétéTypeDescription
optionslist[tuple[str, str]] ou list[str]Liste d’options sous forme de tuples (valeur, libellé) ou de chaînes simples
descriptionstrDescription affichée au-dessus des options

L’objet retourné contient une propriété choice avec la valeur de l’option sélectionnée.

AcceptDeclineConfirmation

AcceptDeclineConfirmation

AcceptDeclineConfirmation est une confirmation spécialisée avec deux options : accepter et refuser. Les clients peuvent l’afficher comme une interface de validation standard avec des raccourcis clavier pour des réponses rapides :

import mistralai.workflows as workflows
import mistralai.workflows.plugins.mistralai as workflows_mistralai


@workflows.workflow.define(
    name="approval-workflow",
    workflow_display_name="Approval",
    workflow_description="Confirm an action",
)
class ApprovalWorkflow(workflows.InteractiveWorkflow):
    @workflows.workflow.entrypoint
    async def run(self) -> workflows_mistralai.ChatAssistantWorkflowOutput:
        confirmation = await self.wait_for_input(
            workflows_mistralai.AcceptDeclineConfirmation(
                description="Do you want to proceed with this action?",
                accept_label="Yes, proceed",
                decline_label="Cancel",
            )
        )

        if workflows_mistralai.is_accepted(confirmation):
            return workflows_mistralai.ChatAssistantWorkflowOutput(
                content=[workflows_mistralai.TextOutput(text="Action confirmed!")]
            )
        else:
            return workflows_mistralai.ChatAssistantWorkflowOutput(
                content=[workflows_mistralai.TextOutput(text="Action cancelled.")]
            )
Une confirmation accepter/refuser affichée dans Vibe Work, avec deux boutons pour accepter et refuser.
Confirmation accepter/refuser dans Vibe Work.
PropriétéTypeDescription
descriptionstrDescription affichée au-dessus des boutons
accept_labelstrLibellé du bouton Accepter
decline_labelstrLibellé du bouton Refuser

Utilisez la fonction auxiliaire is_accepted() pour vérifier si l’utilisateur a accepté ou refusé :

if workflows_mistralai.is_accepted(confirmation):
    # User accepted
    pass
else:
    # User declined
    pass