How to Use Pure Function Calling with Caller Handling
This tutorial demonstrates how to implement "pure" function calling in ChatBotKit, where functions are defined without handlers or static results, giving the caller complete control over function execution.
Learning Objectives
By the end of this tutorial, you will be able to:
- Define pure functions without handlers or result configurations
- Implement a manual conversation loop for full control
- Handle the
activityend reason to detect function calls - Construct response activity messages manually
- Build complex workflows with external function execution
Prerequisites
- Node.js 18+ installed
- A ChatBotKit account with an API secret
- Understanding of async/await and conversation flows
Estimated time: 25 minutes
Understanding Pure Functions
ChatBotKit supports three approaches to function results:
| Approach | Configuration | Execution |
|---|---|---|
| Static | result.data | Server returns data immediately |
| Channel | result.channel | Caller publishes via channel |
| Pure | No result property | Caller handles everything |
With pure functions, when the AI calls a function, the conversation ends with end.reason: 'activity'. You then:
- Inspect the function call
- Execute the function externally
- Construct a response activity message
- Continue the conversation
This pattern is ideal for:
- Complex orchestration or approval workflows
- Human-in-the-loop scenarios
- Persisting function calls to external systems
- Running functions in different processes or services
Step 1: Set Up Your Project
Create a new Node.js project:
Create a .env file:
CHATBOTKIT_API_SECRET=your_api_secret_here
Step 2: Define Pure Functions
Create index.js and define functions without a result property:
Step 3: Set Up the Conversation
Initialize the client and messages:
Step 4: Implement the Manual Conversation Loop
Create a loop that handles function calls manually:
Step 5: Handle Function Calls
When the conversation ends with activity, extract and execute the function:
Step 6: Implement Function Execution
Create the function that executes your business logic:
Complete Example
Here's the complete working example:
Activity Message Structure
The response activity message must follow this structure:
Important: The
resultfield must be a JSON string, not an object.
Use Cases for Pure Functions
Human-in-the-Loop Approval
External Service Execution
Audit Logging
Troubleshooting
Infinite Loop
Always set a maxIterations limit and check the end reason to break out of the loop appropriately.
Missing Activity Data
Ensure you check lastMessage.type === 'activity' and activity.type === 'request' before accessing function data.
Result Not a String
The result field in the response activity must be a JSON string. Use JSON.stringify().
Next Steps
- Learn about channel-based function calling
- Explore background processing with dispatch
- Build multi-agent systems