Enhance model definitions by including supported API endpoints for each model. This allows for better integration and usage tracking with the GitHub Copilot API.
Showing the changes to internal/runtime/executor/github_copilot_executor.go (1 of 4 files). Show all
Unified · Split
| @@ -23,6 +23,7 @@ import ( · 22 unmodified lines | ||
| 23 | 23 | const ( |
| 24 | 24 | githubCopilotBaseURL = "https://api.githubcopilot.com" |
| 25 | 25 | githubCopilotChatPath = "/chat/completions" |
| 26 | + githubCopilotResponsesPath = "/responses" | |
| 26 | 27 | githubCopilotAuthType = "github-copilot" |
| 27 | 28 | githubCopilotTokenCacheTTL = 25 * time.Minute |
| 28 | 29 | // tokenExpiryBuffer is the time before expiry when we should refresh the token. |
| @@ -106,7 +107,11 @@ func (e *GitHubCopilotExecutor) Execute(ctx context.Context, auth *cliproxyauth. · 77 unmodified lines | ||
| 106 | 107 | defer reporter.trackFailure(ctx, &err) |
| 107 | 108 | |
| 108 | 109 | from := opts.SourceFormat |
| 110 | + useResponses := useGitHubCopilotResponsesEndpoint(from) | |
| 109 | 111 | to := sdktranslator.FromString("openai") |
| 112 | + if useResponses { | |
| 113 | + to = sdktranslator.FromString("openai-response") | |
| 114 | + } | |
| 110 | 115 | originalPayload := bytes.Clone(req.Payload) |
| 111 | 116 | if len(opts.OriginalRequest) > 0 { |
| 112 | 117 | originalPayload = bytes.Clone(opts.OriginalRequest) |
| @@ -117,7 +122,11 @@ func (e *GitHubCopilotExecutor) Execute(ctx context.Context, auth *cliproxyauth. · 4 unmodified lines | ||
| 117 | 122 | body = applyPayloadConfigWithRoot(e.cfg, req.Model, to.String(), "", body, originalTranslated) |
| 118 | 123 | body, _ = sjson.SetBytes(body, "stream", false) |
| 119 | 124 | |
| 120 | − url := githubCopilotBaseURL + githubCopilotChatPath | |
| 125 | + path := githubCopilotChatPath | |
| 126 | + if useResponses { | |
| 127 | + path = githubCopilotResponsesPath | |
| 128 | + } | |
| 129 | + url := githubCopilotBaseURL + path | |
| 121 | 130 | httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) |
| 122 | 131 | if err != nil { |
| 123 | 132 | return resp, err |
| @@ -172,6 +181,9 @@ func (e *GitHubCopilotExecutor) Execute(ctx context.Context, auth *cliproxyauth. · 48 unmodified lines | ||
| 172 | 181 | appendAPIResponseChunk(ctx, e.cfg, data) |
| 173 | 182 | |
| 174 | 183 | detail := parseOpenAIUsage(data) |
| 184 | + if useResponses && detail.TotalTokens == 0 { | |
| 185 | + detail = parseOpenAIResponsesUsage(data) | |
| 186 | + } | |
| 175 | 187 | if detail.TotalTokens > 0 { |
| 176 | 188 | reporter.publish(ctx, detail) |
| 177 | 189 | } |
| @@ -194,7 +206,11 @@ func (e *GitHubCopilotExecutor) ExecuteStream(ctx context.Context, auth *cliprox · 16 unmodified lines | ||
| 194 | 206 | defer reporter.trackFailure(ctx, &err) |
| 195 | 207 | |
| 196 | 208 | from := opts.SourceFormat |
| 209 | + useResponses := useGitHubCopilotResponsesEndpoint(from) | |
| 197 | 210 | to := sdktranslator.FromString("openai") |
| 211 | + if useResponses { | |
| 212 | + to = sdktranslator.FromString("openai-response") | |
| 213 | + } | |
| 198 | 214 | originalPayload := bytes.Clone(req.Payload) |
| 199 | 215 | if len(opts.OriginalRequest) > 0 { |
| 200 | 216 | originalPayload = bytes.Clone(opts.OriginalRequest) |
| @@ -205,9 +221,15 @@ func (e *GitHubCopilotExecutor) ExecuteStream(ctx context.Context, auth *cliprox · 4 unmodified lines | ||
| 205 | 221 | body = applyPayloadConfigWithRoot(e.cfg, req.Model, to.String(), "", body, originalTranslated) |
| 206 | 222 | body, _ = sjson.SetBytes(body, "stream", true) |
| 207 | 223 | // Enable stream options for usage stats in stream |
| 208 | − body, _ = sjson.SetBytes(body, "stream_options.include_usage", true) | |
| 224 | + if !useResponses { | |
| 225 | + body, _ = sjson.SetBytes(body, "stream_options.include_usage", true) | |
| 226 | + } | |
| 209 | 227 | |
| 210 | − url := githubCopilotBaseURL + githubCopilotChatPath | |
| 228 | + path := githubCopilotChatPath | |
| 229 | + if useResponses { | |
| 230 | + path = githubCopilotResponsesPath | |
| 231 | + } | |
| 232 | + url := githubCopilotBaseURL + path | |
| 211 | 233 | httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) |
| 212 | 234 | if err != nil { |
| 213 | 235 | return nil, err |
| @@ -283,6 +305,10 @@ func (e *GitHubCopilotExecutor) ExecuteStream(ctx context.Context, auth *cliprox · 69 unmodified lines | ||
| 283 | 305 | } |
| 284 | 306 | if detail, ok := parseOpenAIStreamUsage(line); ok { |
| 285 | 307 | reporter.publish(ctx, detail) |
| 308 | + } else if useResponses { | |
| 309 | + if detail, ok := parseOpenAIResponsesStreamUsage(line); ok { | |
| 310 | + reporter.publish(ctx, detail) | |
| 311 | + } | |
| 286 | 312 | } |
| 287 | 313 | } |
| 288 | 314 | |
| @@ -393,6 +419,10 @@ func (e *GitHubCopilotExecutor) normalizeModel(_ string, body []byte) []byte { · 104 unmodified lines | ||
| 393 | 419 | return body |
| 394 | 420 | } |
| 395 | 421 | |
| 422 | +func useGitHubCopilotResponsesEndpoint(sourceFormat sdktranslator.Format) bool { | |
| 423 | + return sourceFormat.String() == "openai-response" | |
| 424 | +} | |
| 425 | + | |
| 396 | 426 | // isHTTPSuccess checks if the status code indicates success (2xx). |
| 397 | 427 | func isHTTPSuccess(statusCode int) bool { |
| 398 | 428 | return statusCode >= 200 && statusCode < 300 |