feat(photon): add telemetry toggle via hermes photon telemetry

This commit is contained in:
underthestars-zhy 2026-06-10 23:55:48 -07:00 committed by Teknium
parent c196269d8d
commit 0a963d8c9a
4 changed files with 55 additions and 0 deletions

View file

@ -116,6 +116,7 @@ All env vars are documented in `plugin.yaml`. The most important:
| `PHOTON_ALLOWED_USERS` | your number (set by setup) | Comma-separated E.164 allowlist |
| `PHOTON_REQUIRE_MENTION` | false | Gate group chats on a wake word |
| `PHOTON_MAX_INLINE_ATTACHMENT_BYTES` | 20 MB | Max inbound attachment size the sidecar reads & inlines |
| `PHOTON_TELEMETRY` | false | Spectrum SDK telemetry — toggle with `hermes photon telemetry on\|off` (restart the gateway to apply) |
## Attachments & limitations

View file

@ -7,6 +7,7 @@ Subcommands:
setup full first-time setup (device login + project + user + sidecar)
status show login + project + sidecar dep state
install-sidecar npm install inside plugins/platforms/photon/sidecar/
telemetry show or toggle Spectrum SDK telemetry (on/off)
The device-code login runs automatically as the first step of ``setup``;
there is no standalone ``login`` verb (matching how every other Hermes
@ -58,6 +59,15 @@ def register_cli(parser: argparse.ArgumentParser) -> None:
subs.add_parser("status", help="Show login + project + sidecar dep state")
subs.add_parser("install-sidecar", help="Run npm install inside the sidecar directory")
p_telemetry = subs.add_parser(
"telemetry",
help="Show or toggle Spectrum SDK telemetry (on/off)",
)
p_telemetry.add_argument(
"state", nargs="?", choices=("on", "off"),
help="Turn telemetry on or off (omit to show the current state)",
)
parser.set_defaults(func=dispatch)
@ -75,6 +85,8 @@ def dispatch(args: argparse.Namespace) -> int:
return _cmd_status(args)
if sub == "install-sidecar":
return _cmd_install_sidecar(args)
if sub == "telemetry":
return _cmd_telemetry(args)
print(f"unknown subcommand: {sub}", file=sys.stderr)
return 2
@ -303,6 +315,7 @@ def _cmd_status(_args: argparse.Namespace) -> int:
sidecar_installed = (_SIDECAR_DIR / "node_modules").exists()
print(f" node binary : {node_bin or '✗ missing (install Node 18+)'}")
print(f" sidecar deps : {'✓ installed' if sidecar_installed else '✗ run `hermes photon install-sidecar`'}")
print(f" telemetry : {'on' if _telemetry_enabled() else 'off'} (`hermes photon telemetry on|off`)")
return 0
@ -323,6 +336,37 @@ def _cmd_install_sidecar(_args: argparse.Namespace) -> int:
return _install_sidecar()
def _telemetry_enabled() -> bool:
"""Read PHOTON_TELEMETRY from the env / ~/.hermes/.env.
Mirrors the sidecar's truthy set (index.mjs) so the state shown here
always matches what the sidecar will actually do.
"""
try:
from hermes_cli.config import get_env_value
raw = get_env_value("PHOTON_TELEMETRY")
except ImportError:
raw = os.getenv("PHOTON_TELEMETRY")
return (raw or "").strip().lower() in ("1", "true", "yes", "on")
def _cmd_telemetry(args: argparse.Namespace) -> int:
state = getattr(args, "state", None)
if state is None:
print(f"Photon telemetry: {'on' if _telemetry_enabled() else 'off'}")
print(" Toggle with `hermes photon telemetry on` / `hermes photon telemetry off`.")
return 0
try:
from hermes_cli.config import save_env_value
save_env_value("PHOTON_TELEMETRY", "true" if state == "on" else "false")
except Exception as e:
print(f"could not save PHOTON_TELEMETRY: {e}", file=sys.stderr)
return 1
print(f"✓ Spectrum telemetry turned {state} (PHOTON_TELEMETRY in ~/.hermes/.env)")
print(" Restart the gateway for the sidecar to pick it up: hermes gateway restart")
return 0
def _install_sidecar() -> int:
npm = shutil.which("npm") or "npm"
if not shutil.which(npm):

View file

@ -74,3 +74,7 @@ optional_env:
description: "Human label for the home channel"
prompt: "Home channel display name"
password: false
- name: PHOTON_TELEMETRY
description: "Enable Spectrum SDK telemetry in the sidecar (true/false, default false; toggle with `hermes photon telemetry on|off`)"
prompt: "Enable Spectrum telemetry? (true/false)"
password: false

View file

@ -38,6 +38,8 @@
// PHOTON_SIDECAR_TOKEN
// Optional:
// PHOTON_SIDECAR_BIND (default 127.0.0.1)
// PHOTON_TELEMETRY enable Spectrum SDK telemetry ("true"/"1"/"on"/"yes";
// default off — toggle with `hermes photon telemetry`)
import http from "node:http";
import crypto from "node:crypto";
@ -48,6 +50,9 @@ const projectSecret = process.env.PHOTON_PROJECT_SECRET;
const port = parseInt(process.env.PHOTON_SIDECAR_PORT || "8789", 10);
const bind = process.env.PHOTON_SIDECAR_BIND || "127.0.0.1";
const sharedToken = process.env.PHOTON_SIDECAR_TOKEN;
const telemetry = /^(1|true|yes|on)$/i.test(
(process.env.PHOTON_TELEMETRY || "").trim()
);
// Inbound binary content is read into memory and base64-inlined on the NDJSON
// event so the Python adapter can cache the real bytes (and the agent can see
@ -94,6 +99,7 @@ const app = await Spectrum({
projectSecret,
providers: [imessage.config()],
options: { flattenGroups: true },
telemetry,
});
// ---------------------------------------------------------------------------