copilot

package module
v0.1.15-preview.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 20, 2026 License: MIT Imports: 16 Imported by: 0

README

Copilot CLI SDK for Go

A Go SDK for programmatic access to the GitHub Copilot CLI.

Note: This SDK is in technical preview and may change in breaking ways.

Installation

go get github.com/github/copilot-sdk/go

Quick Start

package main

import (
    "fmt"
    "log"

    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    // Create client
    client := copilot.NewClient(&copilot.ClientOptions{
        LogLevel: "error",
    })

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

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

    // Set up event handler
    done := make(chan bool)
    session.On(func(event copilot.SessionEvent) {
        if event.Type == "assistant.message" {
            if event.Data.Content != nil {
                fmt.Println(*event.Data.Content)
            }
        }
        if event.Type == "session.idle" {
            close(done)
        }
    })

    // Send a message
    _, err = session.Send(copilot.MessageOptions{
        Prompt: "What is 2+2?",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Wait for completion
    <-done
}

API Reference

Client
  • NewClient(options *ClientOptions) *Client - Create a new client
  • Start() error - Start the CLI server
  • Stop() []error - Stop the CLI server (returns array of errors, empty if all succeeded)
  • ForceStop() - Forcefully stop without graceful cleanup
  • CreateSession(config *SessionConfig) (*Session, error) - Create a new session
  • ResumeSession(sessionID string) (*Session, error) - Resume an existing session
  • ResumeSessionWithOptions(sessionID string, config *ResumeSessionConfig) (*Session, error) - Resume with additional configuration
  • GetState() ConnectionState - Get connection state
  • Ping(message string) (*PingResponse, error) - Ping the server

ClientOptions:

  • CLIPath (string): Path to CLI executable (default: "copilot" or COPILOT_CLI_PATH env var)
  • CLIUrl (string): URL of existing CLI server (e.g., "localhost:8080", "http://127.0.0.1:9000", or just "8080"). When provided, the client will not spawn a CLI process.
  • Cwd (string): Working directory for CLI process
  • Port (int): Server port for TCP mode (default: 0 for random)
  • UseStdio (bool): Use stdio transport instead of TCP (default: true)
  • LogLevel (string): Log level (default: "info")
  • AutoStart (*bool): Auto-start server on first use (default: true). Use Bool(false) to disable.
  • AutoRestart (*bool): Auto-restart on crash (default: true). Use Bool(false) to disable.
  • Env ([]string): Environment variables for CLI process (default: inherits from current process)

ResumeSessionConfig:

  • Tools ([]Tool): Tools to expose when resuming
  • Provider (*ProviderConfig): Custom model provider configuration
Session
  • Send(options MessageOptions) (string, error) - Send a message
  • On(handler SessionEventHandler) func() - Subscribe to events (returns unsubscribe function)
  • Abort() error - Abort the currently processing message
  • GetMessages() ([]SessionEvent, error) - Get message history
  • Destroy() error - Destroy the session
Helper Functions
  • Bool(v bool) *bool - Helper to create bool pointers for AutoStart/AutoRestart options
Tools

Expose your own functionality to Copilot by attaching tools to a session.

Use DefineTool for type-safe tools with automatic JSON schema generation:

type LookupIssueParams struct {
    ID string `json:"id" jsonschema:"Issue identifier"`
}

lookupIssue := copilot.DefineTool("lookup_issue", "Fetch issue details from our tracker",
    func(params LookupIssueParams, inv copilot.ToolInvocation) (any, error) {
        // params is automatically unmarshaled from the LLM's arguments
        issue, err := fetchIssue(params.ID)
        if err != nil {
            return nil, err
        }
        return issue.Summary, nil
    })

session, _ := client.CreateSession(&copilot.SessionConfig{
    Model: "gpt-5",
    Tools: []copilot.Tool{lookupIssue},
})
Using Tool struct directly

For more control over the JSON schema, use the Tool struct directly:

lookupIssue := copilot.Tool{
    Name:        "lookup_issue",
    Description: "Fetch issue details from our tracker",
    Parameters: map[string]interface{}{
        "type": "object",
        "properties": map[string]interface{}{
            "id": map[string]interface{}{
                "type":        "string",
                "description": "Issue identifier",
            },
        },
        "required": []string{"id"},
    },
    Handler: func(invocation copilot.ToolInvocation) (copilot.ToolResult, error) {
        args := invocation.Arguments.(map[string]interface{})
        issue, err := fetchIssue(args["id"].(string))
        if err != nil {
            return copilot.ToolResult{}, err
        }
        return copilot.ToolResult{
            TextResultForLLM: issue.Summary,
            ResultType:       "success",
            SessionLog:       fmt.Sprintf("Fetched issue %s", issue.ID),
        }, nil
    },
}

session, _ := client.CreateSession(&copilot.SessionConfig{
    Model: "gpt-5",
    Tools: []copilot.Tool{lookupIssue},
})

When the model selects a tool, the SDK automatically runs your handler (in parallel with other calls) and responds to the CLI's tool.call with the handler's result.

Streaming

Enable streaming to receive assistant response chunks as they're generated:

package main

import (
    "fmt"
    "log"

    copilot "github.com/github/copilot-sdk/go"
)

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

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

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

    done := make(chan bool)

    session.On(func(event copilot.SessionEvent) {
        if event.Type == "assistant.message_delta" {
            // Streaming message chunk - print incrementally
            if event.Data.DeltaContent != nil {
                fmt.Print(*event.Data.DeltaContent)
            }
        } else if event.Type == "assistant.reasoning_delta" {
            // Streaming reasoning chunk (if model supports reasoning)
            if event.Data.DeltaContent != nil {
                fmt.Print(*event.Data.DeltaContent)
            }
        } else if event.Type == "assistant.message" {
            // Final message - complete content
            fmt.Println("\n--- Final message ---")
            if event.Data.Content != nil {
                fmt.Println(*event.Data.Content)
            }
        } else if event.Type == "assistant.reasoning" {
            // Final reasoning content (if model supports reasoning)
            fmt.Println("--- Reasoning ---")
            if event.Data.Content != nil {
                fmt.Println(*event.Data.Content)
            }
        }
        if event.Type == "session.idle" {
            close(done)
        }
    })

    _, err = session.Send(copilot.MessageOptions{
        Prompt: "Tell me a short story",
    })
    if err != nil {
        log.Fatal(err)
    }

    <-done
}

When Streaming: true:

  • assistant.message_delta events are sent with DeltaContent containing incremental text
  • assistant.reasoning_delta events are sent with DeltaContent for reasoning/chain-of-thought (model-dependent)
  • Accumulate DeltaContent values to build the full response progressively
  • The final assistant.message and assistant.reasoning events contain the complete content

Note: assistant.message and assistant.reasoning (final events) are always sent regardless of streaming setting.

Transport Modes

stdio (Default)

Communicates with CLI via stdin/stdout pipes. Recommended for most use cases.

client := copilot.NewClient(nil) // Uses stdio by default
TCP

Communicates with CLI via TCP socket. Useful for distributed scenarios.

Environment Variables

  • COPILOT_CLI_PATH - Path to the Copilot CLI executable

License

MIT

Documentation

Overview

Package copilot provides a Go SDK for interacting with the GitHub Copilot CLI.

The copilot package enables Go applications to communicate with the Copilot CLI server, create and manage conversation sessions, and integrate custom tools.

Basic usage:

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

session, err := client.CreateSession(&copilot.SessionConfig{
    Model: "gpt-4",
})
if err != nil {
    log.Fatal(err)
}

session.On(func(event copilot.SessionEvent) {
    if event.Type == "assistant.message" {
        fmt.Println(event.Data.Content)
    }
})

session.Send(copilot.MessageOptions{Prompt: "Hello!"})

Package copilot provides a Go SDK for interacting with the GitHub Copilot CLI.

Index

Constants

View Source
const SdkProtocolVersion = 1

SdkProtocolVersion is the SDK protocol version. This must match the version expected by the copilot-agent-runtime server.

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to the given bool value. Use for setting AutoStart or AutoRestart: AutoStart: Bool(false)

func GetSdkProtocolVersion

func GetSdkProtocolVersion() int

GetSdkProtocolVersion returns the SDK protocol version.

Types

type Attachment

type Attachment struct {
	Type        string `json:"type"` // "file" or "directory"
	Path        string `json:"path"`
	DisplayName string `json:"displayName,omitempty"`
}

Attachment represents a file or directory attachment

type AzureProviderOptions

type AzureProviderOptions struct {
	// APIVersion is the Azure API version. Defaults to "2024-10-21".
	APIVersion string `json:"apiVersion,omitempty"`
}

AzureProviderOptions contains Azure-specific provider configuration

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client manages the connection to the Copilot CLI server and provides session management.

The Client can either spawn a CLI server process or connect to an existing server. It handles JSON-RPC communication, session lifecycle, tool execution, and permission requests.

Example:

// Create a client with default options (spawns CLI server using stdio)
client := copilot.NewClient(nil)

// Or connect to an existing server
client := copilot.NewClient(&copilot.ClientOptions{
    CLIUrl: "localhost:3000",
})

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

func NewClient

func NewClient(options *ClientOptions) *Client

NewClient creates a new Copilot CLI client with the given options.

If options is nil, default options are used (spawns CLI server using stdio). The client is not connected after creation; call Client.Start to connect.

Example:

// Default options
client := copilot.NewClient(nil)

// Custom options
client := copilot.NewClient(&copilot.ClientOptions{
    CLIPath:  "/usr/local/bin/copilot",
    LogLevel: "debug",
})

func (*Client) CreateSession

func (c *Client) CreateSession(config *SessionConfig) (*Session, error)

CreateSession creates a new conversation session with the Copilot CLI.

Sessions maintain conversation state, handle events, and manage tool execution. If the client is not connected and AutoStart is enabled, this will automatically start the connection.

The config parameter is optional; pass nil for default settings.

Returns the created session or an error if session creation fails.

Example:

// Basic session
session, err := client.CreateSession(nil)

// Session with model and tools
session, err := client.CreateSession(&copilot.SessionConfig{
    Model: "gpt-4",
    Tools: []copilot.Tool{
        {
            Name:        "get_weather",
            Description: "Get weather for a location",
            Handler:     weatherHandler,
        },
    },
})

func (*Client) ForceStop

func (c *Client) ForceStop()

ForceStop forcefully stops the CLI server without graceful cleanup.

Use this when Client.Stop fails or takes too long. This method:

  • Clears all sessions immediately without destroying them
  • Force closes the connection
  • Kills the CLI process (if spawned by this client)

Example:

// If normal stop hangs, force stop
done := make(chan struct{})
go func() {
    client.Stop()
    close(done)
}()

select {
case <-done:
    // Stopped successfully
case <-time.After(5 * time.Second):
    client.ForceStop()
}

func (*Client) GetState

func (c *Client) GetState() ConnectionState

GetState returns the current connection state of the client.

Possible states: StateDisconnected, StateConnecting, StateConnected, StateError.

Example:

if client.GetState() == copilot.StateConnected {
    session, err := client.CreateSession(nil)
}

func (*Client) Ping

func (c *Client) Ping(message string) (*PingResponse, error)

Ping sends a ping request to the server to verify connectivity.

The message parameter is optional and will be echoed back in the response. Returns a PingResponse containing the message and server timestamp, or an error.

Example:

resp, err := client.Ping("health check")
if err != nil {
    log.Printf("Server unreachable: %v", err)
} else {
    log.Printf("Server responded at %d", resp.Timestamp)
}

func (*Client) ResumeSession

func (c *Client) ResumeSession(sessionID string) (*Session, error)

ResumeSession resumes an existing conversation session by its ID using default options.

This is a convenience method that calls Client.ResumeSessionWithOptions with nil config.

Example:

session, err := client.ResumeSession("session-123")

func (*Client) ResumeSessionWithOptions

func (c *Client) ResumeSessionWithOptions(sessionID string, config *ResumeSessionConfig) (*Session, error)

ResumeSessionWithOptions resumes an existing conversation session with additional configuration.

This allows you to continue a previous conversation, maintaining all conversation history. The session must have been previously created and not deleted.

Example:

session, err := client.ResumeSessionWithOptions("session-123", &copilot.ResumeSessionConfig{
    Tools: []copilot.Tool{myNewTool},
})

func (*Client) Start

func (c *Client) Start() error

Start starts the CLI server (if not using an external server) and establishes a connection.

If connecting to an external server (via CLIUrl), only establishes the connection. Otherwise, spawns the CLI server process and then connects.

This method is called automatically when creating a session if AutoStart is true (default).

Returns an error if the server fails to start or the connection fails.

Example:

client := copilot.NewClient(&copilot.ClientOptions{AutoStart: boolPtr(false)})
if err := client.Start(); err != nil {
    log.Fatal("Failed to start:", err)
}
// Now ready to create sessions

func (*Client) Stop

func (c *Client) Stop() []error

Stop stops the CLI server and closes all active sessions.

This method performs graceful cleanup:

  1. Destroys all active sessions
  2. Closes the JSON-RPC connection
  3. Terminates the CLI server process (if spawned by this client)

Returns an array of errors encountered during cleanup. An empty slice indicates all cleanup succeeded.

Example:

errors := client.Stop()
for _, err := range errors {
    log.Printf("Cleanup error: %v", err)
}

type ClientOptions

type ClientOptions struct {
	// CLIPath is the path to the Copilot CLI executable (default: "copilot")
	CLIPath string
	// Cwd is the working directory for the CLI process (default: "" = inherit from current process)
	Cwd string
	// Port for TCP transport (default: 0 = random port)
	Port int
	// UseStdio enables stdio transport instead of TCP (default: true)
	UseStdio bool
	// CLIUrl is the URL of an existing Copilot CLI server to connect to over TCP
	// Format: "host:port", "http://host:port", or just "port" (defaults to localhost)
	// Examples: "localhost:8080", "http://127.0.0.1:9000", "8080"
	// Mutually exclusive with CLIPath, UseStdio
	CLIUrl string
	// LogLevel for the CLI server
	LogLevel string
	// AutoStart automatically starts the CLI server on first use (default: true).
	// Use Bool(false) to disable.
	AutoStart *bool
	// AutoRestart automatically restarts the CLI server if it crashes (default: true).
	// Use Bool(false) to disable.
	AutoRestart *bool
	// Env is the environment variables for the CLI process (default: inherits from current process)
	Env []string
}

ClientOptions configures the CopilotClient

type ConnectionState

type ConnectionState string

ConnectionState represents the client connection state

const (
	StateDisconnected ConnectionState = "disconnected"
	StateConnecting   ConnectionState = "connecting"
	StateConnected    ConnectionState = "connected"
	StateError        ConnectionState = "error"
)

type CustomAgentConfig

type CustomAgentConfig struct {
	// Name is the unique name of the custom agent
	Name string `json:"name"`
	// DisplayName is the display name for UI purposes
	DisplayName string `json:"displayName,omitempty"`
	// Description of what the agent does
	Description string `json:"description,omitempty"`
	// Tools is the list of tool names the agent can use (nil for all tools)
	Tools []string `json:"tools,omitempty"`
	// Prompt is the prompt content for the agent
	Prompt string `json:"prompt"`
	// MCPServers are MCP servers specific to this agent
	MCPServers map[string]MCPServerConfig `json:"mcpServers,omitempty"`
	// Infer indicates whether the agent should be available for model inference
	Infer *bool `json:"infer,omitempty"`
}

CustomAgentConfig configures a custom agent

type JSONRPCClient

type JSONRPCClient struct {
	// contains filtered or unexported fields
}

JSONRPCClient is a minimal JSON-RPC 2.0 client for stdio transport

func NewJSONRPCClient

func NewJSONRPCClient(stdin io.WriteCloser, stdout io.ReadCloser) *JSONRPCClient

NewJSONRPCClient creates a new JSON-RPC client

func (*JSONRPCClient) Notify

func (c *JSONRPCClient) Notify(method string, params map[string]interface{}) error

Notify sends a JSON-RPC notification (no response expected)

func (*JSONRPCClient) Request

func (c *JSONRPCClient) Request(method string, params map[string]interface{}) (map[string]interface{}, error)

Request sends a JSON-RPC request and waits for the response

func (*JSONRPCClient) SetNotificationHandler

func (c *JSONRPCClient) SetNotificationHandler(handler NotificationHandler)

SetNotificationHandler sets the handler for incoming notifications

func (*JSONRPCClient) SetRequestHandler

func (c *JSONRPCClient) SetRequestHandler(method string, handler RequestHandler)

SetRequestHandler registers a handler for incoming requests from the server

func (*JSONRPCClient) Start

func (c *JSONRPCClient) Start()

Start begins listening for messages in a background goroutine

func (*JSONRPCClient) Stop

func (c *JSONRPCClient) Stop()

Stop stops the client and cleans up

type JSONRPCError

type JSONRPCError struct {
	Code    int                    `json:"code"`
	Message string                 `json:"message"`
	Data    map[string]interface{} `json:"data,omitempty"`
}

JSONRPCError represents a JSON-RPC error response

func (*JSONRPCError) Error

func (e *JSONRPCError) Error() string

type JSONRPCNotification

type JSONRPCNotification struct {
	JSONRPC string                 `json:"jsonrpc"`
	Method  string                 `json:"method"`
	Params  map[string]interface{} `json:"params"`
}

JSONRPCNotification represents a JSON-RPC 2.0 notification

type JSONRPCRequest

type JSONRPCRequest struct {
	JSONRPC string                 `json:"jsonrpc"`
	ID      json.RawMessage        `json:"id"`
	Method  string                 `json:"method"`
	Params  map[string]interface{} `json:"params"`
}

JSONRPCRequest represents a JSON-RPC 2.0 request

type JSONRPCResponse

type JSONRPCResponse struct {
	JSONRPC string                 `json:"jsonrpc"`
	ID      json.RawMessage        `json:"id,omitempty"`
	Result  map[string]interface{} `json:"result,omitempty"`
	Error   *JSONRPCError          `json:"error,omitempty"`
}

JSONRPCResponse represents a JSON-RPC 2.0 response

type MCPLocalServerConfig

type MCPLocalServerConfig struct {
	Tools   []string          `json:"tools"`
	Type    string            `json:"type,omitempty"` // "local" or "stdio"
	Timeout int               `json:"timeout,omitempty"`
	Command string            `json:"command"`
	Args    []string          `json:"args"`
	Env     map[string]string `json:"env,omitempty"`
	Cwd     string            `json:"cwd,omitempty"`
}

MCPLocalServerConfig configures a local/stdio MCP server

type MCPRemoteServerConfig

type MCPRemoteServerConfig struct {
	Tools   []string          `json:"tools"`
	Type    string            `json:"type"` // "http" or "sse"
	Timeout int               `json:"timeout,omitempty"`
	URL     string            `json:"url"`
	Headers map[string]string `json:"headers,omitempty"`
}

MCPRemoteServerConfig configures a remote MCP server (HTTP or SSE)

type MCPServerConfig

type MCPServerConfig map[string]interface{}

MCPServerConfig can be either MCPLocalServerConfig or MCPRemoteServerConfig Use a map[string]interface{} for flexibility, or create separate configs

type MessageOptions

type MessageOptions struct {
	// Prompt is the message to send
	Prompt string
	// Attachments are file or directory attachments
	Attachments []Attachment
	// Mode is the message delivery mode (default: "enqueue")
	Mode string
}

MessageOptions configures a message to send

type NotificationHandler

type NotificationHandler func(method string, params map[string]interface{})

NotificationHandler handles incoming notifications

type PermissionHandler

type PermissionHandler func(request PermissionRequest, invocation PermissionInvocation) (PermissionRequestResult, error)

PermissionHandler executes a permission request The handler should return a PermissionRequestResult. Returning an error denies the permission.

type PermissionInvocation

type PermissionInvocation struct {
	SessionID string
}

PermissionInvocation provides context about a permission request

type PermissionRequest

type PermissionRequest struct {
	Kind       string                 `json:"kind"`
	ToolCallID string                 `json:"toolCallId,omitempty"`
	Extra      map[string]interface{} `json:"-"` // Additional fields vary by kind
}

PermissionRequest represents a permission request from the server

type PermissionRequestResult

type PermissionRequestResult struct {
	Kind  string        `json:"kind"`
	Rules []interface{} `json:"rules,omitempty"`
}

PermissionRequestResult represents the result of a permission request

type PingResponse

type PingResponse struct {
	Message         string `json:"message"`
	Timestamp       int64  `json:"timestamp"`
	ProtocolVersion *int   `json:"protocolVersion,omitempty"`
}

PingResponse is the response from a ping request

type ProviderConfig

type ProviderConfig struct {
	// Type is the provider type: "openai", "azure", or "anthropic". Defaults to "openai".
	Type string `json:"type,omitempty"`
	// WireApi is the API format (openai/azure only): "completions" or "responses". Defaults to "completions".
	WireApi string `json:"wireApi,omitempty"`
	// BaseURL is the API endpoint URL
	BaseURL string `json:"baseUrl"`
	// APIKey is the API key. Optional for local providers like Ollama.
	APIKey string `json:"apiKey,omitempty"`
	// BearerToken for authentication. Sets the Authorization header directly.
	// Use this for services requiring bearer token auth instead of API key.
	// Takes precedence over APIKey when both are set.
	BearerToken string `json:"bearerToken,omitempty"`
	// Azure contains Azure-specific options
	Azure *AzureProviderOptions `json:"azure,omitempty"`
}

ProviderConfig configures a custom model provider

type RequestHandler

type RequestHandler func(params map[string]interface{}) (map[string]interface{}, *JSONRPCError)

RequestHandler handles incoming server requests and returns a result or error

type ResumeSessionConfig

type ResumeSessionConfig struct {
	// Tools exposes caller-implemented tools to the CLI
	Tools []Tool
	// Provider configures a custom model provider
	Provider *ProviderConfig
	// OnPermissionRequest is a handler for permission requests from the server
	OnPermissionRequest PermissionHandler
	// Streaming enables streaming of assistant message and reasoning chunks.
	// When true, assistant.message_delta and assistant.reasoning_delta events
	// with deltaContent are sent as the response is generated.
	Streaming bool
	// MCPServers configures MCP servers for the session
	MCPServers map[string]MCPServerConfig
	// CustomAgents configures custom agents for the session
	CustomAgents []CustomAgentConfig
}

ResumeSessionConfig configures options when resuming a session

type Session

type Session struct {
	// SessionID is the unique identifier for this session.
	SessionID string
	// contains filtered or unexported fields
}

Session represents a single conversation session with the Copilot CLI.

A session maintains conversation state, handles events, and manages tool execution. Sessions are created via Client.CreateSession or resumed via Client.ResumeSession.

The session provides methods to send messages, subscribe to events, retrieve conversation history, and manage the session lifecycle. All methods are safe for concurrent use.

Example usage:

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

// Subscribe to events
unsubscribe := session.On(func(event copilot.SessionEvent) {
    if event.Type == "assistant.message" {
        fmt.Println("Assistant:", event.Data.Content)
    }
})
defer unsubscribe()

// Send a message
messageID, err := session.Send(copilot.MessageOptions{
    Prompt: "Hello, world!",
})

func NewSession

func NewSession(sessionID string, client *JSONRPCClient) *Session

NewSession creates a new session wrapper with the given session ID and client.

Note: This function is primarily for internal use. Use Client.CreateSession to create sessions with proper initialization.

func (*Session) Abort

func (s *Session) Abort() error

Abort aborts the currently processing message in this session.

Use this to cancel a long-running request. The session remains valid and can continue to be used for new messages.

Returns an error if the session has been destroyed or the connection fails.

Example:

// Start a long-running request in a goroutine
go func() {
    session.Send(copilot.MessageOptions{
        Prompt: "Write a very long story...",
    })
}()

// Abort after 5 seconds
time.Sleep(5 * time.Second)
if err := session.Abort(); err != nil {
    log.Printf("Failed to abort: %v", err)
}

func (*Session) Destroy

func (s *Session) Destroy() error

Destroy destroys this session and releases all associated resources.

After calling this method, the session can no longer be used. All event handlers and tool handlers are cleared. To continue the conversation, use Client.ResumeSession with the session ID.

Returns an error if the connection fails.

Example:

// Clean up when done
if err := session.Destroy(); err != nil {
    log.Printf("Failed to destroy session: %v", err)
}

func (*Session) GetMessages

func (s *Session) GetMessages() ([]SessionEvent, error)

GetMessages retrieves all events and messages from this session's history.

This returns the complete conversation history including user messages, assistant responses, tool executions, and other session events in chronological order.

Returns an error if the session has been destroyed or the connection fails.

Example:

events, err := session.GetMessages()
if err != nil {
    log.Printf("Failed to get messages: %v", err)
    return
}
for _, event := range events {
    if event.Type == "assistant.message" {
        fmt.Println("Assistant:", event.Data.Content)
    }
}

func (*Session) On

func (s *Session) On(handler SessionEventHandler) func()

On subscribes to events from this session.

Events include assistant messages, tool executions, errors, and session state changes. Multiple handlers can be registered and will all receive events. Handlers are called synchronously in the order they were registered.

The returned function can be called to unsubscribe the handler. It is safe to call the unsubscribe function multiple times.

Example:

unsubscribe := session.On(func(event copilot.SessionEvent) {
    switch event.Type {
    case "assistant.message":
        fmt.Println("Assistant:", event.Data.Content)
    case "session.error":
        fmt.Println("Error:", event.Data.Message)
    }
})

// Later, to stop receiving events:
unsubscribe()

func (*Session) Send

func (s *Session) Send(options MessageOptions) (string, error)

Send sends a message to this session and waits for the response.

The message is processed asynchronously. Subscribe to events via Session.On to receive streaming responses and other session events.

Parameters:

  • options: The message options including the prompt and optional attachments.

Returns the message ID of the response, which can be used to correlate events, or an error if the session has been destroyed or the connection fails.

Example:

messageID, err := session.Send(copilot.MessageOptions{
    Prompt: "Explain this code",
    Attachments: []copilot.Attachment{
        {Type: "file", Path: "./main.go"},
    },
})
if err != nil {
    log.Printf("Failed to send message: %v", err)
}

func (*Session) SendAndWait

func (s *Session) SendAndWait(options MessageOptions, timeout time.Duration) (*SessionEvent, error)

SendAndWait sends a message to this session and waits until the session becomes idle.

This is a convenience method that combines Session.Send with waiting for the session.idle event. Use this when you want to block until the assistant has finished processing the message.

Events are still delivered to handlers registered via Session.On while waiting.

Parameters:

  • options: The message options including the prompt and optional attachments.
  • timeout: How long to wait for completion. Defaults to 60 seconds if zero. Controls how long to wait; does not abort in-flight agent work.

Returns the final assistant message event, or nil if none was received. Returns an error if the timeout is reached or the connection fails.

Example:

response, err := session.SendAndWait(copilot.MessageOptions{
    Prompt: "What is 2+2?",
}, 0) // Use default 60s timeout
if err != nil {
    log.Printf("Failed: %v", err)
}
if response != nil {
    fmt.Println(*response.Data.Content)
}

type SessionConfig

type SessionConfig struct {
	// SessionID is an optional custom session ID
	SessionID string
	// Model to use for this session
	Model string
	// Tools exposes caller-implemented tools to the CLI
	Tools []Tool
	// SystemMessage configures system message customization
	SystemMessage *SystemMessageConfig
	// AvailableTools is a list of tool names to allow. When specified, only these tools will be available.
	// Takes precedence over ExcludedTools.
	AvailableTools []string
	// ExcludedTools is a list of tool names to disable. All other tools remain available.
	// Ignored if AvailableTools is specified.
	ExcludedTools []string
	// OnPermissionRequest is a handler for permission requests from the server
	OnPermissionRequest PermissionHandler
	// Streaming enables streaming of assistant message and reasoning chunks.
	// When true, assistant.message_delta and assistant.reasoning_delta events
	// with deltaContent are sent as the response is generated.
	Streaming bool
	// Provider configures a custom model provider (BYOK)
	Provider *ProviderConfig
	// MCPServers configures MCP servers for the session
	MCPServers map[string]MCPServerConfig
	// CustomAgents configures custom agents for the session
	CustomAgents []CustomAgentConfig
}

SessionConfig configures a new session

type SessionCreateResponse

type SessionCreateResponse struct {
	SessionID string `json:"sessionId"`
}

SessionCreateResponse is the response from session.create

type SessionEvent

type SessionEvent = generated.SessionEvent

type SessionEventHandler

type SessionEventHandler func(event SessionEvent)

SessionEventHandler is a callback for session events

type SessionGetMessagesResponse

type SessionGetMessagesResponse struct {
	Events []SessionEvent `json:"events"`
}

SessionGetMessagesResponse is the response from session.getMessages

type SessionSendResponse

type SessionSendResponse struct {
	MessageID string `json:"messageId"`
}

SessionSendResponse is the response from session.send

type SystemMessageAppendConfig

type SystemMessageAppendConfig struct {
	// Mode is optional, defaults to "append"
	Mode string `json:"mode,omitempty"`
	// Content provides additional instructions appended after SDK-managed sections
	Content string `json:"content,omitempty"`
}

SystemMessageAppendConfig is append mode: use CLI foundation with optional appended content.

type SystemMessageConfig

type SystemMessageConfig struct {
	Mode    string `json:"mode,omitempty"`
	Content string `json:"content,omitempty"`
}

SystemMessageConfig represents system message configuration for session creation. Use SystemMessageAppendConfig for default behavior, SystemMessageReplaceConfig for full control. In Go, use one struct or the other based on your needs.

type SystemMessageReplaceConfig

type SystemMessageReplaceConfig struct {
	// Mode must be "replace"
	Mode string `json:"mode"`
	// Content is the complete system message (required)
	Content string `json:"content"`
}

SystemMessageReplaceConfig is replace mode: use caller-provided system message entirely. Removes all SDK guardrails including security restrictions.

type Tool

type Tool struct {
	Name        string
	Description string // optional
	Parameters  map[string]interface{}
	Handler     ToolHandler
}

Tool describes a caller-implemented tool that can be invoked by Copilot

func DefineTool

func DefineTool[T any, U any](name, description string, handler func(T, ToolInvocation) (U, error)) Tool

DefineTool creates a Tool with automatic JSON schema generation from a typed handler function. The handler receives typed arguments (automatically unmarshaled from JSON) and the raw ToolInvocation. The handler can return any value - strings pass through directly, other types are JSON-serialized.

Example:

type GetWeatherParams struct {
    City string `json:"city" jsonschema:"city name"`
    Unit string `json:"unit" jsonschema:"temperature unit (celsius or fahrenheit)"`
}

tool := copilot.DefineTool("get_weather", "Get weather for a city",
    func(params GetWeatherParams, inv copilot.ToolInvocation) (any, error) {
        return fmt.Sprintf("Weather in %s: 22°%s", params.City, params.Unit), nil
    })

type ToolBinaryResult

type ToolBinaryResult struct {
	Data        string `json:"data"`
	MimeType    string `json:"mimeType"`
	Type        string `json:"type"`
	Description string `json:"description,omitempty"`
}

ToolBinaryResult represents binary payloads returned by tools.

type ToolHandler

type ToolHandler func(invocation ToolInvocation) (ToolResult, error)

ToolHandler executes a tool invocation. The handler should return a ToolResult. Returning an error marks the tool execution as a failure.

type ToolInvocation

type ToolInvocation struct {
	SessionID  string
	ToolCallID string
	ToolName   string
	Arguments  interface{}
}

ToolInvocation describes a tool call initiated by Copilot

type ToolResult

type ToolResult struct {
	TextResultForLLM    string                 `json:"textResultForLlm"`
	BinaryResultsForLLM []ToolBinaryResult     `json:"binaryResultsForLlm,omitempty"`
	ResultType          string                 `json:"resultType"`
	Error               string                 `json:"error,omitempty"`
	SessionLog          string                 `json:"sessionLog,omitempty"`
	ToolTelemetry       map[string]interface{} `json:"toolTelemetry,omitempty"`
}

ToolResult represents the result of a tool invocation.

Directories

Path Synopsis
e2e

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL