Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 45 additions & 53 deletions cookbook/copilot-sdk/go/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,59 +18,56 @@ You need to handle various error conditions like connection failures, timeouts,
package main

import (
"context"
"fmt"
"log"
"github.com/github/copilot-sdk/go"
copilot "github.com/github/copilot-sdk/go"
)

func main() {
client := copilot.NewClient()
ctx := context.Background()
client := copilot.NewClient(nil)

if err := client.Start(); err != nil {
if err := client.Start(ctx); err != nil {
log.Fatalf("Failed to start client: %v", err)
}
defer func() {
if err := client.Stop(); err != nil {
log.Printf("Error stopping client: %v", err)
}
}()
defer client.Stop()

session, err := client.CreateSession(copilot.SessionConfig{
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-5",
})
if err != nil {
log.Fatalf("Failed to create session: %v", err)
}
defer session.Destroy()

responseChan := make(chan string, 1)
session.On(func(event copilot.Event) {
if msg, ok := event.(copilot.AssistantMessageEvent); ok {
responseChan <- msg.Data.Content
}
})

if err := session.Send(copilot.MessageOptions{Prompt: "Hello!"}); err != nil {
result, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
if err != nil {
log.Printf("Failed to send message: %v", err)
return
}

response := <-responseChan
fmt.Println(response)
if result != nil && result.Data.Content != nil {
fmt.Println(*result.Data.Content)
}
}
```

## Handling specific error types

```go
import (
"context"
"errors"
"fmt"
"os/exec"
copilot "github.com/github/copilot-sdk/go"
)

func startClient() error {
client := copilot.NewClient()
func startClient(ctx context.Context) error {
client := copilot.NewClient(nil)

if err := client.Start(); err != nil {
if err := client.Start(ctx); err != nil {
var execErr *exec.Error
if errors.As(err, &execErr) {
return fmt.Errorf("Copilot CLI not found. Please install it first: %w", err)
Expand All @@ -90,48 +87,41 @@ func startClient() error {
```go
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()

responseChan := make(chan string, 1)
errChan := make(chan error, 1)

session.On(func(event copilot.Event) {
if msg, ok := event.(copilot.AssistantMessageEvent); ok {
responseChan <- msg.Data.Content
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")
}
})

if err := session.Send(copilot.MessageOptions{Prompt: "Complex question..."}); err != nil {
return err
}

select {
case response := <-responseChan:
fmt.Println(response)
return nil
case err := <-errChan:
return err
case <-ctx.Done():
return fmt.Errorf("request timed out")
if result != nil && result.Data.Content != nil {
fmt.Println(*result.Data.Content)
}
return nil
}
```

## Aborting a request

```go
func abortAfterDelay(session *copilot.Session) {
// Start a request
session.Send(copilot.MessageOptions{Prompt: "Write a very long story..."})
func abortAfterDelay(ctx context.Context, session *copilot.Session) {
// Start a request (non-blocking send)
session.Send(ctx, copilot.MessageOptions{Prompt: "Write a very long story..."})

// Abort it after some condition
time.AfterFunc(5*time.Second, func() {
if err := session.Abort(); err != nil {
if err := session.Abort(ctx); err != nil {
log.Printf("Failed to abort: %v", err)
}
fmt.Println("Request aborted")
Expand All @@ -143,13 +133,18 @@ func abortAfterDelay(session *copilot.Session) {

```go
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"syscall"
copilot "github.com/github/copilot-sdk/go"
)

func main() {
client := copilot.NewClient()
ctx := context.Background()
client := copilot.NewClient(nil)

// Set up signal handling
sigChan := make(chan os.Signal, 1)
Expand All @@ -158,15 +153,11 @@ func main() {
go func() {
<-sigChan
fmt.Println("\nShutting down...")

if err := client.Stop(); err != nil {
log.Printf("Cleanup errors: %v", err)
}

client.Stop()
os.Exit(0)
}()

if err := client.Start(); err != nil {
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}

Expand All @@ -178,14 +169,15 @@ func main() {

```go
func doWork() error {
client := copilot.NewClient()
ctx := context.Background()
client := copilot.NewClient(nil)

if err := client.Start(); err != nil {
if err := client.Start(ctx); err != nil {
return fmt.Errorf("failed to start: %w", err)
}
defer client.Stop()

session, err := client.CreateSession(copilot.SessionConfig{Model: "gpt-5"})
session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"})
if err != nil {
return fmt.Errorf("failed to create session: %w", err)
}
Expand Down
42 changes: 25 additions & 17 deletions cookbook/copilot-sdk/go/managing-local-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,26 @@ You have a folder with many files and want to organize them into subfolders base
package main

import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"github.com/github/copilot-sdk/go"
copilot "github.com/github/copilot-sdk/go"
)

func main() {
ctx := context.Background()

// Create and start client
client := copilot.NewClient()
if err := client.Start(); err != nil {
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}
defer client.Stop()

// Create session
session, err := client.CreateSession(copilot.SessionConfig{
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-5",
})
if err != nil {
Expand All @@ -43,14 +46,20 @@ func main() {
defer session.Destroy()

// Event handler
session.On(func(event copilot.Event) {
switch e := event.(type) {
case copilot.AssistantMessageEvent:
fmt.Printf("\nCopilot: %s\n", e.Data.Content)
case copilot.ToolExecutionStartEvent:
fmt.Printf(" → Running: %s\n", e.Data.ToolName)
case copilot.ToolExecutionCompleteEvent:
fmt.Printf(" ✓ Completed: %s\n", e.Data.ToolName)
session.On(func(event copilot.SessionEvent) {
switch event.Type {
case "assistant.message":
if event.Data.Content != nil {
fmt.Printf("\nCopilot: %s\n", *event.Data.Content)
}
case "tool.execution_start":
if event.Data.ToolName != nil {
fmt.Printf(" → Running: %s\n", *event.Data.ToolName)
}
case "tool.execution_complete":
if event.Data.ToolName != nil {
fmt.Printf(" ✓ Completed: %s\n", *event.Data.ToolName)
}
}
})

Expand All @@ -69,11 +78,10 @@ Analyze the files in "%s" and organize them into subfolders.
Please confirm before moving any files.
`, targetFolder)

if err := session.Send(copilot.MessageOptions{Prompt: prompt}); err != nil {
_, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: prompt})
if err != nil {
log.Fatal(err)
}

session.WaitForIdle()
}
```

Expand Down Expand Up @@ -116,7 +124,7 @@ Analyze files in "%s" and show me how you would organize them
by file type. DO NOT move any files - just show me the plan.
`, targetFolder)

session.Send(copilot.MessageOptions{Prompt: prompt})
session.SendAndWait(ctx, copilot.MessageOptions{Prompt: prompt})
```

## Custom grouping with AI analysis
Expand All @@ -134,7 +142,7 @@ Consider:
Propose folder names that are descriptive and useful.
`, targetFolder)

session.Send(copilot.MessageOptions{Prompt: prompt})
session.SendAndWait(ctx, copilot.MessageOptions{Prompt: prompt})
```

## Safety considerations
Expand Down
32 changes: 17 additions & 15 deletions cookbook/copilot-sdk/go/multiple-sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,49 @@ You need to run multiple conversations in parallel, each with its own context an
package main

import (
"context"
"fmt"
"log"
"github.com/github/copilot-sdk/go"
copilot "github.com/github/copilot-sdk/go"
)

func main() {
client := copilot.NewClient()
ctx := context.Background()
client := copilot.NewClient(nil)

if err := client.Start(); err != nil {
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}
defer client.Stop()

// Create multiple independent sessions
session1, err := client.CreateSession(copilot.SessionConfig{Model: "gpt-5"})
session1, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"})
if err != nil {
log.Fatal(err)
}
defer session1.Destroy()

session2, err := client.CreateSession(copilot.SessionConfig{Model: "gpt-5"})
session2, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"})
if err != nil {
log.Fatal(err)
}
defer session2.Destroy()

session3, err := client.CreateSession(copilot.SessionConfig{Model: "claude-sonnet-4.5"})
session3, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "claude-sonnet-4.5"})
if err != nil {
log.Fatal(err)
}
defer session3.Destroy()

// Each session maintains its own conversation history
session1.Send(copilot.MessageOptions{Prompt: "You are helping with a Python project"})
session2.Send(copilot.MessageOptions{Prompt: "You are helping with a TypeScript project"})
session3.Send(copilot.MessageOptions{Prompt: "You are helping with a Go project"})
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.Send(copilot.MessageOptions{Prompt: "How do I create a virtual environment?"})
session2.Send(copilot.MessageOptions{Prompt: "How do I set up tsconfig?"})
session3.Send(copilot.MessageOptions{Prompt: "How do I initialize a module?"})
session1.Send(ctx, copilot.MessageOptions{Prompt: "How do I create a virtual environment?"})
session2.Send(ctx, copilot.MessageOptions{Prompt: "How do I set up tsconfig?"})
session3.Send(ctx, copilot.MessageOptions{Prompt: "How do I initialize a module?"})
}
```

Expand All @@ -67,7 +69,7 @@ func main() {
Use custom IDs for easier tracking:

```go
session, err := client.CreateSession(copilot.SessionConfig{
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: "user-123-chat",
Model: "gpt-5",
})
Expand All @@ -81,7 +83,7 @@ fmt.Println(session.SessionID) // "user-123-chat"
## Listing sessions

```go
sessions, err := client.ListSessions()
sessions, err := client.ListSessions(ctx)
if err != nil {
log.Fatal(err)
}
Expand All @@ -95,7 +97,7 @@ for _, sessionInfo := range sessions {

```go
// Delete a specific session
if err := client.DeleteSession("user-123-chat"); err != nil {
if err := client.DeleteSession(ctx, "user-123-chat"); err != nil {
log.Printf("Failed to delete session: %v", err)
}
```
Expand Down
Loading