meshcode 2.11.163__tar.gz → 2.11.165__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.163 → meshcode-2.11.165}/PKG-INFO +1 -1
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/__init__.py +1 -1
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/hostd.py +35 -2
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/server.py +113 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/SOURCES.txt +1 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/pyproject.toml +1 -1
- {meshcode-2.11.163 → meshcode-2.11.165}/README.md +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/__main__.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/_launch_smoke.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/_session_handoff_template.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/_update_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/cli.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/compat.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/daemon.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/doctor.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/hooks/__init__.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/hooks/push_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/hooks/repo_path_lock.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/invites.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/launcher.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/preferences.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/protocol_handler.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/run_agent.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/secrets.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/self_update.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/up.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode/upload.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/setup.cfg +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_core.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_doctor.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_ensure_boot_env_urgent_wake.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_fleet_reaper.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_hostd_launch_pinned_env.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_hostd_serve_discovery_split.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_hostd_zombie_sessions.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_launch_smoke.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_live_mesh_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_no_appleevents_on_sweep.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_preflight_hb_gate.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_pretrust_claude.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_prompt_dedup_budget.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_push_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_replica_base_workspace_fallback.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_replica_boot_protocol_unconditional.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_rm_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_session_replay_gate.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_stop_ghost_terminal.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_task_progress.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_terminal_lifecycle.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_up_launch_cmd.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_update_guard.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_urgent_wake_tmux.py +0 -0
- {meshcode-2.11.163 → meshcode-2.11.165}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -2630,9 +2630,31 @@ def _hostd_plist_xml() -> str:
|
|
|
2630
2630
|
wrapper = _hostd_launch_command_path()
|
|
2631
2631
|
wrapper.write_text(
|
|
2632
2632
|
"#!/bin/sh\n"
|
|
2633
|
-
"# MeshCode hostd launcher (
|
|
2634
|
-
"# by `meshcode hostd install`
|
|
2633
|
+
"# MeshCode hostd launcher (storm fix e4eda167 + d84cbfa1 self-heal). Generated\n"
|
|
2634
|
+
"# by `meshcode hostd install` -- do not edit; it is overwritten on reinstall.\n"
|
|
2635
2635
|
f'PATH="{bindir}:$PATH"; export PATH\n'
|
|
2636
|
+
"# Storm RC e4eda167: a KeepAlive supervisor pinned to a FROZEN interpreter\n"
|
|
2637
|
+
"# (e.g. anaconda) relaunches OLD code forever -> the native terminal-window\n"
|
|
2638
|
+
"# storm. Converge UP every relaunch: exec the NEWEST finalized immutable env\n"
|
|
2639
|
+
"# (~/.meshcode/envs/<v> with .build-ok + bin/python3), independent of the\n"
|
|
2640
|
+
"# frozen PATH interpreter whose self-upgrade DEFERS under live agents.\n"
|
|
2641
|
+
'ENVS="$HOME/.meshcode/envs"\n'
|
|
2642
|
+
'NEWEST=""\n'
|
|
2643
|
+
'if [ -d "$ENVS" ]; then\n'
|
|
2644
|
+
' for d in "$ENVS"/*/; do\n'
|
|
2645
|
+
' v=$(basename "$d")\n'
|
|
2646
|
+
' case "$v" in .tmp-*) continue ;; esac\n'
|
|
2647
|
+
' [ -f "$ENVS/$v/.build-ok" ] || continue\n'
|
|
2648
|
+
' [ -x "$ENVS/$v/bin/python3" ] || continue\n'
|
|
2649
|
+
' if [ -z "$NEWEST" ]; then NEWEST="$v"; continue; fi\n'
|
|
2650
|
+
' NEWEST=$(printf "%s\\n%s\\n" "$NEWEST" "$v" | awk -F. \'{ printf "%010d%010d%010d %s\\n", $1, $2, $3, $0 }\' | sort | tail -n1 | cut -d" " -f2)\n'
|
|
2651
|
+
' done\n'
|
|
2652
|
+
'fi\n'
|
|
2653
|
+
'if [ -n "$NEWEST" ] && [ -x "$ENVS/$NEWEST/bin/python3" ]; then\n'
|
|
2654
|
+
' MESHCODE_NO_AUTO_UPDATE=1; export MESHCODE_NO_AUTO_UPDATE\n'
|
|
2655
|
+
' exec "$ENVS/$NEWEST/bin/python3" -m meshcode hostd run\n'
|
|
2656
|
+
'fi\n'
|
|
2657
|
+
"# Fallback (no finalized env, e.g. fresh pip-only install): original behavior.\n"
|
|
2636
2658
|
"unset MESHCODE_NO_UPDATE MESHCODE_NO_AUTO_UPDATE\n"
|
|
2637
2659
|
f'{mc_inv} self-upgrade >> "{logdir / "hostd-update.log"}" 2>&1 || true\n'
|
|
2638
2660
|
"MESHCODE_NO_AUTO_UPDATE=1; export MESHCODE_NO_AUTO_UPDATE\n"
|
|
@@ -2914,6 +2936,17 @@ def _running_daemon_is_stale() -> bool:
|
|
|
2914
2936
|
import importlib.metadata as _ilmd
|
|
2915
2937
|
ondisk = _ilmd.version("meshcode")
|
|
2916
2938
|
from meshcode import self_update as _su
|
|
2939
|
+
# Storm fix e4eda167 (fix B): the CURRENT interpreter may be a lagging
|
|
2940
|
+
# pip install (e.g. anaconda 2.11.157) whose version == the stuck
|
|
2941
|
+
# daemon's running_version => "not stale" => never bounces it. Consider
|
|
2942
|
+
# the NEWEST finalized immutable env too, so an agent launched from ANY
|
|
2943
|
+
# interpreter converges a stale hostd within one launch. FAIL-SAFE.
|
|
2944
|
+
try:
|
|
2945
|
+
_env = _su.newest_installed_env()
|
|
2946
|
+
if _env and _su._is_newer(_env[0], ondisk):
|
|
2947
|
+
ondisk = _env[0]
|
|
2948
|
+
except Exception:
|
|
2949
|
+
pass
|
|
2917
2950
|
return bool(_su._is_newer(ondisk, rv))
|
|
2918
2951
|
except Exception:
|
|
2919
2952
|
return False
|
|
@@ -7789,6 +7789,119 @@ def meshcode_mesh_keep_alive(enabled: bool) -> Dict[str, Any]:
|
|
|
7789
7789
|
return res if isinstance(res, dict) else {"error": str(res)}
|
|
7790
7790
|
|
|
7791
7791
|
|
|
7792
|
+
@mcp.tool()
|
|
7793
|
+
def meshcode_gmail(
|
|
7794
|
+
action: str,
|
|
7795
|
+
to: str = "",
|
|
7796
|
+
subject: str = "",
|
|
7797
|
+
body: str = "",
|
|
7798
|
+
cc: str = "",
|
|
7799
|
+
bcc: str = "",
|
|
7800
|
+
message_id: str = "",
|
|
7801
|
+
q: str = "",
|
|
7802
|
+
max_results: int = 10,
|
|
7803
|
+
) -> Dict[str, Any]:
|
|
7804
|
+
"""Act on the meshwork owner's connected Gmail account (task fb654587).
|
|
7805
|
+
|
|
7806
|
+
OWNER-SCOPED: this agent can only reach the Gmail account connected to
|
|
7807
|
+
ITS OWN meshwork/project. Auth flows through the agent's api_key →
|
|
7808
|
+
mc_gmail_resolve_for_agent (SECURITY DEFINER), which verifies the key,
|
|
7809
|
+
confirms owner/member access to the project, resolves the single active
|
|
7810
|
+
gmail binding, and writes a MANDATORY audit row. Agents NEVER receive the
|
|
7811
|
+
OAuth token or binding_id — the trusted gmail-action edge fn holds the
|
|
7812
|
+
token and performs the Google API call. Every action is audited
|
|
7813
|
+
(meshcode.mc_connector_audit). Scope = readonly + compose + modify
|
|
7814
|
+
(NOT full mail.google.com).
|
|
7815
|
+
|
|
7816
|
+
Actions:
|
|
7817
|
+
- "send": send a new email. Needs: to, subject, body. Optional: cc, bcc.
|
|
7818
|
+
- "reply": reply in a thread. Needs: message_id (msg replied to), body.
|
|
7819
|
+
- "draft": create a draft. Needs: to, subject, body. Optional: cc, bcc.
|
|
7820
|
+
- "search": search messages. Needs: q. Optional: max_results.
|
|
7821
|
+
- "list": list recent msgs. Optional: q, max_results.
|
|
7822
|
+
- "get"/"read": fetch one msg. Needs: message_id.
|
|
7823
|
+
- "list_labels": list mailbox labels.
|
|
7824
|
+
|
|
7825
|
+
Args:
|
|
7826
|
+
action: one of send|reply|draft|search|list|get|read|list_labels.
|
|
7827
|
+
to: recipient email(s), comma-separated (send/draft).
|
|
7828
|
+
subject: subject line (send/draft).
|
|
7829
|
+
body: message body, plain text (send/reply/draft).
|
|
7830
|
+
cc, bcc: optional carbon-copy recipients (send/draft).
|
|
7831
|
+
message_id: Gmail message id (reply/get/read).
|
|
7832
|
+
q: Gmail search query, e.g. "from:boss is:unread" (search/list).
|
|
7833
|
+
max_results: cap results for search/list (default 10).
|
|
7834
|
+
|
|
7835
|
+
Returns the edge fn JSON ({ok, ...} or {ok:false, error/error_code}).
|
|
7836
|
+
"""
|
|
7837
|
+
import urllib.request as _req
|
|
7838
|
+
import urllib.error as _uerr
|
|
7839
|
+
|
|
7840
|
+
api_key = _get_api_key()
|
|
7841
|
+
if not api_key:
|
|
7842
|
+
return {"ok": False, "error": "no api key", "error_code": "auth_failed"}
|
|
7843
|
+
if not _PROJECT_ID:
|
|
7844
|
+
return {"ok": False, "error": "project not resolved", "error_code": "config_error"}
|
|
7845
|
+
|
|
7846
|
+
act = (action or "").strip().lower()
|
|
7847
|
+
valid = {"send", "reply", "draft", "search", "list", "get", "read", "list_labels"}
|
|
7848
|
+
if act not in valid:
|
|
7849
|
+
return {"ok": False, "error": f"unknown action '{action}'",
|
|
7850
|
+
"error_code": "bad_action", "valid_actions": sorted(valid)}
|
|
7851
|
+
|
|
7852
|
+
# Action-specific fields go in a NESTED `params` object — the gmail-action
|
|
7853
|
+
# edge fn reads them from b.params (b.params.to, b.params.message_id, …).
|
|
7854
|
+
params: Dict[str, Any] = {}
|
|
7855
|
+
if to:
|
|
7856
|
+
params["to"] = to
|
|
7857
|
+
if subject:
|
|
7858
|
+
params["subject"] = subject
|
|
7859
|
+
if body:
|
|
7860
|
+
params["body"] = body
|
|
7861
|
+
if cc:
|
|
7862
|
+
params["cc"] = cc
|
|
7863
|
+
if bcc:
|
|
7864
|
+
params["bcc"] = bcc
|
|
7865
|
+
if message_id:
|
|
7866
|
+
params["message_id"] = message_id
|
|
7867
|
+
if q:
|
|
7868
|
+
params["q"] = q
|
|
7869
|
+
if max_results:
|
|
7870
|
+
params["max"] = int(max_results)
|
|
7871
|
+
|
|
7872
|
+
payload = {
|
|
7873
|
+
"agent_api_key": api_key,
|
|
7874
|
+
"project_id": _PROJECT_ID,
|
|
7875
|
+
"agent_name": AGENT_NAME,
|
|
7876
|
+
"action": act,
|
|
7877
|
+
"params": params,
|
|
7878
|
+
}
|
|
7879
|
+
|
|
7880
|
+
url = f"{be.SUPABASE_URL}/functions/v1/gmail-action"
|
|
7881
|
+
data = json.dumps(payload).encode("utf-8")
|
|
7882
|
+
req = _req.Request(url, data=data, method="POST", headers={
|
|
7883
|
+
"Content-Type": "application/json",
|
|
7884
|
+
"apikey": be.SUPABASE_KEY,
|
|
7885
|
+
"Authorization": f"Bearer {be.SUPABASE_KEY}",
|
|
7886
|
+
})
|
|
7887
|
+
try:
|
|
7888
|
+
with _req.urlopen(req, timeout=30) as resp:
|
|
7889
|
+
raw = resp.read().decode("utf-8")
|
|
7890
|
+
return json.loads(raw) if raw else {"ok": True}
|
|
7891
|
+
except _uerr.HTTPError as e:
|
|
7892
|
+
try:
|
|
7893
|
+
parsed = json.loads(e.read().decode("utf-8"))
|
|
7894
|
+
if isinstance(parsed, dict):
|
|
7895
|
+
return parsed
|
|
7896
|
+
except Exception:
|
|
7897
|
+
pass
|
|
7898
|
+
return {"ok": False, "error": f"HTTP {e.code}: {e.reason}",
|
|
7899
|
+
"error_code": "edge_http_error"}
|
|
7900
|
+
except Exception as e:
|
|
7901
|
+
return {"ok": False, "error": f"{type(e).__name__}: {e}",
|
|
7902
|
+
"error_code": "request_failed"}
|
|
7903
|
+
|
|
7904
|
+
|
|
7792
7905
|
def inbox_resource() -> str:
|
|
7793
7906
|
"""Current pending messages for this agent. Read-only — does NOT mark as read."""
|
|
7794
7907
|
pending = be.sb_select(
|
|
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
|
|
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
|