AgentsPlay agents.play@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
network
Visibility
public
Status
active
Compatibility
backward
Decision
ADR-044
Schema
https://openvibe.network/contracts/agents/play.v1.json

agents.play@1 (agent-engine.md §4, 2026-11-12): a named way for several agents to work on one ask, as data, so a person or an AI can write one and openvibe.run can list it. ROLES are the agents it uses (each with what it does, the size of model it wants, and how many may run at once); PHASES run in order, the roles in a phase together when PARALLEL; CHECKS say who checks whose work, against a written BAR; STOP says when the play is over; BUDGET.SPLIT gives each role its share of the parent's budget. The orchestrator turns a play into child runs (agents.run@1's PARENT_RUN, PLAY and ROLE). Rules every play keeps, whatever it says: a child's end never ends its parent; a person's message never waits behind new work; a child's budget is a slice of its parent's.

Fields

FieldTypeRequiredDescriptionConstraints
idstringyes
  • pattern ^[a-z][a-z0-9-]{0,60}$
versioninteger
  • minimum 1
namestringyes
  • minLength 1
  • maxLength 120
summarystringWhen to use it, in a sentence or two.
  • minLength 1
  • maxLength 1000
rolesarray of objectyes
  • minItems 1
  • maxItems 12
  • items: no other fields
roles[].idstringyes
  • pattern ^[a-z][a-z0-9-]{0,60}$
roles[].namestring
  • minLength 1
  • maxLength 80
roles[].doesstringyesWhat this role does, as its instructions begin.
  • minLength 1
  • maxLength 2000
roles[].modelenumsmall: the cheapest that can; strong: the best available; same: the parent's; other-family: a model of another family than the one it checks (a grader).
  • one of "small", "strong", "same", "other-family"
roles[].agentstringA particular agent's id, when the role is always the same agent.
  • minLength 1
  • maxLength 160
roles[].countobject
  • no other fields
roles[].count.mininteger
  • minimum 1
  • maximum 64
roles[].count.maxinteger
  • minimum 1
  • maximum 64
roles[].consultsintegerHow many times another role may consult this one (an advisor's limit).
  • minimum 0
  • maximum 50
phasesarray of object
  • maxItems 20
  • items: no other fields
phases[].idstringyes
  • pattern ^[a-z][a-z0-9-]{0,60}$
phases[].namestring
  • minLength 1
  • maxLength 120
phases[].rolesarray of stringyes
  • minItems 1
  • maxItems 12
  • items: pattern ^[a-z][a-z0-9-]{0,60}$
phases[].parallelboolean
checksarray of object
  • maxItems 12
  • items: no other fields
checks[].bystringyes
  • pattern ^[a-z][a-z0-9-]{0,60}$
checks[].ofstringyes
  • pattern ^[a-z][a-z0-9-]{0,60}$
checks[].barstringWhat passing means, in words the checker can apply.
  • minLength 1
  • maxLength 2000
stopobjectyes
  • no other fields
stop.whenenumyesdone: when the last phase ends; passes: when the checks pass; rounds: after ROUNDS rounds; person: when the person says so.
  • one of "done", "passes", "rounds", "person"
stop.roundsinteger
  • minimum 1
  • maximum 20
budgetobject
  • no other fields
budget.splitobjectEach role's share of the parent's budget (the shares add up to at most 1).
visibilityenum
  • one of "private", "public"
authorobject
  • no other fields
author.typeenumyes
  • one of "user", "agent", "service"
author.idstringyes
  • minLength 1
  • maxLength 160

Examples

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

Valid: advisor
{
  "id": "advisor",
  "version": 1,
  "name": "Advisor",
  "summary": "A small model does the work and asks a strong one at the few hard decisions.",
  "roles": [
    {
      "id": "executor",
      "name": "Executor",
      "does": "Do the task step by step. Ask the advisor only when a decision is hard to undo.",
      "model": "small"
    },
    {
      "id": "advisor",
      "name": "Advisor",
      "does": "Answer the executor's question in a few sentences: what to do and why.",
      "model": "strong",
      "consults": 3
    }
  ],
  "phases": [
    {
      "id": "work",
      "roles": [
        "executor"
      ]
    }
  ],
  "stop": {
    "when": "done"
  },
  "budget": {
    "split": {
      "executor": 0.7,
      "advisor": 0.3
    }
  },
  "visibility": "public",
  "author": {
    "type": "service",
    "id": "network"
  }
}
Valid: fan-out
{
  "id": "fan-out",
  "name": "Fan-out",
  "summary": "Split the work across many small agents, then merge.",
  "roles": [
    {
      "id": "splitter",
      "does": "Split the work into parts that do not touch each other.",
      "model": "strong"
    },
    {
      "id": "worker",
      "does": "Do one part.",
      "model": "small",
      "count": {
        "min": 1,
        "max": 16
      }
    },
    {
      "id": "merger",
      "does": "Merge the parts and check they fit.",
      "model": "strong"
    }
  ],
  "phases": [
    {
      "id": "split",
      "roles": [
        "splitter"
      ]
    },
    {
      "id": "work",
      "roles": [
        "worker"
      ],
      "parallel": true
    },
    {
      "id": "merge",
      "roles": [
        "merger"
      ]
    }
  ],
  "stop": {
    "when": "done"
  }
}
Valid: grader-loop
{
  "id": "grader-loop",
  "name": "Grader loop",
  "summary": "Do it again until a grader of another model family says it meets the bar.",
  "roles": [
    {
      "id": "doer",
      "does": "Do the task; take the grader's notes into the next round.",
      "model": "same"
    },
    {
      "id": "grader",
      "does": "Check the work against the bar and say pass, or what is missing.",
      "model": "other-family"
    }
  ],
  "phases": [
    {
      "id": "do",
      "roles": [
        "doer"
      ]
    },
    {
      "id": "check",
      "roles": [
        "grader"
      ]
    }
  ],
  "checks": [
    {
      "by": "grader",
      "of": "doer",
      "bar": "Every claim has a source; nothing the person asked for is missing."
    }
  ],
  "stop": {
    "when": "passes",
    "rounds": 4
  }
}
Rejected: a-share-over-the-whole
{
  "id": "advisor",
  "version": 1,
  "name": "Advisor",
  "summary": "A small model does the work and asks a strong one at the few hard decisions.",
  "roles": [
    {
      "id": "executor",
      "name": "Executor",
      "does": "Do the task step by step. Ask the advisor only when a decision is hard to undo.",
      "model": "small"
    },
    {
      "id": "advisor",
      "name": "Advisor",
      "does": "Answer the executor's question in a few sentences: what to do and why.",
      "model": "strong",
      "consults": 3
    }
  ],
  "phases": [
    {
      "id": "work",
      "roles": [
        "executor"
      ]
    }
  ],
  "stop": {
    "when": "done"
  },
  "budget": {
    "split": {
      "executor": 0.7,
      "advisor": 1.5
    }
  },
  "visibility": "public",
  "author": {
    "type": "service",
    "id": "network"
  }
}
Rejected: no-roles
{
  "id": "empty",
  "name": "Empty",
  "roles": [],
  "stop": {
    "when": "done"
  }
}
Rejected: no-way-to-stop
{
  "id": "advisor",
  "version": 1,
  "name": "Advisor",
  "summary": "A small model does the work and asks a strong one at the few hard decisions.",
  "roles": [
    {
      "id": "executor",
      "name": "Executor",
      "does": "Do the task step by step. Ask the advisor only when a decision is hard to undo.",
      "model": "small"
    },
    {
      "id": "advisor",
      "name": "Advisor",
      "does": "Answer the executor's question in a few sentences: what to do and why.",
      "model": "strong",
      "consults": 3
    }
  ],
  "phases": [
    {
      "id": "work",
      "roles": [
        "executor"
      ]
    }
  ],
  "budget": {
    "split": {
      "executor": 0.7,
      "advisor": 0.3
    }
  },
  "visibility": "public",
  "author": {
    "type": "service",
    "id": "network"
  }
}

Validate

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