> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ravenna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Forms

> Submit Ravenna request type and workflow forms directly in Microsoft Teams as interactive Adaptive Cards.

Ravenna forms render in Microsoft Teams as interactive Adaptive Cards. Users can submit a request type form to update a ticket, or trigger a workflow form to start an automation, without leaving Teams.

<View title="Human" icon="user">
  ## How forms appear

  When the Agent needs structured input from a user, it posts an Adaptive Card with the configured form fields, a **Submit** button, and a **Dismiss** button. The card replaces itself with a confirmation once submitted.

  Two form types are supported:

  * **Request type forms**: collect the fields configured on a Ravenna [request type](/documentation/tickets/forms/overview). Submitting updates the ticket's fields and publishes the ticket.
  * **Workflow trigger forms**: collect the inputs declared by a [workflow](/documentation/automate/workflows/overview) trigger. Submitting runs the workflow.

  ***

  ## Submitting a form

  <Steps>
    <Step title="Fill in the fields">
      Complete the inputs on the Adaptive Card. Required fields are validated by Teams before submission.
    </Step>

    <Step title="Click Submit">
      Ravenna processes the submission, updates the ticket or runs the workflow, and replaces the card with a confirmation.
    </Step>

    <Step title="Or dismiss">
      Click **Dismiss** if you don't want to submit. The card is replaced with a dismissed-state message and the ticket is not updated.
    </Step>
  </Steps>

  <Info>
    Form submissions are attributed to the Teams user who clicked Submit. Make sure they are a provisioned Ravenna user. Ravenna provisions on the fly via Microsoft Graph the first time someone interacts.
  </Info>
</View>

<View title="Agent" icon="bot">
  ## Mental model

  Form rendering is owned by `TeamsOutboundRenderer`. When the Agent emits a message of type `form` (request type or workflow), the renderer dispatches to the appropriate card builder:

  * `request_type_form` → an "Open form" dialog card (`buildRequestTypeOpenDialogCard`) whose button opens the Ravenna web form as a Teams task module (deep-linked to `/teams/forms/...`). The web form renders the fields and resolves the dynamic options.
  * `workflow_form` → an inline workflow trigger form card (`buildWorkflowTriggerFormCard`) with the trigger's input declarations.

  Both card types follow the same submission contract: a single `Action.Submit` button posts `activity.value` back to the bot with an `actionType` discriminator (`form_submit`, `workflow_form_submit`, or `form_dismiss`), and the form-submission handler routes accordingly.

  ***

  ## Submission flow

  1. The user clicks **Submit** on the Adaptive Card.
  2. Teams sends a `message` activity with no text but an `activity.value` payload containing the form state and `actionType`.
  3. `processFormSubmission` routes by `actionType`:
     * `form_submit` → `convertFlatFormStateToTicketFields` converts the flat Teams form state into Ravenna ticket fields; `FormService.submitForm` applies the fields and publishes the ticket.
     * `workflow_form_submit` → the `RunWorkflow` function triggers the configured workflow with the submitted inputs.
     * `form_dismiss` → the card is replaced with a dismissed-state confirmation.
  4. The card is replaced with a confirmation card showing the submitted values and a deep link back to the ticket.

  ***

  ## Approval forms

  Approval requests use the same submission plumbing but a dedicated `approvalCard` builder:

  * The card surfaces the ticket context and **Approve** / **Decline** buttons.
  * Declining reveals an optional reason input before final submission.
  * Submission posts `activity.value.actionType = 'approval_approve' | 'approval_decline'` plus the decline reason; the handler updates the approval round via `ApprovalService`.

  Approval cards are sent as DMs to each approver when they are added to a round, so they fire without an existing channel conversation.

  ***

  ## Field resolution

  For request-type forms, dynamic options are resolved inside the embedded Ravenna web form rather than baked into the card server-side:

  * **Workspace members**: for assignee / requester / approver fields, the web form resolves the eligible member set so the dropdown is populated.
  * **Applications**: for application-typed fields, the web form resolves the configured application options.

  Resolving inside the web form lets the form support parent/child field dependencies and keeps option data out of the posted card.

  ***

  ## Constraints and gotchas

  * Adaptive Card form fields are limited to the input types Teams supports. Ravenna field types that don't have a 1:1 mapping degrade to the closest supported input.
  * Once submitted, the card is replaced. There's no in-place edit of the submitted card. Users must edit the ticket directly to change values after submission.
  * The `actionType` discriminator on `activity.value` is required for the form-submission router. Custom cards added later must follow the same convention.
  * **Conversational form-fill via the Agent is still being validated on Teams.** The Agent may escalate without rendering the configured request-type form in some flows. Use the explicit form-card flow above as the reliable path until this is finalized.
</View>
