diff --git a/pkg/providers/github_copilot_provider.go b/pkg/providers/github_copilot_provider.go index 6124881f7..d6a745c40 100644 --- a/pkg/providers/github_copilot_provider.go +++ b/pkg/providers/github_copilot_provider.go @@ -2,56 +2,70 @@ package providers import ( "context" - "encoding/json" "fmt" + "time" + + json "encoding/json" copilot "github.com/github/copilot-sdk/go" ) type GitHubCopilotProvider struct { uri string - connectMode string // `stdio` or `grpc`` + connectMode string // `stdio` or `grpc` + client *copilot.Client session *copilot.Session } func NewGitHubCopilotProvider(uri string, connectMode string, model string) (*GitHubCopilotProvider, error) { + var session *copilot.Session + var client *copilot.Client if connectMode == "" { connectMode = "grpc" } switch connectMode { case "stdio": - // todo + //todo case "grpc": - client := copilot.NewClient(&copilot.ClientOptions{ + client = copilot.NewClient(&copilot.ClientOptions{ CLIUrl: uri, }) - if err := client.Start(context.Background()); err != nil { - return nil, fmt.Errorf( - "Can't connect to Github Copilot, https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md#connecting-to-an-external-cli-server for details", - ) + connectCtx, connectCancel := context.WithTimeout(context.Background(), 15*time.Second) + defer connectCancel() + if err := client.Start(connectCtx); err != nil { + return nil, fmt.Errorf("can't connect to Github Copilot: %w", err) } - defer client.Stop() - session, _ = client.CreateSession(context.Background(), &copilot.SessionConfig{ + var err error + session, err = client.CreateSession(connectCtx, &copilot.SessionConfig{ Model: model, Hooks: &copilot.SessionHooks{}, }) + if err != nil { + client.Stop() + return nil, fmt.Errorf("failed to create Copilot session: %w", err) + } } return &GitHubCopilotProvider{ uri: uri, connectMode: connectMode, + client: client, session: session, }, nil } +func (p *GitHubCopilotProvider) Close() { + if p.client != nil { + p.client.Stop() + } +} + // Chat sends a chat request to GitHub Copilot -func (p *GitHubCopilotProvider) Chat( - ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]any, -) (*LLMResponse, error) { +func (p *GitHubCopilotProvider) Chat(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) (*LLMResponse, error) { type tempMessage struct { Role string `json:"role"` Content string `json:"content"` @@ -67,16 +81,25 @@ func (p *GitHubCopilotProvider) Chat( fullcontent, _ := json.Marshal(out) - content, _ := p.session.Send(ctx, copilot.MessageOptions{ + event, err := p.session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: string(fullcontent), }) + if err != nil { + return nil, fmt.Errorf("copilot error: %w", err) + } + + if event == nil || event.Data.Content == nil { + return nil, fmt.Errorf("empty response from Copilot") + } return &LLMResponse{ FinishReason: "stop", - Content: content, + Content: *event.Data.Content, }, nil + } func (p *GitHubCopilotProvider) GetDefaultModel() string { + return "gpt-4.1" }