How to Configure a Custom OpenAI-Compatible Endpoint for AI Summaries in Meetily
Meetily routes AI summary requests to any OpenAI-compatible service by accepting a custom endpoint URL through the builtin_ai_generate_summary Tauri command, which constructs the final request URL as {endpoint}/chat/completions in the LLM client.
Meetily, an open-source meeting assistant built by Zackriya-Solutions, supports flexible AI providers for generating meeting summaries. While it works with OpenAI out of the box, you can configure it to use private proxies, Azure OpenAI, or self-hosted models that implement the OpenAI chat completions API. This is achieved by passing a custom endpoint URL through the Rust backend's provider system, specifically via the CustomOpenAI variant.
Understanding the Architecture Flow
The configuration relies on a three-layer architecture that passes the endpoint from the UI to the HTTP client:
- Frontend Invocation: The React/TypeScript frontend calls the Tauri command
builtin_ai_generate_summarywith thecustomOpenAIEndpointparameter. - Command Routing: Located in
frontend/src-tauri/src/summary/summary_engine/commands.rs, this command forwards the endpoint to the core LLM client. - URL Construction: In
frontend/src-tauri/src/summary/llm_client.rs(lines 173-179), when the provider isLLMProvider::CustomOpenAI, the code constructs the final URL by appending/chat/completionsto your custom endpoint.
Configuring the Custom Endpoint
Frontend Invocation (TypeScript)
To trigger a summary with a custom endpoint, invoke the Tauri command with the provider set to custom-openai:
import { invoke } from '@tauri-apps/api/tauri';
async function generateSummaryViaCustomOpenAI(
transcript: string,
apiKey: string,
model = 'gpt-4',
endpoint = 'https://my-openai-proxy.example.com'
) {
const result = await invoke<string>('builtin_ai_generate_summary', {
provider: 'custom-openai',
modelName: model,
apiKey,
systemPrompt: 'You are a concise meeting-summary assistant.',
userPrompt: transcript,
customOpenAIEndpoint: endpoint,
maxTokens: 1024,
temperature: 0.7,
topP: 0.9,
});
return result;
}
Backend Command Handling (Rust)
The builtin_ai_generate_summary command in commands.rs accepts the optional endpoint and passes it to the LLM client:
#[tauri::command]
pub async fn builtin_ai_generate_summary(
provider: String,
model_name: String,
api_key: String,
system_prompt: String,
user_prompt: String,
custom_openai_endpoint: Option<String>,
) -> Result<String, String> {
let provider = LLMProvider::from_str(&provider)?;
let client = reqwest::Client::new();
summary::llm_client::generate_summary(
&client,
&provider,
&model_name,
&api_key,
&system_prompt,
&user_prompt,
None, // ollama_endpoint
custom_openai_endpoint.as_deref(),
max_tokens,
temperature,
top_p,
None, // app_data_dir
None, // cancellation token
)
.await
}
URL Construction in the LLM Client
Inside frontend/src-tauri/src/summary/llm_client.rs, the code specifically handles the CustomOpenAI variant by trimming trailing slashes and appending the chat completions path:
// Lines 173-179 in llm_client.rs
let url = format!("{}/chat/completions", endpoint.trim_end_matches('/'));
This ensures your custom endpoint receives a properly formatted POST request to /chat/completions with the standard OpenAI request body containing your model, messages, and authentication headers.
Persisting the Configuration
Meetily stores user preferences in a JSON file within the app data directory. To persist the custom endpoint, write it to the settings store under the summary key:
{
"summary": {
"customOpenAIEndpoint": "https://my-openai-proxy.example.com"
}
}
The settings UI in frontend/src/app reads this value and passes it as the customOpenAIEndpoint argument when calling the Tauri command, ensuring the custom endpoint persists across application restarts without hardcoding values in the source.
Summary
- Meetily supports custom OpenAI-compatible endpoints through the
CustomOpenAIprovider variant. - Pass the endpoint URL via the
customOpenAIEndpointparameter in thebuiltin_ai_generate_summaryTauri command. - The backend constructs the request URL in
llm_client.rsby appending/chat/completionsto your endpoint. - Store the endpoint in Meetily's JSON settings file under
summary.customOpenAIEndpointfor persistence. - This approach works with Azure OpenAI, private proxies, and self-hosted models like vLLM or Text Generation Inference.
Frequently Asked Questions
What parameter name should I use for the custom endpoint?
Use customOpenAIEndpoint in TypeScript when calling the Tauri command, which maps to custom_openai_endpoint in the Rust backend. The parameter is optional (Option<String> in Rust) and only required when using the custom-openai provider.
Does this support Azure OpenAI or local models like Ollama?
Yes. Any service implementing the OpenAI chat completions API format works, including Azure OpenAI, vLLM, Text Generation Inference, or reverse proxies. Note that Ollama has its own dedicated provider variant (Ollama) in Meetily, but you can also use the OpenAI-compatible endpoint if Ollama is configured with OpenAI compatibility mode.
Where is the custom endpoint configuration stored?
Meetily stores the endpoint in a JSON configuration file within the application's data directory, managed through frontend/src-tauri/src/config.rs. The frontend settings UI reads and writes to summary.customOpenAIEndpoint in this file.
What API format must my custom endpoint implement?
Your endpoint must accept POST requests at /chat/completions with a JSON body containing model, messages, max_tokens, temperature, and top_p parameters, and return a JSON response matching the OpenAI chat completions schema. Authentication is handled via the Authorization: Bearer {apiKey} header passed through from the frontend.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →