Aller au contenu principal
Version: 3.6.0

Assistant

Overview​

The Assistant message powers end-customer-facing automated conversations. Where Interaction and Reception analyse a conversation to support a human operator, the Assistant message decides whether the AI should answer the customer directly, and produces that answer.

Every Assistant request runs through four stages:

  1. Input Security & Moderation — screens the incoming customer message for moderation issues, sensitive topics, prompt-manipulation attempts and protection violations.
  2. Triage — determines the answer language, extracts the customer's requests, evaluates automation risk, detects an explicit request to talk to a human, and checks whether an escalation is needed.
  3. Path Definition — consolidates every signal above into two decisions, human_handoff and end_conversation, and emits them before the reply is generated.
  4. Response — generates the automated_reply following the path that was defined.
Path decisions arrive before the reply

human_handoff and end_conversation are pushed over the WebSocket as soon as stage 3 completes, ahead of automated_reply. This lets your interface start routing to a human while the reply is still being generated.

API Reference​

Endpoint​

  • WebSocket URL: wss://ws-{{tenant}}.oco.optave.{{tld}}
  • REST Endpoint (POST): https://{{tenant}}.oco.optave.{{tld}}/message/assistant

To be able to send messages, it is necessary to authenticate first.

Request Payload​

The assistant message requires a payload containing the conversation history (conversations), connections.threadId, and context.organizationId (your client-specific organization ID). The other fields are optional.

Send a product identifier when you have one

scope.products[].id is optional. When present, retrieval adds a keyword search on that product alongside the usual vector search, which usually produces a more specific answer. Omitting it does not block the AI from answering.

{
session: {
sessionId: "a1b2c3d4-e5f6-7890-abcd-123456789012",
channel: { language: "en-US" },
interface: { type: "chat" }
},
request: {
requestId: "a1b2c3d4-e5f6-7890-1234-56789ab2345",
attributes: {
variant: "A"
},
connections: {
journeyId: "",
parentId: "",
threadId: "9e8d7c6b-5a49-3827-1605-948372615abc" // REQUIRED
},
context: { // generated by optave
caseId: "",
departmentId: "",
operatorId: "",
organizationId: "f7e8d9c0-b1a2-3456-7890-123456789abc", // REQUIRED
userId: ""
},
reference: {
ids: [
{ name: "ticket_id", value: "T12345" }
],
labels: [],
tags: []
},
resources: {
codes: [],
links: [],
offers: []
},
scope: {
products: [ // Optional - adds a keyword search on this product
{ id: "PRD-4821" }
],
conversations: [ // REQUIRED
{
conversationId: "",
participants: [
{
participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def",
displayName: "John Doe",
role: "user"
},
{
participantId: "5b8c9d0e-2f4a-6b1c-9d8e-123456789abc",
displayName: "Optave Assistant",
role: "assistant"
}
],
messages: [
{
content: "Is the 3-day tour still available for next weekend?",
participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def",
timestamp: "2024-01-15T10:30:00.000Z"
}
],
metadata: {}
}
],
interactions: [
{
content: "Support ticket T12345 has been created for user John Doe",
id: "1",
name: "ticket_created",
role: "system",
timestamp: "2024-01-15T10:29:45.000Z"
}
]
}
}
}

Responses​

🟢 Success (200-201)

Over the WebSocket you receive each superpower as its own message, with a started state followed by a completed state. The Assistant workflow emits, by stage:

Input security & moderation: moderation, moderation_inappropriate, sensitive_topic, identify_language_games, identify_flipping, validate_protections, identify_poem

Triage: answer_language, extract_requests, identify_progress, talk_to_human, automation_risk, verify_activation, check_escalation_need

Path definition: human_handoff, end_conversation

Response: automated_reply

Non-blocking metadata: analyze_sentiment

🔴 Error

Error messages are similar in format to success messages, but contain an error state and a "response" JSON object:

{
action: "superpower",
actionType: "<superpower-name>",
state: "error",
message: {
results: [
{
response: [
{
content: 'Error while fetching results'
}
]
}
]
}
}

Path Decisions​

human_handoff​

"1" means the conversation must be routed to a human; "0" means the AI may continue. The reasons array tells you why, and flags.reversible tells you whether the decision may change on a later message in the same thread.

{
action: "superpower",
actionType: "human_handoff",
state: "completed",
message: {
results: [
{
superpowerName: ["human_handoff"],
response: [
{
role: "assistant",
content: "1",
reasons: ["business_logic"]
}
],
flags: { reversible: true }
}
]
}
}
ReasonMeaning
risk_detectionA security, moderation or risk check was triggered — an inappropriate message, a sensitive topic, a prompt-manipulation attempt, or a high automation risk.
business_logicA business rule requires a human — the customer asked to talk to a human, the request is outside the supported scope, the conversation is not progressing, or a recommendation has already been completed.
escalation_neededThe triage stage explicitly flagged the conversation for escalation.

These are the only three values reasons can contain.

The answer language does not trigger handoff

A conversation is not escalated solely because it is non-English. The answer_language superpower still runs and still decides the language the reply is written in, but it is not a handoff condition. A non-English conversation can still hand off for any of the reasons above — asking to talk to a human, for instance.

Reversible vs. non-reversible

flags.reversible is true only when the single reason is business_logic and the underlying rule is itself temporary (for example, the conversation is not yet making progress). Non-reversible decisions are cached against the threadId, so the thread stays with a human for the rest of its life. Any additional reason — or an explicit escalation — makes the decision non-reversible.

end_conversation​

"1" means the AI's scope has ended (a recommendation was completed) and the conversation can be wrapped up. It is always non-reversible. When it is "1", the message carries a UI action you can render, and the matching human_handoff message carries a "Talk with a human" action.

{
action: "superpower",
actionType: "end_conversation",
state: "completed",
message: {
results: [
{
superpowerName: ["end_conversation"],
response: [
{
role: "assistant",
content: "1"
}
],
flags: { reversible: false },
actions: {
ui: [{ type: "button", label: "End conversation" }]
}
}
]
}
}

automated_reply​

The customer-facing answer. Always check flags.skipReply before rendering it.

{
action: "superpower",
actionType: "automated_reply",
state: "completed",
message: {
results: [
{
superpowerName: ["automated_reply"],
response: [
{
role: "assistant",
content: "One moment while I find a team member to assist you."
}
],
flags: { skipReply: false }
}
]
}
}
Respect skipReply

When flags.skipReply is true, the content is an internal tracking message and must not be shown or forwarded to the customer. This happens on a handoff during the first interaction, before any agent has replied in the thread.

curl \
--request POST \
--url https://{{tenant}}.oco.optave.{{tld}}/message/assistant \
--header "Authorization: Bearer your-access-token-here" \
--header "Content-Type: application/json" \
-d '{
"session": {
"sessionId": "a1b2c3d4-e5f6-7890-abcd-123456789012",
"channel": { "language": "en-US" },
"interface": { "type": "chat" }
},
"request": {
"requestId": "a1b2c3d4-e5f6-7890-1234-56789ab2345",
"attributes": {
"variant": "A"
},
"connections": {
"threadId": "9e8d7c6b-5a49-3827-1605-948372615abc"
},
"context": {
"organizationId": "f7e8d9c0-b1a2-3456-7890-123456789abc"
},
"scope": {
"products": [
{ "id": "PRD-4821" }
],
"conversations": [
{
"conversationId": "7f6e5d4c-3b2a-1098-fedc-ba9876543210",
"participants": [
{
"participantId": "2c4f8a9b-1d3e-5f70-8293-456789012def",
"displayName": "John Doe",
"role": "user"
}
],
"messages": [
{
"content": "Is the 3-day tour still available for next weekend?",
"participantId": "2c4f8a9b-1d3e-5f70-8293-456789012def",
"timestamp": "2024-01-15T10:30:00.000Z"
}
],
"metadata": {}
}
]
}
}
}'
{
action: "superpower",
actionType: "human_handoff",
state: "completed",
message: {
results: [
{
superpowerName: ["human_handoff"],
response: [
{
role: "assistant",
content: "1",
reasons: ["business_logic"]
}
],
flags: { reversible: true }
}
]
}
}