Sagents.Middleware.AskUserQuestion (Sagents v0.8.0-rc.7)

Copy Markdown

Middleware that gives agents a structured way to ask the user questions.

Provides an ask_user tool that triggers the existing interrupt/resume lifecycle with typed question and response data. This enables UIs to render appropriate controls (radio buttons, checkboxes, text inputs) based on the question type.

Configuration

# All response types (default)
Sagents.Middleware.AskUserQuestion

# Restricted to specific types
{Sagents.Middleware.AskUserQuestion, response_types: [:single_select, :multi_select]}

Response Types

  • :single_select - User picks one option from a list (radio buttons)
  • :multi_select - User picks one or more options (checkboxes)
  • :freeform - User provides free-form text input

Interrupt Data

When the agent calls ask_user, execution returns:

{:interrupt, state, %{
  type: :ask_user_question,
  question: "Which database should we use?",
  response_type: :single_select,
  options: [
    %{label: "PostgreSQL", value: "postgresql", description: "Relational DB"},
    %{label: "MongoDB", value: "mongodb", description: "Document store"}
  ],
  allow_other: false,
  allow_cancel: true,
  context: "We need a primary data store for the user service.",
  tool_call_id: "call_123"
}}

Resume Data

Resume with a response map:

# Answer
AgentServer.resume(agent_id, %{type: :answer, selected: ["postgresql"]})

# Answer with additional text
AgentServer.resume(agent_id, %{
  type: :answer,
  selected: ["postgresql"],
  other_text: "Use jsonb columns"
})

# Cancel
AgentServer.resume(agent_id, %{type: :cancel})

Summary

Functions

Process a user's response to a question.

Functions

process_response(response, question_data)

Process a user's response to a question.

Called by handle_resume/4 to validate the response and format it as human-readable text for the LLM.

Returns

  • {:ok, formatted_text} - Valid response, formatted for the LLM
  • {:error, reason} - Invalid response