How Meetily Supports Multiple AI Providers: Ollama, Claude, Groq, and OpenRouter Integration Explained

Meetily supports multiple AI providers through a unified LLM client abstraction layer in its Tauri backend, routing requests to Ollama, Claude, Groq, and OpenRouter via provider-specific modules while exposing a single API to the frontend.

Meetily's open-source meeting assistant enables users to choose from diverse AI backends—from local Ollama instances to cloud providers like Claude, Groq, and OpenRouter—without changing application code. This flexibility is implemented in the Rust-based Tauri backend under frontend/src-tauri/src/summary/, where a provider-agnostic architecture handles authentication, request formatting, and token management automatically.


Provider Enumeration and Abstraction

The foundation of Meetily's multi-provider support is the LLMProvider enum defined in frontend/src-tauri/src/summary/llm_client.rs. This single type enumerates every supported backend:

  • OpenAI – default cloud provider
  • Claude – Anthropic's Claude models
  • Groq – Groq's OpenAI-compatible API
  • Ollama – local Ollama server (no API key required)
  • OpenRouter – the OpenRouter model marketplace
  • BuiltInAI and CustomOpenAI – internal or user-supplied endpoints

The enum implements from_str for parsing user selections and provider_name for display labels. This abstraction ensures the rest of the codebase remains provider-agnostic.


Request Routing in the Summary Service

The summary service (frontend/src-tauri/src/summary/service.rs) orchestrates provider selection. When the UI invokes the summarize command, the service:

  1. Parses the model_provider string into an LLMProvider variant
  2. Conditionally retrieves API keys (omitted for local providers)
  3. Reads custom endpoints for Ollama or CustomOpenAI configurations
  4. Delegates to the LLM client for HTTP request construction

Key routing logic:

let provider = LLMProvider::from_str(&model_provider)?;
let api_key = if provider == LLMProvider::Ollama
              || provider == LLMProvider::BuiltInAI
              || provider == LLMProvider::CustomOpenAI {
    None
} else {
    Some(user_provided_key)
};

This conditional key handling eliminates configuration friction for local deployments while maintaining security for cloud credentials.


Provider-Specific Integration Modules

Each AI backend has a dedicated module implementing discovery, request formatting, and authentication:

Ollama Integration (ollama/ollama.rs)

The Ollama module manages local LLM execution:

  • Validates the endpoint URL (default: http://127.0.0.1:11434)
  • Discovers available models via GET /api/tags
  • Automatically downloads missing models
  • Constructs Ollama-native request bodies without API keys

Claude Integration (anthropic/anthropic.rs)

The Anthropic module handles cloud-based Claude models:

  • Maintains Claude model listings with version and capability metadata
  • Builds Anthropic-specific JSON schemas distinct from OpenAI format
  • Injects required headers including anthropic-version

Groq Integration (groq/groq.rs)

The Groq module leverages Groq's OpenAI-compatible API:

  • Queries /v1/models for available model inventory
  • Caches model listings to reduce API calls
  • Uses standard OpenAI request schemas (Groq maintains compatibility)

OpenRouter Integration (openrouter/openrouter.rs)

The OpenRouter module connects to the model aggregation service:

  • Retrieves the complete OpenRouter model catalog
  • Sets the Authorization header with user-provided OpenRouter credentials
  • Enables access to hundreds of models through a single integration point

Built-in and Custom Endpoints (summary/summary_engine/client.rs)

For self-hosted or internal models, this module supports arbitrary OpenAI-compatible endpoints, allowing enterprises to point Meetily at private inference servers.

All modules expose a consistent interface: fn get_<provider>_models(...) -> Result<Vec<Model>, String>, enabling a unified model picker in the UI.


Unified Request Handling and Response Parsing

The llm_client.rs module centralizes HTTP execution. Despite provider differences, it produces a uniform interface:

  • Request body selection – Most providers use OpenAI-compatible schemas; Claude requires special handling
  • Header injection – Cloud providers receive Authorization headers; Ollama receives none
  • Response normalization – All results parse into a unified LLMResponse type

Example request construction:

let request_body = if provider != &LLMProvider::Claude {
    serde_json::json!({
        "model": model_name,
        "messages": messages,
        "max_tokens": max_tokens,
        "temperature": temperature,
    })
} else {
    serde_json::json!(ClaudeRequest { /* Anthropic-specific fields */ })
};

The frontend communicates through a single Tauri command regardless of provider:

import { invoke } from '@tauri-apps/api/tauri';

async function summarize(meetingId, provider) {
  const result = await invoke('summarize', {
    meetingId,
    modelProvider: provider, // "ollama", "claude", "groq", "openrouter"
  });
  return result;
}

Token Limit Adaptation by Provider

Different providers enforce varying context window limits. The summary processor (frontend/src-tauri/src/summary/processor.rs) adapts chunking strategy accordingly:

if (provider != &LLMProvider::Ollama && provider != &LLMProvider::BuiltInAI)
   || total_tokens < token_threshold { 
    // Apply chunking for cloud providers or large transcripts
}

Local providers (Ollama, BuiltInAI) typically receive complete transcripts—their local operation removes network latency and cost constraints. Cloud providers may receive strategically chunked content to respect rate limits and token quotas.


Key Source Files

Component File Path Purpose
Provider enum and helpers frontend/src-tauri/src/summary/llm_client.rs Defines LLMProvider, request routing, HTTP execution
Summarization service frontend/src-tauri/src/summary/service.rs Parses UI requests, manages credentials
Token-aware processor frontend/src-tauri/src/summary/processor.rs Applies provider-specific chunking logic
Ollama driver frontend/src-tauri/src/ollama/ollama.rs Local model discovery and execution
Claude driver frontend/src-tauri/src/anthropic/anthropic.rs Anthropic API integration
Groq driver frontend/src-tauri/src/groq/groq.rs Groq cloud integration
OpenRouter driver frontend/src-tauri/src/openrouter/openrouter.rs OpenRouter marketplace access

Summary

  • Provider abstraction via LLMProvider enum centralizes backend selection in llm_client.rs
  • Conditional authentication automatically omits API keys for local providers (Ollama, BuiltInAI)
  • Modular drivers in dedicated directories handle provider-specific discovery, headers, and request formats
  • Unified frontend API exposes a single invoke('summarize', ...) command regardless of chosen backend
  • Adaptive token handling applies aggressive chunking only to cloud providers, preserving full context for local models

Frequently Asked Questions

How do I switch between AI providers in Meetily?

Provider selection occurs through the modelProvider parameter in the summarize Tauri command. The UI passes a string like "ollama", "claude", "groq", or "openrouter", which LLMProvider::from_str parses into the appropriate enum variant. No frontend code changes are required to switch providers.

Does Meetily require an API key for every provider?

No. The summary/service.rs routing logic explicitly excludes LLMProvider::Ollama, LLMProvider::BuiltInAI, and LLMProvider::CustomOpenAI from key requirements. Cloud providers (Claude, Groq, OpenRouter, OpenAI) require valid API keys, which the service retrieves from user settings.

Why does Claude use a different request format than other providers?

Anthropic's Claude API predates widespread OpenAI compatibility and maintains a distinct JSON schema. The llm_client.rs module detects LLMProvider::Claude and branches to a ClaudeRequest struct, while Groq, OpenRouter, and most others accept standard OpenAI-compatible payloads.

Can I use a self-hosted model with Meetily?

Yes. The CustomOpenAI variant in LLMProvider supports arbitrary OpenAI-compatible endpoints. Configure your custom base URL in settings, and the summary service routes requests to your self-hosted inference server without cloud dependencies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →