luispater commited on
Commit
a36e9ba
·
unverified ·
1 Parent(s): c23f687

fix(kimi): update base URL and integrate ClaudeExecutor fallback

Browse files

- Updated `KimiAPIBaseURL` to remove versioning from the root path.
- Integrated `ClaudeExecutor` fallback in `KimiExecutor` methods for compatibility with Claude requests.
- Simplified token counting by delegating to `ClaudeExecutor`.

internal/auth/kimi/kimi.go CHANGED
@@ -30,7 +30,7 @@ const (
30
  // kimiTokenURL is the endpoint for exchanging device codes for tokens.
31
  kimiTokenURL = kimiOAuthHost + "/api/oauth/token"
32
  // KimiAPIBaseURL is the base URL for Kimi API requests.
33
- KimiAPIBaseURL = "https://api.kimi.com/coding/v1"
34
  // defaultPollInterval is the default interval for polling token endpoint.
35
  defaultPollInterval = 5 * time.Second
36
  // maxPollDuration is the maximum time to wait for user authorization.
 
30
  // kimiTokenURL is the endpoint for exchanging device codes for tokens.
31
  kimiTokenURL = kimiOAuthHost + "/api/oauth/token"
32
  // KimiAPIBaseURL is the base URL for Kimi API requests.
33
+ KimiAPIBaseURL = "https://api.kimi.com/coding"
34
  // defaultPollInterval is the default interval for polling token endpoint.
35
  defaultPollInterval = 5 * time.Second
36
  // maxPollDuration is the maximum time to wait for user authorization.
internal/runtime/executor/kimi_executor.go CHANGED
@@ -25,6 +25,7 @@ import (
25
 
26
  // KimiExecutor is a stateless executor for Kimi API using OpenAI-compatible chat completions.
27
  type KimiExecutor struct {
 
28
  cfg *config.Config
29
  }
30
 
@@ -64,6 +65,12 @@ func (e *KimiExecutor) HttpRequest(ctx context.Context, auth *cliproxyauth.Auth,
64
 
65
  // Execute performs a non-streaming chat completion request to Kimi.
66
  func (e *KimiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (resp cliproxyexecutor.Response, err error) {
 
 
 
 
 
 
67
  baseModel := thinking.ParseSuffix(req.Model).ModelName
68
 
69
  token := kimiCreds(auth)
@@ -71,7 +78,6 @@ func (e *KimiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req
71
  reporter := newUsageReporter(ctx, e.Identifier(), baseModel, auth)
72
  defer reporter.trackFailure(ctx, &err)
73
 
74
- from := opts.SourceFormat
75
  to := sdktranslator.FromString("openai")
76
  originalPayload := bytes.Clone(req.Payload)
77
  if len(opts.OriginalRequest) > 0 {
@@ -95,7 +101,7 @@ func (e *KimiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req
95
  requestedModel := payloadRequestedModel(opts, req.Model)
96
  body = applyPayloadConfigWithRoot(e.cfg, baseModel, to.String(), "", body, originalTranslated, requestedModel)
97
 
98
- url := kimiauth.KimiAPIBaseURL + "/chat/completions"
99
  httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
100
  if err != nil {
101
  return resp, err
@@ -155,14 +161,18 @@ func (e *KimiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req
155
 
156
  // ExecuteStream performs a streaming chat completion request to Kimi.
157
  func (e *KimiExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (stream <-chan cliproxyexecutor.StreamChunk, err error) {
158
- baseModel := thinking.ParseSuffix(req.Model).ModelName
 
 
 
 
159
 
 
160
  token := kimiCreds(auth)
161
 
162
  reporter := newUsageReporter(ctx, e.Identifier(), baseModel, auth)
163
  defer reporter.trackFailure(ctx, &err)
164
 
165
- from := opts.SourceFormat
166
  to := sdktranslator.FromString("openai")
167
  originalPayload := bytes.Clone(req.Payload)
168
  if len(opts.OriginalRequest) > 0 {
@@ -190,7 +200,7 @@ func (e *KimiExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Aut
190
  requestedModel := payloadRequestedModel(opts, req.Model)
191
  body = applyPayloadConfigWithRoot(e.cfg, baseModel, to.String(), "", body, originalTranslated, requestedModel)
192
 
193
- url := kimiauth.KimiAPIBaseURL + "/chat/completions"
194
  httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
195
  if err != nil {
196
  return nil, err
@@ -269,26 +279,8 @@ func (e *KimiExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Aut
269
 
270
  // CountTokens estimates token count for Kimi requests.
271
  func (e *KimiExecutor) CountTokens(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (cliproxyexecutor.Response, error) {
272
- baseModel := thinking.ParseSuffix(req.Model).ModelName
273
-
274
- from := opts.SourceFormat
275
- to := sdktranslator.FromString("openai")
276
- body := sdktranslator.TranslateRequest(from, to, baseModel, bytes.Clone(req.Payload), false)
277
-
278
- // Use a generic tokenizer for estimation
279
- enc, err := tokenizerForModel("gpt-4")
280
- if err != nil {
281
- return cliproxyexecutor.Response{}, fmt.Errorf("kimi executor: tokenizer init failed: %w", err)
282
- }
283
-
284
- count, err := countOpenAIChatTokens(enc, body)
285
- if err != nil {
286
- return cliproxyexecutor.Response{}, fmt.Errorf("kimi executor: token counting failed: %w", err)
287
- }
288
-
289
- usageJSON := buildOpenAIUsageJSON(count)
290
- translated := sdktranslator.TranslateTokenCount(ctx, to, from, count, usageJSON)
291
- return cliproxyexecutor.Response{Payload: []byte(translated)}, nil
292
  }
293
 
294
  // Refresh refreshes the Kimi token using the refresh token.
 
25
 
26
  // KimiExecutor is a stateless executor for Kimi API using OpenAI-compatible chat completions.
27
  type KimiExecutor struct {
28
+ ClaudeExecutor
29
  cfg *config.Config
30
  }
31
 
 
65
 
66
  // Execute performs a non-streaming chat completion request to Kimi.
67
  func (e *KimiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (resp cliproxyexecutor.Response, err error) {
68
+ from := opts.SourceFormat
69
+ if from.String() == "claude" {
70
+ auth.Attributes["base_url"] = kimiauth.KimiAPIBaseURL
71
+ return e.ClaudeExecutor.Execute(ctx, auth, req, opts)
72
+ }
73
+
74
  baseModel := thinking.ParseSuffix(req.Model).ModelName
75
 
76
  token := kimiCreds(auth)
 
78
  reporter := newUsageReporter(ctx, e.Identifier(), baseModel, auth)
79
  defer reporter.trackFailure(ctx, &err)
80
 
 
81
  to := sdktranslator.FromString("openai")
82
  originalPayload := bytes.Clone(req.Payload)
83
  if len(opts.OriginalRequest) > 0 {
 
101
  requestedModel := payloadRequestedModel(opts, req.Model)
102
  body = applyPayloadConfigWithRoot(e.cfg, baseModel, to.String(), "", body, originalTranslated, requestedModel)
103
 
104
+ url := kimiauth.KimiAPIBaseURL + "/v1/chat/completions"
105
  httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
106
  if err != nil {
107
  return resp, err
 
161
 
162
  // ExecuteStream performs a streaming chat completion request to Kimi.
163
  func (e *KimiExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (stream <-chan cliproxyexecutor.StreamChunk, err error) {
164
+ from := opts.SourceFormat
165
+ if from.String() == "claude" {
166
+ auth.Attributes["base_url"] = kimiauth.KimiAPIBaseURL
167
+ return e.ClaudeExecutor.ExecuteStream(ctx, auth, req, opts)
168
+ }
169
 
170
+ baseModel := thinking.ParseSuffix(req.Model).ModelName
171
  token := kimiCreds(auth)
172
 
173
  reporter := newUsageReporter(ctx, e.Identifier(), baseModel, auth)
174
  defer reporter.trackFailure(ctx, &err)
175
 
 
176
  to := sdktranslator.FromString("openai")
177
  originalPayload := bytes.Clone(req.Payload)
178
  if len(opts.OriginalRequest) > 0 {
 
200
  requestedModel := payloadRequestedModel(opts, req.Model)
201
  body = applyPayloadConfigWithRoot(e.cfg, baseModel, to.String(), "", body, originalTranslated, requestedModel)
202
 
203
+ url := kimiauth.KimiAPIBaseURL + "/v1/chat/completions"
204
  httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
205
  if err != nil {
206
  return nil, err
 
279
 
280
  // CountTokens estimates token count for Kimi requests.
281
  func (e *KimiExecutor) CountTokens(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (cliproxyexecutor.Response, error) {
282
+ auth.Attributes["base_url"] = kimiauth.KimiAPIBaseURL
283
+ return e.ClaudeExecutor.CountTokens(ctx, auth, req, opts)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  }
285
 
286
  // Refresh refreshes the Kimi token using the refresh token.