> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# InfoGatherer

> Collect answers to a series of questions with confirmation support, dynamic question callbacks, and structured data output using the InfoGatherer prefab agent.

InfoGatherer is a pre-built agent that collects answers to a series of questions. It handles the conversation flow automatically, including optional confirmation of critical answers and dynamic question selection.

### Basic Usage

#### Python

```python
from signalwire.prefabs import InfoGathererAgent

agent = InfoGathererAgent(
    questions=[
        {"key_name": "full_name", "question_text": "What is your full name?"},
        {"key_name": "email", "question_text": "What is your email address?", "confirm": True},
        {"key_name": "reason", "question_text": "How can I help you today?"}
    ]
)

if __name__ == "__main__":
    agent.run()
```

#### TypeScript

```typescript
import { InfoGathererAgent } from '@signalwire/sdk';

const agent = new InfoGathererAgent({
  questions: [
    { key_name: 'full_name', question_text: 'What is your full name?' },
    { key_name: 'email', question_text: 'What is your email address?', confirm: true },
    { key_name: 'reason', question_text: 'How can I help you today?' },
  ],
});

agent.run();
```

### Question Format

| Field           | Type    | Required | Description                         |
| --------------- | ------- | -------- | ----------------------------------- |
| `key_name`      | string  | Yes      | Identifier for storing the answer   |
| `question_text` | string  | Yes      | The question to ask the user        |
| `confirm`       | boolean | No       | If true, confirm answer before next |

### Constructor Parameters

```python
InfoGathererAgent(
    questions=None,           # List of question dictionaries
    name="info_gatherer",     # Agent name
    route="/info_gatherer",   # HTTP route
    **kwargs                  # Additional AgentBase arguments
)
```

### Importing InfoGathererAgent

| Language   | Import                                                |
| ---------- | ----------------------------------------------------- |
| Python     | `from signalwire.prefabs import InfoGathererAgent`    |
| TypeScript | `import { InfoGathererAgent } from '@signalwire/sdk'` |

### Flow Diagram

<img class="diagram" src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/signalwire.docs.buildwithfern.com/28dcc8e214a40644b008d27283c7efc4c39223cb190c10b8d7f05ff74f6b56ea/assets/images/sdks/diagrams/09_01_info-gatherer_diagram1.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260817%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260817T013810Z&X-Amz-Expires=604800&X-Amz-Signature=9c1086a387c9f1b8da9ae2373460ee3eb68d5e684f27075406d80f6b68f0bf30&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Diagram showing the InfoGatherer flow from question presentation through answer collection and confirmation." />

### Built-in Functions

InfoGatherer provides these SWAIG functions automatically:

| Function          | Description                         |
| ----------------- | ----------------------------------- |
| `start_questions` | Begin the question sequence         |
| `submit_answer`   | Submit answer and get next question |

### Dynamic Questions

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

```python
from signalwire.prefabs import InfoGathererAgent

def get_questions(query_params, body_params, headers):
    """Dynamically determine questions based on request"""
    question_set = query_params.get('type', 'default')

    if question_set == 'support':
        return [
            {"key_name": "name", "question_text": "What is your name?"},
            {"key_name": "issue", "question_text": "Describe your issue."},
            {"key_name": "urgency", "question_text": "How urgent is this?"}
        ]
    else:
        return [
            {"key_name": "name", "question_text": "What is your name?"},
            {"key_name": "message", "question_text": "How can I help?"}
        ]

# Create agent without static questions
agent = InfoGathererAgent()

# Set the callback for dynamic questions
agent.set_question_callback(get_questions)

if __name__ == "__main__":
    agent.run()
```

### Accessing Collected Data

The collected answers are stored in `global_data`:

```python
# In a SWAIG function or callback:
global_data = raw_data.get("global_data", {})
answers = global_data.get("answers", [])

# answers is a list like:
# [
#     {"key_name": "full_name", "answer": "John Doe"},
#     {"key_name": "email", "answer": "john@example.com"},
#     {"key_name": "reason", "answer": "Product inquiry"}
# ]
```

### Complete Example

```python
#!/usr/bin/env python3
# appointment_scheduler.py - Info gatherer for scheduling appointments
from signalwire.prefabs import InfoGathererAgent

agent = InfoGathererAgent(
    questions=[
        {"key_name": "name", "question_text": "What is your name?"},
        {"key_name": "phone", "question_text": "What is your phone number?", "confirm": True},
        {"key_name": "date", "question_text": "What date would you like to schedule?"},
        {"key_name": "time", "question_text": "What time works best for you?"},
        {"key_name": "notes", "question_text": "Any special notes or requests?"}
    ],
    name="appointment-scheduler"
)

# Add custom language
agent.add_language("English", "en-US", "rime.spore")

# Customize prompt
agent.prompt_add_section(
    "Brand",
    "You are scheduling appointments for Dr. Smith's office."
)

if __name__ == "__main__":
    agent.run()
```

### Implementation Notes

InfoGatherer uses `replace_in_history()` internally to keep the conversation history clean. Each question/answer exchange is replaced in the LLM history so that the conversation context stays focused and doesn't grow excessively with repetitive tool call entries. This is transparent to the user -- they experience a natural conversation flow.

### 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