Skip to main content
This page documents data structures used in the Open Reward Standard. Type definitions are shown in TypeScript notation but apply to any language implementation.

Core Types

JSONValue

Recursive type representing any valid JSON value:
type JSONValue =
  | string
  | number
  | boolean
  | null
  | { [key: string]: JSONValue }
  | JSONValue[]

type JSONObject = { [key: string]: JSONValue }
Used throughout the protocol for flexible, task-specific data.

Block Types

Blocks are the fundamental unit of content in ORS. They can be text or images.

TextBlock

Text content with optional metadata:
interface TextBlock {
  type: "text"
  text: string
  detail?: JSONObject
}
Fields:
  • type: Always "text" (literal)
  • text: The text content (string)
  • detail: Optional metadata about this text block (object)
Example:
{
  "type": "text",
  "text": "What is 2+2?",
  "detail": {"language": "en"}
}

ImageBlock

Image content encoded as base64:
interface ImageBlock {
  type: "image"
  data: string
  mimeType: string
  detail?: JSONObject
}
Fields:
  • type: Always "image" (literal)
  • data: Base64-encoded image data (string)
  • mimeType: MIME type like "image/png", "image/jpeg" (string)
  • detail: Optional metadata about this image (object)
Example:
{
  "type": "image",
  "data": "iVBORw0KGgoAAAANSUhEUgA...",
  "mimeType": "image/png",
  "detail": {"width": 800, "height": 600}
}

Blocks

Array of blocks (text and/or images):
type Blocks = Array<TextBlock | ImageBlock>
Usage: Prompts and tool outputs are represented as blocks. Example (multi-modal prompt):
[
  {
    "type": "text",
    "text": "What object is shown in this image?"
  },
  {
    "type": "image",
    "data": "iVBORw0KGgo...",
    "mimeType": "image/jpeg"
  }
]

Tool Types

ToolSpec

Specification for an available tool:
interface ToolSpec {
  name: string
  description: string
  input_schema: JSONObject | null
}
Fields:
  • name: Tool identifier, used when calling the tool (string)
  • description: Human-readable description of what the tool does (string)
  • input_schema: JSON Schema defining tool parameters, or null if the tool takes no parameters (always present in output, nullable)
Example:
{
  "name": "bash",
  "description": "Execute a bash command in the environment",
  "input_schema": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The bash command to execute"
      }
    },
    "required": ["command"]
  }
}
Note: If input_schema is null, the tool takes no parameters.

ToolOutput

Result of executing a tool:
interface ToolOutput {
  blocks: Blocks
  reward?: number
  finished: boolean
  metadata?: JSONObject
}
Fields:
  • blocks: Output content (array of TextBlock/ImageBlock, required)
  • reward: RL reward signal (number, optional)
  • finished: Whether episode is complete (boolean, default: false). Optional in input — always present in output.
  • metadata: Optional additional data (object)
Example (successful completion):
{
  "blocks": [
    {"text": "Correct! The answer is 4.", "detail": null, "type": "text"}
  ],
  "metadata": null,
  "reward": 1.0,
  "finished": true
}
Example (intermediate step):
{
  "blocks": [
    {"text": "File contents: Hello World", "detail": null, "type": "text"}
  ],
  "metadata": {"file_size": 11},
  "reward": 0.0,
  "finished": false
}
Key Fields: finished:
  • Critical for episode termination
  • When true, the episode is complete
  • Agent should stop calling tools and delete the session
  • Represents task completion (success or failure)
reward:
  • RL feedback signal
  • Environment-defined; common patterns include sparse rewards (only at episode end) and dense rewards (after each action)

ToolCall

Request to execute a tool:
interface ToolCall {
  name: string
  input: JSONObject
  task_id?: string
}
Fields:
  • name: Tool to call (string, required)
  • input: Tool parameters matching its input_schema (object, required)
  • task_id: Optional identifier for SSE reconnection (string). When provided, clients can reconnect to an in-progress or recently completed tool call and retrieve its result within a 60-second linger window.
Example:
{
  "name": "submit",
  "input": {"answer": "42"},
  "task_id": "trace-123"
}

ListToolsOutput

Response from GET /{env_name}/tools:
interface ListToolsOutput {
  tools: ToolSpec[]
}
Example:
{
  "tools": [
    {
      "name": "submit",
      "description": "Submit an answer",
      "input_schema": {...}
    },
    {
      "name": "bash",
      "description": "Execute bash command",
      "input_schema": {...}
    }
  ]
}

Tool Result Types

Tool execution returns one of two result types:

RunToolSuccess

Successful tool execution:
interface RunToolSuccess {
  ok: true
  output: ToolOutput
}
Example:
{
  "ok": true,
  "output": {
    "blocks": [{"text": "Success", "detail": null, "type": "text"}],
    "metadata": null,
    "reward": 1.0,
    "finished": true
  }
}

RunToolError

Failed tool execution:
interface RunToolError {
  ok: false
  error: string
}
Example:
{
  "ok": false,
  "error": "Tool 'submit' failed: Answer must be a number"
}

RunToolOutput

Union type for tool results:
type RunToolOutput = RunToolSuccess | RunToolError
The ok field discriminates between success and error:
  • ok: true → result has output field
  • ok: false → result has error field
Usage: Returned in SSE end event from POST /{env_name}/call.

Task Types

Task

Tasks are environment-specific JSON objects:
type Task = JSONObject
No fixed schema - each environment defines its own task structure. Examples: Math environment:
{
  "question": "What is 2+2?",
  "answer": "4",
  "difficulty": "easy"
}
Coding environment:
{
  "description": "Write a function to reverse a string",
  "test_cases": [
    {"input": "hello", "output": "olleh"},
    {"input": "world", "output": "dlrow"}
  ],
  "time_limit": 5
}
Web navigation:
{
  "goal": "Find the price of product XYZ",
  "start_url": "https://example.com",
  "max_steps": 20
}

Split

Categorization of task lists:
interface Split {
  name: string
  type: "train" | "validation" | "test"
}
Fields:
  • name: Split identifier (string)
  • type: Split category (string, one of: “train”, “validation”, “test”)
Example:
{
  "name": "train",
  "type": "train"
}
Common splits:
  • {"name": "train", "type": "train"} - Training tasks
  • {"name": "validation", "type": "validation"} - Validation tasks
  • {"name": "test", "type": "test"} - Test tasks
Custom splits: Environments can define custom splits (e.g., “hard”, “easy”) which default to type “validation”.

ListTasks

Request body for POST /{env_name}/tasks:
interface ListTasks {
  split: string
}
Example:
{
  "split": "train"
}

NumTasks

Request body for POST /{env_name}/num_tasks:
interface NumTasks {
  split: string
}
Fields:
  • split: Split name to count tasks in (string, required)

GetTask

Request body for POST /{env_name}/task:
interface GetTask {
  split: string
  index: number
}
Fields:
  • split: Split name (string, required)
  • index: Task index within the split (number, required)

GetTaskRange

Request body for POST /{env_name}/task_range:
interface GetTaskRange {
  split: string
  start?: number
  stop?: number
}
Fields:
  • split: Split name (string, required)
  • start: Start index, inclusive (number, optional)
  • stop: Stop index, exclusive (number, optional)

Session Types

CreateSession

Request to create an episode:
interface CreateSession {
  env_name?: string
  task_spec?: JSONObject
  split?: string
  index?: number
  secrets?: { [key: string]: string }
}
Fields:
  • env_name: Environment to instantiate (string, optional — defaults to first registered environment)
  • task_spec: Task data for this episode (object, optional — provide this or split+index)
  • split: Split name to load task from (string, optional — required with index if task_spec not provided)
  • index: Task index within the split (number, optional — required with split if task_spec not provided)
  • secrets: API keys, credentials, etc. (object, optional, defaults to {})
Exactly one of task_spec or the split+index pair must be provided. Providing both or neither is a validation error.
Example (with inline task spec):
{
  "env_name": "math",
  "task_spec": {
    "question": "If x + 5 = 12, what is x?",
    "answer": "7"
  },
  "secrets": {
    "openai_api_key": "sk-..."
  }
}
Example (with split and index):
{
  "env_name": "math",
  "split": "train",
  "index": 42,
  "secrets": {}
}
Security note: Secrets are passed to the environment but should not be logged or persisted by the server.

Type Examples by Use Case

Discovery Flow

// 1. List environments
GET /list_environments
string[]

// 2. List tools
GET /{env_name}/tools
ListToolsOutput

// 3. List splits
GET /{env_name}/splits
Split[]

// 4. List tasks
POST /{env_name}/tasks
Body: ListTasks
→ { tasks: Task[], env_name: string }

Episode Flow

// 1. Create session
POST /create_session
→ { sid: string }

// 2. Create episode
POST /create
Body: CreateSession
Headers: X-Session-ID
→ { sid: string }

// 3. Get prompt
GET /{env_name}/prompt
Headers: X-Session-ID
Blocks

// 4. Call tool
POST /{env_name}/call
Body: ToolCall
Headers: X-Session-ID
SSE response with RunToolOutput

// 5. Delete episode
POST /delete
Headers: X-Session-ID
→ { sid: string }

Type Validation

Implementations should validate:

Input Validation

  • Tool calls match the tool’s input_schema
  • Required fields are present
  • Types match specifications

Output Guarantees

  • ToolOutput.blocks is non-empty array
  • ToolOutput.finished is boolean
  • ToolOutput.reward is number or null
  • Block type is exactly “text” or “image”

Episode Invariants

  • Once finished: true is returned, no more tools should be called
  • Session IDs are unique across the server
  • Tool names match those in list_tools() output

Language-Specific Notes

Python (Reference Implementation)

from ors import (
    TextBlock,
    ImageBlock,
    Blocks,
    ToolOutput,
    ToolSpec,
    Split,
)

# Create tool output
output = ToolOutput(
    blocks=[TextBlock(text="Correct!", type="text")],
    reward=1.0,
    finished=True
)

TypeScript

interface ToolOutput {
  blocks: Blocks;
  reward?: number;
  finished: boolean;
  metadata?: JSONObject;
}

// Create tool output
const output: ToolOutput = {
  blocks: [{type: "text", text: "Correct!"}],
  reward: 1.0,
  finished: true
};

JSON Schema

For validation in any language, use JSON Schema:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "ToolOutput": {
      "type": "object",
      "properties": {
        "blocks": {"type": "array"},
        "reward": {"type": ["number", "null"]},
        "finished": {"type": "boolean"},
        "metadata": {"type": ["object", "null"]}
      },
      "required": ["blocks", "finished"]
    }
  }
}

Next Steps

HTTP API

See how these types are used in API endpoints

Sessions

Understand episode lifecycle and state

Tools Concept

Learn about tool design and usage

Implementation Guide

Implement these types in your server

Key Takeaway: ORS uses simple, composable types. Blocks provide flexible content representation. ToolOutput bundles content, rewards, and episode termination. Task structure is environment-specific for maximum flexibility.