Skip to content
Open
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
22 changes: 11 additions & 11 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,18 @@ 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{}{
Parameters: map[string]any{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]interface{}{
"properties": map[string]any{
"id": map[string]any{
"type": "string",
"description": "Issue identifier",
},
},
"required": []string{"id"},
},
Handler: func(invocation copilot.ToolInvocation) (copilot.ToolResult, error) {
args := invocation.Arguments.(map[string]interface{})
args := invocation.Arguments.(map[string]any)
issue, err := fetchIssue(args["id"].(string))
if err != nil {
return copilot.ToolResult{}, err
Expand Down Expand Up @@ -414,12 +414,12 @@ session, err := client.CreateSession(&copilot.SessionConfig{
// request.Question - The question to ask
// request.Choices - Optional slice of choices for multiple choice
// request.AllowFreeform - Whether freeform input is allowed (default: true)

fmt.Printf("Agent asks: %s\n", request.Question)
if len(request.Choices) > 0 {
fmt.Printf("Choices: %v\n", request.Choices)
}

// Return the user's response
return copilot.UserInputResponse{
Answer: "User's answer here",
Expand Down Expand Up @@ -447,37 +447,37 @@ session, err := client.CreateSession(&copilot.SessionConfig{
AdditionalContext: "Extra context for the model",
}, nil
},

// Called after each tool execution
OnPostToolUse: func(input copilot.PostToolUseHookInput, invocation copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) {
fmt.Printf("Tool %s completed\n", input.ToolName)
return &copilot.PostToolUseHookOutput{
AdditionalContext: "Post-execution notes",
}, nil
},

// Called when user submits a prompt
OnUserPromptSubmitted: func(input copilot.UserPromptSubmittedHookInput, invocation copilot.HookInvocation) (*copilot.UserPromptSubmittedHookOutput, error) {
fmt.Printf("User prompt: %s\n", input.Prompt)
return &copilot.UserPromptSubmittedHookOutput{
ModifiedPrompt: input.Prompt, // Optionally modify the prompt
}, nil
},

// Called when session starts
OnSessionStart: func(input copilot.SessionStartHookInput, invocation copilot.HookInvocation) (*copilot.SessionStartHookOutput, error) {
fmt.Printf("Session started from: %s\n", input.Source) // "startup", "resume", "new"
return &copilot.SessionStartHookOutput{
AdditionalContext: "Session initialization context",
}, nil
},

// Called when session ends
OnSessionEnd: func(input copilot.SessionEndHookInput, invocation copilot.HookInvocation) (*copilot.SessionEndHookOutput, error) {
fmt.Printf("Session ended: %s\n", input.Reason)
return nil, nil
},

// Called when an error occurs
OnErrorOccurred: func(input copilot.ErrorOccurredHookInput, invocation copilot.HookInvocation) (*copilot.ErrorOccurredHookOutput, error) {
fmt.Printf("Error in %s: %s\n", input.ErrorContext, input.Error)
Expand Down
86 changes: 43 additions & 43 deletions go/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ type Client struct {
sessions map[string]*Session
sessionsMux sync.Mutex
isExternalServer bool
conn interface{} // stores net.Conn for external TCP connections
useStdio bool // resolved value from options
autoStart bool // resolved value from options
autoRestart bool // resolved value from options
conn any // stores net.Conn for external TCP connections
useStdio bool // resolved value from options
autoStart bool // resolved value from options
autoRestart bool // resolved value from options
modelsCache []ModelInfo
modelsCacheMux sync.Mutex
}
Expand Down Expand Up @@ -399,8 +399,8 @@ func (c *Client) ForceStop() {
}

// buildProviderParams converts a ProviderConfig to a map for JSON-RPC params.
func buildProviderParams(p *ProviderConfig) map[string]interface{} {
params := make(map[string]interface{})
func buildProviderParams(p *ProviderConfig) map[string]any {
params := make(map[string]any)
if p.Type != "" {
params["type"] = p.Type
}
Expand All @@ -417,7 +417,7 @@ func buildProviderParams(p *ProviderConfig) map[string]interface{} {
params["bearerToken"] = p.BearerToken
}
if p.Azure != nil {
azure := make(map[string]interface{})
azure := make(map[string]any)
if p.Azure.APIVersion != "" {
azure["apiVersion"] = p.Azure.APIVersion
}
Expand Down Expand Up @@ -465,7 +465,7 @@ func (c *Client) CreateSession(config *SessionConfig) (*Session, error) {
}
}

params := make(map[string]interface{})
params := make(map[string]any)
if config != nil {
if config.Model != "" {
params["model"] = config.Model
Expand All @@ -477,12 +477,12 @@ func (c *Client) CreateSession(config *SessionConfig) (*Session, error) {
params["reasoningEffort"] = config.ReasoningEffort
}
if len(config.Tools) > 0 {
toolDefs := make([]map[string]interface{}, 0, len(config.Tools))
toolDefs := make([]map[string]any, 0, len(config.Tools))
for _, tool := range config.Tools {
if tool.Name == "" {
continue
}
definition := map[string]interface{}{
definition := map[string]any{
"name": tool.Name,
"description": tool.Description,
}
Expand All @@ -497,7 +497,7 @@ func (c *Client) CreateSession(config *SessionConfig) (*Session, error) {
}
// Add system message configuration if provided
if config.SystemMessage != nil {
systemMessage := make(map[string]interface{})
systemMessage := make(map[string]any)

if config.SystemMessage.Mode != "" {
systemMessage["mode"] = config.SystemMessage.Mode
Expand Down Expand Up @@ -559,9 +559,9 @@ func (c *Client) CreateSession(config *SessionConfig) (*Session, error) {
}
// Add custom agents configuration
if len(config.CustomAgents) > 0 {
customAgents := make([]map[string]interface{}, 0, len(config.CustomAgents))
customAgents := make([]map[string]any, 0, len(config.CustomAgents))
for _, agent := range config.CustomAgents {
agentMap := map[string]interface{}{
agentMap := map[string]any{
"name": agent.Name,
"prompt": agent.Prompt,
}
Expand Down Expand Up @@ -598,7 +598,7 @@ func (c *Client) CreateSession(config *SessionConfig) (*Session, error) {
}
// Add infinite sessions configuration
if config.InfiniteSessions != nil {
infiniteSessions := make(map[string]interface{})
infiniteSessions := make(map[string]any)
if config.InfiniteSessions.Enabled != nil {
infiniteSessions["enabled"] = *config.InfiniteSessions.Enabled
}
Expand Down Expand Up @@ -680,7 +680,7 @@ func (c *Client) ResumeSessionWithOptions(sessionID string, config *ResumeSessio
}
}

params := map[string]interface{}{
params := map[string]any{
"sessionId": sessionID,
}

Expand All @@ -689,12 +689,12 @@ func (c *Client) ResumeSessionWithOptions(sessionID string, config *ResumeSessio
params["reasoningEffort"] = config.ReasoningEffort
}
if len(config.Tools) > 0 {
toolDefs := make([]map[string]interface{}, 0, len(config.Tools))
toolDefs := make([]map[string]any, 0, len(config.Tools))
for _, tool := range config.Tools {
if tool.Name == "" {
continue
}
definition := map[string]interface{}{
definition := map[string]any{
"name": tool.Name,
"description": tool.Description,
}
Expand Down Expand Up @@ -745,9 +745,9 @@ func (c *Client) ResumeSessionWithOptions(sessionID string, config *ResumeSessio
}
// Add custom agents configuration
if len(config.CustomAgents) > 0 {
customAgents := make([]map[string]interface{}, 0, len(config.CustomAgents))
customAgents := make([]map[string]any, 0, len(config.CustomAgents))
for _, agent := range config.CustomAgents {
agentMap := map[string]interface{}{
agentMap := map[string]any{
"name": agent.Name,
"prompt": agent.Prompt,
}
Expand Down Expand Up @@ -840,7 +840,7 @@ func (c *Client) ListSessions() ([]SessionMetadata, error) {
}
}

result, err := c.client.Request("session.list", map[string]interface{}{})
result, err := c.client.Request("session.list", map[string]any{})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -880,7 +880,7 @@ func (c *Client) DeleteSession(sessionID string) error {
}
}

params := map[string]interface{}{
params := map[string]any{
"sessionId": sessionID,
}

Expand Down Expand Up @@ -947,7 +947,7 @@ func (c *Client) Ping(message string) (*PingResponse, error) {
return nil, fmt.Errorf("client not connected")
}

params := map[string]interface{}{}
params := map[string]any{}
if message != "" {
params["message"] = message
}
Expand Down Expand Up @@ -978,7 +978,7 @@ func (c *Client) GetStatus() (*GetStatusResponse, error) {
return nil, fmt.Errorf("client not connected")
}

result, err := c.client.Request("status.get", map[string]interface{}{})
result, err := c.client.Request("status.get", map[string]any{})
if err != nil {
return nil, err
}
Expand All @@ -1000,7 +1000,7 @@ func (c *Client) GetAuthStatus() (*GetAuthStatusResponse, error) {
return nil, fmt.Errorf("client not connected")
}

result, err := c.client.Request("auth.getStatus", map[string]interface{}{})
result, err := c.client.Request("auth.getStatus", map[string]any{})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1047,7 +1047,7 @@ func (c *Client) ListModels() ([]ModelInfo, error) {
}

// Cache miss - fetch from backend while holding lock
result, err := c.client.Request("models.list", map[string]interface{}{})
result, err := c.client.Request("models.list", map[string]any{})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1250,7 +1250,7 @@ func (c *Client) connectViaTcp() error {

// setupNotificationHandler configures handlers for session events, tool calls, and permission requests.
func (c *Client) setupNotificationHandler() {
c.client.SetNotificationHandler(func(method string, params map[string]interface{}) {
c.client.SetNotificationHandler(func(method string, params map[string]any) {
if method == "session.event" {
// Extract sessionId and event
sessionID, ok := params["sessionId"].(string)
Expand Down Expand Up @@ -1287,7 +1287,7 @@ func (c *Client) setupNotificationHandler() {
}

// handleToolCallRequest handles a tool call request from the CLI server.
func (c *Client) handleToolCallRequest(params map[string]interface{}) (map[string]interface{}, *JSONRPCError) {
func (c *Client) handleToolCallRequest(params map[string]any) (map[string]any, *JSONRPCError) {
sessionID, _ := params["sessionId"].(string)
toolCallID, _ := params["toolCallId"].(string)
toolName, _ := params["toolName"].(string)
Expand All @@ -1305,19 +1305,19 @@ func (c *Client) handleToolCallRequest(params map[string]interface{}) (map[strin

handler, ok := session.getToolHandler(toolName)
if !ok {
return map[string]interface{}{"result": buildUnsupportedToolResult(toolName)}, nil
return map[string]any{"result": buildUnsupportedToolResult(toolName)}, nil
}

arguments := params["arguments"]
result := c.executeToolCall(sessionID, toolCallID, toolName, arguments, handler)

return map[string]interface{}{"result": result}, nil
return map[string]any{"result": result}, nil
}

// executeToolCall executes a tool handler and returns the result.
func (c *Client) executeToolCall(
sessionID, toolCallID, toolName string,
arguments interface{},
arguments any,
handler ToolHandler,
) (result ToolResult) {
invocation := ToolInvocation{
Expand Down Expand Up @@ -1347,9 +1347,9 @@ func (c *Client) executeToolCall(
}

// handlePermissionRequest handles a permission request from the CLI server.
func (c *Client) handlePermissionRequest(params map[string]interface{}) (map[string]interface{}, *JSONRPCError) {
func (c *Client) handlePermissionRequest(params map[string]any) (map[string]any, *JSONRPCError) {
sessionID, _ := params["sessionId"].(string)
permissionRequest, _ := params["permissionRequest"].(map[string]interface{})
permissionRequest, _ := params["permissionRequest"].(map[string]any)

if sessionID == "" {
return nil, &JSONRPCError{Code: -32602, Message: "invalid permission request payload"}
Expand All @@ -1365,18 +1365,18 @@ func (c *Client) handlePermissionRequest(params map[string]interface{}) (map[str
result, err := session.handlePermissionRequest(permissionRequest)
if err != nil {
// Return denial on error
return map[string]interface{}{
"result": map[string]interface{}{
return map[string]any{
"result": map[string]any{
"kind": "denied-no-approval-rule-and-could-not-request-from-user",
},
}, nil
}

return map[string]interface{}{"result": result}, nil
return map[string]any{"result": result}, nil
}

// handleUserInputRequest handles a user input request from the CLI server.
func (c *Client) handleUserInputRequest(params map[string]interface{}) (map[string]interface{}, *JSONRPCError) {
func (c *Client) handleUserInputRequest(params map[string]any) (map[string]any, *JSONRPCError) {
sessionID, _ := params["sessionId"].(string)
question, _ := params["question"].(string)

Expand All @@ -1393,7 +1393,7 @@ func (c *Client) handleUserInputRequest(params map[string]interface{}) (map[stri

// Parse choices
var choices []string
if choicesRaw, ok := params["choices"].([]interface{}); ok {
if choicesRaw, ok := params["choices"].([]any); ok {
for _, choice := range choicesRaw {
if s, ok := choice.(string); ok {
choices = append(choices, s)
Expand All @@ -1417,17 +1417,17 @@ func (c *Client) handleUserInputRequest(params map[string]interface{}) (map[stri
return nil, &JSONRPCError{Code: -32603, Message: err.Error()}
}

return map[string]interface{}{
return map[string]any{
"answer": response.Answer,
"wasFreeform": response.WasFreeform,
}, nil
}

// handleHooksInvoke handles a hooks invocation from the CLI server.
func (c *Client) handleHooksInvoke(params map[string]interface{}) (map[string]interface{}, *JSONRPCError) {
func (c *Client) handleHooksInvoke(params map[string]any) (map[string]any, *JSONRPCError) {
sessionID, _ := params["sessionId"].(string)
hookType, _ := params["hookType"].(string)
input, _ := params["input"].(map[string]interface{})
input, _ := params["input"].(map[string]any)

if sessionID == "" || hookType == "" {
return nil, &JSONRPCError{Code: -32602, Message: "invalid hooks invoke payload"}
Expand All @@ -1445,7 +1445,7 @@ func (c *Client) handleHooksInvoke(params map[string]interface{}) (map[string]in
return nil, &JSONRPCError{Code: -32603, Message: err.Error()}
}

result := make(map[string]interface{})
result := make(map[string]any)
if output != nil {
result["output"] = output
}
Expand All @@ -1458,7 +1458,7 @@ func buildFailedToolResult(internalError string) ToolResult {
TextResultForLLM: "Invoking this tool produced an error. Detailed information is not available.",
ResultType: "failure",
Error: internalError,
ToolTelemetry: map[string]interface{}{},
ToolTelemetry: map[string]any{},
}
}

Expand All @@ -1468,6 +1468,6 @@ func buildUnsupportedToolResult(toolName string) ToolResult {
TextResultForLLM: fmt.Sprintf("Tool '%s' is not supported by this client instance.", toolName),
ResultType: "failure",
Error: fmt.Sprintf("tool '%s' not supported", toolName),
ToolTelemetry: map[string]interface{}{},
ToolTelemetry: map[string]any{},
}
}
Loading
Loading