OMP Docs
Models & providers

Custom models & providers

Connect omp to a local server, an OpenAI-compatible gateway, or a model that is not in the built-in catalog.

Connect a model omp does not already know

Use a custom provider when your model runs at a private URL, behind a company gateway, or under an id that omp does not list. You can declare the exact model yourself or let omp discover the models exposed by the server.

You often do not need this file for local inference. omp automatically looks for Ollama at http://127.0.0.1:11434, llama.cpp at http://127.0.0.1:8080, and LM Studio at http://127.0.0.1:1234/v1. Start the server and open /model; if its models are already there, select one and stop.

Otherwise, create ~/.omp/agent/models.yml. This is the smallest valid configuration for an unauthenticated server that implements OpenAI Chat Completions:

providers:
  local-openai:
    baseUrl: http://127.0.0.1:8000/v1
    api: openai-completions
    auth: none
    models:
      - id: Qwen/Qwen2.5-Coder-32B-Instruct

The provider id, local-openai, is yours to choose. The model id must be the exact id accepted by the server. Use openai-responses instead if the server implements /v1/responses rather than /v1/chat/completions.

For a newly declared model, omitted metadata defaults to its id as the display name, text-only input, no configurable reasoning, a 128,000-token context window, a 16,384-token output limit, and zero cost. Those defaults make a minimal entry usable, but you should set the real limits and capabilities when they differ.

Verify and select it

First ask omp to load the file and list just your provider:

omp models local-openai

A valid, available model appears under local-openai with its context, output, thinking, and image capabilities. A YAML or schema problem instead prints models.yml validation failed and the field that failed.

Then exercise the endpoint with an exact selector:

omp -p --model local-openai/Qwen/Qwen2.5-Coder-32B-Instruct "Reply with only OK"

Exact provider/model-id selectors avoid ambiguity when several providers expose the same model id. To make it your normal interactive model, start omp, enter /model, find the provider and model, and assign it to Default. The model hub reloads models.yml when it opens and saves the role assignment. /switch (or Alt+P) switches only the current session.

See Model roles for assigning the same model to smol, slow, plan, or another role.

Add authentication

For a remote OpenAI-compatible service, point apiKey at an environment variable:

providers:
  myco:
    baseUrl: https://llm.internal.example/v1
    apiKey: MYCO_LLM_API_KEY
    api: openai-responses
    models:
      - id: myco-large
        name: MyCo Large
        reasoning: true
        input: [text, image]
        contextWindow: 200000
        maxTokens: 32000
        cost:
          input: 3
          output: 15
          cacheRead: 0.3
          cacheWrite: 3.75
export MYCO_LLM_API_KEY='…'
omp models myco

omp looks up the environment variable by that exact name. If no variable is found, it falls back to using the text literally.

Do not commit literal API keys

apiKey is resolved as follows:

  1. A value beginning with ! is a shell command; its trimmed stdout is the key.
  2. Otherwise, omp looks for an environment variable with that exact name.
  3. If no such variable exists, omp uses the configured text as the literal key.

Prefer environment variables or secret-manager commands over committing a literal credential. See Environment variables and Providers for built-in provider authentication.

auth defaults to apiKey. Use auth: none only for a genuinely unauthenticated endpoint. auth: oauth is valid only when that provider's OAuth support is already supplied by omp or an extension; models.yml cannot define a new OAuth flow.

Set authHeader: true only when a gateway specifically needs Authorization: Bearer <resolved-apiKey> injected as an ordinary header. Standard provider clients already apply their normal authentication scheme.

Discover a server's model list

If an OpenAI-compatible server exposes GET /v1/models, discovery avoids maintaining a models list by hand:

providers:
  lab:
    baseUrl: http://127.0.0.1:8000/v1
    api: openai-completions
    auth: none
    discovery:
      type: openai-models-list

Run omp models refresh lab to force an online refresh and show only matching models. Ordinary launches use the cached catalog when it is fresh.

discovery.type accepts:

TypeUse it for
ollamaOllama's native /api/tags and /api/show endpoints.
llama.cppllama.cpp's native model and properties endpoints.
lm-studioLM Studio's OpenAI-compatible model list and metadata.
openai-models-listA generic OpenAI-compatible GET /v1/models endpoint.
litellmA LiteLLM gateway; uses its richer metadata routes and falls back to /v1/models.
proxyA mixed OpenAI/Anthropic proxy whose model rows advertise supported_endpoint_types.

Except for proxy, discovery requires provider-level api. proxy derives a model's API from its advertised endpoint types and uses provider-level api only as a fallback. Optional discovery.timeoutMs must be a positive number of milliseconds.

Do not label a generic OpenAI-compatible server as ollama: Ollama discovery expects Ollama's native endpoints. Use openai-models-list instead.

Override a built-in provider

A provider entry without models changes an existing provider rather than replacing its catalog. This is useful for a company gateway or for correcting metadata:

providers:
  openai:
    baseUrl: https://gateway.internal.example/v1
    apiKey: COMPANY_OPENAI_KEY
    headers:
      X-Team: coding
    modelOverrides:
      gpt-5.4:
        contextWindow: 400000

Provider headers, compat, and remoteCompaction are baselines. Model headers replace provider headers with the same name, and modelOverrides patches one bundled or discovered model. If a custom models entry uses the same provider and id as an existing model, the custom definition replaces that model's transport configuration.

File and provider reference

The default path is ~/.omp/agent/models.yml; ~/.omp/agent/models.yaml is used when the .yml file is absent. If neither YAML file exists and legacy models.json does, omp migrates it to models.yml. The root object accepts only providers.

Each key below providers becomes the provider portion of the selector.

Provider fieldMeaning
baseUrlEndpoint root. Required when models is non-empty. It must be a non-empty string.
apiDefault API for declared or discovered models. May instead be set on every declared model.
apiKeyEnvironment-variable name, !command, or literal credential. Required for declared models unless auth is none or oauth.
authapiKey (default), none, or oauth.
headersString-to-string request headers. Values support environment-variable and !command resolution.
authHeaderWhen true, adds a Bearer Authorization header from apiKey.
modelsFull model definitions owned by this provider.
discoveryLive catalog configuration: type plus optional positive timeoutMs.
modelOverridesMap from model id to sparse metadata patches.
compatAdvanced request/response compatibility overrides; normally omit it and use omp's automatic detection.
disableStrictToolsDisables strict tool-schema markers for endpoints, commonly Anthropic-compatible proxies, that reject them.
remoteCompactionProvider-wide remote compaction configuration. Model values merge on top.
guardrailIdentifierAmazon Bedrock guardrail id or ARN.
guardrailVersionBedrock guardrail version; defaults to DRAFT when a guardrail is set.
guardrailTraceBedrock trace mode: enabled, disabled, or enabled_full.
transportOnly pi-native; routes through a compatible omp auth-gateway. Requires that gateway as baseUrl and its bearer as apiKey.

A provider without models must still do something: set at least one usable override such as baseUrl, headers, apiKey, auth: none, compat, disableStrictTools, guardrailIdentifier, remoteCompaction, modelOverrides, or discovery.

API values

api valueEndpoint family
openai-completionsOpenAI-compatible Chat Completions.
openai-responsesOpenAI-compatible Responses API.
openai-codex-responsesCodex-flavored Responses API.
azure-openai-responsesAzure-hosted Responses API.
anthropic-messagesAnthropic Messages API.
bedrock-converse-streamAmazon Bedrock Converse streaming.
google-generative-aiGemini public API.
google-gemini-cliGemini CLI-compatible API.
google-vertexGemini through Vertex AI.

These are the transports built into omp. An endpoint with a different wire protocol requires an extension, not another string in models.yml.

Model field reference

Model fieldMeaning
idRequired, non-empty upstream model id.
namePicker label; defaults to id.
apiOverrides provider api for this model.
baseUrlOverrides provider baseUrl for this model.
reasoningMarks the model as reasoning-capable. Must be true for a thinking control surface to apply.
thinkingExplicit effort controls; see below. Omit it to let known model identity and compatibility determine controls.
inputSupported inputs: [text] or [text, image].
imageInputDecoderOnly stb; converts WebP input for a local backend that cannot decode it.
tokenizerOptional local token estimator: claude-v3, claude-v47, claude-v5, claude-v5-sonnet, qwen3, deepseek-v3, kimi-k2, or glm5.
supportsToolsWhether the endpoint supports tool calling.
costPer-million-token rates. A full definition requires input, output, cacheRead, and cacheWrite.
premiumMultiplierMultiplier applied to reported model cost.
contextWindowPositive total context-token limit used by the context meter and overflow handling.
maxTokensPositive maximum output tokens.
omitMaxOutputTokensOmits the maximum-output-token request field when true.
headersPer-model headers, merged over provider headers. Values support env names and !command.
compatPer-model compatibility overrides, merged over provider compat.
contextPromotionTargetModel id or provider/model-id to switch to after a context-overflow error, before compaction.
compactionModelModel selector to prefer for compaction.
remoteCompactionPer-model remote compaction settings.

modelOverrides accepts the same metadata fields except id, api, and baseUrl. Its cost object may be partial, while a full model definition's cost must contain all four rates.

Thinking fields

A new explicit thinking block uses this shape:

reasoning: true
thinking:
  mode: effort
  efforts: [low, medium, high]
  defaultLevel: medium
FieldMeaning
modeRequired: effort, budget, google-level, anthropic-adaptive, or anthropic-budget-effort.
effortsRequired for new configs: an ordered, non-empty subset of minimal, low, medium, high, xhigh, max.
defaultLevelDefault from the supported effort set.
effortMapOptional mapping from those effort names to provider-specific strings.
supportsDisplayWhether the provider accepts a thinking-display preference.

Legacy levels, or the pair minLevel and maxLevel, are still accepted and normalized to efforts; prefer efforts in new files.

Remote compaction fields

remoteCompaction may appear at provider, model, or override level. It accepts enabled, api, endpoint, model, v2StreamingEnabled, v2Endpoint, and streamingEndpoint. Endpoint and model strings must be non-empty. Leave this block out unless your provider offers a compatible server-side compaction endpoint.

Advanced compatibility fields

Most OpenAI-compatible services work without compat. Set these fields only to match documented endpoint behavior or to address a concrete request error. Every field is optional; provider values form the baseline and model values merge over them.

Request and streaming: supportsStore, supportsDeveloperRole, supportsMultipleSystemMessages, maxTokensField (max_completion_tokens or max_tokens), supportsUsageInStreaming, supportsToolChoice, supportsForcedToolChoice, alwaysSendMaxTokens, strictResponsesPairing, streamIdleTimeoutMs, cacheControlFormat (anthropic), supportsLongPromptCacheRetention, supportsImageDetailOriginal, and extraBody.

Reasoning: supportsReasoningEffort, supportsReasoningParams, reasoningEffortMap, thinkingFormat (openai, openrouter, zai, qwen, or qwen-chat-template), qwenTemplateReasoningEffort, reasoningContentField (reasoning_content, reasoning, or reasoning_text), requiresReasoningContentForToolCalls, allowsSyntheticReasoningContentForToolCalls, requiresAssistantContentForToolCalls, disableReasoningOnForcedToolChoice, disableReasoningOnToolChoice, and whenThinking. whenThinking contains another partial compatibility block applied only while thinking is active.

Tools and message history: requiresToolResultName, requiresMistralToolIds, requiresAssistantAfterToolResult, requiresThinkingAsText, supportsStrictMode, toolStrictMode (all_strict or none), and requiresToolResultId.

Streaming and Anthropic-compatible behavior: streamMarkupHealingPattern (kimi, dsml, qwen, or thinking), supportsEagerToolInputStreaming, allowAnthropicHeaderOverrides, and replayUnsignedThinking.

Gateway routing: openRouterRouting and vercelGatewayRouting, each with optional only and order string lists.

Bedrock prompt caching: promptCacheMode (none, automatic, or explicit), promptCacheMinimumTokens, promptCacheMaximumCheckpoints, and supportsLongPromptCacheRetention.

Troubleshooting


Source: omp.sh — MIT, Stencil Labs. Initially imported on 2026-10-03; updates via automatic sync.

OMP Docs· always in sync with upstream
oh-my-piomp.sh/docsContent MIT · Stencil Labs