meshcode 2.11.147__tar.gz → 2.11.148__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.11.147 → meshcode-2.11.148}/PKG-INFO +1 -1
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/__init__.py +1 -1
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/server.py +30 -3
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.11.147 → meshcode-2.11.148}/pyproject.toml +1 -1
- {meshcode-2.11.147 → meshcode-2.11.148}/README.md +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/__main__.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/_session_handoff_template.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/cli.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/compat.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/daemon.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/doctor.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/helper_visuals.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/hooks/__init__.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/hooks/repo_path_lock.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/hostd.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/invites.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/launcher.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/swarm.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/meshcode_mcp/test_swarm.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/preferences.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/protocol_handler.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/run_agent.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/secrets.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/self_update.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/up.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode/upload.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/setup.cfg +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_core.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_doctor.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_helper_visuals.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_hostd_launch_pinned_env.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_hostd_serve_discovery_split.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_hostd_zombie_sessions.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_live_mesh_guard.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_pretrust_claude.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_session_replay_gate.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_stop_ghost_terminal.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_swarm_events.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_task_progress.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_terminal_lifecycle.py +0 -0
- {meshcode-2.11.147 → meshcode-2.11.148}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -969,6 +969,15 @@ _current_tool = ""
|
|
|
969
969
|
_IDLE_THRESHOLD_S = 120 # seconds without tool call → IDLE
|
|
970
970
|
_SLEEPING_THRESHOLD_S = 300 # seconds in waiting without activity → SLEEPING
|
|
971
971
|
_WORKING_COOLDOWN_S = 60 # seconds after last tool returns before flipping to ONLINE
|
|
972
|
+
|
|
973
|
+
# ── P1 heartbeat throttle (2.11.148) ──
|
|
974
|
+
# When status+task haven't changed, skip the full mc_agents UPDATE and
|
|
975
|
+
# write only a cheap mc_heartbeats ping. Idle agents go from ~every 5s
|
|
976
|
+
# full-row writes to ~every 15s, staying under the 20s-live / 90s-offline
|
|
977
|
+
# thresholds while cutting Realtime fan-out ~3×.
|
|
978
|
+
_HB_THROTTLE_S = 15.0
|
|
979
|
+
_hb_last_state: "tuple[str, str] | None" = None
|
|
980
|
+
_hb_last_full_write: float = 0.0
|
|
972
981
|
_working_timer: Optional[_threading.Timer] = None
|
|
973
982
|
|
|
974
983
|
|
|
@@ -2564,8 +2573,18 @@ def _heartbeat_loop_inner():
|
|
|
2564
2573
|
# no longer wired to a status write.
|
|
2565
2574
|
|
|
2566
2575
|
# Sync current state to DB (in case realtime missed it)
|
|
2576
|
+
# P1 throttle (2.11.148): skip full mc_agents UPDATE when state
|
|
2577
|
+
# hasn't changed recently — write cheap mc_heartbeats only.
|
|
2578
|
+
global _hb_last_state, _hb_last_full_write
|
|
2579
|
+
_hb_cur = (_current_state, _current_tool)
|
|
2580
|
+
_hb_now = _time.monotonic()
|
|
2567
2581
|
try:
|
|
2568
|
-
|
|
2582
|
+
if _hb_cur == _hb_last_state and (_hb_now - _hb_last_full_write) < _HB_THROTTLE_S:
|
|
2583
|
+
be.heartbeat(_PROJECT_ID, AGENT_NAME)
|
|
2584
|
+
else:
|
|
2585
|
+
be.set_status(_PROJECT_ID, AGENT_NAME, _current_state, _current_tool, api_key=_get_api_key())
|
|
2586
|
+
_hb_last_state = _hb_cur
|
|
2587
|
+
_hb_last_full_write = _hb_now
|
|
2569
2588
|
except Exception as e:
|
|
2570
2589
|
log.warning(f"status sync failed (agent may show stale status): {e}")
|
|
2571
2590
|
# Realtime subscription recovery: if the WebSocket is connected but
|
|
@@ -6458,11 +6477,19 @@ def meshcode_boot() -> Dict[str, Any]:
|
|
|
6458
6477
|
_overdue.append(_t)
|
|
6459
6478
|
else:
|
|
6460
6479
|
_due_today.append(_t)
|
|
6480
|
+
def _compact_due(_t):
|
|
6481
|
+
return {
|
|
6482
|
+
"id": str(_t.get("id", ""))[:8],
|
|
6483
|
+
"title": str(_t.get("title", ""))[:80],
|
|
6484
|
+
"due_at": _t.get("due_at"),
|
|
6485
|
+
"priority": _t.get("priority"),
|
|
6486
|
+
}
|
|
6487
|
+
_due_all = _due_today + _overdue
|
|
6461
6488
|
calendar_block = {
|
|
6462
6489
|
"pending_due_today": len(_due_today),
|
|
6463
6490
|
"overdue": len(_overdue),
|
|
6464
|
-
"next_due": (
|
|
6465
|
-
"due_tasks":
|
|
6491
|
+
"next_due": (_compact_due(_due_all[0]) if _due_all else None),
|
|
6492
|
+
"due_tasks": [_compact_due(_t) for _t in _due_all],
|
|
6466
6493
|
}
|
|
6467
6494
|
resp["calendar_context"] = calendar_block
|
|
6468
6495
|
except Exception:
|
|
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
|
|
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
|
|
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
|
|
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
|