epicenter icon indicating copy to clipboard operation
epicenter copied to clipboard

feat(whispering): add custom transformation end point

Open vishesh-sachan opened this issue 1 month ago • 0 comments

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

  1. Added CustomEndpoint provider to the inference providers list (providers.ts)
  2. Created custom endpoint completion service (custom-endpoint.ts) using OpenAI SDK for compatibility
  3. Extended CompletionService interface to support optional baseURL parameter (types.ts)
  4. Updated settings schema with apiKeys.customEndpoint and inference.customEndpoint.baseURL fields
  5. Extended transformation step types with CustomEndpoint model and baseURL fields (transformations.ts)
  6. Added transformation handler for CustomEndpoint in transformer.ts

UI Implementation

  1. Added configuration UI in Configuration.svelte with helpful examples for Ollama, LM Studio, and llama.cpp
  2. Created API key input component (CustomEndpointApiKeyInput.svelte) with guidance that most local endpoints don't require keys

Database

  1. 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.2 model
  • [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 type instead of interface in 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
  • Model Name with guidance to use ollama list to see available models
  • Optional API Key with note that most local endpoints don't require it

How It Works

  1. User creates a transformation with CustomEndpoint as the provider
  2. Configures base URL and model name
  3. Sets it as the active transformation (global setting, same as other providers)
  4. All future transcriptions automatically run through the local model
  5. Same UI components and flow as OpenAI/Groq/Anthropic - no special behavior

Additional Notes

Design Decisions

  • OpenAI-compatible approach: Used OpenAI SDK with custom baseURL rather 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.2 model, 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)

  1. apps/whispering/src/lib/services/completion/custom-endpoint.ts (new)
  2. apps/whispering/src/lib/services/completion/types.ts (modified)
  3. apps/whispering/src/lib/services/completion/index.ts (modified)
  4. apps/whispering/src/lib/constants/inference/providers.ts (modified)
  5. apps/whispering/src/lib/settings/settings.ts (modified)
  6. apps/whispering/src/lib/services/db/models/transformations.ts (modified)
  7. apps/whispering/src/lib/query/transformer.ts (modified)
  8. apps/whispering/src/lib/components/transformations-editor/Configuration.svelte (modified)
  9. apps/whispering/src/lib/components/settings/api-key-inputs/CustomEndpointApiKeyInput.svelte (new)
  10. apps/whispering/src/lib/services/db/dexie.ts (modified - migration v0.6)

vishesh-sachan avatar Nov 01 '25 03:11 vishesh-sachan