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

# agents.source@1 · OpenVibe.Services

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

# AgentsSource `agents.source@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.0.0
- Owner: network
- Visibility: public
- Status: active
- Compatibility: backward
- Decision: [ADR-044](/docs/adr/ADR-044)
- Schema: [`https://openvibe.network/contracts/agents/source.v1.json`](/docs/contracts/agents.source.json)

agents.source@1 (agent-engine.md §5, 2026-11-12): one place where asks are taken in without opening an agent app, and how. KIND is the place (the feed, chat rooms and DMs, comments, git.openvibe.codes, a composer, notifications, mail, a schedule or a goal, a webhook, a machine's events); ON turns it on; WHO says whose words may start work there (only its owner, a list of people, their followers, or anyone); RULE says in words what counts as an ask; CREATES is the run an accepted ask becomes (its kind, target, agent and play); BUDGET is each such run's hard limit; ANSWER is how the run speaks back on the thread (a reply, a card that follows the run, a notice, or nothing). Intake stores the ask first and acts after, with backoff; an inferred ask confirms before it acts (agents.run@1's MANDATE.STRENGTH).

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `id` | string | yes |  | - `pattern ^src_[A-Za-z0-9]{8,40}$` |
| `kind` | enum | yes |  | - `one of "feed", "chat", "comments", "git", "composer", "notifications", "mail", "schedule", "goal", "webhook", "machine"` |
| `name` | string |  |  | - `minLength 1`<br>- `maxLength 120` |
| `owner` | object | yes |  | - `no other fields` |
| `owner.type` | enum | yes |  | - `one of "user", "agent", "service"` |
| `owner.id` | string | yes |  | - `minLength 1`<br>- `maxLength 160` |
| `on` | boolean | yes |  |  |
| `where` | object |  | Which one of that kind: a room, a repository, a feed, a machine. | - `no other fields` |
| `where.service` | string | yes |  | - `pattern ^[a-z][a-z0-9-]{0,40}$` |
| `where.kind` | string |  |  | - `pattern ^[a-z][a-z0-9_-]{0,40}$` |
| `where.id` | string |  |  | - `minLength 1`<br>- `maxLength 200` |
| `where.url` | string |  |  | - `pattern ^https://`<br>- `format uri`<br>- `maxLength 2048` |
| `who` | object | yes |  | - `no other fields` |
| `who.may` | enum | yes |  | - `one of "owner", "list", "followers", "anyone"` |
| `who.list` | array of string |  |  | - `maxItems 200`<br>- `unique items`<br>- `items: pattern ^usr_[A-Za-z0-9]{6,40}$` |
| `rule` | string |  | What counts as an ask here, in words (a post that asks for a feature or reports a bug; a message that names @Vibe). | - `minLength 1`<br>- `maxLength 2000` |
| `creates` | object | yes |  | - `no other fields` |
| `creates.kind` | enum | yes |  | - `one of "chat", "ask", "task", "code", "machine", "goal"` |
| `creates.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. |  |
| `creates.agent` | string |  |  | - `minLength 1`<br>- `maxLength 160` |
| `creates.play` | string |  | The play (agents.play@1's ID) this run's tree follows: solo, advisor, plan-execute, fan-out, team, grader-loop, research-build, issue-to-pr, watch, or a person's own. On a child run it is its parent's. | - `pattern ^[a-z][a-z0-9-]{0,60}$` |
| `budget` | object |  |  | - `no other fields` |
| `budget.usd` | number |  |  | - `minimum 0` |
| `budget.tokens` | integer |  |  | - `minimum 0` |
| `budget.seconds` | number |  |  | - `minimum 0` |
| `budget.steps` | integer |  |  | - `minimum 1` |
| `answer` | enum |  |  | - `one of "reply", "card", "notice", "none"` |
| `created_at` | string |  |  | - `format date-time` |
| `updated_at` | string |  |  | - `format date-time` |

## Examples

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

 Valid: the-owners-feed

~~~~
{
  "id": "src_01K9R5ABCDEF",
  "kind": "feed",
  "name": "Asks on my feed",
  "owner": {
    "type": "user",
    "id": "usr_01K9R2V6M8Q4T0B7C3D5E9F2GH"
  },
  "on": true,
  "where": {
    "service": "community",
    "kind": "feed",
    "id": "home"
  },
  "who": {
    "may": "owner"
  },
  "rule": "A post that asks for a feature or reports a bug in OpenVibe.",
  "creates": {
    "kind": "code",
    "target": "openvibe",
    "play": "issue-to-pr"
  },
  "budget": {
    "usd": 5
  },
  "answer": "card",
  "created_at": "2026-11-12T11:00:00Z",
  "updated_at": "2026-11-12T11:00:00Z"
}
~~~~

Valid: vibe-in-a-room

~~~~
{
  "id": "src_01K9R5GHJKMN",
  "kind": "chat",
  "owner": {
    "type": "user",
    "id": "usr_01K9R2V6M8Q4T0B7C3D5E9F2GH"
  },
  "on": true,
  "where": {
    "service": "chat",
    "kind": "room",
    "id": "design-crit",
    "url": "https://openvibe.chat/r/design-crit"
  },
  "who": {
    "may": "list",
    "list": [
      "usr_01K9R6PQRSTVWXYZ0123456789"
    ]
  },
  "rule": "A message that names @Vibe.",
  "creates": {
    "kind": "chat"
  },
  "answer": "reply"
}
~~~~

Rejected: a-kind-of-place-not-known

~~~~
{
  "id": "src_01K9R5ABCDEF",
  "kind": "carrier-pigeon",
  "name": "Asks on my feed",
  "owner": {
    "type": "user",
    "id": "usr_01K9R2V6M8Q4T0B7C3D5E9F2GH"
  },
  "on": true,
  "where": {
    "service": "community",
    "kind": "feed",
    "id": "home"
  },
  "who": {
    "may": "owner"
  },
  "rule": "A post that asks for a feature or reports a bug in OpenVibe.",
  "creates": {
    "kind": "code",
    "target": "openvibe",
    "play": "issue-to-pr"
  },
  "budget": {
    "usd": 5
  },
  "answer": "card",
  "created_at": "2026-11-12T11:00:00Z",
  "updated_at": "2026-11-12T11:00:00Z"
}
~~~~

Rejected: a-list-of-not-people

~~~~
{
  "id": "src_01K9R5ABCDEF",
  "kind": "feed",
  "name": "Asks on my feed",
  "owner": {
    "type": "user",
    "id": "usr_01K9R2V6M8Q4T0B7C3D5E9F2GH"
  },
  "on": true,
  "where": {
    "service": "community",
    "kind": "feed",
    "id": "home"
  },
  "who": {
    "may": "list",
    "list": [
      "everyone@example.com"
    ]
  },
  "rule": "A post that asks for a feature or reports a bug in OpenVibe.",
  "creates": {
    "kind": "code",
    "target": "openvibe",
    "play": "issue-to-pr"
  },
  "budget": {
    "usd": 5
  },
  "answer": "card",
  "created_at": "2026-11-12T11:00:00Z",
  "updated_at": "2026-11-12T11:00:00Z"
}
~~~~

Rejected: nothing-to-create

~~~~
{
  "id": "src_01K9R5ABCDEF",
  "kind": "feed",
  "name": "Asks on my feed",
  "owner": {
    "type": "user",
    "id": "usr_01K9R2V6M8Q4T0B7C3D5E9F2GH"
  },
  "on": true,
  "where": {
    "service": "community",
    "kind": "feed",
    "id": "home"
  },
  "who": {
    "may": "owner"
  },
  "rule": "A post that asks for a feature or reports a bug in OpenVibe.",
  "budget": {
    "usd": 5
  },
  "answer": "card",
  "created_at": "2026-11-12T11:00:00Z",
  "updated_at": "2026-11-12T11:00:00Z"
}
~~~~

## Validate

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