mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
fix(photon): add home channel env seed and simplify space resolution
This commit is contained in:
parent
0d25cae041
commit
3b983e7791
4 changed files with 1841 additions and 42 deletions
|
|
@ -133,11 +133,22 @@ def is_connected(cfg: PlatformConfig) -> bool:
|
|||
|
||||
|
||||
def _env_enablement() -> Optional[dict]:
|
||||
"""Seed PlatformConfig.extra from env so env-only setups appear in status."""
|
||||
"""Seed PlatformConfig.extra from env so env-only setups appear in status.
|
||||
|
||||
The special ``home_channel`` key is handled by the core plugin hook and
|
||||
becomes a proper ``HomeChannel`` on ``PlatformConfig``.
|
||||
"""
|
||||
project_id, project_secret = load_project_credentials()
|
||||
if not (project_id and project_secret):
|
||||
return None
|
||||
return {"project_id": project_id, "project_secret": project_secret}
|
||||
seed = {"project_id": project_id, "project_secret": project_secret}
|
||||
home = os.getenv("PHOTON_HOME_CHANNEL", "").strip()
|
||||
if home:
|
||||
seed["home_channel"] = {
|
||||
"chat_id": home,
|
||||
"name": os.getenv("PHOTON_HOME_CHANNEL_NAME", "Home"),
|
||||
}
|
||||
return seed
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -354,50 +354,26 @@ async function resolveSpace(spaceId) {
|
|||
if (phoneTarget && imessage) {
|
||||
try {
|
||||
const im = imessage(app);
|
||||
if (typeof im.user === "function" && typeof im.space === "function") {
|
||||
const user = await im.user(phoneTarget);
|
||||
const space = await im.space(user);
|
||||
rememberKnownSpace(spaceId, space);
|
||||
rememberKnownSpace(phoneTarget, space);
|
||||
rememberKnownSpace(space?.id, space);
|
||||
return space;
|
||||
}
|
||||
const user = await im.user(phoneTarget);
|
||||
const space = await im.space(user);
|
||||
rememberKnownSpace(spaceId, space);
|
||||
rememberKnownSpace(phoneTarget, space);
|
||||
rememberKnownSpace(space?.id, space);
|
||||
return space;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"photon-sidecar: phone->DM resolution failed; falling back to " +
|
||||
"id-based lookup: " +
|
||||
"photon-sidecar: phone->DM resolution failed: " +
|
||||
(e && e.stack ? e.stack : String(e))
|
||||
);
|
||||
}
|
||||
}
|
||||
// spectrum-ts exposes the same Space methods via `app.space(spaceId)` /
|
||||
// narrowed helpers; we fall back through a few accessor shapes to
|
||||
// tolerate small SDK API drift.
|
||||
if (typeof app.space === "function") {
|
||||
const space = await app.space(spaceId);
|
||||
rememberKnownSpace(spaceId, space);
|
||||
rememberKnownSpace(space?.id, space);
|
||||
return space;
|
||||
}
|
||||
if (app.spaces && typeof app.spaces.get === "function") {
|
||||
const space = await app.spaces.get(spaceId);
|
||||
rememberKnownSpace(spaceId, space);
|
||||
rememberKnownSpace(space?.id, space);
|
||||
return space;
|
||||
}
|
||||
if (imessage) {
|
||||
const im = imessage(app);
|
||||
if (typeof im.space === "function") {
|
||||
try {
|
||||
const space = await im.space({ id: spaceId });
|
||||
rememberKnownSpace(spaceId, space);
|
||||
rememberKnownSpace(space?.id, space);
|
||||
return space;
|
||||
} catch {
|
||||
/* fall through */
|
||||
}
|
||||
}
|
||||
}
|
||||
// No cache hit and not a phone/DM target. spectrum-ts exposes no API to
|
||||
// rehydrate an arbitrary opaque space id: a Space is only obtained from the
|
||||
// inbound `[space, message]` stream (cached above in `knownSpaces`) or
|
||||
// reconstructed for a DM from its phone number. So a group space whose cache
|
||||
// entry was lost — e.g. after a sidecar restart with no fresh inbound message
|
||||
// in that group — cannot be resolved here; a new inbound message in the group
|
||||
// re-warms the cache. DMs are unaffected (reconstructed from the phone).
|
||||
throw new Error(`unable to resolve space id ${spaceId}`);
|
||||
}
|
||||
|
||||
|
|
@ -430,7 +406,7 @@ const server = http.createServer(async (req, res) => {
|
|||
}
|
||||
const space = await resolveSpace(spaceId);
|
||||
const result = await space.send(spectrumText(text));
|
||||
return ok(res, { messageId: result?.id || result?.messageId || null });
|
||||
return ok(res, { messageId: result?.id || null });
|
||||
}
|
||||
if (req.url === "/send-attachment") {
|
||||
const { spaceId, path, name, mimeType, caption, kind } =
|
||||
|
|
@ -465,7 +441,7 @@ const server = http.createServer(async (req, res) => {
|
|||
);
|
||||
}
|
||||
}
|
||||
return ok(res, { messageId: result?.id || result?.messageId || null });
|
||||
return ok(res, { messageId: result?.id || null });
|
||||
}
|
||||
if (req.url === "/typing") {
|
||||
const { spaceId, state = "start" } = body || {};
|
||||
|
|
|
|||
1781
plugins/platforms/photon/sidecar/package-lock.json
generated
Normal file
1781
plugins/platforms/photon/sidecar/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,7 @@ from __future__ import annotations
|
|||
import pytest
|
||||
|
||||
from hermes_cli.config import get_env_value, save_env_value
|
||||
from plugins.platforms.photon.adapter import _env_enablement
|
||||
from plugins.platforms.photon import cli
|
||||
|
||||
|
||||
|
|
@ -36,3 +37,33 @@ def test_autoconfigure_access_preserves_existing_allowlist(
|
|||
assert get_env_value("PHOTON_ALLOWED_USERS") == "+19998887777,+15551112222"
|
||||
# The still-unset home channel is filled.
|
||||
assert get_env_value("PHOTON_HOME_CHANNEL") == "+15551234567"
|
||||
|
||||
|
||||
def test_env_enablement_seeds_home_channel(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("PHOTON_PROJECT_ID", "project_123")
|
||||
monkeypatch.setenv("PHOTON_PROJECT_SECRET", "secret_123")
|
||||
monkeypatch.setenv("PHOTON_HOME_CHANNEL", "+15551234567")
|
||||
monkeypatch.setenv("PHOTON_HOME_CHANNEL_NAME", "Primary DM")
|
||||
|
||||
seed = _env_enablement()
|
||||
|
||||
assert seed is not None
|
||||
assert seed["home_channel"] == {
|
||||
"chat_id": "+15551234567",
|
||||
"name": "Primary DM",
|
||||
}
|
||||
|
||||
|
||||
def test_env_enablement_home_channel_defaults_name(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("PHOTON_PROJECT_ID", "project_123")
|
||||
monkeypatch.setenv("PHOTON_PROJECT_SECRET", "secret_123")
|
||||
monkeypatch.setenv("PHOTON_HOME_CHANNEL", "+15551234567")
|
||||
monkeypatch.delenv("PHOTON_HOME_CHANNEL_NAME", raising=False)
|
||||
|
||||
seed = _env_enablement()
|
||||
|
||||
assert seed is not None
|
||||
assert seed["home_channel"] == {
|
||||
"chat_id": "+15551234567",
|
||||
"name": "Home",
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue