Go SDK Cookbook
Short, practical recipes for using the GitHub Copilot SDK with Go. Each recipe is concise, copy-pasteable, and points to complete runnable examples.
Setup
Install the GitHub Copilot SDK for Go:
go get github.com/github/copilot-sdk/go
Import in your code:
import copilot " github.com/github/copilot-sdk/go "
Error Handling
Handle errors gracefully including connection failures, timeouts, and cleanup.
Basic Error Handling
Basic Example
Specific Error Types
package main
import (
" context "
" fmt "
" log "
copilot " github.com/github/copilot-sdk/go "
)
func main () {
ctx := context . Background ()
client := copilot . NewClient ( nil )
if err := client . Start ( ctx ); err != nil {
log . Fatalf ( "Failed to start client: %v " , err )
}
defer client . Stop ()
session , err := client . CreateSession ( ctx , & copilot . SessionConfig {
Model : "gpt-5" ,
})
if err != nil {
log . Fatalf ( "Failed to create session: %v " , err )
}
defer session . Destroy ()
result , err := session . SendAndWait ( ctx , copilot . MessageOptions { Prompt : "Hello!" })
if err != nil {
log . Printf ( "Failed to send message: %v " , err )
return
}
if result != nil && result . Data . Content != nil {
fmt . Println ( * result . Data . Content )
}
}
Timeout Handling
import (
" context "
" errors "
" fmt "
" time "
copilot " github.com/github/copilot-sdk/go "
)
func sendWithTimeout ( session * copilot . Session ) error {
ctx , cancel := context . WithTimeout ( context . Background (), 30 * time . Second )
defer cancel ()
result , err := session . SendAndWait ( ctx , copilot . MessageOptions { Prompt : "Complex question..." })
if err != nil {
if errors . Is ( err , context . DeadlineExceeded ) {
return fmt . Errorf ( "request timed out" )
}
return err
}
if result != nil && result . Data . Content != nil {
fmt . Println ( * result . Data . Content )
}
return nil
}
Graceful Shutdown
import (
" context "
" fmt "
" log "
" os "
" os/signal "
" syscall "
copilot " github.com/github/copilot-sdk/go "
)
func main () {
ctx := context . Background ()
client := copilot . NewClient ( nil )
// Set up signal handling
sigChan := make ( chan os . Signal , 1 )
signal . Notify ( sigChan , os . Interrupt , syscall . SIGTERM )
go func () {
<- sigChan
fmt . Println ( " \n Shutting down..." )
client . Stop ()
os . Exit ( 0 )
}()
if err := client . Start ( ctx ); err != nil {
log . Fatal ( err )
}
// ... do work ...
}
Always use defer client.Stop() to ensure cleanup happens even when errors occur. Go’s defer mechanism makes resource cleanup reliable and concise.
Multiple Sessions
Manage multiple independent conversations simultaneously.
package main
import (
" context "
" fmt "
" log "
copilot " github.com/github/copilot-sdk/go "
)
func main () {
ctx := context . Background ()
client := copilot . NewClient ( nil )
if err := client . Start ( ctx ); err != nil {
log . Fatal ( err )
}
defer client . Stop ()
// Create multiple independent sessions
session1 , _ := client . CreateSession ( ctx , & copilot . SessionConfig { Model : "gpt-5" })
session2 , _ := client . CreateSession ( ctx , & copilot . SessionConfig { Model : "gpt-5" })
session3 , _ := client . CreateSession ( ctx , & copilot . SessionConfig { Model : "claude-sonnet-4.5" })
defer session1 . Destroy ()
defer session2 . Destroy ()
defer session3 . Destroy ()
// Each session maintains its own conversation history
session1 . Send ( ctx , copilot . MessageOptions { Prompt : "You are helping with a Python project" })
session2 . Send ( ctx , copilot . MessageOptions { Prompt : "You are helping with a TypeScript project" })
session3 . Send ( ctx , copilot . MessageOptions { Prompt : "You are helping with a Go project" })
// Follow-up messages stay in their respective contexts
session1 . SendAndWait ( ctx , copilot . MessageOptions { Prompt : "How do I create a virtual environment?" })
session2 . SendAndWait ( ctx , copilot . MessageOptions { Prompt : "How do I set up tsconfig?" })
session3 . SendAndWait ( ctx , copilot . MessageOptions { Prompt : "How do I initialize a module?" })
fmt . Println ( "All sessions completed" )
}
Custom Session IDs
session , err := client . CreateSession ( ctx , & copilot . SessionConfig {
SessionID : "user-123-chat" ,
Model : "gpt-5" ,
})
if err != nil {
log . Fatal ( err )
}
fmt . Printf ( "Session ID: %s \n " , session . SessionID )
Use Cases
Multi-User Apps One session per user with custom session IDs
Parallel Processing Run multiple AI tasks concurrently
Model Comparison Compare outputs from different models
Session Persistence
Save and resume sessions across application restarts.
import (
" context "
" encoding/json "
" os "
copilot " github.com/github/copilot-sdk/go "
)
func saveSession ( session * copilot . Session ) error {
state := session . GetState ()
data , err := json . Marshal ( state )
if err != nil {
return err
}
return os . WriteFile ( "session.json" , data , 0644 )
}
func restoreSession ( ctx context . Context , client * copilot . Client ) ( * copilot . Session , error ) {
data , err := os . ReadFile ( "session.json" )
if err != nil {
return nil , err
}
var state copilot . SessionState
if err := json . Unmarshal ( data , & state ); err != nil {
return nil , err
}
return client . CreateSession ( ctx , & copilot . SessionConfig {
Model : "gpt-5" ,
State : & state ,
})
}
Session persistence is useful for long-running workflows or when you need to maintain conversation context between application restarts.
Deferred Cleanup Pattern
Go’s defer makes resource cleanup elegant:
func doWork () error {
ctx := context . Background ()
client := copilot . NewClient ( nil )
if err := client . Start ( ctx ); err != nil {
return fmt . Errorf ( "failed to start: %w " , err )
}
defer client . Stop ()
session , err := client . CreateSession ( ctx , & copilot . SessionConfig { Model : "gpt-5" })
if err != nil {
return fmt . Errorf ( "failed to create session: %w " , err )
}
defer session . Destroy ()
// ... do work ...
return nil
}
Running Examples
All complete, runnable examples are available in the cookbook/copilot-sdk/go/recipe directory.
Navigate to the recipe directory
cd cookbook/copilot-sdk/go/recipe
Run any example
go run error-handling.go
go run multiple-sessions.go
go run persisting-sessions.go
Best Practices
Always Use defer for Cleanup
Use defer to ensure Stop() and Destroy() are called, maintaining Go’s resource cleanup idioms. defer client . Stop ()
defer session . Destroy ()
The Copilot CLI might not be installed. Check for specific error types. var execErr * exec . Error
if errors . As ( err , & execErr ) {
return fmt . Errorf ( "CLI not found: %w " , err )
}
Use context.WithTimeout for all long-running requests. ctx , cancel := context . WithTimeout ( context . Background (), 30 * time . Second )
defer cancel ()
Use fmt.Errorf with %w to preserve error chains for debugging. return fmt . Errorf ( "failed to create session: %w " , err )
Additional Recipes
Explore more advanced recipes in the source repository:
Resources