Skip to content

feat(demo): provider picker for OpenAI-compatible hosts#429

Open
tsushanth wants to merge 1 commit into
MacPaw:mainfrom
tsushanth:feat/issue-308-demo-provider-picker
Open

feat(demo): provider picker for OpenAI-compatible hosts#429
tsushanth wants to merge 1 commit into
MacPaw:mainfrom
tsushanth:feat/issue-308-demo-provider-picker

Conversation

@tsushanth

Copy link
Copy Markdown

Why

Closes #308.

The Demo is hardcoded to `api.openai.com`, so testing against any other OpenAI-compatible endpoint (Gemini's compat layer, Groq, OpenRouter, a local server, etc.) requires editing source. The issue specifically asks for a predefined provider picker that auto-populates host/basePath, with a "Custom…" escape hatch for everything else, and persistence across launches.

What

  • New `APIProvider` enum (`Demo/App/APIProvider.swift`) with cases for OpenAI, Gemini, Groq, OpenRouter, and Custom. Each known case carries its default host + basePath.
  • `APIKeyModalView` gains a provider Picker. Host/basePath text fields are read-only for known providers and editable when `Custom…` is selected.
  • `provider`, `host`, `basePath`, and `apiKey` are all `@AppStorage` keys, so the chosen configuration survives relaunch.
  • `APIProvidedView` builds `OpenAI.Configuration` from the stored values and rewires all stores on any change.

Screenshots / behaviour

  • Open the Demo, pick `Gemini (OpenAI-compatible)`: host becomes `generativelanguage.googleapis.com`, basePath becomes `/v1beta/openai`.
  • Pick `Custom…`: both fields go editable so you can point at `localhost:8080` or any internal endpoint.
  • Continue button is gated on a non-empty API key + non-empty host.

Build

`xcodebuild -project Demo/Demo.xcodeproj -scheme Demo -destination 'generic/platform=iOS Simulator' build` → `** BUILD SUCCEEDED **`.

Scope

SDK code is untouched — this is purely a Demo improvement, as the issue requested. Happy to follow up with a similar picker in the iOS example or take docs PRs separately.

Closes MacPaw#308.

Adds an `APIProvider` enum and a SwiftUI picker in `APIKeyModalView` so
the Demo can talk to any OpenAI-compatible endpoint without code changes.
Selecting `Gemini`, `Groq`, or `OpenRouter` auto-populates host +
basePath; selecting `Custom…` makes both fields editable.

Provider, host, base path, and API key are all persisted via
`@AppStorage`, so they survive relaunches. `APIProvidedView` now builds
the `OpenAI.Configuration` from these stored values and rewires the
stores on any change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a provider picker and persistent host/basePath configuration to the Demo app so it can target OpenAI-compatible endpoints without editing source (closes #308).

Changes:

  • Introduces APIProvider with predefined host/basePath defaults plus a Custom… option.
  • Extends APIKeyModalView UI to select provider and edit host/basePath when custom, persisting values via @AppStorage.
  • Updates APIProvidedView to build OpenAI.Configuration from stored host/basePath and rewire clients when those values change.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Demo/Demo.xcodeproj/project.pbxproj Adds APIProvider.swift to the Demo target.
Demo/App/DemoApp.swift Persists provider/host/basePath and wires bindings into the root views.
Demo/App/APIProvider.swift Defines provider presets (host + basePath) and display names.
Demo/App/APIProvidedView.swift Builds OpenAI.Configuration from persisted values and rewires stores on change.
Demo/App/APIKeyModalView.swift Adds provider picker + host/basePath controls and commits config to storage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +123 to 127
private static func makeConfiguration(apiKey: String, host: String, basePath: String) -> OpenAI.Configuration {
let resolvedHost = host.isEmpty ? "api.openai.com" : host
let resolvedBasePath = basePath.isEmpty ? "/v1" : basePath
return OpenAI.Configuration(token: apiKey, host: resolvedHost, basePath: resolvedBasePath)
}
imageStore.openAIClient = client
assistantStore.openAIClient = client
miscStore.openAIClient = client
responsesStore.client = client.responses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make Demo configurable for providers through UI

2 participants