meshcode 1.6.0__tar.gz → 1.8.0__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.6.0 → meshcode-1.8.0}/PKG-INFO +1 -1
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/__init__.py +1 -1
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/backend.py +44 -1
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/server.py +92 -2
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-1.6.0 → meshcode-1.8.0}/pyproject.toml +1 -1
- {meshcode-1.6.0 → meshcode-1.8.0}/README.md +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/cli.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/comms_v4.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/invites.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/launcher.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/launcher_install.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/protocol_v2.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/run_agent.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/secrets.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode/setup_clients.py +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-1.6.0 → meshcode-1.8.0}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.8.0"
|
|
@@ -164,7 +164,7 @@ def register_agent(project: str, name: str, role: str = "") -> Dict:
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
|
|
167
|
-
def send_message(project_id: str, from_agent: str, to_agent: str, payload: Any, msg_type: str = "msg", parent_msg_id: Optional[str] = None) -> Dict:
|
|
167
|
+
def send_message(project_id: str, from_agent: str, to_agent: str, payload: Any, msg_type: str = "msg", parent_msg_id: Optional[str] = None, sensitive: bool = False) -> Dict:
|
|
168
168
|
if not isinstance(payload, dict):
|
|
169
169
|
payload = {"text": str(payload)}
|
|
170
170
|
msg = {
|
|
@@ -177,6 +177,8 @@ def send_message(project_id: str, from_agent: str, to_agent: str, payload: Any,
|
|
|
177
177
|
}
|
|
178
178
|
if parent_msg_id:
|
|
179
179
|
msg["parent_msg_id"] = parent_msg_id
|
|
180
|
+
if sensitive:
|
|
181
|
+
msg["is_sensitive"] = True
|
|
180
182
|
result = sb_insert("mc_messages", msg)
|
|
181
183
|
if isinstance(result, dict) and result.get("_error"):
|
|
182
184
|
return {"error": result["_error"]}
|
|
@@ -257,6 +259,47 @@ def set_status(project_id: str, agent: str, status: str, task: str = "") -> Dict
|
|
|
257
259
|
return {"ok": True, "status": status}
|
|
258
260
|
|
|
259
261
|
|
|
262
|
+
def task_create(api_key, project_id, creator_agent, title, description="", assignee="*", priority="normal", parent_task_id=None):
|
|
263
|
+
return sb_rpc("mc_task_create", {
|
|
264
|
+
"p_api_key": api_key,
|
|
265
|
+
"p_project_id": project_id,
|
|
266
|
+
"p_creator_agent": creator_agent,
|
|
267
|
+
"p_title": title,
|
|
268
|
+
"p_description": description,
|
|
269
|
+
"p_assignee": assignee,
|
|
270
|
+
"p_priority": priority,
|
|
271
|
+
"p_parent_task_id": parent_task_id,
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def task_list(api_key, project_id, agent, status_filter=None):
|
|
276
|
+
return sb_rpc("mc_task_list", {
|
|
277
|
+
"p_api_key": api_key,
|
|
278
|
+
"p_project_id": project_id,
|
|
279
|
+
"p_agent": agent,
|
|
280
|
+
"p_status_filter": status_filter,
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def task_claim(api_key, project_id, task_id, claiming_agent):
|
|
285
|
+
return sb_rpc("mc_task_claim", {
|
|
286
|
+
"p_api_key": api_key,
|
|
287
|
+
"p_project_id": project_id,
|
|
288
|
+
"p_task_id": task_id,
|
|
289
|
+
"p_claiming_agent": claiming_agent,
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def task_complete(api_key, project_id, task_id, completing_agent, summary=""):
|
|
294
|
+
return sb_rpc("mc_task_complete", {
|
|
295
|
+
"p_api_key": api_key,
|
|
296
|
+
"p_project_id": project_id,
|
|
297
|
+
"p_task_id": task_id,
|
|
298
|
+
"p_completing_agent": completing_agent,
|
|
299
|
+
"p_summary": summary,
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
|
|
260
303
|
def get_history(project_id: str, limit: int = 20) -> List[Dict]:
|
|
261
304
|
return sb_select(
|
|
262
305
|
"mc_messages",
|
|
@@ -363,6 +363,14 @@ meshcode_wait / meshcode_check / meshcode_read now includes an `id` field
|
|
|
363
363
|
(use it for in_reply_to) and a `parent_id` field (so you can see whether
|
|
364
364
|
the message you received is itself a reply to something).
|
|
365
365
|
|
|
366
|
+
SENSITIVE DATA: when sharing API keys, credentials, customer data, personal
|
|
367
|
+
information, secrets, or anything that should not be in a public log, set
|
|
368
|
+
sensitive=True in your meshcode_send call. Sensitive messages are NEVER
|
|
369
|
+
included in public meshwork exports, even if the meshwork owner publishes
|
|
370
|
+
the meshwork. The flag is enforced at the database level — there is no way
|
|
371
|
+
for a public viewer to read sensitive messages. Use this liberally — false
|
|
372
|
+
positives are harmless, false negatives are a privacy leak.
|
|
373
|
+
|
|
366
374
|
LOOP-SAFETY RULES (IMPORTANT — prevent token-burning ping-pong):
|
|
367
375
|
- Do NOT reply "Done" / "OK" / "Got it" to every message. If a message
|
|
368
376
|
is a status update or pure ack, just process it and call meshcode_wait
|
|
@@ -383,6 +391,17 @@ YOUR FIRST ACTIONS WHEN THIS SESSION STARTS:
|
|
|
383
391
|
idle/listening state. Stay there forever unless one of the
|
|
384
392
|
break-out conditions above fires.
|
|
385
393
|
|
|
394
|
+
TASK BOARD: the meshwork has a shared task list. Use it instead of just messages
|
|
395
|
+
when work needs tracking. Tools:
|
|
396
|
+
meshcode_tasks(status_filter='open') — list tasks you could pick up
|
|
397
|
+
meshcode_task_claim(task_id) — atomically claim one (CAS — fails if
|
|
398
|
+
another agent already claimed)
|
|
399
|
+
meshcode_task_complete(task_id, summary)— mark done with a 1-line summary
|
|
400
|
+
meshcode_task_create(title, description, assignee='*') — create one (commanders
|
|
401
|
+
usually do this)
|
|
402
|
+
The dashboard renders the board live. Prefer claiming open tasks over starting
|
|
403
|
+
fresh work — it makes coordination visible to humans.
|
|
404
|
+
|
|
386
405
|
AVAILABLE MESH TOOLS (all from this MCP server):
|
|
387
406
|
meshcode_wait — block until a mesh message arrives (your idle state)
|
|
388
407
|
meshcode_done — broadcast a GLOBAL DONE to break every agent out of wait
|
|
@@ -394,6 +413,10 @@ AVAILABLE MESH TOOLS (all from this MCP server):
|
|
|
394
413
|
meshcode_broadcast — send to ALL agents in the meshwork
|
|
395
414
|
meshcode_register — re-register if disconnected
|
|
396
415
|
meshcode_init — re-initialize agent context (rarely needed)
|
|
416
|
+
meshcode_tasks — list tasks on the shared board
|
|
417
|
+
meshcode_task_create — create a new task
|
|
418
|
+
meshcode_task_claim — atomically claim an open task
|
|
419
|
+
meshcode_task_complete — mark a claimed task done
|
|
397
420
|
|
|
398
421
|
You are not a single-turn chatbot. You are a persistent mesh agent. Act
|
|
399
422
|
accordingly.
|
|
@@ -490,7 +513,8 @@ except Exception:
|
|
|
490
513
|
# ----------------- TOOLS -----------------
|
|
491
514
|
|
|
492
515
|
@mcp.tool()
|
|
493
|
-
def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None
|
|
516
|
+
def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None,
|
|
517
|
+
sensitive: bool = False) -> Dict[str, Any]:
|
|
494
518
|
"""Send a message to another agent in the meshwork.
|
|
495
519
|
|
|
496
520
|
If you only have plain text, just pass it as a string and it will be
|
|
@@ -505,6 +529,13 @@ def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None) -> D
|
|
|
505
529
|
message is a threaded reply — the dashboard renders it under the
|
|
506
530
|
original. Use this especially when replying to one of several
|
|
507
531
|
outstanding broadcasts so humans can tell which is which.
|
|
532
|
+
sensitive: If True, this message will NEVER appear in a public meshwork
|
|
533
|
+
export, regardless of whether the meshwork is published. ALWAYS
|
|
534
|
+
set this to True when sharing API keys, credentials, customer
|
|
535
|
+
data, secrets, personal information, or anything that should not
|
|
536
|
+
be visible to anyone outside the meshwork. The owner can publish
|
|
537
|
+
the meshwork without leaking sensitive messages, because the
|
|
538
|
+
sensitive flag is enforced at the database level.
|
|
508
539
|
"""
|
|
509
540
|
if isinstance(message, str):
|
|
510
541
|
payload: Dict[str, Any] = {"text": message}
|
|
@@ -513,7 +544,7 @@ def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None) -> D
|
|
|
513
544
|
else:
|
|
514
545
|
payload = {"text": str(message)}
|
|
515
546
|
return be.send_message(_PROJECT_ID, AGENT_NAME, to, payload, msg_type="msg",
|
|
516
|
-
parent_msg_id=in_reply_to)
|
|
547
|
+
parent_msg_id=in_reply_to, sensitive=sensitive)
|
|
517
548
|
|
|
518
549
|
|
|
519
550
|
@mcp.tool()
|
|
@@ -763,6 +794,65 @@ def meshcode_init(project: str, agent: str, role: str = "") -> Dict[str, Any]:
|
|
|
763
794
|
return {"ok": True, "project": project, "agent": agent, "register": result}
|
|
764
795
|
|
|
765
796
|
|
|
797
|
+
@mcp.tool()
|
|
798
|
+
def meshcode_task_create(title: str, description: str = "", assignee: str = "*",
|
|
799
|
+
priority: str = "normal", parent_task_id: Optional[str] = None) -> Dict[str, Any]:
|
|
800
|
+
"""Create a task in the meshwork's shared backlog. Use this when you (typically
|
|
801
|
+
the commander) want to assign work that needs tracking.
|
|
802
|
+
|
|
803
|
+
Args:
|
|
804
|
+
title: Short title of the task.
|
|
805
|
+
description: Longer description / acceptance criteria.
|
|
806
|
+
assignee: Agent name to assign to, or "*" for any agent (anyone can claim).
|
|
807
|
+
priority: 'low' / 'normal' / 'high' / 'urgent'.
|
|
808
|
+
parent_task_id: Optional parent task id for nesting subtasks.
|
|
809
|
+
|
|
810
|
+
Returns: {"ok": true, "task_id": "...", "title": "..."}
|
|
811
|
+
"""
|
|
812
|
+
api_key = _get_api_key()
|
|
813
|
+
return be.task_create(api_key, _PROJECT_ID, AGENT_NAME, title,
|
|
814
|
+
description=description, assignee=assignee,
|
|
815
|
+
priority=priority, parent_task_id=parent_task_id)
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
@mcp.tool()
|
|
819
|
+
def meshcode_tasks(status_filter: Optional[str] = None) -> Dict[str, Any]:
|
|
820
|
+
"""List tasks in the meshwork. Use this to discover work you can pick up.
|
|
821
|
+
|
|
822
|
+
Args:
|
|
823
|
+
status_filter: 'open' / 'in_progress' / 'done' / etc. None = all.
|
|
824
|
+
|
|
825
|
+
Returns: {"ok": true, "tasks": [...]}
|
|
826
|
+
"""
|
|
827
|
+
api_key = _get_api_key()
|
|
828
|
+
return be.task_list(api_key, _PROJECT_ID, AGENT_NAME, status_filter=status_filter)
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
@mcp.tool()
|
|
832
|
+
def meshcode_task_claim(task_id: str) -> Dict[str, Any]:
|
|
833
|
+
"""Atomically claim an open task. If the task is already claimed by someone
|
|
834
|
+
else (or assigned to a different agent), this returns an error and another
|
|
835
|
+
task should be picked.
|
|
836
|
+
|
|
837
|
+
Args:
|
|
838
|
+
task_id: The uuid of the task you want to claim.
|
|
839
|
+
"""
|
|
840
|
+
api_key = _get_api_key()
|
|
841
|
+
return be.task_claim(api_key, _PROJECT_ID, task_id, AGENT_NAME)
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
@mcp.tool()
|
|
845
|
+
def meshcode_task_complete(task_id: str, summary: str = "") -> Dict[str, Any]:
|
|
846
|
+
"""Mark a task as done. Only the claimer can complete it.
|
|
847
|
+
|
|
848
|
+
Args:
|
|
849
|
+
task_id: The uuid of the task you previously claimed.
|
|
850
|
+
summary: Short description of what was accomplished + any artifacts.
|
|
851
|
+
"""
|
|
852
|
+
api_key = _get_api_key()
|
|
853
|
+
return be.task_complete(api_key, _PROJECT_ID, task_id, AGENT_NAME, summary=summary)
|
|
854
|
+
|
|
855
|
+
|
|
766
856
|
# ----------------- RESOURCES -----------------
|
|
767
857
|
|
|
768
858
|
@mcp.resource("meshcode://inbox")
|
|
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
|
|
File without changes
|
|
File without changes
|