.d8888b. 888888b. 888 d8P
d88P Y88b 888 "88b 888 d8P
888 888 888 .88P 888 d8P
888 8888888K. 888d88K
888 888 "Y88b 8888888b
888 888 888 888 888 Y88b
Y88b d88P 888 d88P 888 Y88b
"Y8888P" 8888888P" 888 Y88b .ai
The official Go SDK for ChatBotKit - a platform for building and deploying conversational AI applications. With ChatBotKit you can create bots and agents with custom data, skillsets, and integrations while keeping AI orchestration on the ChatBotKit platform.
Build lighter, future-proof AI agents. When you build with ChatBotKit, the heavy lifting happens on our servers, not in your application. This architectural advantage delivers:
🪶 Lightweight Agents: Your agents stay lean because complex AI processing, model orchestration, and tool execution happen server-side. Less code in your app means faster load times and simpler maintenance.
🛡️ Robust & Streamlined: Server-side processing provides a more reliable experience with built-in error handling, automatic retries, and consistent behavior across all platforms.
🔄 Backward & Forward Compatible: As AI technology evolves with new models, new capabilities, and new paradigms, your agents automatically benefit. No code changes required on your end.
🔮 Future-Proof: Agents you build today will remain capable tomorrow. When we add support for new AI models or capabilities, your existing agents gain those powers without any updates to your codebase.
This means you can focus on building great user experiences while ChatBotKit handles the complexity of the ever-changing AI landscape.
go get github.com/chatbotkit/go-sdkpackage main
import (
"context""fmt""log""github.com/chatbotkit/go-sdk/agent""github.com/chatbotkit/go-sdk/sdk"
)
funcmain() {
// Create a client with your API keyclient:=sdk.New(sdk.Options{
Secret: "your-api-key",
})
// Run a simple conversationresult, err:=agent.Complete(context.Background(), client, agent.CompleteOptions{
Model: "gpt-4o",
Messages: []agent.Message{
{Type: "user", Text: "Hello! Tell me a joke."},
},
})
iferr!=nil {
log.Fatal(err)
}
fmt.Println(result.Text)
}go.mod # Single Go module
├── sdk/ # Main SDK client
│ └── integration/ # Integration clients (Widget, Slack, Discord, WhatsApp, Telegram, Messenger, Instagram, Notion, Sitemap, Support, Extract, Trigger, Twilio, Email, McpServer, Teams, GoogleChat)
├── agent/ # Agent execution functionality
├── types/ # Generated API types
└── internal/httpclient/ # Internal HTTP client with streaming support
The main sdk package provides access to all ChatBotKit API resources:
client:=sdk.New(sdk.Options{
Secret: "your-api-key",
BaseURL: "https://api.chatbotkit.com", // optionalRunAsUserID: "user-id", // optionalTimezone: "America/New_York", // optional
})
// Access resourcesclient.Bot// Bot managementclient.Conversation// Conversation managementclient.Dataset// Dataset managementclient.Skillset// Skillset managementclient.File// File managementclient.Contact// Contact managementclient.Secret// Secret managementclient.Channel// Channel operationsclient.Blueprint// Blueprint managementclient.Graphql// GraphQL operationsclient.Integration// Integration managementclient.Integration.Widget// Widget integrationsclient.Integration.Slack// Slack integrationsclient.Integration.Discord// Discord integrationsclient.Integration.WhatsApp// WhatsApp integrationsclient.Integration.Telegram// Telegram integrationsclient.Integration.Messenger// Messenger integrationsclient.Integration.Instagram// Instagram integrationsclient.Integration.Notion// Notion integrationsclient.Integration.Sitemap// Sitemap integrationsclient.Integration.Support// Support integrationsclient.Integration.Extract// Extract integrationsclient.Integration.Trigger// Trigger integrationsclient.Integration.Trigger.Execution// Trigger execution managementclient.Integration.Twilio// Twilio integrationsclient.Integration.Email// Email integrationsclient.Integration.McpServer// MCP server integrationsclient.Integration.Microsoftteams// Microsoft Teams integrationsclient.Integration.GoogleChat// Google Chat integrationsclient.Memory// Memory managementclient.Partner// Partner operationsclient.Platform// Platform content and catalogue accessclient.Policy// Policy managementclient.Portal// Portal managementclient.Team// Team managementclient.Task// Task managementclient.Task.Execution// Task execution managementclient.Usage// Usage reportingclient.Space// Space managementclient.Event// Event log accessclient.Event.Log// Event log operationsclient.Magic// Magic AI generationclient.Magic.Prompt// Magic prompt templates// List botsbots, err:=client.Bot.List(ctx, nil)
// Fetch a botbot, err:=client.Bot.Fetch(ctx, "bot-id")
// Create a botbot, err:=client.Bot.Create(ctx, types.BotCreateRequest{
Name: "My Bot",
Description: "A helpful assistant",
Backstory: "You are a friendly AI assistant.",
})
// Update a botbot, err:=client.Bot.Update(ctx, "bot-id", types.BotUpdateRequest{
Name: "Updated Bot Name",
})
// Delete a botresp, err:=client.Bot.Delete(ctx, "bot-id")// Create a conversationconv, err:=client.Conversation.Create(ctx, types.ConversationCreateRequest{})
// List conversationsconvs, err:=client.Conversation.List(ctx, nil)
// Continue an existing conversationresp, err:=client.Conversation.Complete(ctx, "conversation-id", types.ConversationCompleteRequest{
Text: "Hello!",
})
// Or use the stateless endpoint with empty conversation IDresp, err:=client.Conversation.Complete(ctx, "", types.ConversationCompleteRequest{
Text: "Hello!",
})// Create a datasetdataset, err:=client.Dataset.Create(ctx, types.DatasetCreateRequest{
Name: "Knowledge Base",
})
// Add a recordrecord, err:=client.Dataset.Record.Create(ctx, "dataset-id", types.DatasetRecordCreateRequest{
Text: "Important information...",
})
// Search the datasetresults, err:=client.Dataset.Search(ctx, "dataset-id", types.DatasetSearchRequest{
Text: "search query",
})The agent package provides high-level functionality for running AI agents:
Run a single conversation completion:
result, err:=agent.Complete(ctx, client, agent.CompleteOptions{
Model: "gpt-4o",
Backstory: "You are a helpful assistant.",
Messages: []agent.Message{
{Type: "user", Text: "What is 2+2?"},
},
})Run a multi-turn agent execution:
result, err:=agent.Execute(ctx, client, agent.ExecuteOptions{
Model: "gpt-4o",
Backstory: "You are a task completion agent.",
MaxIterations: 10,
Messages: []agent.Message{
{Type: "user", Text: "Write a haiku about programming."},
},
})
for_, response:=rangeresult.Responses {
fmt.Println(response)
}
fmt.Printf("Exit: %d - %s\n", result.Exit.Code, result.Exit.Message)Run a conversation with custom tool handlers that execute when the AI calls them:
// Define your toolstools:= agent.Tools{
"get_weather": {
Description: "Get the current weather for a location",
Parameters: agent.FunctionParameters{
"properties": map[string]any{
"location": map[string]any{"type": "string", "description": "The city name"},
"unit": map[string]any{
"type": "string",
"description": "Temperature unit",
"enum": []string{"celsius", "fahrenheit"},
},
},
"required": []string{"location"},
},
Handler: func(ctx context.Context, argsmap[string]interface{}) (interface{}, error) {
location, ok:=args["location"].(string)
if!ok {
returnnil, fmt.Errorf("location is required")
}
returnmap[string]interface{}{
"temperature": 72,
"location": location,
}, nil
},
},
}
// Stream with tool supportevents, errs:=agent.CompleteWithTools(ctx, client, agent.CompleteWithToolsOptions{
Model: "gpt-4o",
Backstory: "You are a helpful assistant with access to tools.",
Messages: messages,
Tools: tools,
})
// Process events including tool callsforevent:=rangeevents {
switche:=event.(type) {
case agent.TokenAgentEvent:
fmt.Print(e.Token)
case agent.ToolCallStartEvent:
fmt.Printf("[Calling %s...]\n", e.Name)
case agent.ToolCallEndEvent:
fmt.Printf("[%s returned: %v]\n", e.Name, e.Result)
case agent.ToolCallErrorEvent:
fmt.Printf("[%s error: %s]\n", e.Name, e.Error)
}
}Run an autonomous agent task with built-in planning, progress tracking, and exit control:
events, errs:=agent.ExecuteWithTools(ctx, client, agent.ExecuteWithToolsOptions{
Model: "gpt-4o",
Backstory: "You are an autonomous task executor.",
MaxIterations: 20,
Messages: []agent.Message{
{Type: "user", Text: "Research and summarize the topic..."},
},
Tools: tools, // Your custom tools
})
// Process eventsforevent:=rangeevents {
switche:=event.(type) {
case agent.IterationEvent:
fmt.Printf("=== Iteration %d ===\n", e.Iteration)
case agent.TokenAgentEvent:
fmt.Print(e.Token)
case agent.ToolCallStartEvent:
fmt.Printf("[Calling %s...]\n", e.Name)
case agent.AgentExitEvent:
fmt.Printf("Exit: code=%d, message=%s\n", e.Code, e.Message)
}
}The ExecuteWithTools function automatically includes three system tools:
- plan: Create or update a task execution plan
- progress: Track completed steps and current status
- exit: Exit the execution with a status code
For stateful execution, create a conversation first and then pass ConversationID plus an optional initial Text. Once the first iteration has sent the user prompt, omit Text on later iterations so the server continues from the existing conversation state.
The Go examples named stateless-agent and stateful-agent are agent-package examples built on agent.CompleteWithTools. They are intentionally different from the higher-level ExecuteWithTools flow and from the Node SDK *-agentic-loop examples, which use the lower-level conversation client directly.
model:="gpt-4o"conversation, err:=client.Conversation.Create(ctx, types.ConversationCreateRequest{
Model: &model,
})
iferr!=nil {
log.Fatal(err)
}
prompt:="What is the weather in San Francisco and what time is it in Los Angeles?"events, errs:=agent.CompleteWithTools(ctx, client, agent.CompleteWithToolsOptions{
ConversationID: conversation.ID,
Text: &prompt,
Tools: tools,
})
forevent:=rangeevents {
_=event
}
iferr:=<-errs; err!=nil {
log.Fatal(err)
}
events, errs=agent.CompleteWithTools(ctx, client, agent.CompleteWithToolsOptions{
ConversationID: conversation.ID,
Tools: tools,
})Load skills from local directories and pass them as a feature to the agent. Skills are defined using SKILL.md files with front matter containing name and description.
// Load skills from directoriesskillsResult, err:=agent.LoadSkills([]string{"./skills"})
iferr!=nil {
log.Fatal(err)
}
// Create the skills feature for the APIskillsFeature:=agent.CreateSkillsFeature(skillsResult.Skills)
// Use in API calls via extensions.featuresevents, errs:=agent.CompleteWithTools(ctx, client, agent.CompleteWithToolsOptions{
Model: "gpt-4o",
Backstory: "You are a helpful assistant.",
Messages: messages,
Tools: tools,
// Pass skillsFeature to the API via extensions
})
// Reload skills when neededskillsResult.Reload()Create a SKILL.md file in each skill directory:
---name: My Skilldescription: A brief description of what this skill does---# My Skill
Additional documentation for the skill...skillsResult, err:=agent.LoadSkills([]string{"./skills"})Skills can be baked into the binary at compile time using Go's embed package:
//go:embed skillsvarskillsFS embed.FSsubFS, _:=fs.Sub(skillsFS, "skills")
skillsResult, err:=agent.LoadSkillsFromFS(subFS)LoadSkillsFromFS accepts any fs.FS, so it works with embed.FS, os.DirFS, or any custom implementation.
LoadSkills(directories)- Load skills from OS directories containing SKILL.md filesLoadSkillsFromFS(fsys)- Load skills from anyfs.FS, includingembed.FSCreateSkillsFeature(skills)- Create a feature map for the APIGetSkills()- Get a thread-safe copy of loaded skillsReload()- Rescan the source for skill changes
The SDK provides a set of default tools for common file and shell operations:
// Get the default toolstools:=agent.DefaultTools()
// Available tools:// - read: Read file contents with optional line ranges// - write: Write or modify file contents// - edit: Replace exact string occurrences in files// - exec: Execute shell commands with timeoutevents, errs:=agent.ExecuteWithTools(ctx, client, agent.ExecuteWithToolsOptions{
Model: "gpt-4o",
Backstory: "You are an autonomous agent.",
Messages: []agent.Message{
{Type: "user", Text: "Create a file called hello.txt with 'Hello World'"},
},
Tools: tools,
MaxIterations: 20,
})You can also combine default tools with custom tools:
tools:=agent.DefaultTools()
tools["my_custom_tool"] = agent.ToolDefinition{
Description: "My custom tool",
Parameters: agent.FunctionParameters{"properties": map[string]any{...}},
Handler: myHandler,
}The SDK supports streaming responses for real-time processing of AI responses. This is useful for showing tokens as they arrive or processing events incrementally.
events, errs:=client.Conversation.CompleteStream(ctx, conversationID, types.ConversationCompleteRequest{
Text: "Tell me a story",
})
// Process events as they arriveforevent:=rangeevents {
switchevent.Type {
case"token":
// A partial token has arrivedfmt.Print(".")
case"result":
// The final resultfmt.Println("\nDone!")
}
}
// Check for errors after the stream closesiferr:=<-errs; err!=nil {
log.Fatal(err)
}events, errs:=agent.CompleteStream(ctx, client, agent.CompleteOptions{
Model: "gpt-4o",
Messages: []agent.Message{
{Type: "user", Text: "Write a poem"},
},
})
forevent:=rangeevents {
// Process streaming eventsfmt.Printf("Event type: %s\n", event.Type)
}
iferr:=<-errs; err!=nil {
log.Fatal(err)
}| Method | Description |
|---|---|
Conversation.CompleteStream | Stream a conversation completion |
Conversation.SendStream | Stream a send message operation |
Conversation.ReceiveStream | Stream a receive message operation |
agent.CompleteStream | Stream agent completion |
agent.CompleteWithTools | Stream agent completion with tool execution |
agent.ExecuteWithTools | Stream autonomous agent execution with tools |
The types package contains all API request and response types, auto-generated from the OpenAPI specification:
import"github.com/chatbotkit/go-sdk/types"// Request typesreq:= types.BotCreateRequest{
Name: "My Bot",
Description: "Description",
}
// Response typesvarresp types.BotCreateResponseTo regenerate the types from the latest API spec:
cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package typesAPI errors are returned with a message and code:
bot, err:=client.Bot.Fetch(ctx, "invalid-id")
iferr!=nil {
// Error includes message and optional code from the APIfmt.Printf("Error: %v\n", err)
}| Option | Description |
|---|---|
Secret | API authentication token (required) |
BaseURL | Custom API base URL |
RunAsUserID | Execute requests as a specific user |
Timezone | Timezone for timestamp handling |
- Go 1.21 or later
Versions are published as Git tags - for a Go module, the tag is the release.
The version is driven by the VERSION file:
- Bump
VERSION(semver, novprefix - e.g.0.2.0) in a pull request. - Merge to
main. TheTag Releaseworkflow readsVERSIONand, if the matchingvX.Y.Ztag does not yet exist, creates and pushes it, then triggers theReleaseworkflow to publish GitHub release notes.
Consumers then pin the new version:
go get github.com/chatbotkit/go-sdk@v0.2.0While the API is still evolving the module stays on v0.x (minor versions may
introduce breaking changes); it will move to v1.0.0 once the API is stable.
See LICENSE for details.