Reference

Event Protocol

Complete specification for the application-level event contract between HUMA clients and the HUMA server.

Protocol Version 0.2.0

Overview

HUMA uses a bidirectional event protocol over WebSocket. Clients send events to inform the agent about state changes and tool results. The server sends events when the agent wants to take action or communicate.

Client
Your Application
context-update, tool-result, addon-tool-event
tool-call, cancel-tool-call, messaging, error
Server
HUMA Agent

Client Events (3 types)

  • context-update — push new state
  • tool-result — return tool output
  • addon-tool-event — in-flight addon data

Server Events (4 types)

  • tool-call — request tool execution
  • cancel-tool-call — abort pending tool
  • messaging — typing & message delivery
  • error — validation or server error

Transport

All communication uses Socket.IO over WebSocket.

Sending to Server

socket.emit('message', )

Receiving from Server

socket.on('event', handler)  // tool-call, messaging
socket.on('error', handler)  // error events

Client Events

Every client event is a JSON object sent via socket.emit('message', event). There are exactly three event types.

Validation: The event must be a JSON object with a type field set to one of: context-update, tool-result, addon-tool-event. Any Record field is recursively checked for dangerous keys (__proto__, constructor, prototype).

context-update

Pushes new context to the HUMA agent. This is the primary way to inform the agent about what is happening in the client application.

context-update
socket.emit('message', {
  type: 'context-update',
  triggering: true,
  name: 'new-message',
  context: {
    group: { id: 'group-123', name: 'Movie Night' },
    members: [
      { name: 'Alice', id: 'user-1' },
      { name: 'Bob', id: 'user-2' }
    ],
    conversationHistory: '[14:30] Alice: What movie should we watch?'
  },
  description: 'Alice sent a message: "What movie should we watch?"'
})
FieldTypeRequiredDescription
typestringYesAlways "context-update"
triggeringbooleanYesWhether this event should trigger the agent to respond
namestringYesEvent name identifying what happened (1–128 chars)
contextobjectYesArbitrary key-value data representing current state
descriptionstringYesHuman-readable description of what triggered this event

The triggering Field

triggering: true

The agent SHOULD respond. Use for new input that warrants a reaction (e.g., user sent a message). Also activates emotion and reflection processes.

triggering: false

Informational only. Context is received but no response generated. Use for background state sync, initial hydration, or events where the agent hasn't spoken yet.

Examples

User message (agent should respond):

{
  type: 'context-update',
  triggering: true,
  name: 'new-message',
  context: {
    group: { id: 'group-123', name: 'Movie Night' },
    conversationHistory: '[14:30] Alice: What movie?\n[14:31] Bob: Something fun'
  },
  description: 'Bob sent a message: "Something fun"'
}

Initial context hydration (no response needed):

{
  type: 'context-update',
  triggering: false,
  name: 'new-message',
  context: {
    group: { id: 'group-123', name: 'Movie Night' },
    conversationHistory: '[14:30] Alice: What movie should we watch?'
  },
  description: 'You joined the group'
}

tool-result

Returns the result of a tool call that the agent previously requested via a tool-call server event.

tool-result
socket.emit('message', {
  type: 'tool-result',
  triggering: true,
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  outcome: 'success',
  result: { title: 'Inception', year: 2010, rating: 8.8 }
})
FieldTypeRequiredDescription
typestringYesAlways "tool-result"
triggeringbooleanYesWhether to trigger further agent action
toolCallIdstringYesThe toolCallId from the original tool-call event
toolNamestringYesThe tool name from the original tool-call event
outcomestringYes"success", "failure", or "canceled"
resultanyNoReturn value on success. Must be JSON-serializable, max 65,536 chars.
errorstringNoError message on failure

The outcome Field

OutcomeMeaning
successTool executed successfully. result may contain the return value.
failureTool failed. error should contain the error message.
canceledTool was canceled in response to a cancel-tool-call from the server.

The triggering Field in Tool Results

triggering: true

The agent should process this result and potentially continue its action. This is the typical value for successful tool calls.

triggering: false

Result is recorded but doesn't trigger further action. Use for canceled results or side-effect-only tools (e.g., update_preferences).

Examples

Success:

{
  type: 'tool-result',
  triggering: true,
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  outcome: 'success',
  result: '{"title":"Inception","year":2010,"rating":8.8}'
}

Failure:

{
  type: 'tool-result',
  triggering: true,
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  outcome: 'failure',
  error: 'Movie not found: Nonexistent Movie'
}

Canceled (response to cancel-tool-call):

{
  type: 'tool-result',
  triggering: false,
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  outcome: 'canceled'
}

Non-triggering (side-effect only):

{
  type: 'tool-result',
  triggering: false,
  toolCallId: '660e8400-e29b-41d4-a716-446655440001',
  toolName: 'update_preferences',
  outcome: 'success',
  result: 'Preferences updated for Alice'
}

addon-tool-event

Sends data back to a server-side addon tool during its execution. This is not a final result — it is an in-flight data exchange. The most common use case is confirming message delivery from the messaging addon.

addon-tool-event
socket.emit('message', {
  type: 'addon-tool-event',
  toolCallId: '770e8400-e29b-41d4-a716-446655440002',
  data: {
    messageIndex: 0,
    success: true,
    context: {
      conversationHistory: '[14:30] Alice: What movie?\n[14:31] Agent: How about Inception?'
    }
  }
})
FieldTypeRequiredDescription
typestringYesAlways "addon-tool-event"
toolCallIdstringYesThe toolCallId from the addon's originating event
dataobjectYesPayload for the addon (structure depends on the addon)

Messaging Addon Confirmation

When confirming message delivery from the messaging addon, the data field contains:

data FieldTypeDescription
messageIndexnumberZero-based index echoed from message_sent
successbooleanWhether the message was delivered successfully
contextobject?Updated conversation context (on success), to keep agent state synchronized
errorstring?Error message (on failure)

Success confirmation:

{
  type: 'addon-tool-event',
  toolCallId: '',
  data: {
    messageIndex: 0,
    success: true,
    context: {
      conversationHistory: '...'
    }
  }
}

Failure confirmation:

{
  type: 'addon-tool-event',
  toolCallId: '',
  data: {
    messageIndex: 0,
    success: false,
    error: 'Failed to send: rate limited'
  }
}
Timeout: The server waits up to 30 seconds for each confirmation. If no confirmation arrives, it assumes success and proceeds.

Server Events

All server events arrive on the "event" Socket.IO channel: socket.on('event', handler). Each event is a JSON object with a type field.

tool-call

The agent is requesting the client to execute a tool.

tool-call
{
  type: 'tool-call',
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  arguments: {
    title: 'Inception',
    year: 2010
  }
}
FieldTypeDescription
typestringAlways "tool-call"
toolCallIdstringUnique identifier (UUID). Use this in the tool-result response.
toolNamestringName of the tool to execute. Must match a registered tool.
argumentsobjectArguments for the tool, as determined by the agent.

Client Responsibility

1. Look up the tool by toolName.

2. Execute the tool with the provided arguments.

3. Send back a tool-result event with the matching toolCallId and toolName.

If the tool is unknown, send a failed result:

{
  type: 'tool-result',
  triggering: true,
  toolCallId: '',
  toolName: '',
  outcome: 'failure',
  error: 'Unknown tool: '
}

cancel-tool-call

The agent is requesting cancellation of a previously issued tool call. This happens when the agent is interrupted (e.g., a new triggering event arrives while a tool is still executing).

cancel-tool-call
{
  type: 'cancel-tool-call',
  toolCallId: '550e8400-e29b-41d4-a716-446655440000',
  toolName: 'lookup_movie',
  reason: 'canceled by agent'
}
FieldTypeDescription
typestringAlways "cancel-tool-call"
toolCallIdstringThe toolCallId of the tool call to cancel
toolNamestringName of the tool being canceled
reasonstring?Human-readable reason for cancellation

Client Responsibility

Abort the in-flight tool execution if possible, then send a canceled result:

{
  type: 'tool-result',
  triggering: false,
  toolCallId: '',
  toolName: '',
  outcome: 'canceled'
}

messaging

Events from the messaging addon. This addon handles the agent's message-sending lifecycle with realistic typing delays.

FieldTypeDescription
typestringAlways "messaging"
eventstring"typing_start", "message_sent", or "typing_end"
toolCallIdstring?Tool call ID for the send_message invocation
messagestring?Message text (present on message_sent)
messageIndexnumber?Zero-based index in the burst (present on message_sent)
messageCountnumber?Total messages in the burst (present on message_sent)
reasonstring?Reason for typing_end (e.g., "canceled")
extra_argsobject?Additional parameters passed through from the agent

Messaging Lifecycle

The full lifecycle for a burst of N messages:

Servertyping_startClient shows typing indicator
Servermessage_sentClient delivers message
Clientaddon-tool-eventServer receives confirmation
(repeat for remaining messages)

Client Responsibilities

typing_start

Show a typing/composing indicator on the platform.

message_sent

Deliver the message to the platform, then send an addon-tool-event confirmation back to the server.

socket.emit('message', {
  type: 'addon-tool-event',
  toolCallId: data.toolCallId,
  data: {
    messageIndex: data.messageIndex,
    success: true,
    context: { conversationHistory: '...' }
  }
})

typing_end

Hide the typing indicator. reason: "canceled" means the messaging burst was aborted.

error

Server-side error. Arrives on the "error" Socket.IO channel: socket.on('error', handler).

error
{
  type: 'error',
  message: 'context-update requires boolean "triggering"',
  code: 'INVALID_EVENT'
}
FieldTypeDescription
typestringAlways "error"
messagestringHuman-readable error description
codestring?Error code (e.g., "INVALID_EVENT")

Validation Limits

ConstraintValue
Maximum name length (context-update)128 characters
Maximum result size (tool-result)65,536 characters (JSON-serialized)
Allowed outcome values (tool-result)"success", "failure", "canceled"
Forbidden keys (recursive, in context and data fields)__proto__, constructor, prototype
Messaging addon confirmation timeout30 seconds