---
title: "agents.run-start@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/agents.run-start"
updated: null
---

# agents.run-start@1 · OpenVibe.Services

HTML: [agents.run-start@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/agents.run-start)

# AgentsRunStart `agents.run-start@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.2.0
- Owner: network
- Visibility: public
- Status: active
- Compatibility: backward
- Decision: [ADR-044](/docs/adr/ADR-044)
- Schema: [`https://openvibe.network/contracts/agents/run-start.v1.json`](/docs/contracts/agents.run-start.json)

agents.run-start@1 (agent-engine.md, 2026-11-12): what starts a run, the same on every product's POST /api/v1/runs and on the Frame's POST /api/frame/runs. Only TEXT is required: the goal, the question or the first message, in the person's own words. KIND chooses the sort of run (agents.run@1's kinds); absent, the Frame's orchestrator decides whether to answer, plan, or hand the work to another product as a child run. AGENT names who does it (an agent's id; auto lets the product choose). MODEL and WHERE are the picker's choices; TARGET is a code run's (new, openvibe or a repository); CONTEXT is where it was asked; ATTACHMENTS are files by Media id or address; SOURCES and DEPTH are an answer's (frame.ask@1's); PARENT\_RUN makes it a sub-agent's run inside its parent's budget; BUDGET is its own hard limit. An Idempotency-Key header makes a repeated start return the first run. Since 1.1.0 a start may name a PLAY, continue another run (LINEAGE), and carry intake's MANDATE.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `text` | string | yes |  | - `minLength 1`<br>- `maxLength 16000` |
| `title` | string |  |  | - `minLength 1`<br>- `maxLength 200` |
| `kind` | string |  |  | - `pattern ^[a-z][a-z0-9-]{0,30}$` |
| `agent` | string |  | An agent's id on the product that will run it, or auto. | - `minLength 1`<br>- `maxLength 160` |
| `model` | object |  | The picker's choice (frame.choices@1). Absent: the person's default for this kind of work. | - `no other fields` |
| `model.id` | string | yes |  | - `pattern ^[A-Za-z0-9._:/@+\| -]+$`<br>- `minLength 1`<br>- `maxLength 200` |
| `model.source` | enum |  | openvibe: Exchange's directory, paid in credits. keys: the person's own key. machines: a model on the person's own computer (Link). plans: a signed-in plan through a harness. | - `one of "openvibe", "keys", "machines", "plans"` |
| `model.machine` | string |  |  | - `maxLength 40` |
| `model.name` | string |  |  | - `minLength 1`<br>- `maxLength 200` |
| `model.effort` | string |  |  | - `minLength 1`<br>- `maxLength 40` |
| `where` | object |  | Where the run's work happens. openvibe: OpenVibe's own computers. machine: the person's own computer or robot through Link (ID is the device). runner: a Codes runner. this-computer: the machine that serves the run itself (Link's agent serve). | - `no other fields` |
| `where.kind` | enum | yes |  | - `one of "openvibe", "machine", "runner", "this-computer"` |
| `where.id` | string |  |  | - `minLength 1`<br>- `maxLength 160` |
| `where.name` | string |  |  | - `minLength 1`<br>- `maxLength 200` |
| `target` | one of |  | What a code run works on. new: a new project in the person's own space. openvibe: OpenVibe itself; the orchestrator finds the repositories and opens pull requests, never merges. An object names one repository. |  |
| `context` | object |  | Where the run was asked: the site, the page and what the page is about. A run may use it; it never grants access. | - `no other fields` |
| `context.site` | string |  |  | - `minLength 1`<br>- `maxLength 60` |
| `context.url` | string |  | The page's address. | - `format uri`<br>- `maxLength 2000` |
| `context.title` | string |  |  | - `maxLength 300` |
| `context.kind` | string |  |  | - `maxLength 60` |
| `context.id` | string |  |  | - `maxLength 160` |
| `attachments` | array of object |  |  | - `maxItems 20`<br>- `items: no other fields` |
| `attachments[].kind` | enum | yes |  | - `one of "image", "file", "audio", "video"` |
| `attachments[].media_id` | string |  |  | - `minLength 1`<br>- `maxLength 60` |
| `attachments[].url` | string |  | An https address the reader may fetch. | - `format uri`<br>- `maxLength 2000` |
| `attachments[].name` | string |  |  | - `maxLength 300` |
| `attachments[].mime` | string |  |  | - `maxLength 120` |
| `attachments[].bytes` | integer |  |  | - `minimum 0` |
| `attachments[].width` | integer |  |  | - `minimum 1` |
| `attachments[].height` | integer |  |  | - `minimum 1` |
| `attachments[].alt` | string |  | What a picture shows, in words. | - `maxLength 500` |
| `sources` | array of enum |  |  | - `maxItems 4`<br>- `unique items`<br>- `items: one of "web", "openvibe", "mine", "page"` |
| `depth` | enum |  |  | - `one of "quick", "balanced", "deep"` |
| `parent_run` | string |  |  | - `minLength 1`<br>- `maxLength 160` |
| `budget` | object |  | The hard limit the run may not exceed. A field that is absent is not limited. USD is money; TOKENS counts model tokens in and out; SECONDS is wall time; STEPS counts the appended steps. | - `no other fields` |
| `budget.usd` | number |  |  | - `minimum 0` |
| `budget.tokens` | integer |  |  | - `minimum 0` |
| `budget.seconds` | number |  |  | - `minimum 0` |
| `budget.steps` | integer |  |  | - `minimum 1` |
| `play` | string |  | The play to run (agents.play@1's ID); absent, the orchestrator chooses (most asks are solo). | - `pattern ^[a-z][a-z0-9-]{0,60}$` |
| `mandate` | object \| null |  | Set by intake, never by a browser: the Source, thread and asker the run is answering (agents.run@1's MANDATE). A product ignores it from a caller that is not the intake service. |  |
| `lineage` | object \| null |  | Start as a continuation of another run of the same person: a fork at a turn, a hand-off, or a regenerated turn (agents.run@1's LINEAGE). |  |
| `blueprint` | string |  | Since 1.2.0: run this blueprint version once without installing it (Try it; a public agent used one time). The run uses the starter's own keys and places, and every tool asks first whatever the blueprint says. With AGENT, AGENT wins. | - `pattern ^bp_[A-Za-z0-9_-]{3,40}@[1-9][0-9]{0,5}$` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: a-code-run-on-openvibe

~~~~
{
  "text": "Add a goal bar overlay streamers can put on their stream, with the sub goal and progress.",
  "kind": "code",
  "target": "openvibe",
  "model": {
    "id": "openvibe/auto",
    "source": "openvibe"
  },
  "where": {
    "kind": "openvibe"
  },
  "context": {
    "site": "live",
    "url": "https://openvibe.live/dashboard",
    "title": "Dashboard"
  },
  "attachments": [
    {
      "kind": "image",
      "media_id": "med_01K9R2V6M8Q4T0B7C3D5E9F2GH",
      "alt": "A sketch of the bar"
    }
  ],
  "budget": {
    "usd": 5,
    "steps": 400
  }
}
~~~~

Valid: a-fork-of-a-conversation

~~~~
{
  "text": "Same idea, but for a phone screen",
  "lineage": {
    "from": "chat:c_8f3k2m",
    "at_turn": 3,
    "how": "fork"
  }
}
~~~~

Valid: a-question-with-sources

~~~~
{
  "text": "What happened in tech news today?",
  "kind": "ask",
  "sources": [
    "web",
    "openvibe"
  ],
  "depth": "balanced"
}
~~~~

Valid: just-words

~~~~
{
  "text": "A goal bar for my sub goal"
}
~~~~

Valid: try-a-blueprint

~~~~
{
  "text": "Find the best moments from tonight",
  "blueprint": "bp_01JD8C4QJ7Z3K9W2X5V6N1M0PA@3"
}
~~~~

Valid: with-a-play

~~~~
{
  "text": "Write the patch notes for 4.225.0 and have them checked",
  "kind": "task",
  "play": "grader-loop"
}
~~~~

Rejected: a-blueprint-without-a-version

~~~~
{
  "text": "Find the best moments",
  "blueprint": "bp_01JD8C4QJ7Z3K9W2X5V6N1M0PA"
}
~~~~

Rejected: a-play-that-is-not-a-name

~~~~
{
  "text": "Do it",
  "play": "Grader Loop!"
}
~~~~

Rejected: a-target-that-is-not-one

~~~~
{
  "text": "fix it",
  "kind": "code",
  "target": "everything"
}
~~~~

Rejected: no-words

~~~~
{
  "kind": "chat"
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('agents.run-start@1', value);   // { valid, errors: [{ path, message }] }
~~~~
