# UserProxyAgent State

The `UserProxyAgentState` is used to define an agent whose role is a bridge between the workflow and the user. This state outlines the configuration of the agent, including the communication context, user messages, roles, data schemas, known data, and outcomes. This specification provides a comprehensive overview of the `UserProxyAgentState` and its related objects.

### UserProxyAgentState

The `UserProxyAgentState` is a specialized state in a serverless workflow designed to facilitate communication between the workflow and a user through an AI agent. This state specifies the agent's role, communication channels, messages, data schemas, and possible outcomes.

<table data-header-hidden><thead><tr><th width="196"></th><th width="324"></th><th width="169"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Description</strong></td><td><strong>Type</strong></td><td><strong>Required</strong></td></tr><tr><td>agentName</td><td>The name of the agent.</td><td>string</td><td>yes</td></tr><tr><td>agentRole</td><td>The role of the agent in the conversation. Can be 'relay' or 'facilitator'. Default is 'relay'.</td><td>string</td><td>no</td></tr><tr><td>userMessage</td><td>The user message.</td><td>string</td><td>no</td></tr><tr><td><a href="#usermessagedef">relayMessage</a></td><td>Used for the 'relay' role, message to relay to the user. See <a href="#usermessagedef">UserMessageDef</a>.</td><td>object</td><td>no</td></tr><tr><td><a href="#dataschema">collectDataSchema</a></td><td>Used for the 'facilitator' role, JSON schema for data to ask the user for. See <a href="#dataschema">DataSchema</a>.</td><td>object</td><td>no</td></tr><tr><td>knownData</td><td>The data that the agent already knows about the user and the conversation in JSON format.</td><td>string</td><td>no</td></tr><tr><td><a href="#onagentoutcome">agentOutcomes</a></td><td>Define list of agent outcomes. Each outcome is described by the <a href="#onagentoutcome">OnAgentOutcome</a> schema.</td><td>array</td><td>yes</td></tr><tr><td><a href="https://docs.a4b.vn/xflow/3.-core-concepts/workflow-data-handling#state-data-filters">dataFilter</a></td><td>Filter to apply to the state data.</td><td>string</td><td>no</td></tr></tbody></table>

#### DataSchema

The `DataSchema` object describes the schema for date-related outputs.

| **Field** | **Type** | **Description**                                               | **Required** |
| --------- | -------- | ------------------------------------------------------------- | ------------ |
| schema    | string   | URI of the JSON Schema used to describe the agent data output | yes          |

#### UserMessageDef

The `UserMessageDef` object describes the structure of the user messages sent to the AI agent.

| **Field**              | **Type** | **Description**                                                                                  | **Required** |
| ---------------------- | -------- | ------------------------------------------------------------------------------------------------ | ------------ |
| text                   | string   | The text of the user message                                                                     | yes          |
| [media](#mediacontent) | array    | The media file URLs of the user message, each described by [MediaContent](#mediacontent) schema. | no           |
| mediaExp               | string   | The jq expression for list of media file URLs of the user message                                | no           |

#### MediaContent

The `MediaContent` object defines the structure for media files associated with user messages.

| **Field**   | **Type** | **Description**                           | **Required**                                  |
| ----------- | -------- | ----------------------------------------- | --------------------------------------------- |
| uuid        | string   | The unique identifier of media content.   | yes                                           |
| url         | string   | The URL of the media file                 | One of `url` or `base64Data` must be provided |
| base64Data  | string   | The base64 encoded data of the media file | One of `url` or `base64Data` must be provided |
| mimeType    | string   | The mime type of the media file           | no                                            |
| description | string   | The description of media content.         | no                                            |

#### OnAgentOutcome

The `OnAgentOutcome` object defines the actions to be performed based on the outcome of the AI agent. The actions are executed if the outcome matches the specified conditions.

| **Field**                                                                                                 | **Type** | **Description**                                                                                                                                    | **Required** |
| --------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| condition                                                                                                 | string   | Expression, if defined, must evaluate to true for this outcome to be matched. If false, the outcome is disregarded.                                | yes          |
| finish                                                                                                    | boolean  | If true, the agent will finish after this action is executed. If false, the agent will continue to process.                                        | yes          |
| [dataFilter](https://docs.a4b.vn/xflow/3.-core-concepts/workflow-data-handling#event-data-filters)        | object   | Event data filter described by the [EventDataFilter](https://docs.a4b.vn/xflow/3.-core-concepts/workflow-data-handling#event-data-filters) schema. | no           |
| [transition](https://github.com/serverlessworkflow/specification/blob/0.9.x/specification.md#transitions) | object   | The outgoing transition when the outcome is selected, if not defined the default transition will be used.                                          | no           |

### Example:

#### Relay role example:

<table><thead><tr><th>YAML</th><th data-hidden>JSON</th></tr></thead><tbody><tr><td><pre class="language-yaml" data-line-numbers><code class="lang-yaml">states:
  - name: InformRagResult
    agentName: InformRagResult
    type: userproxyagent
    agentRole: relay
    conversationId: ${ .request.userChannelContext.conversationId }
    userMessage: '${ .request.question }'
    userChannelContext: ${ .request.userChannelContext }
    userContext: ${ .request.userContext }
    relayMessage:
      text: ${ ._ai_agent_state.RagAgent.agentOutcome.finish.output.returnValues.answer }
      mediaExp: ${ ._ai_agent_state.RagAgent.agentOutcome.finish.output.returnValues.images }
    output: |-
      {
          "type": "object",
          "properties": {
              "answer": {
                  "type": "string"
              }
          },
          "required": ["answer"]
      }
    agentOutcomes:
    - condition: '${ true }'
      finish: true
      transition: Finish
</code></pre></td><td><pre class="language-json" data-line-numbers><code class="lang-json">{
    "states": [
        {
            "name": "InformRagResult",
            "agentName": "InformRagResult",
            "type": "userproxyagent",
            "agentRole": "relay",
            "conversationId": "${ .request.userChannelContext.conversationId }",
            "userMessage": "${ .request.question }",
            "userChannelContext": "${ .request.userChannelContext }",
            "userContext": "${ .request.userContext }",
            "relayMessage": {
                "text": "${ ._ai_agent_state.RagAgent.agentOutcome.finish.output.returnValues.answer }",
                "mediaExp": "${ ._ai_agent_state.RagAgent.agentOutcome.finish.output.returnValues.images }"
            },
            "output": "{\n    \"type\": \"object\",\n    \"properties\": {\n        \"answer\": {\n            \"type\": \"string\"\n        }\n    },\n    \"required\": [\"answer\"]\n}",
            "agentOutcomes": [
                {
                    "condition": "${ true }",
                    "finish": true,
                    "transition": "Finish"
                }
            ]
        }
    ]
}
</code></pre></td></tr></tbody></table>

#### Facilitator role example:

<table><thead><tr><th>YAML</th><th data-hidden>JSON</th></tr></thead><tbody><tr><td><pre class="language-yaml" data-line-numbers><code class="lang-yaml">states:
  - name: BuyProductTransactionUserProxy
    agentName: BuyProductTransactionUserProxy
    type: userproxyagent
    agentRole: facilitator
    userMessage: '${ .request.question }'
    conversationId: ${ .request.userChannelContext.conversationId }
    userChannelContext: ${ .request.userChannelContext }
    userContext: ${ .request.userContext }
    collectDataSchema: |-
      {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Unique sku code of the product, this field can be identified by trying to identify by product name in user request and check if it match with the name of the product from the list of available products. If cannot identity, ask user to select the product from the list of available products"
          },
          "fullName": {
            "type": "string",
            "description": "Customer full name"
          },
          "phoneNumber": {
            "type": "string",
            "description": "Customer phone number"
          },
          "address": {
            "type": "string",
            "description": "Customer address to deliver the product"
          }
        },
        "required": ["sku", "fullName", "phoneNumber", "address"]
      }
    knownData: |-
      ${
        { 
          "fullName": .request.customer.fullName,
          "phoneNumber": .request.customer.phoneNumber,
          "userRequest": .request.question,
          "availableProducts": .request.products
        }
      }
    output: |-
      {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Unique sku code of the product"
          },
          "fullName": {
            "type": "string",
            "description": "Customer full name"
          },
          "phoneNumber": {
            "type": "string",
            "description": "Customer phone number"
          },
          "address": {
            "type": "string",
            "description": "Customer address to deliver the product"
          }
        },
        "required": ["sku", "fullName", "phoneNumber", "address"]
      }
    agentOutcomes:
      - condition: '${ true }'
        finish: true
        transition: CollectOrderInfo
    transition: Finish
</code></pre></td><td><pre class="language-json" data-line-numbers><code class="lang-json">{
    "states": [
        {
            "name": "BuyProductTransactionUserProxy",
            "agentName": "BuyProductTransactionUserProxy",
            "type": "userproxyagent",
            "agentRole": "facilitator",
            "userMessage": "${ .request.question }",
            "conversationId": "${ .request.userChannelContext.conversationId }",
            "userChannelContext": "${ .request.userChannelContext }",
            "userContext": "${ .request.userContext }",
            "collectDataSchema": "{\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"sku\": {\n      \"type\": \"string\",\n      \"description\": \"Unique sku code of the product, this field can be identified by trying to identify by product name in user request and check if it match with the name of the product from the list of available products. If cannot identity, ask user to select the product from the list of available products\"\n    },\n    \"fullName\": {\n      \"type\": \"string\",\n      \"description\": \"Customer full name\"\n    },\n    \"phoneNumber\": {\n      \"type\": \"string\",\n      \"description\": \"Customer phone number\"\n    },\n    \"address\": {\n      \"type\": \"string\",\n      \"description\": \"Customer address to deliver the product\"\n    }\n  },\n  \"required\": [\"sku\", \"fullName\", \"phoneNumber\", \"address\"]\n}",
            "knownData": "${\n  { \n    \"fullName\": .request.customer.fullName,\n    \"phoneNumber\": .request.customer.phoneNumber,\n    \"userRequest\": .request.question,\n    \"availableProducts\": .request.products\n  }\n}",
            "output": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"sku\": {\n      \"type\": \"string\",\n      \"description\": \"Unique sku code of the product\"\n    },\n    \"fullName\": {\n      \"type\": \"string\",\n      \"description\": \"Customer full name\"\n    },\n    \"phoneNumber\": {\n      \"type\": \"string\",\n      \"description\": \"Customer phone number\"\n    },\n    \"address\": {\n      \"type\": \"string\",\n      \"description\": \"Customer address to deliver the product\"\n    }\n  },\n  \"required\": [\"sku\", \"fullName\", \"phoneNumber\", \"address\"]\n}",
            "agentOutcomes": [
                {
                    "condition": "${ true }",
                    "finish": true,
                    "transition": "CollectOrderInfo"
                }
            ],
            "transition": "Finish"
        }
    ]
}
</code></pre></td></tr></tbody></table>

***

This document provides a detailed view of the `UserProxyAgentState` state and its related objects, including comprehensive schema definitions, required fields, and descriptions for each attribute within the `UserProxyAgentState` and associated schemas. This specification ensures clarity and completeness for integrating AI agents within serverless workflows.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.a4b.vn/xflow/developer-guide/workflow-states-reference/userproxyagent-state.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
