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

# Data Types

> Core data structures in the ORS protocol

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:

```typescript theme={null}
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:

```typescript theme={null}
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**:

```json theme={null}
{
  "type": "text",
  "text": "What is 2+2?",
  "detail": {"language": "en"}
}
```

***

### ImageBlock

Image content encoded as base64:

```typescript theme={null}
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**:

```json theme={null}
{
  "type": "image",
  "data": "iVBORw0KGgoAAAANSUhEUgA...",
  "mimeType": "image/png",
  "detail": {"width": 800, "height": 600}
}
```

***

### Blocks

Array of blocks (text and/or images):

```typescript theme={null}
type Blocks = Array<TextBlock | ImageBlock>
```

**Usage**: Prompts and tool outputs are represented as blocks.

**Example** (multi-modal prompt):

```json theme={null}
[
  {
    "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:

```typescript theme={null}
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**:

```json theme={null}
{
  "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:

```typescript theme={null}
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):

```json theme={null}
{
  "blocks": [
    {"text": "Correct! The answer is 4.", "detail": null, "type": "text"}
  ],
  "metadata": null,
  "reward": 1.0,
  "finished": true
}
```

**Example** (intermediate step):

```json theme={null}
{
  "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:

```typescript theme={null}
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**:

```json theme={null}
{
  "name": "submit",
  "input": {"answer": "42"},
  "task_id": "trace-123"
}
```

***

### ListToolsOutput

Response from `GET /{env_name}/tools`:

```typescript theme={null}
interface ListToolsOutput {
  tools: ToolSpec[]
}
```

**Example**:

```json theme={null}
{
  "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:

```typescript theme={null}
interface RunToolSuccess {
  ok: true
  output: ToolOutput
}
```

**Example**:

```json theme={null}
{
  "ok": true,
  "output": {
    "blocks": [{"text": "Success", "detail": null, "type": "text"}],
    "metadata": null,
    "reward": 1.0,
    "finished": true
  }
}
```

***

### RunToolError

Failed tool execution:

```typescript theme={null}
interface RunToolError {
  ok: false
  error: string
}
```

**Example**:

```json theme={null}
{
  "ok": false,
  "error": "Tool 'submit' failed: Answer must be a number"
}
```

***

### RunToolOutput

Union type for tool results:

```typescript theme={null}
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:

```typescript theme={null}
type Task = JSONObject
```

**No fixed schema** - each environment defines its own task structure.

**Examples**:

Math environment:

```json theme={null}
{
  "question": "What is 2+2?",
  "answer": "4",
  "difficulty": "easy"
}
```

Coding environment:

```json theme={null}
{
  "description": "Write a function to reverse a string",
  "test_cases": [
    {"input": "hello", "output": "olleh"},
    {"input": "world", "output": "dlrow"}
  ],
  "time_limit": 5
}
```

Web navigation:

```json theme={null}
{
  "goal": "Find the price of product XYZ",
  "start_url": "https://example.com",
  "max_steps": 20
}
```

***

### Split

Categorization of task lists:

```typescript theme={null}
interface Split {
  name: string
  type: "train" | "validation" | "test"
}
```

**Fields**:

* `name`: Split identifier (string)
* `type`: Split category (string, one of: "train", "validation", "test")

**Example**:

```json theme={null}
{
  "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`:

```typescript theme={null}
interface ListTasks {
  split: string
}
```

**Example**:

```json theme={null}
{
  "split": "train"
}
```

***

### NumTasks

Request body for `POST /{env_name}/num_tasks`:

```typescript theme={null}
interface NumTasks {
  split: string
}
```

**Fields**:

* `split`: Split name to count tasks in (string, required)

***

### GetTask

Request body for `POST /{env_name}/task`:

```typescript theme={null}
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`:

```typescript theme={null}
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:

```typescript theme={null}
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 `{}`)

<Note>
  Exactly one of `task_spec` or the `split`+`index` pair must be provided. Providing both or neither is a validation error.
</Note>

**Example** (with inline task spec):

```json theme={null}
{
  "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):

```json theme={null}
{
  "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

```typescript theme={null}
// 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

```typescript theme={null}
// 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)

```python theme={null}
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

```typescript theme={null}
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:

```json theme={null}
{
  "$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

<CardGroup cols={2}>
  <Card title="HTTP API" icon="network-wired" href="/specification/http-api">
    See how these types are used in API endpoints
  </Card>

  <Card title="Sessions" icon="clock" href="/specification/sessions">
    Understand episode lifecycle and state
  </Card>

  <Card title="Tools Concept" icon="wrench" href="/concepts/tools">
    Learn about tool design and usage
  </Card>

  <Card title="Implementation Guide" icon="code" href="/guides/implementing-server">
    Implement these types in your server
  </Card>
</CardGroup>

***

**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.
