Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ChatBotKitCBK.AIEmailDiscordGo ReferenceFollow on Twitter

 .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

ChatBotKit Go SDK

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.

Why ChatBotKit?

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.

Installation

go get github.com/chatbotkit/go-sdk

Quick Start

package 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)
}

SDK Structure

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

SDK Client

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

Resource Operations

Bots

// 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")

Conversations

// 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!",
})

Datasets

// 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",
})

Agent Package

The agent package provides high-level functionality for running AI agents:

Complete

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?"},
},
})

Execute

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)

Complete with Tools

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)
}
}

Execute with Tools

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,
})

Skills Loading

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()

SKILL.md Format

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

Loading from the filesystem

skillsResult, err:=agent.LoadSkills([]string{"./skills"})

Loading from an embedded filesystem

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.

Skills API

  • LoadSkills(directories) - Load skills from OS directories containing SKILL.md files
  • LoadSkillsFromFS(fsys) - Load skills from any fs.FS, including embed.FS
  • CreateSkillsFeature(skills) - Create a feature map for the API
  • GetSkills() - Get a thread-safe copy of loaded skills
  • Reload() - Rescan the source for skill changes

Default Tools

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,
}

Streaming

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.

Streaming with Conversation Client

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)
}

Streaming with Agent Package

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)
}

Available Streaming Methods

MethodDescription
Conversation.CompleteStreamStream a conversation completion
Conversation.SendStreamStream a send message operation
Conversation.ReceiveStreamStream a receive message operation
agent.CompleteStreamStream agent completion
agent.CompleteWithToolsStream agent completion with tool execution
agent.ExecuteWithToolsStream autonomous agent execution with tools

Types Package

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.BotCreateResponse

Regenerating Types

To regenerate the types from the latest API spec:

cd sites/main
pnpm script:generate-api-types --output ../../sdks/go/types/types.go --package types

Error Handling

API 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)
}

Configuration Options

OptionDescription
SecretAPI authentication token (required)
BaseURLCustom API base URL
RunAsUserIDExecute requests as a specific user
TimezoneTimezone for timestamp handling

Requirements

  • Go 1.21 or later

Releasing

Versions are published as Git tags - for a Go module, the tag is the release. The version is driven by the VERSION file:

  1. Bump VERSION (semver, no v prefix - e.g. 0.2.0) in a pull request.
  2. Merge to main. The Tag Release workflow reads VERSION and, if the matching vX.Y.Z tag does not yet exist, creates and pushes it, then triggers the Release workflow to publish GitHub release notes.

Consumers then pin the new version:

go get github.com/chatbotkit/go-sdk@v0.2.0

While 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.

License

See LICENSE for details.

About

Create conversational AI solutions with custom data and abilities using ChatBotKit for Go applications.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages