openclaw - ✅(Solved) Fix [Proposal] Structured signal layer for agent-to-agent communication (inspired by game comms systems) [1 pull requests, 4 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#50072Fetched 2026-04-08 00:59:29
View on GitHub
Comments
4
Participants
3
Timeline
12
Reactions
0
Author
Timeline (top)
commented ×4cross-referenced ×3mentioned ×2subscribed ×2

Fix Action

Fixed

PR fix notes

PR #50066: feat(agents): auto-log sessions_send to JSONL for observability

Description (problem / solution / changelog)

Summary

Add automatic JSONL logging for sessions_send completions. Every call — success, timeout, or error — appends a structured entry to ~/.openclaw/shared/signals/bus.jsonl.

This gives multi-agent operators a communication audit trail without requiring agent cooperation or skill installation.

Why

Agent-to-agent communication via sessions_send is invisible to operators. When the target replies ANNOUNCE_SKIP, there's no record the conversation happened. Debugging cross-agent failures means guessing which agent talked to which and when.

Related: #47911 (fleet status could consume this data), #50072 (signal layer proposal).

Changes

  • sessions-send-comms-log.ts — New module: async JSONL logger with truncation (200 chars), 50 MB size guard, OPENCLAW_COMMS_LOG=off kill switch
  • sessions-send-tool.ts — 7 appendCommsLog call sites covering all exit paths
  • sessions-send-comms-log.test.ts — 7 tests

Design notes

  • Fire-and-forget: errors swallowed, never disrupts sessions_send
  • Fully async I/O (fs.promises.mkdir + fs.promises.appendFile)
  • Zero dependencies (Node.js builtins only)
  • Privacy: previews truncated to 200 chars; disable with OPENCLAW_COMMS_LOG=off

Test plan

  • 7 unit tests passing (vitest)
  • Lint clean (oxlint)
  • TypeScript clean
  • Manual test with 6-agent setup

Changed files

  • src/agents/tools/sessions-send-comms-log.test.ts (added, +171/-0)
  • src/agents/tools/sessions-send-comms-log.ts (added, +113/-0)
  • src/agents/tools/sessions-send-tool.ts (modified, +61/-1)
RAW_BUFFERClick to expand / collapse

Problem

In multi-agent setups, agents coordinate through sessions_send — but most coordination doesn't need full natural language:

  • "I'm done" costs the same tokens as a complex discussion
  • No status visibility — you can't tell if an agent is idle, working, or blocked without asking
  • Invisible handoffs — when the target replies ANNOUNCE_SKIP, there's no record the conversation happened
  • One channel for everything — urgent alerts and progress updates use the same expensive mechanism

Proposal

Add a structured signal layer with predefined signal types:

SignalUse case
TASK_COMPLETEFinished, output ready
HANDOFFPassing task to another agent
BLOCKEDStuck, need help
NEED_INFONeed specific info from another agent
PROGRESSStatus update (e.g., "60% done")
ACKConfirmed receipt

Each signal is a lightweight JSONL entry (zero LLM cost), appended to a shared bus file. Signals complement sessions_send — use signals for coordination, sessions_send for discussion.

Layered communication

LayerWhatCost
L1 SignalStructured event (TASK_COMPLETE, BLOCKED)Zero
L2 StatusAgent state broadcast (idle / working / blocked)Zero
L3 TrustReliability tracking between agentsZero
L4 Full messagesessions_sendFull LLM

Design inspiration

This mirrors how competitive multiplayer games (e.g., Dota 2) handle team coordination under time pressure — multiple communication channels at different cost levels:

ChannelCostPrecisionExample
Voice/text chatHigh (attention)Low (ambiguous)"Let's smoke on slark" / "Can someone break Invoker's Linken?"
Map pingZeroHigh>Roshan / ⚠️ >Pudge is missing!
Alt+click statusZeroPerfect>Ravage: Ready / >BKB: 12s cooldown

The majority of effective team coordination uses signals and status pings, not voice or text. Multi-agent systems have the same dynamic.

Use cases

  • Task handoff: Dev agent finishes a script → TASK_COMPLETE signal → design agent picks it up. Zero tokens spent on the handoff.
  • Operator visibility: Dashboard shows all agent states and recent signals at a glance.
  • Debugging: When a task gets stuck, the signal trail shows exactly where and why.
  • Pre-send check: Query an agent's state before sending work — if they're blocked, don't pile on more tasks.

Relation to existing work

  • PR #50066 adds automatic JSONL logging for sessions_send — signals would write to the same bus.jsonl, creating a unified communication log
  • #47911 (openclaw fleet status) could consume signal data for real-time agent status
  • A working prototype exists (skill-level) with signal script, status management, trust scoring, and web dashboard

extent analysis

Fix Plan

To implement the proposed structured signal layer, follow these steps:

  1. Define signal types: Create an enumeration of signal types, such as TASK_COMPLETE, HANDOFF, BLOCKED, NEED_INFO, PROGRESS, and ACK.
  2. Implement signal sending: Modify the agent code to send signals as lightweight JSONL entries to a shared bus file.
  3. Create a signal receiver: Develop a mechanism to receive and process signals, updating agent states and triggering actions as needed.
  4. Integrate with existing logging: Utilize the existing JSONL logging mechanism (PR #50066) to write signals to the same bus.jsonl file.

Example Code (Python)

import json

# Define signal types
SIGNAL_TYPES = {
    'TASK_COMPLETE': 1,
    'HANDOFF': 2,
    'BLOCKED': 3,
    'NEED_INFO': 4,
    'PROGRESS': 5,
    'ACK': 6
}

# Send a signal
def send_signal(signal_type, data):
    signal = {'type': signal_type, 'data': data}
    with open('bus.jsonl', 'a') as f:
        json.dump(signal, f)
        f.write('\n')

# Receive and process signals
def process_signals():
    with open('bus.jsonl', 'r') as f:
        for line in f:
            signal = json.loads(line)
            # Update agent state and trigger actions based on signal type
            if signal['type'] == SIGNAL_TYPES['TASK_COMPLETE']:
                # Update task status
                pass
            elif signal['type'] == SIGNAL_TYPES['HANDOFF']:
                # Pass task to another agent
                pass

Verification

To verify the fix, test the following scenarios:

  • Send a signal and verify it is written to the bus.jsonl file.
  • Receive and process a signal, ensuring the agent state is updated correctly.
  • Integrate with existing logging and verify that signals are correctly logged.

Extra Tips

  • Ensure proper error handling and logging mechanisms are in place for signal sending and receiving.
  • Consider implementing a signal queue or buffer to handle high volumes of signals.
  • Utilize the existing prototype (skill-level) as a reference for implementing the signal layer.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING