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

# Run usage

> Using runs with The Context Company custom instrumentation for TypeScript

An [agent run](/concepts#agent-runs) represents a single execution of your agent, from the moment it receives a user input to the final response.

All setter methods return `this`, so you can chain calls:

```typescript theme={null}
r.prompt("What is the weather in London?").metadata({ userId: "user-123" }).response("15°C and cloudy.");
await r.end();
```

## Required

### Initialize run

```typescript theme={null}
import { run } from "@contextcompany/custom";

const r = run();
```

| Parameter        | Required | Description                                                                                                               |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `runId`          | No       | Custom run ID. If not provided, a UUID is automatically generated.                                                        |
| `sessionId`      | No       | Group multiple runs into an [agent session](/concepts#agent-sessions). See [Track agent sessions](#track-agent-sessions). |
| `conversational` | No       | Set to `true` to indicate the run was initiated by a user. See [Conversational runs](/concepts#conversational-runs).      |
| `startTime`      | No       | Custom start time. Defaults to `new Date()`.                                                                              |
| `timeout`        | No       | Timeout in milliseconds. Defaults to `1200000` (20 minutes).                                                              |

```typescript theme={null}
import { run } from "@contextcompany/custom";

const r = run({
  runId: "your-custom-uuid",
  sessionId: "session-123",
  conversational: true,
});
```

Every run has a `.runId` property you can use to retrieve its ID (auto-generated or custom):

```typescript theme={null}
const runId = r.runId;
```

### Set prompt

The prompt is **required** before calling `.end()`.

```typescript theme={null}
r.prompt(userPrompt);
// or
r.prompt({ user_prompt: userPrompt, system_prompt: systemPrompt });
```

| Parameter       | Required | Description                                           |
| --------------- | -------- | ----------------------------------------------------- |
| `userPrompt`    | **Yes**  | The user input to the agent                           |
| `system_prompt` | No       | A system message to include alongside the user prompt |

```typescript theme={null}
// User prompt only
r.prompt("What is the weather in London?");

// User prompt with system prompt
r.prompt({
  user_prompt: "What is the weather in London?",
  system_prompt: "You are a helpful weather agent.",
});
```

### End run

End the run and export it. A run must have a **prompt** set before calling `.end()`. The run cannot be modified after calling `.end()`.

```typescript theme={null}
import { run } from "@contextcompany/custom";

const r = run();
r.prompt("What is the weather in London?");

// --- Your agent loop ---
// ...
// --- End of agent loop ---

r.response("The weather in London is 15°C and cloudy.");
await r.end();
```

***

## Optional run data

### Set response

```typescript theme={null}
r.response(text);
```

| Parameter | Required | Description                       |
| --------- | -------- | --------------------------------- |
| `text`    | **Yes**  | The final response from the agent |

```typescript theme={null}
r.response("The weather in London is 15°C and cloudy.");
```

### Mark run as failed

Sets the status code to error and exports the payload. The run cannot be modified after calling `.error()`. Unlike `.end()`, calling `.error()` does not require a prompt to be set. Any un-ended children (steps, tool calls) are automatically ended with error status.

```typescript theme={null}
r.error(statusMessage?);
```

| Parameter       | Required | Description                |
| --------------- | -------- | -------------------------- |
| `statusMessage` | No       | A description of the error |

```typescript theme={null}
import { run } from "@contextcompany/custom";

const r = run();
r.prompt("What is the weather in London?");

try {
  const result = await callWeatherApi();
  r.response(result);
  await r.end();
} catch (e) {
  await r.error(String(e));
}
```

***

## Add custom metadata

Custom metadata allows you to add additional properties to your [agent runs](/concepts#agent-runs). This is particularly useful for tying agent runs to your own specific business logic, letting you filter and analyze agent runs by user, organization, feature, or some other dimension.

```typescript theme={null}
r.metadata(data);
```

| Parameter | Required | Description                  |
| --------- | -------- | ---------------------------- |
| `data`    | **Yes**  | An object of key-value pairs |

```typescript theme={null}
r.metadata({
  userId: "4a6b111c-b53a-4d00-a877-67185022ab9e",
  orgId: "org-123",
});
```

Agent runs are automatically indexed by your custom metadata fields and can be filtered directly in the dashboard.

### Identifying the agent

If your product ships more than one named agent, set the reserved `tcc.agent` metadata key to scope the run to a specific [agent](/concepts#agents). The dashboard's top-level agent selector, per-agent patterns and recaps, and the `agent` filter on the [REST API](/access-data/api) and [MCP tools](/access-data/mcp) all read from this key.

```typescript theme={null}
r.metadata({
  "tcc.agent": "support-agent",
});
```

<Note>
  Agent names that collide with reserved dashboard routes (for example `runs`, `sessions`, `patterns`, `recaps`, `overview`, `search`, `failures`, `feedback`, `tools`, `topics`, `views`, `settings`, `mcp-and-api`) are dropped.
</Note>

***

### Identifying users and organizations

Attach the end user and their organization to a run as first-class identity using the reserved `tcc.userId`, `tcc.userName`, `tcc.orgId`, and `tcc.orgName` metadata keys. This is **not the same** as adding a `userId` field to custom metadata — these keys promote user and org identity to dedicated dashboard filters and unlock native user/org search, per-user views, and per-org analytics. See [User and organization identity](/concepts#user-and-organization-identity) for the full concept.

Set these whenever you have a stable identifier for the end user or their organization in your product.

```typescript theme={null}
r.metadata({
  "tcc.userId": "user-123",
  "tcc.userName": "Jane Doe",
  "tcc.orgId": "org-456",
  "tcc.orgName": "Acme Inc.",
});
```

<Note>
  `tcc.userName` and `tcc.orgName` require the corresponding ID (`tcc.userId` / `tcc.orgId`) to also be set. Names without IDs are dropped.
</Note>

***

## Add user feedback

User feedback allows you to collect score (thumbs up & thumbs down) and text feedback (up to 2000 characters) from end users on your [agent runs](/concepts#agent-runs).

This is useful for tracking user satisfaction, identifying problematic responses, and filtering agent runs in the dashboard to focus on positive or negative feedback.

Both `score` and `text` are optional individually, but each request must include at least one of them.

`score` is the thumbs rating. Use only `"thumbs_up"` or `"thumbs_down"`.

`text` is written feedback from your user, up to 2000 characters.

| Parameter | Required | Description                                             |
| --------- | -------- | ------------------------------------------------------- |
| `score`   | No       | Thumbs rating. Must be `"thumbs_up"` or `"thumbs_down"` |
| `text`    | No       | Written user feedback, up to 2000 characters            |

Use the `submitFeedback` function with a run ID:

```typescript theme={null}
import { run, submitFeedback } from "@contextcompany/custom";

const r = run();
r.prompt("What is the weather in London?");
r.response("The weather in London is 15°C and cloudy.");
await r.end();

// Submit score and/or text feedback using the run ID
await submitFeedback({
  runId: r.runId,
  score: "thumbs_up", // Optional thumbs rating: "thumbs_up" or "thumbs_down"
  text: "Very helpful!", // Optional written user feedback, up to 2000 characters
});
```

Agent runs with feedback can be filtered in the dashboard using the feedback filter.

***

## Track agent sessions

[Agent sessions](/concepts#agent-sessions) represent multiple agent runs that are grouped together. The most common use case is tracking entire conversations between a human user and an AI agent in chatbot interfaces.

Agent sessions can be tracked by passing a `sessionId` when creating a run:

```typescript theme={null}
import { run } from "@contextcompany/custom";

const sessionId = "unique-session-identifier";

// First message in the conversation
const r1 = run({ sessionId });
r1.prompt("What is the weather in London?");
r1.response("The weather in London is 15°C and cloudy.");
await r1.end();

// Second message in the same conversation
const r2 = run({ sessionId });
r2.prompt("What about Paris?");
r2.response("The weather in Paris is 18°C and sunny.");
await r2.end();
```

The `sessionId` should be a unique string identifier. We recommend using a UUID.

Agent sessions are automatically indexed and can be filtered directly in the dashboard.

***

## Factory pattern

If you have all run data available upfront (post-hoc logging, batch imports, replaying from logs), use the `sendRun` function:

```typescript theme={null}
import { sendRun } from "@contextcompany/custom";

await sendRun({
  prompt: {
    user_prompt: "What's the weather?",
    system_prompt: "You are a helpful assistant.",
  },
  response: "72°F in San Francisco",
  startTime: new Date("2025-01-01T00:00:00Z"),
  endTime: new Date("2025-01-01T00:00:01Z"),
  metadata: { agent: "weather-bot" },
  steps: [
    {
      prompt: JSON.stringify(messages),
      response: assistantContent,
      model: "gpt-4o",
      tokens: { uncached: 120, completion: 45 },
      startTime: new Date("2025-01-01T00:00:00Z"),
      endTime: new Date("2025-01-01T00:00:01Z"),
    },
  ],
  toolCalls: [
    {
      name: "get_weather",
      args: { city: "San Francisco" },
      result: { temp: 72, unit: "F" },
      startTime: new Date("2025-01-01T00:00:00Z"),
      endTime: new Date("2025-01-01T00:00:01Z"),
    },
  ],
});
```
