Getting started
Install
go get github.com/pontus-devoteam/agent-sdk-go
The SDK requires Go 1.24 or newer and has no third party runtime dependencies.
Your first agent
package main
import (
"fmt"
"log"
"os"
"github.com/pontus-devoteam/agent-sdk-go/pkg/agent"
"github.com/pontus-devoteam/agent-sdk-go/pkg/model/providers/openai"
"github.com/pontus-devoteam/agent-sdk-go/pkg/runner"
)
func main() {
provider := openai.NewProvider(os.Getenv("OPENAI_API_KEY"))
provider.SetDefaultModel("gpt-4o-mini")
assistant := agent.NewAgent("Assistant")
assistant.SetModelProvider(provider)
assistant.WithModel("gpt-4o-mini")
assistant.SetSystemInstructions("You are a helpful assistant.")
r := runner.NewRunner()
r.WithDefaultProvider(provider)
result, err := r.RunSync(assistant, &runner.RunOptions{
Input: "Explain goroutines in two sentences.",
MaxTurns: 5,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.FinalOutput)
}
Adding tools
A tool is a Go function plus a JSON schema describing its parameters.
weatherTool := tool.NewFunctionTool(
"get_weather",
"Get the current weather for a city",
func(ctx context.Context, params map[string]interface{}) (interface{}, error) {
city, _ := params["city"].(string)
return fmt.Sprintf("It is sunny in %s.", city), nil
},
).WithSchema(map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"city": map[string]interface{}{
"type": "string",
"description": "The city to get the weather for",
},
},
"required": []string{"city"},
})
assistant.WithTools(weatherTool)
A tool without parameters is sent to the API as a function without a parameter schema, which every supported provider accepts.
Tools can also be created from OpenAI style definitions:
assistant.AddToolFromDefinition(definition, executeFn)
Streaming
stream, err := r.RunStreaming(ctx, assistant, &runner.RunOptions{Input: "Tell me a story"})
if err != nil {
log.Fatal(err)
}
for event := range stream.Stream {
switch event.Type {
case model.StreamEventTypeContent:
fmt.Print(event.Content)
case model.StreamEventTypeToolCall:
fmt.Printf("\n[calling %s]\n", event.ToolCall.Name)
case model.StreamEventTypeError:
log.Fatal(event.Error)
}
}
The model is resolved per turn, so a handoff during a streaming run switches to the model - and the provider - of the agent taking over.
Structured output
type WeatherReport struct {
City string `json:"city"`
Temperature float64 `json:"temperature"`
Condition string `json:"condition"`
}
assistant.WithOutputType(WeatherReport{})