Add OpenAI-compatible profiles - #626
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR implements multi-profile support for OpenAI-compatible integrations, enabling users to configure and manage multiple independent providers with separate credentials, models, and settings. SDK protocols add stable provider identity and multi-provider hooks, PluginManager/PromptProcessingService discover expanded roles, OpenAI plugin refactors to profiles with UI/persistence, and tests exercise the flow. ChangesMulti-Profile OpenAI Integration Support
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
TypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/Tests/OpenAICompatiblePluginTests.swift (1)
231-268: ⚡ Quick winConsider testing both default and additional profile LLM for symmetry.
While this test correctly validates profile-scoped LLM behavior for an additional profile,
testProfileSpecificTranscriptionUsesSeparateCredentialsAndURLstests both the default profile and an additional profile, providing more comprehensive coverage. Consider adding a default profile setup with its own model/temperature and verifying both profiles work independently in a single test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@TypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/Tests/OpenAICompatiblePluginTests.swift` around lines 231 - 268, The test testProfileSpecificLLMUsesSeparateCredentialModelAndTemperature should also set up and assert behavior for the default profile so both default and additional profiles are validated; add configuration calls on the plugin for the default profile (e.g., plugin.setApiKey, plugin.selectLLMModel, plugin.setLLMTemperatureMode/.setLLMTemperatureValue) before creating the "Inception" profile, then call the provider(s) for the default profile (use plugin.additionalLLMProviders and the plugin's primary LLM provider or lookup by profile id) and assert the default request used the default baseURL, Authorization header, model and temperature, while keeping the existing assertions for inception (refer to PluginTestHostServices, OpenAICompatiblePlugin, plugin.addProfile, additionalLLMProviders, and provider.process to locate relevant code).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@TypeWhisper/Services/PluginManager.swift`:
- Around line 346-356: The current lookup in PluginManager.swift uses a single
first { ... } that mixes llmProviderId, display name, providerName and aliases
so a display-name/alias from an earlier provider can shadow a later provider
whose llmProviderId exactly matches providerName; change the logic to first try
to find an exact id match using
provider.llmProviderId.caseInsensitiveCompare(lookup) == .orderedSame, and only
if that returns nil fall back to a second pass that checks display name,
providerName and legacy aliases (case-insensitive) against lookup; keep the
existing trimming/guard and return type, and reference llmProviders,
provider.llmProviderId, provider.llmProviderDisplayName, provider.providerName
and provider.llmProviderLegacyAliases when making the two-pass search.
- Around line 287-296: The disable-path currently only checks if plugin.instance
as? TranscriptionEnginePlugin equals the selected provider, but plugins can also
expose additionalTranscriptionEngines via
AdditionalTranscriptionEnginesProviding; when disabling a plugin you must also
check if the selected transcription engine is one of plugin.instance as?
AdditionalTranscriptionEnginesProviding -> additionalTranscriptionEngines and,
if so, pick and set a safe fallback (e.g., another available
TranscriptionEnginePlugin) and update the selected/active transcription engine
state; modify the disable logic to compare against both the direct
TranscriptionEnginePlugin and the additionalTranscriptionEngines collection
before leaving the active provider unchanged.
---
Nitpick comments:
In
`@TypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/Tests/OpenAICompatiblePluginTests.swift`:
- Around line 231-268: The test
testProfileSpecificLLMUsesSeparateCredentialModelAndTemperature should also set
up and assert behavior for the default profile so both default and additional
profiles are validated; add configuration calls on the plugin for the default
profile (e.g., plugin.setApiKey, plugin.selectLLMModel,
plugin.setLLMTemperatureMode/.setLLMTemperatureValue) before creating the
"Inception" profile, then call the provider(s) for the default profile (use
plugin.additionalLLMProviders and the plugin's primary LLM provider or lookup by
profile id) and assert the default request used the default baseURL,
Authorization header, model and temperature, while keeping the existing
assertions for inception (refer to PluginTestHostServices,
OpenAICompatiblePlugin, plugin.addProfile, additionalLLMProviders, and
provider.process to locate relevant code).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2753f837-1833-47e4-8e49-cd9a21bb2287
📒 Files selected for processing (8)
TypeWhisper.xcodeproj/project.pbxprojTypeWhisper/Services/PluginManager.swiftTypeWhisper/Services/PromptProcessingService.swiftTypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/OpenAICompatiblePlugin.swiftTypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/Tests/OpenAICompatiblePluginTests.swiftTypeWhisperPluginSDK/Plugins/OpenAICompatiblePlugin/manifest.jsonTypeWhisperPluginSDK/Sources/TypeWhisperPluginSDK/TypeWhisperPlugin.swiftTypeWhisperTests/APIRouterAndHandlersTests.swift
Summary
1.5.0plus OpenAI Compatible to1.1.0withminHostVersion: 1.5.0.Issue Context
Issue #625 asks for multiple OpenAI-compatible profiles so endpoints such as Alter and Inception can be configured independently and selected separately for transcription and LLM prompt processing, without duplicate plugin bundles and without breaking existing single-profile setups.
Closes #625
Daily Build
The scheduled release workflow derives daily tags from
MARKETING_VERSION. This branch sets the host app version to1.5.0, so after it lands onmain, the next scheduled daily build will use av1.5.0-daily.<date>tag.Test Plan
swift test --package-path TypeWhisperPluginSDK --filter OpenAICompatiblePluginTestsxcodebuild test -project TypeWhisper.xcodeproj -scheme TypeWhisper -destination 'platform=macOS,arch=arm64' -parallel-testing-enabled NO -only-testing:TypeWhisperTests/APIRouterAndHandlersTests -only-testing:TypeWhisperTests/PluginManifestValidationTests -only-testing:TypeWhisperTests/WorkflowServiceTests CODE_SIGN_IDENTITY='-' CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NOgit diff --checkswift test --package-path TypeWhisperPluginSDKxcodebuild test -project TypeWhisper.xcodeproj -scheme TypeWhisper -destination 'platform=macOS,arch=arm64' -parallel-testing-enabled NO CODE_SIGN_IDENTITY='-' CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO/Users/marco/Projects/typewhisper-dev-tools/build-typewhisper-mac-dev.sh --run /Users/marco/Projects/typewhisper-mac/Users/marco/Projects/typewhisper-dev-tools/build-typewhisper-plugin-dev.sh OpenAICompatiblePlugin /Users/marco/Projects/typewhisper-macSummary by CodeRabbit
New Features
Bug Fixes / Improvements
Chores