Skip to content

docs: add send_message tool page (agent-facing proactive gateway delivery) #811

Description

@MervinPraison

Source change

PraisonAI PR: MervinPraison/PraisonAI#2188 (merged — fixes #2183)

Adds a new agent-facing built-in tool: send_message. Lets a running agent proactively reach the user mid-task on the channel the conversation came from (or any other configured channel) through the existing gateway delivery stack — and list reachable targets.

Before this change, proactive delivery was only reachable from the scheduler or the gateway send CLI; an agent had no way to message the user during a task.

Doc action required

Type: NEW PAGE (no existing docs page covers this; existing send_message references in the docs are about bot adapter methods, not the new agent-facing tool).

File to create: docs/features/send-message-tool.mdx

Folder: docs/features/ (per AGENTS.md §1.8 — never docs/concepts/).

Pattern to mirror: docs/features/clarify-tool.mdx — same shape (agent-facing built-in that resolves a per-turn handler/messenger from context; fails cleanly when not available).

Add to docs.json: under the Features group, NEVER under Concepts. Do not modify auto-generated docs/js/ or docs/rust/ entries.


SDK ground truth (read before writing)

The implementation agent MUST read these files in MervinPraison/PraisonAI before writing the page (per AGENTS.md §1.2 SDK-first cycle):

What Path Why
Tool source praisonaiagents/tools/messaging_tools.py Function signature, args, return, behaviour
Tool registration praisonaiagents/tools/__init__.py Lazy import path
Protocol & dataclasses praisonaiagents/gateway/protocols.py (OutboundMessengerProtocol, DeliveryResult, TargetInfo) Wrapper-side contract
Context registry praisonaiagents/session/context.py (register_outbound_messenger, get_outbound_messenger, clear_outbound_messenger, register_gateway_loop, get_gateway_loop, clear_gateway_loop) How the gateway plugs the messenger in
Tests (examples of usage) tests/unit/tools/test_send_message_tool.py Real call patterns

The PR description is here: MervinPraison/PraisonAI#2188

Verify all values against source — don't copy any spec from this issue without confirming it.


Public API (from SDK)

Import

from praisonaiagents import Agent
from praisonaiagents.tools import send_message

Function signature

send_message(
    target: str = "origin",
    message: str = "",
    action: str = "send",
) -> str

Arguments

Arg Type Default Description
target str "origin" Symbolic destination. One of: "origin" (chat the conversation came from), "<platform>" (platform's home channel, e.g. "telegram"), "<platform>:<chat_id>[:<thread_id>]" (explicit chat), or a friendly alias for a known target.
message str "" Text to send. Append " MEDIA:<path>" one or more times to attach local files, e.g. "Report ready MEDIA:/tmp/report.pdf".
action str "send" "send" to deliver a message, or "list" to return a JSON array of reachable targets.

Returns

  • action="send": human-readable summary string (e.g. "Delivered to slack:#ops", or "Failed to send to ...: <detail>").
  • action="list": JSON string of [{target, platform, kind, label}, ...]kind is one of "origin", "home", "alias".

When it's available

  • Available when running inside a gateway/bot (Telegram, Slack, Discord, WhatsApp, etc.) — the gateway registers an OutboundMessengerProtocol impl into the per-turn context.

  • Unavailable for plain CLI / one-shot runs. The tool does not raise — it returns the literal string:

    "No active gateway: send_message is only available inside a running bot/gateway (e.g. Telegram, Slack, Discord). It is unavailable for CLI/one-shot runs."

This graceful-fallback behaviour must be documented (mirror how clarify-tool.mdx documents its fallback).


Required page structure (per AGENTS.md §2)

Use this exact skeleton. Fill from SDK source, not from this issue:

---
title: "Send Message Tool"
sidebarTitle: "Send Message"
description: "Let agents proactively message the user through Telegram, Slack, Discord, and other gateways mid-task"
icon: "paper-plane"
---

{/* One-sentence intro */}
Send Message lets a running agent reach the user proactively on their configured channels — \"I've finished the report, sending it to you on Telegram\" — without waiting for the next user turn.

{/* Hero diagram — see §3 below */}

## Quick Start
<Steps>
  <Step title="Enable the tool"> ... agent-centric minimal example ... </Step>
  <Step title="List reachable targets"> ... send_message(action=\"list\") ... </Step>
  <Step title="Send with attachments"> ... MEDIA:/path example ... </Step>
</Steps>

---

## How It Works
{/* sequence diagram: Agent → send_message → OutboundMessenger → Gateway → User */}
{/* short table: tool / messenger protocol / gateway registers it */}

---

## Targets
{/* table of target forms: origin / <platform> / <platform>:<chat_id>[:<thread_id>] / alias */}
{/* small \"choose your target\" mermaid graph */}

---

## Attachments (MEDIA:)
{/* explain MEDIA:<path> directive, multiple supported, path can contain no whitespace */}

---

## Listing Targets
{/* show action=\"list\" + sample JSON */}

---

## When It's Available
{/* gateway/bot: yes. CLI one-shot: no — returns the no-gateway string, doesn't raise. */}
{/* short table: runtime → behaviour */}

---

## User Interaction Flow
{/* per AGENTS.md §1.1 rule 11 — narrate a real scenario:
    User starts a long-running task on Telegram → leaves chat →
    agent finishes report → agent calls send_message(\"origin\", \"Done MEDIA:/tmp/r.pdf\") →
    user gets a Telegram push with the file. */}

---

## Configuration Reference
{/* Link to auto-gen SDK reference once it's generated for messaging_tools.
    Until then, just the args table above. Do NOT duplicate full SDK signatures. */}

---

## Common Patterns
{/* 2–3: notify on long task completion; cross-channel handoff; pick target from list first */}

---

## Best Practices
<AccordionGroup>
  <Accordion title=\"Always confirm channel before sending\">...</Accordion>
  <Accordion title=\"Use 'origin' by default\">...</Accordion>
  <Accordion title=\"Handle the no-gateway fallback in instructions\">...</Accordion>
  <Accordion title=\"Keep messages short  they hit a phone\">...</Accordion>
</AccordionGroup>

---

## Related
<CardGroup cols={2}>
  <Card title=\"Clarify Tool\" href=\"/docs/features/clarify-tool\">Ask the user mid-task</Card>
  <Card title=\"Channels Gateway\" href=\"/docs/features/channels-gateway\">Connect to Telegram/Slack/Discord/WhatsApp</Card>
  <Card title=\"Bot Gateway\" href=\"/docs/features/bot-gateway\">Run the gateway server</Card>
  <Card title=\"Bot Routing\" href=\"/docs/features/bot-routing\">Route messages by channel</Card>
</CardGroup>

Hero diagram (use this exact mermaid block — matches §3 color scheme)

graph LR
    subgraph "Send Message Flow"
        A[🤖 Agent] --> B[📤 send_message]
        B --> C[🛰️ Gateway]
        C --> D[📱 User]
    end

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef gateway fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef user fill:#10B981,stroke:#7C90A0,color:#fff

    class A agent
    class B tool
    class C gateway
    class D user
Loading

"How it works" sequence diagram

sequenceDiagram
    participant Agent
    participant SendMessage as send_message
    participant Context as SessionContext
    participant Messenger as OutboundMessenger
    participant Gateway
    participant User

    Agent->>SendMessage: send_message("origin", "Done MEDIA:/tmp/r.pdf")
    SendMessage->>Context: get_outbound_messenger()
    Context-->>SendMessage: messenger (or None)
    alt no gateway
        SendMessage-->>Agent: "No active gateway: ..."
    else gateway active
        SendMessage->>Messenger: send(target, text, media=[...])
        Messenger->>Gateway: deliver
        Gateway->>User: push (Telegram/Slack/etc.)
        Messenger-->>SendMessage: DeliveryResult(ok, target, summary)
        SendMessage-->>Agent: summary
    end
Loading

Code examples to include (verify each runs)

1. Agent-centric Quick Start (top of page — per AGENTS.md §1.1 rule 9):

from praisonaiagents import Agent
from praisonaiagents.tools import send_message

agent = Agent(
    name="Reporter",
    instructions="When you finish a long task, message the user on their channel.",
    tools=[send_message],
)

agent.start("Generate the weekly report and notify me when it's ready.")

2. List targets first:

# The model calls:
#   send_message(action="list")
# and gets back JSON like:
#   [{"target": "telegram:home", "platform": "telegram", "kind": "home", "label": "Telegram"}]

3. Send with media attachment:

# Model call:
#   send_message("origin", "Weekly report ready MEDIA:/tmp/report.pdf")
# Returns: "Delivered to origin"

4. Explicit channel target:

# Model call:
#   send_message("slack:#ops", "Deploy finished ✅")

Concepts to explain (per AGENTS.md §6 — for non-developers)

Every concept on the page gets one short sentence + (if useful) a small mermaid diagram:

  1. "origin" vs explicit target vs alias — small decision-style mermaid graph so the reader knows which to use when. AGENTS.md §6.1: "If multiple options in one page, people might be confused on what to choose, so create the mermaid diagram to choose what option at what instance."
  2. MEDIA: directive — one sentence + a one-line example.
  3. Gateway-required runtime — table: CLI → unavailable (graceful), Bot/Gateway → available.
  4. action="send" vs action="list" — one-line comparison table.

Writing rules (recap from AGENTS.md §6)

  • One-sentence section intros. No "In this section..." / "As you can see..." / "Let's take a look at...".
  • Active voice. Direct. Specific.
  • Agent-centric examples at the top.
  • Non-developers must feel "is it really this easy?" after reading.
  • Use friendly imports: from praisonaiagents.tools import send_message (not deep submodule paths).

docs.json update

After creating the file, add to docs.json under the Features group:

"docs/features/send-message-tool"

Place it near the other agent-tool / gateway feature entries (e.g. next to docs/features/clarify-tool and the gateway pages). Do NOT add under the Concepts group. Validate the JSON after editing.


Acceptance checklist (per AGENTS.md §9)

  • File at docs/features/send-message-tool.mdx
  • Frontmatter: title, sidebarTitle, description, icon: "paper-plane"
  • Hero mermaid diagram with the §3 colour scheme + white text
  • Quick Start <Steps> with agent-centric example first
  • All three action paths shown: implicit send / action="send" / action="list"
  • MEDIA: directive documented with at least one example
  • Targets table covers all four forms: origin, <platform>, <platform>:<chat_id>[:<thread_id>], alias
  • No-gateway fallback documented (exact quoted string, doesn't raise)
  • User interaction flow narrative included
  • <AccordionGroup> Best Practices section
  • <CardGroup> Related section with at least Clarify Tool + Channels Gateway + Bot Gateway
  • Added to docs.json under Features (not Concepts); valid JSON
  • No edits under docs/concepts/, docs/js/, docs/rust/
  • All code examples run as-is (no your-key-here placeholders)
  • Imports use the friendly form from praisonaiagents.tools import send_message
  • Cross-checked every spec on this page against praisonaiagents/tools/messaging_tools.py and praisonaiagents/gateway/protocols.py

Out of scope (do NOT include)

  • Internals of _run_async thread/loop handling — that's implementation, not user-facing.
  • Wrapper-side BotOutboundMessenger implementation details — belongs in a separate gateway-internals page if needed.
  • Editing docs/sdk/reference/** — that tree is auto-generated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claudeTrigger Claude Code analysisdocumentationImprovements or additions to documentationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions