This example demonstrates a minimal multi-turn chat interface using the Runner orchestration component. It focuses on core functionality with an in-memory session backend, making it easy to understand and run.
This implementation showcases the essential features for building conversational AI applications:
- ๐ Multi-turn Conversations: Maintains context across multiple exchanges
- ๐ Flexible Output: Support for both streaming (real-time) and non-streaming (batch) response modes
- ๐พ Session Management: Conversation state preservation and continuity
- ๐ง Tool Integration: Working calculator and time tools with proper execution
- ๐ Simple Interface: Clean, focused chat experience
- Context Preservation: The assistant remembers previous conversation turns
- Flexible Response Modes: Choose between streaming (real-time) or non-streaming (batch) output
- Session Continuity: Consistent conversation state across the chat session
- Tool Call Execution: Proper execution and display of tool calling procedures
- Tool Visualization: Clear indication of tool calls, arguments, and responses
- Error Handling: Graceful error recovery and reporting
- Go 1.21 or later
- Valid OpenAI API key (or compatible API endpoint)
| Variable | Description | Default Value |
|---|---|---|
OPENAI_API_KEY |
API key for the openai model | `` |
OPENAI_BASE_URL |
Base URL for the openai model API endpoint | https://api.openai.com/v1 |
ANTHROPIC_AUTH_TOKEN |
API key for the anthropic model | `` |
ANTHROPIC_BASE_URL |
Base URL for the anthropic model API endpoint | https://api.anthropic.com |
| Argument | Description | Default Value |
|---|---|---|
-model |
Name of the model to use | deepseek-v4-flash |
-variant |
Variant to use when calling the OpenAI provider | openai |
-streaming |
Enable streaming mode for responses | true |
-enable-parallel |
Enable parallel tool execution (faster performance) | false |
cd examples/runner
export OPENAI_API_KEY="your-api-key-here"
go run .export OPENAI_API_KEY="your-api-key"
go run . -model gpt-4oexport OPENAI_API_KEY="your-api-key"
go run . -variant deepseekChoose between streaming and non-streaming responses:
# Default streaming mode (real-time character output)
go run .
# Non-streaming mode (complete response at once)
go run . -streaming=falseWhen to use each mode:
- Streaming mode (
-streaming=true, default): Best for interactive chat where you want to see responses appear in real-time, providing immediate feedback and better user experience. - Non-streaming mode (
-streaming=false): Better for automated scripts, batch processing, or when you need the complete response before processing it further.
Control how multiple tools are executed when the AI makes multiple tool calls:
# Default serial tool execution (safe and compatible)
go run .
# Parallel tool execution (faster performance)
go run . -enable-parallel=trueWhen to use each mode:
- Serial execution (default, no flag needed):
- ๐ Tools execute one by one in sequence
- ๐ก๏ธ Safe and compatible default behavior
- ๐ Better for debugging tool execution issues
- Parallel execution (
-enable-parallel=true):- โก faster performance when multiple tools are called
- โ Best for independent tools (calculator + time, weather + population)
- โ Tools execute simultaneously using goroutines
To see all available command line options:
go run . --helpOutput:
Usage of ./runner:
-enable-parallel
Enable parallel tool execution (default: false, serial execution)
-model string
Name of the model to use (default "deepseek-v4-flash")
-variant string
Name of the variant to use when calling the OpenAI provider (default "openai")
-streaming
Enable streaming mode for responses (default true)
The example includes two working tools:
- Function:
calculator - Operations: add, subtract, multiply, divide
- Usage: "Calculate 15 * 25" or "What's 100 divided by 7?"
- Arguments: operation (string), a (number), b (number)
- Function:
current_time - Timezones: UTC, EST, PST, CST, or local time
- Usage: "What time is it in EST?" or "Current time please"
- Arguments: timezone (optional string)
When you ask for calculations or time information, you'll see:
๐ง Tool calls initiated:
โข calculator (ID: call_abc123)
Args: {"operation":"multiply","a":25,"b":4}
๐ Executing tools...
โ
Tool response (ID: call_abc123): {"operation":"multiply","a":25,"b":4,"result":100}
๐ค Assistant: I calculated 25 ร 4 = 100 for you.
The interface is simple and intuitive:
๐ Runner quickstart: multi-turn chat with tools
Model: deepseek-v4-flash
Streaming: true
Parallel tools: false
Session backend: in-memory (simple demo)
Type '/exit' to end the conversation
Available tools: calculator, current_time
==================================================
โ
Chat ready! Session: demo-session-1703123456
๐ค You: Hello! How are you today?
๐ค Assistant: Hello! I'm doing well, thank you for asking. I'm here and ready to help you with whatever you need. How are you doing today?
๐ค You: I'm good! Can you remember what I just asked you?
๐ค Assistant: Yes, I can! You just asked me how I was doing today, and I responded that I'm doing well. This shows that I'm maintaining context from our conversation. Is there anything specific you'd like to chat about or any way I can help you?
๐ค You: /exit
๐ Goodbye!
- To end the chat loop cleanly, type
/exitand press Enter. - To stop the whole program at any time, press Ctrl+C.
- To stop a single running agent run safely in your own app, cancel the
context.Contextyou passed intoRunner.Run(do not just stop reading the event channel). See:examples/cancelrun(cancel via Enter/Ctrl+C, drain events)examples/managedrunner(cancel by requestID, detached cancellation)docs/mkdocs/en/runner.md(run control guide)
This example uses in-memory session storage for simplicity. This means:
- โ Fast and no external dependencies
- โ Perfect for development and testing
โ ๏ธ Session data is lost when the program exits
For production use with persistent session storage (Redis, PostgreSQL, MySQL), see the examples/session/ directory which demonstrates advanced session management features including:
- Multiple session backends (Redis, PostgreSQL, MySQL)
- Session switching with
/use <id>command - Session listing with
/sessionscommand - Creating new sessions with
/newcommand