Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/data/nav/aitransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ export default {
pages: [
{
name: 'Overview',
link: '/docs/ai-transport/features/token-streaming',
link: '/docs/ai-transport/token-streaming',
index: true,
},
{
name: 'Message per response',
link: '/docs/ai-transport/features/token-streaming/message-per-response',
link: '/docs/ai-transport/token-streaming/message-per-response',
},
{
name: 'Message per token',
link: '/docs/ai-transport/features/token-streaming/message-per-token',
link: '/docs/ai-transport/token-streaming/message-per-token',
},
],
},
Expand All @@ -41,19 +41,19 @@ export default {
pages: [
{
name: 'Overview',
link: '/docs/ai-transport/features/sessions-identity',
link: '/docs/ai-transport/sessions-identity',
},
{
name: 'Identifying users and agents',
link: '/docs/ai-transport/features/sessions-identity/identifying-users-and-agents',
link: '/docs/ai-transport/sessions-identity/identifying-users-and-agents',
},
{
name: 'Online status',
link: '/docs/ai-transport/features/sessions-identity/online-status',
link: '/docs/ai-transport/sessions-identity/online-status',
},
{
name: 'Resuming sessions',
link: '/docs/ai-transport/features/sessions-identity/resuming-sessions',
link: '/docs/ai-transport/sessions-identity/resuming-sessions',
},
],
},
Expand All @@ -62,23 +62,23 @@ export default {
pages: [
{
name: 'Accepting user input',
link: '/docs/ai-transport/features/messaging/accepting-user-input',
link: '/docs/ai-transport/messaging/accepting-user-input',
},
{
name: 'Tool calls',
link: '/docs/ai-transport/features/messaging/tool-calls',
link: '/docs/ai-transport/messaging/tool-calls',
},
{
name: 'Human-in-the-loop',
link: '/docs/ai-transport/features/messaging/human-in-the-loop',
link: '/docs/ai-transport/messaging/human-in-the-loop',
},
{
name: 'Chain of thought',
link: '/docs/ai-transport/features/messaging/chain-of-thought',
link: '/docs/ai-transport/messaging/chain-of-thought',
},
{
name: 'Citations',
link: '/docs/ai-transport/features/messaging/citations',
link: '/docs/ai-transport/messaging/citations',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ meta_keywords: "user input, AI prompts, message correlation, identified clients,

User input enables users to send prompts and requests to AI agents over Ably channels. The agent subscribes to a channel to receive user messages, processes them, and sends responses back. This pattern uses [Ably Pub/Sub](/docs/basics) for realtime, bi-directional communication between users and agents.

User input works alongside [token streaming](/docs/ai-transport/features/token-streaming) patterns to create complete conversational AI experiences. While token streaming handles agent-to-user output, user input handles user-to-agent prompts.
User input works alongside [token streaming](/docs/ai-transport/token-streaming) patterns to create complete conversational AI experiences. While token streaming handles agent-to-user output, user input handles user-to-agent prompts.

## How it works <a id="how-it-works"/>

Expand All @@ -20,22 +20,22 @@ User input follows a channel-based pattern where both users and agents connect t
This decoupled approach means agents don't need to manage persistent connections to individual users. Instead, they subscribe to channels and respond to messages as they arrive.

<Aside data-type="further-reading">
Learn more about channel-based communication in [channel-oriented sessions](/docs/ai-transport/features/sessions-identity#connection-oriented-vs-channel-oriented-sessions).
Learn more about channel-based communication in [channel-oriented sessions](/docs/ai-transport/sessions-identity#connection-oriented-vs-channel-oriented-sessions).
</Aside>

## Identify the user <a id="identify-user"/>

Agents need to verify that incoming messages are from legitimate users. Use [identified clients](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-identity) or [user claims](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-claims) to establish a verified identity or role for the user.
Agents need to verify that incoming messages are from legitimate users. Use [identified clients](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-identity) or [user claims](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-claims) to establish a verified identity or role for the user.

<Aside data-type="further-reading">
For more information about establishing verified identities and roles, see [Identifying users and agents](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents).
For more information about establishing verified identities and roles, see [Identifying users and agents](/docs/ai-transport/sessions-identity/identifying-users-and-agents).
</Aside>

### Verify by user identity <a id="verify-identity"/>

Use the `clientId` to identify the user who sent a message. This enables personalized responses, per-user rate limiting, or looking up user-specific preferences from your database.

When a user [authenticates with Ably](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#authenticating), embed their identity in the JWT:
When a user [authenticates with Ably](/docs/ai-transport/sessions-identity/identifying-users-and-agents#authenticating), embed their identity in the JWT:

<Code>
```javascript
Expand All @@ -62,9 +62,9 @@ await channel.subscribe('user-input', (message) => {

### Verify by role <a id="verify-role"/>

Use [user claims](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-claims) to verify that a message comes from a user rather than another agent sharing the channel. This is useful when the agent needs to distinguish message sources without needing the specific user identity.
Use [user claims](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-claims) to verify that a message comes from a user rather than another agent sharing the channel. This is useful when the agent needs to distinguish message sources without needing the specific user identity.

When a user [authenticates with Ably](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#authenticating), embed their role in the JWT:
When a user [authenticates with Ably](/docs/ai-transport/sessions-identity/identifying-users-and-agents#authenticating), embed their role in the JWT:

<Code>
```javascript
Expand Down Expand Up @@ -135,7 +135,7 @@ await channel.subscribe('user-input', (message) => {
</Code>

<Aside data-type="note">
The agent can use `message.clientId` to identify which user sent the prompt. This is a verified identity when using [identified clients](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-identity).
The agent can use `message.clientId` to identify which user sent the prompt. This is a verified identity when using [identified clients](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-identity).
</Aside>

## Publish agent responses <a id="publish-agent-responses"/>
Expand Down Expand Up @@ -195,7 +195,7 @@ await channel.subscribe('agent-response', (message) => {

For longer AI responses, you'll typically want to stream tokens back to the user rather than waiting for the complete response. The `promptId` correlation allows users to associate streamed tokens with their original prompt.

When streaming tokens using [message-per-response](/docs/ai-transport/features/token-streaming/message-per-response) or [message-per-token](/docs/ai-transport/features/token-streaming/message-per-token) patterns, include the `promptId` in the message extras:
When streaming tokens using [message-per-response](/docs/ai-transport/token-streaming/message-per-response) or [message-per-token](/docs/ai-transport/token-streaming/message-per-token) patterns, include the `promptId` in the message extras:

<Code>
```javascript
Expand Down Expand Up @@ -228,7 +228,7 @@ async function streamResponse(channel, prompt, promptId) {
</Code>

<Aside data-type="note">
When appending tokens, include the `extras` with all headers to preserve them on the message. If you omit `extras` from an append operation, any existing headers will be removed. See token streaming with the [message per response](/docs/ai-transport/features/token-streaming/message-per-response) pattern for more details.
When appending tokens, include the `extras` with all headers to preserve them on the message. If you omit `extras` from an append operation, any existing headers will be removed. See token streaming with the [message per response](/docs/ai-transport/token-streaming/message-per-response) pattern for more details.
</Aside>

## Handle multiple concurrent prompts <a id="concurrent"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ for await (const event of stream) {
</Code>

<Aside data-type="note">
To learn how to stream individual tokens as they are generated, see the [token streaming](/docs/ai-transport/features/token-streaming) documentation.
To learn how to stream individual tokens as they are generated, see the [token streaming](/docs/ai-transport/token-streaming) documentation.
</Aside>

#### Subscribing
Expand Down Expand Up @@ -131,7 +131,7 @@ await channel.subscribe((message) => {
</Code>

<Aside data-type="further-reading">
To learn about hydrating responses from channel history, including using `rewind` or `untilAttach`, handling in-progress responses, and correlating with database records, see client hydration in the [message-per-response](/docs/ai-transport/features/token-streaming/message-per-response#hydration) and [message-per-token](/docs/ai-transport/features/token-streaming/message-per-token#hydration) documentation.
To learn about hydrating responses from channel history, including using `rewind` or `untilAttach`, handling in-progress responses, and correlating with database records, see client hydration in the [message-per-response](/docs/ai-transport/token-streaming/message-per-response#hydration) and [message-per-token](/docs/ai-transport/token-streaming/message-per-token#hydration) documentation.
</Aside>

### Threading pattern <a id="threading"/>
Expand Down Expand Up @@ -201,7 +201,7 @@ for await (const event of stream) {
</Code>

<Aside data-type="note">
To learn how to stream individual tokens as they are generated, see the [token streaming](/docs/ai-transport/features/token-streaming) documentation.
To learn how to stream individual tokens as they are generated, see the [token streaming](/docs/ai-transport/token-streaming) documentation.
</Aside>

#### Subscribing
Expand Down Expand Up @@ -254,5 +254,5 @@ async function onClickViewReasoning(responseId) {
</Code>

<Aside data-type="further-reading">
For more advanced hydration strategies, including using channel history with `untilAttach`, handling in-progress responses, and correlating with database records, see client hydration in the [message-per-response](/docs/ai-transport/features/token-streaming/message-per-response#hydration) and [message-per-token](/docs/ai-transport/features/token-streaming/message-per-token#hydration) documentation.
For more advanced hydration strategies, including using channel history with `untilAttach`, handling in-progress responses, and correlating with database records, see client hydration in the [message-per-response](/docs/ai-transport/token-streaming/message-per-response#hydration) and [message-per-token](/docs/ai-transport/token-streaming/message-per-token#hydration) documentation.
</Aside>
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ await channel.annotations.publish(msgSerial, {
</Code>

<Aside data-type="note">
When streaming response tokens using the [message-per-response](/docs/ai-transport/message-per-response) pattern, citations can be published while the response is still being streamed since the `serial` of the response message is known after the [initial message is published](/docs/ai-transport/features/token-streaming/message-per-response#publishing).
When streaming response tokens using the [message-per-response](/docs/ai-transport/message-per-response) pattern, citations can be published while the response is still being streamed since the `serial` of the response message is known after the [initial message is published](/docs/ai-transport/token-streaming/message-per-response#publishing).
</Aside>

<Aside data-type="note">
Identify the agent with a [`clientId`](/docs/messages#properties) in order to attribute a citation to a specific agent. This is useful in multi-agent architectures where multiple agents may contribute citations to the same response. For more information, see [Agent identity](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#agent-identity).
Identify the agent with a [`clientId`](/docs/messages#properties) in order to attribute a citation to a specific agent. This is useful in multi-agent architectures where multiple agents may contribute citations to the same response. For more information, see [Agent identity](/docs/ai-transport/sessions-identity/identifying-users-and-agents#agent-identity).
</Aside>

## Subscribing to summaries <a id="annotation-summary"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async function requestHumanApproval(toolCall) {

Authorized humans subscribe to approval requests on the conversation channel and publish their decisions. The `requestId` correlates the response with the original request.

Use [identified clients](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-identity) or [user claims](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-claims) to establish a verified identity or role for the approver. For example, when a user [authenticates with Ably](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#authenticating), embed their identity and role in the JWT:
Use [identified clients](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-identity) or [user claims](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-claims) to establish a verified identity or role for the approver. For example, when a user [authenticates with Ably](/docs/ai-transport/sessions-identity/identifying-users-and-agents#authenticating), embed their identity and role in the JWT:

<Code>
```javascript
Expand All @@ -70,7 +70,7 @@ const claims = {
The `clientId` and user claims are automatically attached to every message the user publishes and cannot be forged, so agents can trust this identity and role information.

<Aside data-type="further-reading">
For more information about establishing verified identities and roles, see [Identifying users and agents](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents).
For more information about establishing verified identities and roles, see [Identifying users and agents](/docs/ai-transport/sessions-identity/identifying-users-and-agents).
</Aside>

<Code>
Expand Down Expand Up @@ -112,7 +112,7 @@ For audit trails, use [integration rules](/docs/integrations) to stream approval
Use the `clientId` to identify the approver and look up their permissions in your database or user management system. This approach is useful when permissions are managed externally or change frequently.

<Aside data-type="note">
This approach requires the user to authenticate as an [identified client](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-identity) with a verified `clientId`.
This approach requires the user to authenticate as an [identified client](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-identity) with a verified `clientId`.
</Aside>

<Code>
Expand Down Expand Up @@ -153,7 +153,7 @@ await channel.subscribe('approval-response', async (message) => {
Use [user claims](/docs/auth/capabilities#custom-restrictions-on-channels-) to embed roles directly in the JWT for role-based access control (RBAC). This approach is useful when permissions are role-based rather than user-specific, allowing you to make authorization decisions based on the user's role without looking up individual user permissions.

<Aside data-type="note">
This approach uses [authenticated claims for users](/docs/ai-transport/features/sessions-identity/identifying-users-and-agents#user-claims) to embed custom claims in JWTs that represent user roles or attributes.
This approach uses [authenticated claims for users](/docs/ai-transport/sessions-identity/identifying-users-and-agents#user-claims) to embed custom claims in JWTs that represent user roles or attributes.
</Aside>

Different actions may require different authorization levels - for example, a user might approve low-value purchases, a manager might approve purchases up to a certain limit, while an admin can approve any purchase amount. When an approval arrives, compare the approver's role against the minimum required role for that action type:
Expand Down
Loading