Info Gatherer

View as Markdown

Prefab Agents

Prefabs are pre-built agent archetypes for common use cases. Use them directly or extend them to quickly build information gatherers, FAQ bots, surveys, receptionists, and concierges.

What Are Prefabs?

Prefabs are ready-to-use agent classes that implement common conversational patterns:

PrefabDescription
InfoGathererCollect answers to a series of questions
FAQBotAnswer questions from a knowledge base
SurveyConduct automated surveys with validation
ReceptionistGreet callers and transfer to departments
ConciergeProvide information and booking assistance

Why Use Prefabs?

  • Faster Development: Pre-built conversation flows
  • Best Practices: Proven patterns for common scenarios
  • Extensible: Inherit and customize as needed
  • Production-Ready: Includes validation, error handling, summaries

Quick Examples

InfoGatherer

1from signalwire_agents.prefabs import InfoGathererAgent
2
3agent = InfoGathererAgent(
4 questions=[
5 {"key_name": "name", "question_text": "What is your name?"},
6 {"key_name": "email", "question_text": "What is your email?", "confirm": True},
7 {"key_name": "reason", "question_text": "How can I help you?"}
8 ]
9)
10agent.run()

FAQBot

1from signalwire_agents.prefabs import FAQBotAgent
2
3agent = FAQBotAgent(
4 faqs=[
5 {"question": "What are your hours?", "answer": "We're open 9 AM to 5 PM."},
6 {"question": "Where are you located?", "answer": "123 Main Street, Downtown."}
7 ]
8)
9agent.run()

Survey

1from signalwire_agents.prefabs import SurveyAgent
2
3agent = SurveyAgent(
4 survey_name="Customer Satisfaction",
5 questions=[
6 {"id": "rating", "text": "Rate your experience?", "type": "rating", "scale": 5},
7 {"id": "feedback", "text": "Any comments?", "type": "open_ended", "required": False}
8 ]
9)
10agent.run()

Receptionist

1from signalwire_agents.prefabs import ReceptionistAgent
2
3agent = ReceptionistAgent(
4 departments=[
5 {"name": "sales", "description": "Product inquiries", "number": "+15551234567"},
6 {"name": "support", "description": "Technical help", "number": "+15551234568"}
7 ]
8)
9agent.run()

Concierge

1from signalwire_agents.prefabs import ConciergeAgent
2
3agent = ConciergeAgent(
4 venue_name="Grand Hotel",
5 services=["room service", "spa", "restaurant"],
6 amenities={
7 "pool": {"hours": "7 AM - 10 PM", "location": "2nd Floor"},
8 "gym": {"hours": "24 hours", "location": "3rd Floor"}
9 }
10)
11agent.run()

Chapter Contents

SectionDescription
InfoGathererCollect information through questions
FAQBotAnswer frequently asked questions
SurveyConduct automated surveys
ReceptionistGreet and transfer callers
ConciergeProvide venue information and services

Importing Prefabs

1# Import individual prefabs
2from signalwire_agents.prefabs import InfoGathererAgent
3from signalwire_agents.prefabs import FAQBotAgent
4from signalwire_agents.prefabs import SurveyAgent
5from signalwire_agents.prefabs import ReceptionistAgent
6from signalwire_agents.prefabs import ConciergeAgent
7
8# Or import all
9from signalwire_agents.prefabs import (
10 InfoGathererAgent,
11 FAQBotAgent,
12 SurveyAgent,
13 ReceptionistAgent,
14 ConciergeAgent
15)

Extending Prefabs

All prefabs inherit from AgentBase, so you can extend them:

1from signalwire_agents.prefabs import FAQBotAgent
2from signalwire_agents.core.function_result import SwaigFunctionResult
3
4class MyFAQBot(FAQBotAgent):
5 def __init__(self):
6 super().__init__(
7 faqs=[
8 {"question": "What is your return policy?", "answer": "30-day returns."}
9 ]
10 )
11
12 # Add custom prompt sections
13 self.prompt_add_section("Brand", "You represent Acme Corp.")
14
15 # Add custom functions
16 self.define_tool(
17 name="escalate",
18 description="Escalate to human agent",
19 parameters={"type": "object", "properties": {}},
20 handler=self.escalate
21 )
22
23 def escalate(self, args, raw_data):
24 return SwaigFunctionResult("Transferring to agent...").connect("+15551234567")

Basic Usage

1from signalwire_agents.prefabs import InfoGathererAgent
2
3agent = InfoGathererAgent(
4 questions=[
5 {"key_name": "full_name", "question_text": "What is your full name?"},
6 {"key_name": "email", "question_text": "What is your email address?", "confirm": True},
7 {"key_name": "reason", "question_text": "How can I help you today?"}
8 ]
9)
10
11if __name__ == "__main__":
12 agent.run()

Question Format

FieldTypeRequiredDescription
key_namestringYesIdentifier for storing the answer
question_textstringYesThe question to ask the user
confirmbooleanNoIf true, confirm answer before next

Constructor Parameters

1InfoGathererAgent(
2 questions=None, # List of question dictionaries
3 name="info_gatherer", # Agent name
4 route="/info_gatherer", # HTTP route
5 **kwargs # Additional AgentBase arguments
6)

Flow Diagram

InfoGatherer Flow.
InfoGatherer Flow

Built-in Functions

InfoGatherer provides these SWAIG functions automatically:

FunctionDescription
start_questionsBegin the question sequence
submit_answerSubmit answer and get next question

Dynamic Questions

Instead of static questions, use a callback to determine questions at runtime:

1from signalwire_agents.prefabs import InfoGathererAgent
2
3
4def get_questions(query_params, body_params, headers):
5 """Dynamically determine questions based on request"""
6 question_set = query_params.get('type', 'default')
7
8 if question_set == 'support':
9 return [
10 {"key_name": "name", "question_text": "What is your name?"},
11 {"key_name": "issue", "question_text": "Describe your issue."},
12 {"key_name": "urgency", "question_text": "How urgent is this?"}
13 ]
14 else:
15 return [
16 {"key_name": "name", "question_text": "What is your name?"},
17 {"key_name": "message", "question_text": "How can I help?"}
18 ]
19
20
21# Create agent without static questions
22agent = InfoGathererAgent()
23
24# Set the callback for dynamic questions
25agent.set_question_callback(get_questions)
26
27if __name__ == "__main__":
28 agent.run()

Accessing Collected Data

The collected answers are stored in global_data:

1# In a SWAIG function or callback:
2global_data = raw_data.get("global_data", {})
3answers = global_data.get("answers", [])
4
5# answers is a list like:
6# [
7# {"key_name": "full_name", "answer": "John Doe"},
8# {"key_name": "email", "answer": "john@example.com"},
9# {"key_name": "reason", "answer": "Product inquiry"}
10# ]

Complete Example

1#!/usr/bin/env python3
2# appointment_scheduler.py - Info gatherer for scheduling appointments
3from signalwire_agents.prefabs import InfoGathererAgent
4
5
6agent = InfoGathererAgent(
7 questions=[
8 {"key_name": "name", "question_text": "What is your name?"},
9 {"key_name": "phone", "question_text": "What is your phone number?", "confirm": True},
10 {"key_name": "date", "question_text": "What date would you like to schedule?"},
11 {"key_name": "time", "question_text": "What time works best for you?"},
12 {"key_name": "notes", "question_text": "Any special notes or requests?"}
13 ],
14 name="appointment-scheduler"
15)
16
17# Add custom language
18agent.add_language("English", "en-US", "rime.spore")
19
20# Customize prompt
21agent.prompt_add_section(
22 "Brand",
23 "You are scheduling appointments for Dr. Smith's office."
24)
25
26if __name__ == "__main__":
27 agent.run()

Best Practices

Questions

  • Keep questions clear and specific
  • Use confirm=true for critical data (email, phone)
  • Limit to 5-7 questions max per session
  • Order from simple to complex

key_name Values

  • Use descriptive, unique identifiers
  • snake_case convention recommended
  • Match your backend/database field names

Dynamic Questions

  • Use callbacks for multi-purpose agents
  • Validate questions in callback
  • Handle errors gracefully