Skip to content

Commit 9611dbf

Browse files
committed
fix(api): create Copilot provider from device flow token, load custom provider IDs
EndpointManager.setupProviders() only checked config.apiKey to decide whether to create a provider. GitHub Copilot uses device flow tokens stored in CopilotTokenStore, so also check CopilotTokenStore.shared.isSignedIn. Also iterate saved_provider_ids to pick up user-created providers with timestamp IDs that weren't covered by ProviderType.allCases. Guard ModelListManager against duplicate initialization.
1 parent a638b21 commit 9611dbf

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

Sources/APIFramework/EndpointManager.swift

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,11 @@ public class EndpointManager: ObservableObject {
642642
}
643643

644644
/// Only create provider if it has API key or doesn't require one.
645+
/// GitHub Copilot also accepts device flow tokens from CopilotTokenStore.
645646
let requiresKey = providerType.requiresApiKey
646-
if !requiresKey || config.apiKey != nil {
647+
let hasAuth = config.apiKey != nil ||
648+
(providerType == .githubCopilot && CopilotTokenStore.shared.isSignedIn)
649+
if !requiresKey || hasAuth {
647650
/// For local llama, create one provider per model using registry identifiers.
648651
if providerType == .localLlama {
649652
if let modelManager = localModelManager {
@@ -751,6 +754,30 @@ public class EndpointManager: ObservableObject {
751754
}
752755
}
753756

757+
// Also check saved_provider_ids for any user-created provider IDs (may have timestamps)
758+
if let savedProviderIds = UserDefaults.standard.stringArray(forKey: "saved_provider_ids") {
759+
for savedProviderId in savedProviderIds {
760+
// Skip if we already loaded this provider
761+
if providers[savedProviderId] != nil {
762+
continue
763+
}
764+
765+
// Try to load configuration for this custom ID
766+
if let config = loadProviderConfiguration(for: savedProviderId) {
767+
let requiresKey = config.providerType.requiresApiKey
768+
let hasAuth = config.apiKey != nil ||
769+
(config.providerType == .githubCopilot && CopilotTokenStore.shared.isSignedIn)
770+
if !requiresKey || hasAuth {
771+
providers[savedProviderId] = createProvider(type: config.providerType, config: config)
772+
providerConfigs[savedProviderId] = config
773+
logger.debug("Loaded saved provider \(savedProviderId) with \(config.models.count) models")
774+
} else {
775+
logger.debug("Saved provider \(savedProviderId) not loaded - requires API key")
776+
}
777+
}
778+
}
779+
}
780+
754781
logger.debug("Setup complete. Active providers: \(self.providers.keys.sorted().joined(separator: ", "))")
755782
}
756783

@@ -1200,8 +1227,11 @@ public class EndpointManager: ObservableObject {
12001227
}
12011228

12021229
/// Only create provider if it has API key or doesn't require one.
1230+
/// GitHub Copilot also accepts device flow tokens from CopilotTokenStore.
12031231
let requiresKey = providerType.requiresApiKey
1204-
if !requiresKey || config.apiKey != nil {
1232+
let hasAuth = config.apiKey != nil ||
1233+
(providerType == .githubCopilot && CopilotTokenStore.shared.isSignedIn)
1234+
if !requiresKey || hasAuth {
12051235
/// For local llama, create one provider per model using registry identifiers.
12061236
if providerType == .localLlama {
12071237
if let modelManager = localModelManager {

Sources/APIFramework/ModelListManager.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public class ModelListManager: ObservableObject {
3030

3131
/// Initialize the manager with required dependencies
3232
public func initialize(endpointManager: EndpointManager) {
33+
// Skip if already initialized with this endpoint manager
34+
if self.endpointManager != nil {
35+
logger.debug("ModelListManager already initialized, skipping")
36+
return
37+
}
3338
logger.info("Initializing ModelListManager with EndpointManager")
3439
self.endpointManager = endpointManager
3540

0 commit comments

Comments
 (0)