`mcs_send_message` — Chat Message Dispatch Code Point


Overview

The mcs_send_message code point is a unified message dispatcher for the MelodyArc Chat Service (MCS).
It can be used from invoke points or directly from code to send a message to a conversation, start a new conversation if none exists, attach metadata or event details, and optionally close the current task or conversation.

This code point ensures all outbound messages are logged, properly associated with the correct conversation, and handled in a consistent, reusable way across all operator flows.


1️⃣ Purpose

mcs_send_message centralizes the logic for sending chat messages from skills, operators, or automated workflows.
It handles both simple “send a message” cases and more complex workflows such as:

  • Starting a new MCS conversation if one doesn’t exist.
  • Sending a message into an existing conversation.
  • Adding contextual metadata or event payloads.
  • Closing the current task and updating operator_state with closure details.

2️⃣ Execution Flow

  1. Loads dependencies: chat_service and get_aea_helpers.
  2. Determines the conversation ID, either from _token.task.event.conversation_id or by starting a new one.
  3. Determines the sender ID, using _token.user_id, _user, or "unknown_user".
  4. Resolves the message content from one of the following (in order):
    • _this[message_path]
    • _token[message_path]
    • _token.message
    • Default fallback "Hello, this is the first message."
  5. Builds a structured message payload containing:
    • sender_id
    • content
    • source
    • Optional send_ingress, metadata, and events
  6. Sends the message through _mcs.appendMessage() if a conversation exists, otherwise _mcs.startConversation().
  7. Logs the result via logger.log("chat_message_sent", {...}, "info").
  8. Returns a structured response object (see below).

3️⃣ Attributes (Invoke Configuration)

When used in an invoke point, configuration values are defined in the attributes section of the invoke.
Each key becomes available to the code point as _token.<attribute_name> at runtime.

When called directly from another code point, you can pass the same values as parameters to mcs_send_message() — either individually or inside an options object.
For example:

await mcs_send_message({
  conversation_id: _token.mcs.conversation_id,
  message: _this.response_text,
  metadata: { type: "user_update" },
  close_conversation: true,
  close_reason: "User conversation ended."
});


| Attribute | Type | Description |
|------------|------|-------------|
| `message` | `string` | The message body to send (used if `message_path` is not provided). |
| `message_path` | `string` | A key path (e.g., `_this.summary`) that points to the message value in `_this` or `_token`. |
| `metadata` | `object` | Optional metadata to attach to the message. |
| `events` | `object` | Optional event data (e.g., `{ stop: true }`) to include with the message. |
| `send_ingress` | `boolean` | Whether to send ingress events to MCS. |
| `close_conversation` | `boolean` | If `true`, closes the current task after sending the message. |
| `close_reason` | `string` | Optional text describing why the conversation or task was closed. |
| `source` | `string` | Value used to determine who the message is from either 'user' or 'operator'. |
| `user_id` | `string` | Used in conjunction with source.  Add the operators 'slug' here to denote which operator the message is from.|

These attributes give full control over how and when messages are sent, without modifying code.

---

## 4️⃣  Return Object

The code point returns a structured object describing the outcome of the send operation:

```json
{
  "status": "success",
  "message_response": { "conversation_id": "conv_123", "message_id": "msg_456" },
  "conversation_id": "conv_123",
  "operator_state.last_closed_reason": "Task closed by message sent: converse_entity_control",
  "flags": { "close": true }
}

If an error occurs, the returned object will contain:

{ "status": "failed", "error": "Network error: <details>" }

5️⃣ Example — Using via Invoke

This example shows an invoke point that uses mcs_send_message to send a response message and close the conversation after sending.

{
  "organization_id": "org_REPLACE",
  "name": "send_user_update",
  "partition": "op_chat",
  "description": "Sends a message to the user and closes the conversation",
  "tags": ["skill", "operator:chat", "folder:chat"],
  "attributes": {
    "conversation_id": "[[_token.mcs.conversation_id]]",
    "message_path": "_this.response_text",
    "metadata": { "type": "user_update" },
    "close_conversation": true,
    "close_reason": "User conversation ended."
  },
  "code": "mcs_send_message",
  "version": "latest"
}

🧩 How it works:

  • _this.response_text is resolved and sent to MCS as the chat message.
  • The conversation is closed after sending.
  • operator_state.last_closed_reason is updated to “User conversation ended.”
  • A log entry chat_message_sent is created for observability.

6️⃣ Example — Using via Code

You can also call mcs_send_message directly inside another code point.

const conversationId = _token?.mcs?.conversation_id;

const msg_user = {
  conversation_id: conversationId,
  message: `This is the desire statement we generated:\n\n ${_this.summarized_desire}`,
};

await mcs_send_message(msg_user);

🧩 What happens:

  • If conversation_id is valid, _mcs.appendMessage() sends the text to that conversation.
  • If not, a new MCS conversation is created automatically.
  • The send result is logged and returned, allowing you to chain it into other logic.

7️⃣ Best Practices

✅ Define attributes declaratively in the invoke to keep code points reusable.
✅ Use message_path for dynamic messages stored in _this.
✅ Always include a conversation_id when sending follow-ups to an active user session.
✅ When closing a task, include close_reason for audit clarity.
✅ Use metadata to track message purpose or category (e.g., "type": "user_prompt").
✅ Leverage events to communicate stop conditions or transitions to other services.


🧠 Summary

mcs_send_message is the standard interface for sending messages to users through MCS when using the entity controller is not possible.
It can be triggered via an invoke or used directly in code, automatically managing conversation context, task closure, and logging.
This keeps message handling consistent, traceable, and fully integrated into MelodyArc’s operator and task lifecycle. *


Maintained by: MelodyArc Platform Engineering
Applies to: All chat-related skills and system messaging tasks
Reference Implementation: mcs_send_message.js
Version: 1.0