meshcode 2.6.3__tar.gz → 2.6.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-2.6.3 → meshcode-2.6.4}/PKG-INFO +1 -1
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/__init__.py +1 -1
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/server.py +56 -1
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.6.3 → meshcode-2.6.4}/pyproject.toml +1 -1
- {meshcode-2.6.3 → meshcode-2.6.4}/README.md +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/cli.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/comms_v4.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/invites.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/launcher.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/launcher_install.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/preferences.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/run_agent.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/secrets.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/self_update.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode/setup_clients.py +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/setup.cfg +0 -0
- {meshcode-2.6.3 → meshcode-2.6.4}/tests/test_status_enum_coverage.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
-
__version__ = "2.6.
|
|
2
|
+
__version__ = "2.6.4"
|
|
@@ -1337,7 +1337,7 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
|
|
|
1337
1337
|
# The in-memory dedupe (_SEEN_MSG_IDS) can mark messages as "seen" via
|
|
1338
1338
|
# realtime without the agent actually processing them. Always check DB.
|
|
1339
1339
|
try:
|
|
1340
|
-
db_pending = be.count_pending(_PROJECT_ID, AGENT_NAME)
|
|
1340
|
+
db_pending = be.count_pending(_PROJECT_ID, AGENT_NAME, api_key=_get_api_key())
|
|
1341
1341
|
if db_pending and db_pending > 0:
|
|
1342
1342
|
# Fetch and return the messages — mark_read=True so the next
|
|
1343
1343
|
# meshcode_wait() won't re-refuse with the same messages.
|
|
@@ -1409,6 +1409,33 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
|
|
|
1409
1409
|
_IN_WAIT = False
|
|
1410
1410
|
|
|
1411
1411
|
|
|
1412
|
+
def _mark_realtime_msgs_read_in_db(messages: List[Dict[str, Any]]) -> None:
|
|
1413
|
+
"""Mark realtime-delivered messages as read in DB (background thread).
|
|
1414
|
+
|
|
1415
|
+
Without this, messages delivered via realtime stay read=false in the DB
|
|
1416
|
+
and inflate pending counts when the agent restarts.
|
|
1417
|
+
"""
|
|
1418
|
+
import threading
|
|
1419
|
+
msg_ids = [m.get("id") for m in messages if m.get("id")]
|
|
1420
|
+
if not msg_ids:
|
|
1421
|
+
return
|
|
1422
|
+
api_key = _get_api_key()
|
|
1423
|
+
if not api_key:
|
|
1424
|
+
return
|
|
1425
|
+
|
|
1426
|
+
def _do():
|
|
1427
|
+
for mid in msg_ids:
|
|
1428
|
+
try:
|
|
1429
|
+
be.sb_rpc("mc_mark_message_read", {
|
|
1430
|
+
"p_api_key": api_key,
|
|
1431
|
+
"p_project_id": _PROJECT_ID,
|
|
1432
|
+
"p_message_id": mid,
|
|
1433
|
+
})
|
|
1434
|
+
except Exception:
|
|
1435
|
+
pass
|
|
1436
|
+
threading.Thread(target=_do, daemon=True).start()
|
|
1437
|
+
|
|
1438
|
+
|
|
1412
1439
|
async def _meshcode_wait_inner(actual_timeout: int, include_acks: bool) -> Dict[str, Any]:
|
|
1413
1440
|
|
|
1414
1441
|
def _return_from_buffered(buffered: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
|
|
@@ -1436,6 +1463,9 @@ async def _meshcode_wait_inner(actual_timeout: int, include_acks: bool) -> Dict[
|
|
|
1436
1463
|
# are no real messages or done signals, treat as nothing useful.
|
|
1437
1464
|
if not split["messages"] and not split["done_signals"] and not split["acks"]:
|
|
1438
1465
|
return None
|
|
1466
|
+
# Mark realtime-delivered messages as read in DB so they don't
|
|
1467
|
+
# inflate pending counts on agent restart.
|
|
1468
|
+
_mark_realtime_msgs_read_in_db(deduped)
|
|
1439
1469
|
out: Dict[str, Any] = {
|
|
1440
1470
|
"got_message": True,
|
|
1441
1471
|
"source": "realtime",
|
|
@@ -1468,6 +1498,31 @@ async def _meshcode_wait_inner(actual_timeout: int, include_acks: bool) -> Dict[
|
|
|
1468
1498
|
# Realtime unavailable — plain sleep fallback so we still honor timeout.
|
|
1469
1499
|
await asyncio.sleep(actual_timeout)
|
|
1470
1500
|
|
|
1501
|
+
# Fallback: poll DB for messages that realtime may have missed
|
|
1502
|
+
# (connection drop, startup race, etc.)
|
|
1503
|
+
try:
|
|
1504
|
+
api_key = _get_api_key()
|
|
1505
|
+
if api_key:
|
|
1506
|
+
db_pending = be.count_pending(_PROJECT_ID, AGENT_NAME, api_key=api_key)
|
|
1507
|
+
if db_pending and db_pending > 0:
|
|
1508
|
+
raw = be.read_inbox(_PROJECT_ID, AGENT_NAME, mark_read=True, api_key=api_key)
|
|
1509
|
+
if raw:
|
|
1510
|
+
msgs = [
|
|
1511
|
+
{"from": m["from_agent"], "type": m.get("type", "msg"),
|
|
1512
|
+
"ts": m.get("created_at"), "payload": m.get("payload", {}),
|
|
1513
|
+
"id": m.get("id"), "parent_id": m.get("parent_msg_id")}
|
|
1514
|
+
for m in raw
|
|
1515
|
+
]
|
|
1516
|
+
deduped = _filter_and_mark(msgs)
|
|
1517
|
+
if deduped:
|
|
1518
|
+
split = _split_messages(deduped)
|
|
1519
|
+
if not include_acks:
|
|
1520
|
+
split["acks"] = []
|
|
1521
|
+
if split["messages"] or split["done_signals"]:
|
|
1522
|
+
return {"got_message": True, "source": "db_fallback", **split}
|
|
1523
|
+
except Exception:
|
|
1524
|
+
pass
|
|
1525
|
+
|
|
1471
1526
|
# Check if there's any pending work before returning timeout
|
|
1472
1527
|
pending_tasks = _get_pending_tasks_summary()
|
|
1473
1528
|
out: Dict[str, Any] = {"timed_out": True}
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|