added kilocode auth, needs adjusting

This commit is contained in:
DetroitTommy
2026-02-15 13:44:26 -05:00
parent d560c20c26
commit 1dbeb0827a
15 changed files with 755 additions and 12 deletions

121
sdk/auth/kilo.go Normal file
View File

@@ -0,0 +1,121 @@
package auth
import (
"context"
"fmt"
"time"
"github.com/router-for-me/CLIProxyAPI/v6/internal/auth/kilo"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
)
// KiloAuthenticator implements the login flow for Kilo AI accounts.
type KiloAuthenticator struct{}
// NewKiloAuthenticator constructs a Kilo authenticator.
func NewKiloAuthenticator() *KiloAuthenticator {
return &KiloAuthenticator{}
}
func (a *KiloAuthenticator) Provider() string {
return "kilo"
}
func (a *KiloAuthenticator) RefreshLead() *time.Duration {
return nil
}
// Login manages the device flow authentication for Kilo AI.
func (a *KiloAuthenticator) Login(ctx context.Context, cfg *config.Config, opts *LoginOptions) (*coreauth.Auth, error) {
if cfg == nil {
return nil, fmt.Errorf("cliproxy auth: configuration is required")
}
if ctx == nil {
ctx = context.Background()
}
if opts == nil {
opts = &LoginOptions{}
}
kilocodeAuth := kilo.NewKiloAuth()
fmt.Println("Initiating Kilo device authentication...")
resp, err := kilocodeAuth.InitiateDeviceFlow(ctx)
if err != nil {
return nil, fmt.Errorf("failed to initiate device flow: %w", err)
}
fmt.Printf("Please visit: %s\n", resp.VerificationURL)
fmt.Printf("And enter code: %s\n", resp.Code)
fmt.Println("Waiting for authorization...")
status, err := kilocodeAuth.PollForToken(ctx, resp.Code)
if err != nil {
return nil, fmt.Errorf("authentication failed: %w", err)
}
fmt.Printf("Authentication successful for %s\n", status.UserEmail)
profile, err := kilocodeAuth.GetProfile(ctx, status.Token)
if err != nil {
return nil, fmt.Errorf("failed to fetch profile: %w", err)
}
var orgID string
if len(profile.Orgs) > 1 {
fmt.Println("Multiple organizations found. Please select one:")
for i, org := range profile.Orgs {
fmt.Printf("[%d] %s (%s)\n", i+1, org.Name, org.ID)
}
if opts.Prompt != nil {
input, err := opts.Prompt("Enter the number of the organization: ")
if err != nil {
return nil, err
}
var choice int
fmt.Sscanf(input, "%d", &choice)
if choice > 0 && choice <= len(profile.Orgs) {
orgID = profile.Orgs[choice-1].ID
} else {
orgID = profile.Orgs[0].ID
fmt.Printf("Invalid choice, defaulting to %s\n", profile.Orgs[0].Name)
}
} else {
orgID = profile.Orgs[0].ID
fmt.Printf("Non-interactive mode, defaulting to organization: %s\n", profile.Orgs[0].Name)
}
} else if len(profile.Orgs) == 1 {
orgID = profile.Orgs[0].ID
}
defaults, err := kilocodeAuth.GetDefaults(ctx, status.Token, orgID)
if err != nil {
fmt.Printf("Warning: failed to fetch defaults: %v\n", err)
defaults = &kilo.Defaults{}
}
ts := &kilo.KiloTokenStorage{
Token: status.Token,
OrganizationID: orgID,
Model: defaults.Model,
Email: status.UserEmail,
Type: "kilo",
}
fileName := kilo.CredentialFileName(status.UserEmail)
metadata := map[string]any{
"email": status.UserEmail,
"organization_id": orgID,
"model": defaults.Model,
}
return &coreauth.Auth{
ID: fileName,
Provider: a.Provider(),
FileName: fileName,
Storage: ts,
Metadata: metadata,
}, nil
}

View File

@@ -413,6 +413,8 @@ func (s *Service) ensureExecutorsForAuth(a *coreauth.Auth) {
s.coreManager.RegisterExecutor(executor.NewKimiExecutor(s.cfg))
case "kiro":
s.coreManager.RegisterExecutor(executor.NewKiroExecutor(s.cfg))
case "kilo":
s.coreManager.RegisterExecutor(executor.NewKiloExecutor(s.cfg))
case "github-copilot":
s.coreManager.RegisterExecutor(executor.NewGitHubCopilotExecutor(s.cfg))
default:
@@ -844,6 +846,9 @@ func (s *Service) registerModelsForAuth(a *coreauth.Auth) {
case "kiro":
models = s.fetchKiroModels(a)
models = applyExcludedModels(models, excluded)
case "kilo":
models = executor.FetchKiloModels(context.Background(), a, s.cfg)
models = applyExcludedModels(models, excluded)
default:
// Handle OpenAI-compatibility providers by name using config
if s.cfg != nil {