Skip to content

Marvin: using the VIDAI Control Plane as the backend

Marvin reads its OpenAI configuration from MARVIN_* env vars. Set them to the control plane's values and every @marvin.fn, classification, extraction, and image call routes through it.

TL;DR

export MARVIN_OPENAI_BASE_URL=https://your-vidai-server.example.com/v1
export MARVIN_OPENAI_API_KEY=your-vidai-key
export MARVIN_CHAT_COMPLETIONS_MODEL=gpt-4o-mini
import marvin

@marvin.fn
def priority(ticket: str) -> str:
    """Return URGENT, NORMAL, or LOW."""

print(priority("printer is on fire"))

Prerequisites

  • pip install marvin.
  • Control plane base URL and an API key from API Keys.
  • A model registered on the Models page.

Passing config explicitly

If you'd rather set config in code:

import marvin
marvin.settings.openai.api_key = "your-vidai-key"
marvin.settings.openai.chat.completions.model = "gpt-4o-mini"
# base URL is on the underlying openai client:
marvin.settings.openai.api_base = "https://your-vidai-server.example.com/v1"

Extraction, classification, generation

All of Marvin's high-level primitives run through the same configuration:

from pydantic import BaseModel
import marvin

class Contact(BaseModel):
    name: str
    email: str | None

contacts = marvin.extract("Alice ([email protected]) and Bob", target=Contact)
sentiment = marvin.classify("Great support!", labels=["+", "-", "neutral"])
tagline   = marvin.generate("a haiku about ships")

Each call is a control-plane request that appears in Request Logs.

AI models / functions

@marvin.fn and marvin.Model classes wrap the same underlying client. No extra config — the env vars above are all it needs:

@marvin.fn
def is_urgent(message: str) -> bool:
    """Return True if the message describes an urgent issue."""

print(is_urgent("printer is on fire"))

Verify it works

import marvin

@marvin.fn
def probe(prompt: str) -> str:
    """Return exactly the string 'ok'."""

print(probe("test"))

If something's off

Raise an issue at github.com/vidaiUK/vidai-quickstart/issues with your Marvin config and the call that reproduces the issue. We'll get it sorted.

Where to go next