Skip to main content

Custom LLM Providers

work-summary ships with Gemini as the default provider, but any LLM can be plugged in via the provider plugin system.

How It Works

Set llm.provider in your config to an npm package name or a local file path. The package must export a factory function that returns an object with a rawPrompt(prompt) method.

{
"llm": {
"provider": "@work-summary/openai",
"apiKey": "sk-...",
"model": "gpt-4o"
}
}

When llm.provider is omitted or set to "gemini", the built-in Gemini adapter is used (backward compatible — no changes needed for existing setups).


@work-summary/openai

The official OpenAI-compatible adapter covers OpenAI, Ollama, Groq, Mistral, Together.ai, LM Studio, and any other endpoint that speaks the OpenAI Chat Completions format.

Install

npm install -g @work-summary/openai openai

Usage

OpenAI

{
"llm": {
"provider": "@work-summary/openai",
"apiKey": "sk-...",
"model": "gpt-4o"
}
}

Ollama (local, no API key needed)

{
"llm": {
"provider": "@work-summary/openai",
"apiKey": "ollama",
"model": "llama3.2",
"baseUrl": "http://localhost:11434/v1"
}
}

Groq

{
"llm": {
"provider": "@work-summary/openai",
"apiKey": "gsk_...",
"model": "llama-3.1-70b-versatile",
"baseUrl": "https://api.groq.com/openai/v1"
}
}

Mistral

{
"llm": {
"provider": "@work-summary/openai",
"apiKey": "...",
"model": "mistral-large-latest",
"baseUrl": "https://api.mistral.ai/v1"
}
}

Writing Your Own Provider

A provider is a Node.js module (CommonJS) that exports a factory function.

Interface

export interface LLMProvider {
rawPrompt(prompt: string): Promise<string>;
}

export interface LLMProviderConfig {
provider?: string;
apiKey?: string;
model?: string;
baseUrl?: string;
promptTemplate?: string;
[key: string]: unknown; // any extra fields from llm config
}

// Your module must export this:
export default function createProvider(config: LLMProviderConfig): LLMProvider;

Minimal example

// my-provider.js
module.exports = function createProvider(config) {
return {
async rawPrompt(prompt) {
const res = await fetch('https://my-llm-api.example.com/v1/complete', {
method: 'POST',
headers: {
Authorization: `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt, model: config.model }),
});
const data = await res.json();
return data.text;
},
};
};

Set in your config:

{
"llm": {
"provider": "./my-provider.js",
"apiKey": "...",
"model": "my-model"
}
}

Publishing as an npm package

If you publish @your-scope/my-provider to npm, users can install it globally and reference it by name:

{ "llm": { "provider": "@your-scope/my-provider" } }
Security note

Provider modules are loaded with Node.js require(). Only use provider packages from sources you trust — treat them with the same caution as any npm dependency.


Config Reference

KeyTypeDescription
llm.providerstring"gemini" (default), an npm package name, or a relative path ("./my-provider.js").
llm.apiKeystringPassed to the provider factory as config.apiKey.
llm.modelstringPassed to the provider factory as config.model.
llm.baseUrlstringPassed to the provider factory as config.baseUrl. Used by OpenAI-compat providers to target custom endpoints.