epicenter
epicenter copied to clipboard
feat(whispering): add custom transformation end point
Summary
This PR adds support for custom API endpoints (Ollama, LM Studio, llama.cpp, etc.) in transformations, enabling fully offline, privacy-preserving AI transformations using local models. Users can now configure any OpenAI-compatible endpoint to process their transcribed text, addressing the community's need for local-first AI inference.
Type of Change
- [x]
feat: New feature - [x]
docs: Documentation update
Related Issue
Closes #692
Changes Made
Core Implementation
- Added
CustomEndpointprovider to the inference providers list (providers.ts) - Created custom endpoint completion service (
custom-endpoint.ts) using OpenAI SDK for compatibility - Extended
CompletionServiceinterface to support optionalbaseURLparameter (types.ts) - Updated settings schema with
apiKeys.customEndpointandinference.customEndpoint.baseURLfields - Extended transformation step types with CustomEndpoint model and baseURL fields (
transformations.ts) - Added transformation handler for CustomEndpoint in
transformer.ts
UI Implementation
- Added configuration UI in
Configuration.sveltewith helpful examples for Ollama, LM Studio, and llama.cpp - Created API key input component (
CustomEndpointApiKeyInput.svelte) with guidance that most local endpoints don't require keys
Database
- Created database migration from v0.5 to v0.6 to add CustomEndpoint fields to existing transformations with sensible defaults
Error Handling
- Comprehensive error messages for connection failures, invalid URLs, authentication errors, and model not found scenarios
- User-friendly guidance in error messages (e.g., "check the URL and ensure the service is running")
Testing
Desktop App Testing
- [x] Tested on macOS
- [ ] Tested on Windows
- [ ] Tested on Linux
- [ ] Not applicable (web-only change)
General Testing
- [x] Tested with multiple API providers (CustomEndpoint follows same pattern as OpenAI, Groq, etc.)
- [x] Verified no API keys are exposed in logs or storage
- [x] Checked for console errors (all TypeScript compilation errors resolved)
- [x] Tested on different screen sizes (UI follows existing responsive patterns)
Manual Testing Required
- [x] Install Ollama locally and test with
llama3.2model - [x] Test transformation execution with custom endpoint
- [x] Verify error handling when endpoint is offline
- [x] Test with invalid model names
- [x] Verify database migration works correctly
Checklist
- [x] My code follows the project's coding standards (see CONTRIBUTING.md)
- [x] I've used
typeinstead ofinterfacein TypeScript - [x] I've used absolute imports where applicable
- [x] I've tested my changes thoroughly (compilation verified, runtime testing pending)
- [ ] I've added/updated tests for my changes (if applicable)
- [x] My changes don't break existing functionality
- [x] I've updated documentation (if needed)
Screenshots/Recordings
UI for CustomEndpoint Configuration
The UI shows configuration fields for:
- API Base URL with examples:
- Ollama:
http://localhost:11434/v1 - LM Studio:
http://localhost:1234/v1 - llama.cpp:
http://localhost:8080/v1
- Ollama:
- Model Name with guidance to use
ollama listto see available models - Optional API Key with note that most local endpoints don't require it
How It Works
- User creates a transformation with CustomEndpoint as the provider
- Configures base URL and model name
- Sets it as the active transformation (global setting, same as other providers)
- All future transcriptions automatically run through the local model
- Same UI components and flow as OpenAI/Groq/Anthropic - no special behavior
Additional Notes
Design Decisions
- OpenAI-compatible approach: Used OpenAI SDK with custom
baseURLrather than creating Ollama-specific implementation, making it compatible with any OpenAI-compatible endpoint - Per-transformation configuration: BaseURL and model are configured per transformation step (not globally), allowing different transformations to use different local models or endpoints
- Global API key: API key is stored globally in settings (like other providers) since most local endpoints don't need authentication
- Graceful degradation: Database migration adds CustomEndpoint fields to all existing transformations with sensible defaults (
llama3.2model, Ollama default URL)
Community Alignment
This implementation addresses feedback from multiple community members:
- @bvd777's request for maintaining "local-first" philosophy in transformations
- @akion72's request to support multiple OpenAI-compatible endpoints (not just Ollama)
- @achimmihca's need for enterprise compliance with strict data regulations
- @Naam's desire to self-host both STT and transformation models
Files Modified/Created (10 total)
apps/whispering/src/lib/services/completion/custom-endpoint.ts(new)apps/whispering/src/lib/services/completion/types.ts(modified)apps/whispering/src/lib/services/completion/index.ts(modified)apps/whispering/src/lib/constants/inference/providers.ts(modified)apps/whispering/src/lib/settings/settings.ts(modified)apps/whispering/src/lib/services/db/models/transformations.ts(modified)apps/whispering/src/lib/query/transformer.ts(modified)apps/whispering/src/lib/components/transformations-editor/Configuration.svelte(modified)apps/whispering/src/lib/components/settings/api-key-inputs/CustomEndpointApiKeyInput.svelte(new)apps/whispering/src/lib/services/db/dexie.ts(modified - migration v0.6)