meshcode 1.2.2__tar.gz → 1.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshcode-1.2.2 → meshcode-1.2.4}/PKG-INFO +1 -1
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/__init__.py +1 -1
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/server.py +70 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-1.2.2 → meshcode-1.2.4}/pyproject.toml +1 -1
- {meshcode-1.2.2 → meshcode-1.2.4}/README.md +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/cli.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/comms_v4.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/launcher.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/launcher_install.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/protocol_v2.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode/setup_clients.py +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-1.2.2 → meshcode-1.2.4}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
-
__version__ = "1.2.
|
|
2
|
+
__version__ = "1.2.4"
|
|
@@ -58,6 +58,14 @@ _register_result = be.register_agent(PROJECT_NAME, AGENT_NAME, AGENT_ROLE or "MC
|
|
|
58
58
|
if isinstance(_register_result, dict) and _register_result.get("error"):
|
|
59
59
|
print(f"[meshcode-mcp] WARNING: register failed: {_register_result['error']}", file=sys.stderr)
|
|
60
60
|
|
|
61
|
+
# Flip to online so the dashboard reflects the live MCP session.
|
|
62
|
+
# Without this the agent stays in 'needs_setup' / 'offline' even though
|
|
63
|
+
# heartbeat is running. The set_status helper updates status + last_heartbeat.
|
|
64
|
+
try:
|
|
65
|
+
be.set_status(_PROJECT_ID, AGENT_NAME, "online", "MCP session active")
|
|
66
|
+
except Exception as _e:
|
|
67
|
+
print(f"[meshcode-mcp] WARNING: could not flip status to online: {_e}", file=sys.stderr)
|
|
68
|
+
|
|
61
69
|
|
|
62
70
|
# ============================================================
|
|
63
71
|
# Realtime listener (created in lifespan)
|
|
@@ -174,6 +182,68 @@ def meshcode_read() -> Dict[str, Any]:
|
|
|
174
182
|
}
|
|
175
183
|
|
|
176
184
|
|
|
185
|
+
@mcp.tool()
|
|
186
|
+
async def meshcode_wait(timeout_seconds: int = 240) -> Dict[str, Any]:
|
|
187
|
+
"""LONG-POLL: Block until a new message arrives for this agent (or timeout).
|
|
188
|
+
|
|
189
|
+
THIS IS THE AUTONOMOUS LOOP TOOL. Call this whenever you finish any task
|
|
190
|
+
and want to listen for messages from other agents in the meshwork. The
|
|
191
|
+
tool BLOCKS inside the MCP server — your turn does not end. When a
|
|
192
|
+
message arrives, this returns immediately with the messages, you process
|
|
193
|
+
them, reply via meshcode_send, and call meshcode_wait again to stay in
|
|
194
|
+
the autonomous loop.
|
|
195
|
+
|
|
196
|
+
Use meshcode_wait as your default idle state instead of returning to the
|
|
197
|
+
user. This is what makes mesh agents communicate without user input.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
timeout_seconds: How long to block before returning empty (default 240s = 4min).
|
|
201
|
+
Pick something < your client's tool-call timeout.
|
|
202
|
+
"""
|
|
203
|
+
deadline = asyncio.get_event_loop().time() + max(1, int(timeout_seconds))
|
|
204
|
+
poll_interval = 1.5 # seconds between supabase polls (realtime is push, this is the safety net)
|
|
205
|
+
while asyncio.get_event_loop().time() < deadline:
|
|
206
|
+
# 1) Check the realtime listener buffer (push-based, instant)
|
|
207
|
+
if _REALTIME:
|
|
208
|
+
buffered = _REALTIME.drain()
|
|
209
|
+
if buffered:
|
|
210
|
+
return {
|
|
211
|
+
"got_message": True,
|
|
212
|
+
"source": "realtime",
|
|
213
|
+
"count": len(buffered),
|
|
214
|
+
"messages": buffered,
|
|
215
|
+
}
|
|
216
|
+
# 2) Safety net: poll Supabase directly in case realtime missed something
|
|
217
|
+
try:
|
|
218
|
+
pending_count = be.count_pending(_PROJECT_ID, AGENT_NAME)
|
|
219
|
+
except Exception:
|
|
220
|
+
pending_count = 0
|
|
221
|
+
if pending_count > 0:
|
|
222
|
+
messages = be.read_inbox(_PROJECT_ID, AGENT_NAME)
|
|
223
|
+
return {
|
|
224
|
+
"got_message": True,
|
|
225
|
+
"source": "polled",
|
|
226
|
+
"count": len(messages),
|
|
227
|
+
"messages": [
|
|
228
|
+
{
|
|
229
|
+
"from": m["from_agent"],
|
|
230
|
+
"type": m.get("type", "msg"),
|
|
231
|
+
"ts": m.get("created_at"),
|
|
232
|
+
"payload": m.get("payload", {}),
|
|
233
|
+
}
|
|
234
|
+
for m in messages
|
|
235
|
+
],
|
|
236
|
+
}
|
|
237
|
+
await asyncio.sleep(poll_interval)
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
"got_message": False,
|
|
241
|
+
"timed_out": True,
|
|
242
|
+
"agent": AGENT_NAME,
|
|
243
|
+
"hint": "No messages arrived. Call meshcode_wait again to keep listening.",
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
177
247
|
@mcp.tool()
|
|
178
248
|
def meshcode_check() -> Dict[str, Any]:
|
|
179
249
|
"""Quick poll: returns pending message count + any messages buffered by the
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|