> ## Documentation Index
> Fetch the complete documentation index at: https://developer.watson-orchestrate.ibm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sending context to conversations

> Use context variables to create more personalized, context-aware interactions by providing the agent with relevant data about the user or the environment, such as user ID, role, tenant, locale, or session-specific values from upstream systems.

Context variables pass additional information from your application into an agent run, making that data available to the agent while it processes a message. Context is [scoped to a single run](#persisting-context-across-turns), which means values are not automatically carried forward to the next message, and your client must re-send them to persist across turns.

At a high level, using context variables involves the following steps:

1. Deliver values to the run by using a JWT token, an API payload, or an embedded-chat event.
2. Declare which variables an agent can access in its definition.
3. Reference those variables in the agent's instructions, descriptions, or guidelines so the runtime injects their values into the model prompt.
4. Persist values across turns by resending them in each subsequent call.

For implementation details specific to each integration surface, see:

* [Context variables in the embedded chat](/webchat/context_variables)
* [Providing access to context variables in native agents](/agents/build_agent#providing-access-to-context-variables)
* [Providing access to context variables in external agents](/agents/connect_agent#providing-access-to-context-variables)
* [Using context variables in Python tools](/tools/create_tool#using-context-variables)

Use the following table to find the approach for your scenario:

| Scenario                                                                     | Action                                                                                                                                               | Learn more                                                                         |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Pass a stable identity value, such as user ID, role, or tenant               | Embed it in the **JWT**                                                                                                                              | [JWT token](#jwt-token)                                                            |
| Pass a value that changes between turns                                      | Include it in the **runs payload** or inject it by using `pre:send`                                                                                  | [Runs API payload](#api-payload), [`pre:send` event](#embedded-chat-presend-event) |
| Avoid conflict when the same name exists in both the JWT and the API payload | Use distinct variable names. If the same name appears in both, the JWT value takes precedence.                                                       | [Precedence](#precedence)                                                          |
| Configure an agent to use a context variable in its prompt                   | Set `context_access_enabled: true`, list the variable in `context_variables`, and reference `{var}` in the instructions, descriptions, or guidelines | [Configure an agent](#configuring-an-agent-to-use-context-variables)               |
| Retain a value across turns or threads                                       | Carry context forward in the client by using event handlers, or resend the values in each API call                                                   | [Persisting context across turns](#persisting-context-across-turns)                |
| Update a context variable from within a tool                                 | Use a **Python tool** or **flow tool** with an `AgentRun` parameter                                                                                  | [Tool support](#tool-support)                                                      |
| Name a custom context variable                                               | Avoid the `wxo_` prefix and hyphens; use distinct names for JWT-supplied and payload-supplied variables                                              | [Naming rules](#naming-rules)                                                      |
| Use context variables through a channel such as Slack or Teams               | Channels provide fixed, read-only context values supplied by the platform. Custom context variables, updating, and persistence are not supported.    | [Channel support](#channel-support)                                                |

## Types of context variables

Context variables are either **system variables**, which the platform populates automatically, or **custom variables**, which your application supplies.

### System variables

System variables are predefined variables whose values the platform populates automatically. By default, agents cannot access any system variable. You must explicitly list each one in the agent's [`context_variables` field](#configuring-an-agent-to-use-context-variables) to expose it.

| Variable        | Description                                                                            |
| --------------- | -------------------------------------------------------------------------------------- |
| `wxo_email_id`  | Email address of the user who invoked the agent or tool.                               |
| `wxo_user_name` | Username of the user who invoked the agent or tool.                                    |
| `wxo_tenant_id` | Unique tenant identifier for the request.                                              |
| `wxo_thread_id` | Unique identifier for the conversation thread that groups all related messages.        |
| `wxo_run_id`    | Unique identifier for the individual run within a thread, generated for every message. |

### Custom variables

Custom variables are values that your application defines and passes to a run. Use them to carry any data that the agent or a tool needs, such as `clientID`, `role`, `locale`, or `selected_product`.

To make a custom variable available to an agent, declare it in the `context_variables` field of the agent definition:

```yaml theme={null}
context_access_enabled: true
context_variables:
  - clientID
  - channel
```

#### Naming rules

Follow these rules when you name custom context variables. Violations are not always reported as errors and can cause silent collisions or parsing failures:

* **Do not use the `wxo_` prefix.** It is reserved for system variables. Using it can cause collisions with platform-managed values.
* **Do not use hyphens (`-`).** They can cause parsing errors. Use underscores (`_`) instead.
* **Use distinct names for JWT-supplied and API-payload-supplied variables.** If the same name appears in both, the JWT value takes precedence. For more information, see [Precedence](#precedence).

## Delivering context variables to a run

You can deliver context to a run in the following ways. The right method depends on how stable the value is and where it originates.

### JWT token

Embed context in the signed JWT that authenticates the embedded chat. Because the JWT is signed server-side, clients cannot tamper with its values, and neither a tool, an agentic workflow, nor the [API payload](#api-payload) can overwrite a variable that is delivered in the JWT. If you need to update a value during a session, omit it from the JWT and pass it in the [API payload](#api-payload) instead.

Use this method when:

* The value is tied to user identity, such as user ID, role, organization, tenant identifier, or permission level.
* The value does not change during the session.

For implementation details, see [Context variables in the embedded chat, Method 1: JWT token](/webchat/context_variables#method-1-context-variables-jwt-token).

### API payload

Pass context as a dictionary in the `context` field of the request body when you call one of these endpoints:

* [Runs API](/apis/orchestrate-agent/chat-with-orchestrate-assistant)
* [Chat Completions API](/apis/orchestrate-agent/chat-with-agents)
* [Streaming Chat Completions API](/apis/orchestrate-agent/chat-with-orchestrate-assistant-as-stream)

Use this method when:

* The value changes between turns or is not available at JWT-signing time.
* The client must update a value without reissuing a JWT.

### Embedded chat `pre:send` event

When you embed the chat, the host page can inject or modify context per message by using the [`pre:send`](/webchat/events/preSend) event handler, before the message is sent to the runtime.

```javascript theme={null}
function preSendHandler(event, instance) {
  event.message.context = {
    ...event.message.context,
    clientID: "12345",
    user_name: "John Doe",
  };
}
```

Use this method when:

* The value changes per message or varies during the session.
* The host page resolves the value at send time, such as current page, form state, or selected profile.

For implementation details, see [Context variables in the embedded chat, Method 2: Instance methods](/webchat/context_variables#method-2-context-variables-instance-methods-presend-event).

## Configuring an agent to use context variables

By default, agents invoked during a run cannot access context variables. You must explicitly enable access at the agent level and list each variable individually. A variable that exists in the run but is not listed is not available to the agent.

##### `context_access_enabled`

Set `context_access_enabled: true` in the agent definition to allow the agent to read context variables. When this field is `false` (the default), context variables are present in the run but the agent cannot read them.

##### `context_variables`

After you enable access, use the `context_variables` field to specify exactly which variables the agent can read. This field acts as an allowlist: only the variables listed here are available to the agent during execution.

Variables declared in `context_variables` can be system variables or custom variables.

### Referencing variables in the agent definition

After you declare a variable in `context_variables`, reference it anywhere in the agent's `instructions`, `description`, or `guidelines` by wrapping its name in curly braces: `{variable_name}`. The runtime substitutes the live value at execution time.

```yaml wrap theme={null}
spec_version: v1
style: react_core
name: service_now_agent
llm: watsonx/meta-llama/llama-3-2-90b-vision-instruct
description: Agent description
instructions: |
  You have access to clientID: {clientID}
collaborators: []
tools: []
context_access_enabled: true
context_variables:
  - clientID
  - channel
```

<Note>
  **Injection is opt-in per variable.** A variable that is present in the run but not listed in `context_variables`, or not referenced with `{...}` in the instructions, descriptions, or guidelines, is not injected into the model prompt.
</Note>

##### Example: exposing system and custom variables

The following agent definition makes `wxo_email_id` and four custom variables available. The platform supplies the value of `wxo_email_id`, and your application supplies the rest.

```yaml wrap highlight={8-12,19-23} theme={null}
spec_version: v1
style: react_core
name: askHR_agent
llm: watsonx/meta-llama/llama-3-2-90b-vision-instruct
description: You are a helpful agent that answers HR-related queries
instructions: >-
  You have access to the following context values:
     `wxo_email_id: {wxo_email_id}`
     `name: {name}`
     `role: {role}`
     `user_name: {user_name}`
     `email_id: {email_id}`
  Pass these values exactly as provided.
  Do not ask the user for these values, they are always available in the context.
collaborators: []
tools: []
context_access_enabled: true
context_variables:
  - wxo_email_id   # system variable, platform fills this in automatically
  - name           # custom variables, your application supplies these
  - role
  - user_name
  - email_id
```

In this configuration:

* `wxo_email_id` is a system variable. Because it is listed in `context_variables`, the platform injects its value. The agent can reference it as `{wxo_email_id}` in the instructions.
* `name`, `role`, `user_name`, and `email_id` are custom variables that your application passes in the run payload or JWT.
* `wxo_user_name`, `wxo_tenant_id`, `wxo_thread_id`, and `wxo_run_id` are not listed, so they are not available to this agent.

## Precedence

When the same variable name appears in both the JWT and the API payload (or `pre:send` injection), **the JWT value takes precedence**.

```
JWT value  >  API payload value
```

The runtime ignores the API payload value for any name that also exists in the JWT. This applies to all three API endpoints that accept a `context` field: the Runs API, the Chat Completions API, and the Streaming Chat Completions API.

To avoid conflicts, use distinct variable names for stable JWT context and dynamic payload context, or omit a variable from the JWT if you intend to update it from the client.

<Warning>
  **JWT values cannot be modified.** Neither a tool nor the API payload can overwrite a variable that was delivered in the JWT.
</Warning>

## Persisting context across turns

**Context is scoped to a single run.** Values, including any updates that a tool writes during that run, are available only within that one invocation. The runtime does not carry them forward to the next message automatically.

**Context does not persist across a thread.** The platform does not retain context values between runs. If your use case requires values to survive across multiple turns in a conversation, your client application must carry them forward explicitly.

### Embedded chat event handlers

Use the `pre:receive` event to read the context that is returned in the agent response and hold it in client-side state. Then reinject it on the next `pre:send`.

```javascript theme={null}
let carriedContext = {};

// Read context back from the agent response
function preReceiveHandler(event, instance) {
  if (event.message.context) {
    carriedContext = { ...event.message.context };
  }
}

// Reinject carried context on the next outbound message
function preSendHandler(event, instance) {
  event.message.context = {
    ...carriedContext,
    ...event.message.context,
  };
}

function onChatLoad(instance) {
  instance.on('pre:send', preSendHandler);
  instance.on('pre:receive', preReceiveHandler);
}
```

### Re-send by using the API payload

Include the context values again in each API request. Every run response returns the current context state, so your application can read the values and pass them back in the next call.

The context is returned in the following locations:

* **Streaming responses:** in the `message.created` and `run.completed` events.
* **Non-streaming responses:** in the message that is associated with the run.

## Tool support

Only Python tools and agentic workflows can read and update context variables. All other tool types cannot access the run context. Updates that a tool writes are visible to all tools that are called later in the same run but are not persisted after the run ends. If subsequent runs need those values, your client must resend them. See [Persisting context across turns](#persisting-context-across-turns).

Tools interact with context variables in the following ways:

* **Read:** A tool can read any context variable that is present in the run, including system variables such as `wxo_email_id`. This lets tools act on user identity, session data, or any custom value that the client passes.
* **Update:** A tool can write new values or overwrite existing custom variables during a run. Updates are visible to all tools that are called later in the same run. Tools cannot update system variables (`wxo_*`).

You can also pass context variables as arguments to a Python tool function. When you pass them as function arguments, the agent runtime fills them automatically without prompting the user.

For implementation details, code examples, and constraints, see [Using context variables in Python tools](/tools/create_tool#using-context-variables).

## Channel support

The mechanisms described in this topic for delivering, updating, and persisting context are not available through channel integrations. For channels such as Slack or Teams, context support is limited to a fixed set of read-only values that the platform supplies from the channel session, such as the sender identifier or channel type. Custom context variables, tool updates, and cross-turn persistence are not supported. For more information, see [Channel-specific context variables](https://www.ibm.com/docs/en/watsonx/watson-orchestrate/base?topic=channels-channel-specific-context-variables).

If your use case requires custom context variables through a channel, you might need a custom implementation.

<Note>
  These limitations for channels do not apply to embedded chat. The full context-variable capabilities described in this topic are available through the embedded chat integration.
</Note>
