> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vlm.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Mastra Compatibility

> Use Orion-2 with Mastra for hybrid client tools and server-side code execution.

Orion-2 works with [Mastra](https://mastra.ai/) as a visual agent harness. Point a Mastra agent at the VLM Run OpenAI-compatible endpoint, enable hybrid tool execution, and Mastra can call your local tools while Orion-2 runs vision and document work through its [code-execution sandbox](/agents/code-execution).

## What works

With Mastra as the orchestrator and Orion-2 as the model, the following are supported:

| Capability               | Who runs it      | Example                                   |
| ------------------------ | ---------------- | ----------------------------------------- |
| Client / local tools     | Mastra           | Weather lookup, DB queries, internal APIs |
| Server `execute_code`    | Orion-2          | Factorial, transforms, multi-step Python  |
| Document and image tasks | Orion-2          | Invoice summary, detection, annotation    |
| Streaming                | Mastra + Orion-2 | `agent.stream(...)` against Orion-2       |

Hybrid mode is required so Mastra executes client tools locally while Orion-2 keeps server tools such as `execute_code`.

## Prerequisites

* A VLM Run API key from the [API Keys](https://app.vlm.run/dashboard/settings/api-keys) page
* Node.js with `@mastra/core`, `@ai-sdk/openai-compatible`, and `zod`

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
npm install @mastra/core @ai-sdk/openai-compatible zod
export VLMRUN_API_KEY="<VLMRUN_API_KEY>"
```

## Configure Mastra with Orion-2

Use the OpenAI-compatible chat endpoint and an Orion-2 model id:

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { Agent } from "@mastra/core/agent";
import { createTool } from "@mastra/core/tools";
import { z } from "zod";

const vlmrun = createOpenAICompatible({
  name: "vlmrun",
  baseURL: "https://api.vlm.run/v1/openai",
  apiKey: process.env.VLMRUN_API_KEY!,
});

const getWeather = createTool({
  id: "get_weather",
  description: "Return the current weather for a city",
  inputSchema: z.object({ city: z.string() }),
  execute: async ({ city }) => `The weather in ${city} is 72F and sunny.`,
});

const agent = new Agent({
  id: "orion2-mastra-agent",
  name: "Orion-2 Mastra Agent",
  model: vlmrun.chatModel("vlmrun-orion-2:auto"),
  tools: { getWeather },
  instructions:
    "When asked about weather, call get_weather. " +
    "For code or document tasks, use execute_code and do not invent results.",
});
```

Pass hybrid tool execution on each generate or stream call:

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const result = await agent.generate("What is the weather in San Francisco? Use the tool.", {
  providerOptions: {
    vlmrun: {
      session_id: crypto.randomUUID(),
      tool_execution: "hybrid",
    },
  },
});

console.log(result.text);
```

<Info>
  Use `model: "vlmrun-orion-2:auto"` for the default Orion-2 tier. Other tiers and pinned variants are listed in [Code Execution](/agents/code-execution#model-variants).
</Info>

## Verified scenarios

These scenarios exercise the Mastra + Orion-2 harness end to end.

### 1. Client tool calling

Mastra receives Orion-2 tool calls and runs them locally.

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const result = await agent.generate(
  "What is the weather in San Francisco? Use the tool.",
  {
    providerOptions: {
      vlmrun: {
        session_id: crypto.randomUUID(),
        tool_execution: "hybrid",
      },
    },
  },
);
// Orion-2 requests get_weather; Mastra executes it and returns the answer.
```

**Expected:** `get_weather` runs once in Mastra, and the final text includes the tool result (for example `72` / sunny).

### 2. Server-side code execution

Orion-2 writes and runs Python in its sandbox. Mastra does not need a local code tool.

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const result = await agent.generate(
  "Compute factorial(6) using the execute_code tool. Return only the integer result.",
  {
    providerOptions: {
      vlmrun: {
        session_id: crypto.randomUUID(),
        tool_execution: "hybrid",
      },
    },
  },
);
// Orion-2 calls execute_code on the server; Mastra client tools are unused.
```

**Expected:** final text includes `720`, with no client tool calls.

### 3. Document understanding with code execution

Orion-2 can summarize and extract from PDFs and images through `execute_code` while Mastra remains the orchestrator. Attach the document using the same OpenAI-compatible input shapes as the [Agents API](/agents/inputs) (for example `file_url` / `image_url`).

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const invoiceUrl =
  "https://storage.googleapis.com/vlm-data-public-prod/hub/examples/document.invoice/wordpress-pdf-invoice-plugin-sample.pdf";

const result = await agent.generate(
  `Summarize this PDF invoice: ${invoiceUrl}. ` +
    "Use execute_code with the document and return vendor, invoice number, date, and total.",
  {
    providerOptions: {
      vlmrun: {
        session_id: crypto.randomUUID(),
        tool_execution: "hybrid",
      },
    },
  },
);
```

**Expected:** Orion-2 uses `execute_code` against the document and returns invoice fields (vendor, number, date, total). Client tools are not used for this path.

## Hybrid tool execution

| Mode                       | Behavior                                                                   |
| -------------------------- | -------------------------------------------------------------------------- |
| `tool_execution: "hybrid"` | Mastra runs client tools; Orion-2 runs server tools such as `execute_code` |
| Without hybrid             | Client tool round-trips may not complete correctly through Mastra          |

Always send a `session_id` (UUID) with hybrid requests so Orion-2 can keep workspace and artifact context for the turn. See [Artifacts](/agents/artifacts) for retrieving generated files.

## Streaming

Streaming works the same way as generate:

```typescript theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const output = await agent.stream("What is the weather in San Francisco? Use the tool.", {
  providerOptions: {
    vlmrun: {
      session_id: crypto.randomUUID(),
      tool_execution: "hybrid",
    },
  },
});

for await (const chunk of output.fullStream) {
  // handle stream chunks
}

console.log(await output.text);
```

## Related

<CardGroup cols={2}>
  <Card title="Code Execution" icon="terminal" href="/agents/code-execution">
    Orion-2 sandbox, libraries, and model variants
  </Card>

  <Card title="OpenAI Compatibility" icon="plug" href="/agents/integrations/integrations-openai-compatibility">
    Base URL, API key, and chat completions shape
  </Card>

  <Card title="Agent Inputs" icon="file-import" href="/agents/inputs">
    Images, documents, and toolset selection
  </Card>

  <Card title="Gateway MCP + Mastra" icon="network-wired" href="/gateway/mcp-server">
    Different path: load VLM Run tools into Mastra via MCP
  </Card>
</CardGroup>
