meshcode 2.4.5__tar.gz → 2.4.7__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.
Files changed (30) hide show
  1. {meshcode-2.4.5 → meshcode-2.4.7}/PKG-INFO +1 -1
  2. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/__init__.py +1 -1
  3. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/server.py +91 -9
  4. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/PKG-INFO +1 -1
  5. {meshcode-2.4.5 → meshcode-2.4.7}/pyproject.toml +1 -1
  6. {meshcode-2.4.5 → meshcode-2.4.7}/README.md +0 -0
  7. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/cli.py +0 -0
  8. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/comms_v4.py +0 -0
  9. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/invites.py +0 -0
  10. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/launcher.py +0 -0
  11. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/launcher_install.py +0 -0
  12. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/__init__.py +0 -0
  13. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/__main__.py +0 -0
  14. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/backend.py +0 -0
  15. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/realtime.py +0 -0
  16. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/test_backend.py +0 -0
  17. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  18. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  19. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/preferences.py +0 -0
  20. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/protocol_v2.py +0 -0
  21. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/run_agent.py +0 -0
  22. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/secrets.py +0 -0
  23. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/self_update.py +0 -0
  24. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode/setup_clients.py +0 -0
  25. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/SOURCES.txt +0 -0
  26. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/dependency_links.txt +0 -0
  27. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/entry_points.txt +0 -0
  28. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/requires.txt +0 -0
  29. {meshcode-2.4.5 → meshcode-2.4.7}/meshcode.egg-info/top_level.txt +0 -0
  30. {meshcode-2.4.5 → meshcode-2.4.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.4.5
3
+ Version: 2.4.7
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """MeshCode — Real-time communication between AI agents."""
2
- __version__ = "2.4.5"
2
+ __version__ = "2.4.7"
@@ -45,18 +45,34 @@ def _try_auto_wake(from_agent: str, preview: str) -> None:
45
45
 
46
46
  Conditions to fire (ALL must be true):
47
47
  - _AUTO_WAKE is enabled
48
+ - from_agent != self (never wake yourself on self-echo)
48
49
  - NOT in meshcode_wait (wait loop already handles delivery)
49
50
  - _current_state is 'sleeping' (truly idle, not working, not just online)
51
+ - No tool calls in the last 30 seconds (broad idle window)
50
52
  - LLM CPU is low (not actively generating)
51
53
  Otherwise the keystroke would interrupt the user's typing or
52
54
  the LLM mid-thought.
53
55
  """
54
56
  if not _AUTO_WAKE or _IN_WAIT:
55
57
  return
58
+ # Self-echo guard: never wake on a message you sent yourself.
59
+ # Realtime can echo INSERTs back to the sender (or to all subscribers
60
+ # in some routing paths) — without this guard, every meshcode_send by
61
+ # the agent would inject AppleScript into its own terminal mid-session.
62
+ if from_agent and AGENT_NAME and from_agent == AGENT_NAME:
63
+ return
56
64
  # Only fire when agent is actually sleeping — never when working or online
57
65
  # (working = LLM generating; online = brief post-tool window; both would be interrupted)
58
66
  if _current_state != 'sleeping':
59
67
  return
68
+ # Recent-activity guard: even if state says 'sleeping', any tool call
69
+ # in the last 30s means the LLM was just typing or about to type. The
70
+ # _IN_WAIT + state check has gaps between tool calls; this widens it.
71
+ try:
72
+ if (_time.time() - _last_tool_at) < 30.0:
73
+ return
74
+ except Exception:
75
+ pass
60
76
  # Belt-and-suspenders: also check parent CPU is low (LLM not generating right now)
61
77
  try:
62
78
  if _get_parent_cpu() > 5.0:
@@ -678,19 +694,63 @@ COMMANDER PROTOCOL (you are the team lead):
678
694
 
679
695
  _INSTRUCTIONS = _build_instructions()
680
696
 
681
- # Pre-load persistent memories into instructions (saves 1 tool call per session)
697
+ # Pre-load persistent memories into instructions (tiered, ~10x cheaper than legacy
698
+ # load-all). Strategy:
699
+ # - critical: full content always preloaded (cap 10 keys per agent)
700
+ # - reference: key list only (fetch values on demand via meshcode_recall)
701
+ # - episodic: NEVER preloaded — search via meshcode_recall_search instead
702
+ # Falls back to legacy load-all if migration 080 isn't applied yet (overload missing).
682
703
  try:
683
- _memories = be.sb_rpc("mc_memory_list", {
684
- "p_api_key": _get_api_key(),
704
+ _api_key = _get_api_key()
705
+ _crit = be.sb_rpc("mc_memory_list", {
706
+ "p_api_key": _api_key,
685
707
  "p_agent_name": AGENT_NAME,
708
+ "p_tier": "critical",
686
709
  "p_project_name": PROJECT_NAME,
687
710
  })
688
- if isinstance(_memories, dict) and _memories.get("ok") and _memories.get("memories"):
689
- _mem_lines = []
690
- for m in _memories["memories"]:
691
- _mem_lines.append(f" {m['key']}: {json.dumps(m['value'], default=str)}")
692
- _INSTRUCTIONS += "\nPRE-LOADED MEMORIES:\n" + "\n".join(_mem_lines) + "\n"
693
- log.info(f"pre-loaded {len(_mem_lines)} memories into instructions")
711
+ _ref = be.sb_rpc("mc_memory_list", {
712
+ "p_api_key": _api_key,
713
+ "p_agent_name": AGENT_NAME,
714
+ "p_tier": "reference",
715
+ "p_project_name": PROJECT_NAME,
716
+ })
717
+
718
+ _crit_ok = isinstance(_crit, dict) and _crit.get("ok")
719
+ _ref_ok = isinstance(_ref, dict) and _ref.get("ok")
720
+
721
+ if _crit_ok or _ref_ok:
722
+ _sections = []
723
+ if _crit_ok and _crit.get("memories"):
724
+ _crit_lines = [f" {m['key']}: {json.dumps(m['value'], default=str)}"
725
+ for m in _crit["memories"]]
726
+ _sections.append("CRITICAL MEMORIES (always loaded):\n" + "\n".join(_crit_lines))
727
+ if _ref_ok and _ref.get("memories"):
728
+ _ref_keys = [m["key"] for m in _ref["memories"]]
729
+ _sections.append(
730
+ "REFERENCE MEMORIES (key list — fetch on demand via meshcode_recall(key)):\n "
731
+ + ", ".join(_ref_keys)
732
+ )
733
+ _sections.append(
734
+ "EPISODIC MEMORIES: not preloaded. Search via "
735
+ "meshcode_recall_search(query) when you need past incident context."
736
+ )
737
+ _INSTRUCTIONS += "\n" + "\n\n".join(_sections) + "\n"
738
+ log.info(
739
+ f"pre-loaded tiered memories: critical={len(_crit.get('memories', [])) if _crit_ok else 0}, "
740
+ f"reference={len(_ref.get('memories', [])) if _ref_ok else 0}"
741
+ )
742
+ else:
743
+ # Legacy fallback: migration 080 not applied → load all (old behavior)
744
+ _legacy = be.sb_rpc("mc_memory_list", {
745
+ "p_api_key": _api_key,
746
+ "p_agent_name": AGENT_NAME,
747
+ "p_project_name": PROJECT_NAME,
748
+ })
749
+ if isinstance(_legacy, dict) and _legacy.get("ok") and _legacy.get("memories"):
750
+ _mem_lines = [f" {m['key']}: {json.dumps(m['value'], default=str)}"
751
+ for m in _legacy["memories"]]
752
+ _INSTRUCTIONS += "\nPRE-LOADED MEMORIES (legacy):\n" + "\n".join(_mem_lines) + "\n"
753
+ log.info(f"pre-loaded {len(_mem_lines)} memories (legacy fallback)")
694
754
  except Exception as _e:
695
755
  log.debug(f"memory pre-load skipped: {_e}")
696
756
 
@@ -1630,6 +1690,28 @@ def meshcode_forget(key: str) -> Dict[str, Any]:
1630
1690
  })
1631
1691
 
1632
1692
 
1693
+ @mcp.tool()
1694
+ @with_working_status
1695
+ def meshcode_recall_search(query: str) -> Dict[str, Any]:
1696
+ """Full-text search across episodic memories. Use this when you need
1697
+ past-incident or debug-log context that wasn't preloaded at boot.
1698
+
1699
+ Returns top 10 matches ranked by relevance, with snippets of the
1700
+ stored value. Episodic memories are not preloaded — search them on
1701
+ demand instead of polluting the system prompt.
1702
+
1703
+ Args:
1704
+ query: Plain English search query.
1705
+ """
1706
+ api_key = _get_api_key()
1707
+ return be.sb_rpc("mc_memory_search", {
1708
+ "p_api_key": api_key,
1709
+ "p_agent_name": AGENT_NAME,
1710
+ "p_query": query,
1711
+ "p_project_name": PROJECT_NAME,
1712
+ })
1713
+
1714
+
1633
1715
  # ----------------- RESOURCES -----------------
1634
1716
 
1635
1717
  @mcp.tool()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.4.5
3
+ Version: 2.4.7
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meshcode"
7
- version = "2.4.5"
7
+ version = "2.4.7"
8
8
  description = "Real-time communication between AI agents — Supabase-backed CLI"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes