Skip to content

OpenAI Agent Plugin (ovos-openai-plugin)

In a nutshell

This plugin lets OVOS talk to AI chat services that follow OpenAI's popular format. That includes OpenAI itself, but also many private or locally-run alternatives that copy the same style. It is the bridge that connects your assistant to a chosen AI "brain", whether that brain lives in the cloud or on your own machine. See AI Agents & Personas for how this fits in, and the Glossary for unfamiliar terms.

ovos-openai-plugin connects OVOS to any OpenAI-compatible Chat Completions API, including OpenAI itself, local models via Ollama or llama.cpp, self-hosted proxies, and ovos-persona-server.

Install: pip install ovos-openai-plugin

GitHub: OpenVoiceOS/ovos-openai-plugin

Removed legacy solver

The old ovos-solver-openai-plugin entry point and the OpenAIChatCompletionsSolver / OpenAICompletionsSolver classes no longer exist. Personas that referenced them must switch to the ovos-chat-openai-plugin agent engine (still listed under a persona's handlers key).


Plugins Overview

Entry point Plugin name Class Purpose
opm.agents.chat ovos-chat-openai-plugin OpenAIChatEngine Multi-turn chat for personas
opm.agents.memory ovos-openai-rag-memory-plugin PersonaServerRAGMemory RAG memory backed by an ovos-persona-server vector store
opm.agents.summarizer ovos-summarizer-openai-plugin OpenAISummarizer Summarize arbitrary text
opm.transformer.dialog ovos-dialog-transformer-openai-plugin OpenAIDialogTransformer Rewrite TTS dialog in a different voice or style
opm.lang.translate ovos-translate-openai-plugin OpenAITextTranslator Translate text between languages
opm.lang.detect ovos-lang-detect-openai-plugin OpenAITextLangDetector Detect the language of text
opm.plugin.persona Remote Llama (pre-built persona) Demo persona pointing at a public ollama/LLama server

All engines wrap the same OpenAIChatCompletions API client, so any OpenAI-compatible Chat Completions server (OpenAI, ollama, llama.cpp, vLLM, LocalAI, ovos-persona-server, …) works by pointing api_url at its /v1 base.

Remote Llama demo persona sends text to a third-party public server

The pre-built Remote Llama persona ships pointed at a public ollama/LLama server operated by a third party. Who operates that server, how long it retains conversation text, and whether it logs requests are not stated by the plugin. For privacy, point api_url at your own local model (see gguf-plugin.md) or another self-hosted endpoint instead of using this demo persona as-is.


Common Configuration Keys

All plugins wrap OpenAIChatCompletions internally.

Key Type Default Description
api_url str https://api.openai.com/v1 Base URL (the /v1 root). /chat/completions is appended automatically. Change for local/self-hosted servers.
key str "" API key sent as a Bearer token. Omit (or use "sk-nokey") for servers that don't require auth.
model str gpt-4o-mini Model identifier (e.g. gpt-4o, llama3.1:8b).
max_tokens int 300 Maximum number of tokens in the completion.
temperature float 0.5 Sampling temperature. Higher = more creative.
top_p float 0.2 Nucleus sampling probability mass.
frequency_penalty float 0 Penalise repeated tokens by frequency.
presence_penalty float 0 Penalise tokens that have already appeared.
stop_token str\|list null One or more stop sequences that terminate generation.

Chat Engine (opm.agents.chat)

Class: OpenAIChatEngine, ovos_openai_plugin/chat.py:OpenAIChatEngine

OPM plugin name: ovos-chat-openai-plugin

Multi-turn conversational LLM. The primary engine type used inside personas. Works with any OpenAI-compatible endpoint.

Tool / function calling

OpenAIChatEngine sets supports_tools = True, so it advertises native function-calling to callers. continue_chat(messages, …, tools=…) accepts ToolBox objects and/or raw OpenAI tool dicts. When the model decides to call a tool, the returned AgentMessage carries tool_calls (assistant tool_calls turns and MessageRole.TOOL results are serialized back to the API on the next round-trip), letting the caller run a tool loop. This is the same hook the agentic loop engines drive.

Memory lives in ovos-persona, not this plugin

The chat engine is stateless. It only sees the messages it is handed each turn. Short-term conversational memory is supplied by ovos-persona (which accumulates the history), not by ovos-openai-plugin. The only memory backend this package ships is the server-coupled RAG memory described below.

Plugin-specific keys

Key Type Default Description
system_prompt str null Instruction prepended to every conversation as a system message.
allow_system_prompts bool false When true, caller system messages are merged with the configured prompt.

System prompt merging

allow_system_prompts Caller sends system message Result
false (default) yes Caller's system message stripped, configured system_prompt used
false no Configured system_prompt prepended
true yes Both merged: configured_prompt + "\n" + caller_prompt
true no Configured system_prompt prepended

OpenAI configuration example

{
  "ovos-chat-openai-plugin": {
    "api_url": "https://api.openai.com/v1",
    "key": "sk-...",
    "model": "gpt-4o-mini",
    "max_tokens": 150,
    "temperature": 0.5,
    "system_prompt": "You are a concise and helpful voice assistant."
  }
}

Local Ollama configuration

{
  "ovos-chat-openai-plugin": {
    "api_url": "http://localhost:11434/v1",
    "key": "sk-nokey",
    "model": "llama3.1:8b",
    "system_prompt": "You are a helpful assistant."
  }
}

Remote persona server

ovos-persona-server exposes any OVOS persona behind an OpenAI-compatible HTTP endpoint. This lets you keep API keys on a single server and offload LLM computation:

{
  "ovos-chat-openai-plugin": {
    "api_url": "http://my-persona-server:6712/v1",
    "key": "sk-nokey",
    "model": "my-persona-name"
  }
}

Persona Configuration

{
  "name": "My Local LLM",
  "handlers": ["ovos-chat-openai-plugin"],
  "ovos-chat-openai-plugin": {
    "api_url": "http://localhost:11434/v1",
    "key": "sk-nokey",
    "model": "llama3.1:8b",
    "system_prompt": "You are a helpful assistant who gives short and factual answers in twenty words or fewer."
  }
}

Activate by voice: "Chat with My Local LLM".


RAG Memory (opm.agents.memory)

Class: PersonaServerRAGMemory, ovos_openai_plugin/rag_memory.py:PersonaServerRAGMemory

OPM plugin name: ovos-openai-rag-memory-plugin

A persona memory_module (an AgentContextManager). Before each turn it queries a vector store hosted by an ovos-persona-server and injects the retrieved chunks into the conversation context. The persona's normal chat engine still generates the answer, so RAG composes with any chat backend. This is the server/OpenAI-coupled memory backend. Local-only memory plugins live in ovos-memory-plugins instead.

Key Type Default Description
api_url str null Base URL of the persona-server's OpenAI-compatible API (e.g. http://localhost:8337/openai/v1).
vector_store_id str Vector store to search.
key str null Optional bearer token.
inject_mode str system How retrieved context is added: system / system_prompt / developer / user / tool.
retrieval dict Sub-block: max_num_results, min_score, query_mode (utterance/history), query_history_turns.
context dict Sub-block: header, chunk_prefix, chunk_separator, include_sources, tool_name.
system_prompt str null Base system prompt (kept stable for caching when inject_mode="system").
max_history int 10 Conversation turns retained.
{
  "name": "kb-assistant",
  "handlers": ["ovos-chat-openai-plugin"],
  "memory_module": "ovos-openai-rag-memory-plugin",
  "ovos-openai-rag-memory-plugin": {
    "api_url": "http://localhost:8337/openai/v1",
    "vector_store_id": "vs_...",
    "inject_mode": "system",
    "retrieval": {"max_num_results": 5, "query_mode": "utterance"}
  }
}

Dialog Transformer (opm.transformer.dialog)

Class: OpenAIDialogTransformer, ovos_openai_plugin/dialog_transformers.py:OpenAIDialogTransformer

OPM plugin name: ovos-dialog-transformer-openai-plugin

Intercepts OVOS TTS dialog just before it is spoken and rewrites it using an LLM. Useful for giving the assistant a distinct personality or adapting the reading level. Default priority: 10.

Key Type Default Description
system_prompt str "Your task is to rewrite text as if it was spoken by a different character" High-level instruction for the rewrite model.
rewrite_prompt str null Per-call directive appended before each dialog string. Can also be passed at call time via context["prompt"].
{
  "dialog_transformers": {
    "ovos-dialog-transformer-openai-plugin": {
      "api_url": "https://api.openai.com/v1",
      "key": "sk-...",
      "model": "gpt-4o-mini",
      "rewrite_prompt": "rewrite the text as if you were explaining it to a 5-year-old"
    }
  }
}

Rewrite prompt examples

rewrite_prompt Effect
"rewrite the text as if you were explaining it to a 5-year-old" Simpler vocabulary
"rewrite the text as if it was an angry old man speaking" Grumpy character voice
"Add more 'dude'ness to it" Casual/surfer tone
"Explain it like you're a Shakespearean actor" Archaic dramatic style

The rewrite_prompt can also be passed per-call via the context dict:

text, ctx = transformer.transform(dialog, context={"prompt": "make it sound pirate-y"})

Summarizer (opm.agents.summarizer)

Class: OpenAISummarizer, ovos_openai_plugin/summarizer.py:OpenAISummarizer

OPM plugin name: ovos-summarizer-openai-plugin

Condenses long documents into a short plain-text summary (2 paragraphs by default). Intended for consumption by skills before TTS, not directly by end-users.

Key Type Default Description
system_prompt str "Your task is to summarize text in a couple paragraphs." Instruction for the summarization model.
prompt_template str See below Template with a {content} placeholder.

Default prompt_template:

Your task is to summarize the text into a suitable format.
Answer in plaintext with no formatting, 2 paragraphs long at most.
Focus on the most important information.
---------------------
{content}
{
  "ovos-summarizer-openai-plugin": {
    "api_url": "https://api.openai.com/v1",
    "key": "sk-...",
    "model": "gpt-4o-mini"
  }
}

Translator (opm.lang.translate)

Class: OpenAITextTranslator, ovos_openai_plugin/translate.py:OpenAITextTranslator

OPM plugin name: ovos-translate-openai-plugin

Translates plain text between languages by prompting the LLM. Language codes follow BCP-47 (e.g. en-us, pt-pt, es-es); the code is resolved to an English display name for the prompt. There is no special handling for OVOS template syntax: feeding it an .intent file line gives no guarantee that {variables}, [optional], or (alt|ernatives) markers survive translation.

{
  "language": {
    "translation_module": "ovos-translate-openai-plugin",
    "ovos-translate-openai-plugin": {
      "api_url": "https://api.openai.com/v1",
      "key": "sk-...",
      "model": "gpt-4o-mini"
    }
  }
}
from ovos_openai_plugin.translate import OpenAITextTranslator

translator = OpenAITextTranslator({"key": "sk-...", "model": "gpt-4o-mini"})
result = translator.translate("Hello, world!", target="pt-pt", source="en-us")
print(result)  # "Olá, mundo!"

Language Detector (opm.lang.detect)

Class: OpenAITextLangDetector, ovos_openai_plugin/translate.py:OpenAITextLangDetector

OPM plugin name: ovos-lang-detect-openai-plugin

Detects the BCP-47 language code of a given text using an LLM.

{
  "language": {
    "detection_module": "ovos-lang-detect-openai-plugin",
    "ovos-lang-detect-openai-plugin": {
      "api_url": "https://api.openai.com/v1",
      "key": "sk-...",
      "model": "gpt-4o-mini"
    }
  }
}
from ovos_openai_plugin.translate import OpenAITextLangDetector

detector = OpenAITextLangDetector({"key": "sk-...", "model": "gpt-4o-mini"})
lang = detector.detect("The quick brown fox jumps over the lazy dog")
print(lang)  # "en"

Combining sections into one mycroft.conf

The dialog transformer, language detector, and translator sections above each show their own mycroft.conf block in isolation. In practice they just sit side by side under their own top-level keys (dialog_transformers, language). There's nothing to merge, only to place each block from above under its matching top-level key in the same file.


Source code: OpenVoiceOS/ovos-openai-plugin.


Read next: GGUF / Local LLM Related: LLM Transformers · Agent Engine Types · Personas & PersonaService · Persona Server