How to Configure a Custom OpenAI-Compatible Endpoint for AI Summaries in Meetily
Meetily routes AI summary requests to any OpenAI-compatible service—such as Azure OpenAI or private proxies—by accepting a runtime endpoint URL via the builtin_ai_generate_summary Tauri command, which the LLM client uses to dynamically construct the request target.
Meetily is an open-source meeting assistant that generates AI summaries from your transcripts. When you need to use a custom OpenAI-compatible endpoint rather than the default OpenAI API, you can configure this at runtime through the Rust backend. According to the Meetily source code, the application does not hard-code the API URL; instead, it builds the request path dynamically using your supplied endpoint, enabling integration with self-hosted models, Azure OpenAI, or corporate proxies.
Architecture Flow for Custom Endpoints
The configuration flows through three distinct layers:
- Frontend invocation – The React UI calls the Tauri command
builtin_ai_generate_summarywith the provider string'custom-openai'and includes your endpoint as thecustomOpenAIEndpointargument. - Command routing – The command handler in
src-tauri/src/summary/summary_engine/commands.rsreceives this value and forwards it to the core summary generator. - LLM client processing – In
src-tauri/src/summary/llm_client.rs(lines 173–179), the code matchesLLMProvider::CustomOpenAIand constructs the final URL usingformat!("{}/chat/completions", endpoint.trim_end_matches('/')).
Implementing the Custom Endpoint
Frontend TypeScript Invocation
To generate a summary through a private OpenAI-compatible service, invoke the Tauri command with the provider identifier and your custom URL:
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', // Maps to LLMProvider::CustomOpenAI
modelName: model,
apiKey,
systemPrompt: 'You are a concise meeting-summary assistant.',
userPrompt: transcript,
customOpenAIEndpoint: endpoint, // The custom endpoint URL
maxTokens: 1024,
temperature: 0.7,
topP: 0.9,
});
return result; // Returns the generated summary text
}
Rust Backend Command Handler
The builtin_ai_generate_summary command receives the optional endpoint and passes it to the LLM client. This excerpt from src-tauri/src/summary/summary_engine/commands.rs shows the parameter forwarding:
#[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>,
// ... other optional args ...
) -> Result<String, String> {
let provider = LLMProvider::from_str(&provider)?;
let client = reqwest::Client::new();
// Pass the optional endpoint to the core LLM client
summary::llm_client::generate_summary(
&client,
&provider,
&model_name,
&api_key,
&system_prompt,
&user_prompt,
None, // ollama_endpoint (unused here)
custom_openai_endpoint.as_deref(),
max_tokens,
temperature,
top_p,
None, // app_data_dir
None, // cancellation token
)
.await
}
URL Construction Logic
When processing a request with LLMProvider::CustomOpenAI, the generate_summary function in src-tauri/src/summary/llm_client.rs constructs the API URL by trimming trailing slashes and appending the standard OpenAI chat completions path:
format!("{}/chat/completions", endpoint.trim_end_matches('/'))
This ensures your custom endpoint receives requests at https://your-domain.com/chat/completions regardless of whether you include a trailing slash in your configuration.
Persisting the Custom Endpoint
To avoid manual entry for each summary generation, Meetily stores user settings in JSON format within the application data directory. The configuration structure includes:
{
"summary": {
"customOpenAIEndpoint": "https://my-openai-proxy.example.com"
}
}
When the settings UI updates this field, the frontend retrieves the stored value and includes it as the customOpenAIEndpoint argument in subsequent invocations of builtin_ai_generate_summary.
Summary
- Meetily supports custom OpenAI-compatible endpoints via the
builtin_ai_generate_summaryTauri command. - Set the provider to
'custom-openai'and pass your URL via thecustomOpenAIEndpointparameter. - The LLM client in
src-tauri/src/summary/llm_client.rsconstructs the final request URL by appending/chat/completionsto your trimmed endpoint. - Endpoints can be persisted in the app’s JSON settings under the
summary.customOpenAIEndpointkey. - This architecture supports Azure OpenAI, self-hosted models like vLLM or Text Generation Inference, and corporate API gateways.
Frequently Asked Questions
What file handles the URL construction for custom OpenAI endpoints?
The URL construction occurs in src-tauri/src/summary/llm_client.rs at lines 173–179, where the code executes format!("{}/chat/completions", endpoint.trim_end_matches('/')) when the provider enum matches LLMProvider::CustomOpenAI.
Can I use Azure OpenAI Service with Meetily?
Yes. Configure your Azure OpenAI endpoint (e.g., https://my-resource.openai.azure.com/openai/deployments/my-deployment) as the customOpenAIEndpoint and provide your Azure API key. Meetily will route chat completion requests to that Azure URL following the OpenAI-compatible interface.
Is the API key sent directly to the custom endpoint?
Yes. The apiKey parameter passed to builtin_ai_generate_summary is forwarded to the LLM client and included in the HTTP Authorization header as a Bearer token when making requests to your custom endpoint, using the same authentication scheme as the standard OpenAI API.
Where does Meetily store my custom endpoint configuration?
Meetily persists the endpoint in its internal JSON settings file within the application data directory, typically accessed via the Tauri app-data path and stored under the key summary.customOpenAIEndpoint. This allows the configuration to persist across application restarts without hard-coding values in the source.
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 →