Skip to content

feat(photon): upgrade sidecar to spectrum-ts v8 and correlate tapbacks to bot messages - #53333

Closed
underthestars-zhy wants to merge 3 commits into
NousResearch:mainfrom
photon-hq:ryan/photon-fix
Closed

feat(photon): upgrade sidecar to spectrum-ts v8 and correlate tapbacks to bot messages#53333
underthestars-zhy wants to merge 3 commits into
NousResearch:mainfrom
photon-hq:ryan/photon-fix

Conversation

@underthestars-zhy

Copy link
Copy Markdown
Contributor

What does this PR do?

Two related changes to the Photon (iMessage) platform plugin — its Node.js sidecar and Python adapter.

1. Upgrade the spectrum-ts SDK 3.1.0 → 8.0.0. The SDK ships breaking majors, so it's pinned exactly and migrated deliberately (never @latest):

  • v5 split the monolithic SDK into scoped @spectrum-ts/* packages, with spectrum-ts as an umbrella re-export. The mixed-attachments postinstall patch now targets @spectrum-ts/imessage/dist/index.js (tab-indented output to match the new build).
  • v8 made richlink outbound-only — inbound rich links now arrive as plain text — so the getBalloonBundleId / toRichlinkMessage branches were removed from the iMessage mapper patch.

2. Correlate tapbacks to the message they reacted to. Previously the agent received reaction:added:❤️ with no idea what was tapped back. Now:

  • The sidecar extracts a capped (≤2000 char) text preview from the already-hydrated reaction target (plain text + our patched mixed text/attachment groups; null for attachment/voice-only targets) and emits it as targetText in the NDJSON reaction payload — no extra round trip.
  • The adapter sets reply_to_message_id, reply_to_text, and reply_to_is_own_message on the MessageEvent, so the gateway injects [Replying to your previous message: "…"] when the agent receives a tapback on one of its own messages.

Related Issue

N/A — no linked issue.

Type of Change

  • ✨ New feature (non-breaking change that adds functionality) — tapback reply-context correlation
  • ♻️ Refactor / dependency upgrade — spectrum-ts 3.x → 8.x (deliberate pinned SDK migration)

Changes Made

Tapback correlation

  • plugins/platforms/photon/sidecar/index.mjs — add reactionTargetText() (capped preview of the hydrated reaction target) and emit targetText from normalizeContent().
  • plugins/platforms/photon/adapter.py — populate reply_to_message_id / reply_to_text / reply_to_is_own_message on reaction MessageEvents; document targetText in the payload contract.
  • tests/plugins/platforms/photon/test_reactions.py — new tests covering the reply-correlation fields.

spectrum-ts v7 → v8 upgrade

  • plugins/platforms/photon/sidecar/package.json / package-lock.json — bump exact pin to 8.0.0.
  • plugins/platforms/photon/sidecar/patch-spectrum-mixed-attachments.mjs — retarget the postinstall patch at @spectrum-ts/imessage/dist/index.js; drop the richlink mapper branches (v8 made it outbound-only).
  • plugins/platforms/photon/sidecar/index.mjs / cli.py — update version references/comments (3.x → 8.x; note the v5 package split).
  • plugins/platforms/photon/README.md — document the v5 package split, the v8 richlink change, and the postinstall patch-validation step.
  • tests/plugins/platforms/photon/test_spectrum_patch.py — rewrite fixtures to the v7/v8 mapper shape and new @spectrum-ts/imessage module path.

How to Test

  1. pytest tests/plugins/platforms/photon/ -q108 passed (includes the new reaction tests and the rewritten spectrum-patch fixtures).
  2. Reinstall the sidecar (npm ci in plugins/platforms/photon/sidecar/) and confirm the postinstall patch applies cleanly against @spectrum-ts/imessage@8.0.0.
  3. From a phone, send a tapback (e.g. ❤️) on a message the bot sent → the agent's next turn shows [Replying to your previous message: "<original text>"].

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/plugins/platforms/photon/ -q (the affected suite) and all 108 tests pass
  • I've added tests for my changes
  • I've tested on my platform: macOS (Darwin 27)

Documentation & Housekeeping

  • I've updated relevant documentation (photon README.md, sidecar/adapter docstrings)
  • N/A — no config keys added/changed (cli-config.yaml.example)
  • N/A — no architecture/workflow changes
  • I've considered cross-platform impact — the Photon sidecar is macOS-only (iMessage); no Windows surface
  • N/A — no agent tool descriptions/schemas changed

Screenshots / Logs

$ pytest tests/plugins/platforms/photon/ -q
........................................................................ [ 66%]
....................................                                     [100%]
108 passed in 16.77s

Update the Photon platform plugin's Node.js sidecar from spectrum-ts
3.1.0 to 7.0.0, which splits the SDK into scoped `@spectrum-ts/*`
packages with `spectrum-ts` as the umbrella re-export.

- Bump exact pin in package.json/package-lock.json to 7.0.0
- Update mixed-attachments patch script to target the new
  `@spectrum-ts/imessage/dist/index.js` path and tab-indented output
- Rewrite test fixture to match v7.x mapper shape (tab-indented,
  `const ... = async` declarations, single-line builder calls) and
  point at `@spectrum-ts/imessage/dist/index.js`
- Update README upgrade guide to document the v5 package split and
  the postinstall patch validation step
- Update comments in cli.py and index.mjs to reference v5/v7 changes
v8 made `richlink` outbound-only; inbound rich links now arrive as
plain `text`. Remove the `getBalloonBundleId`/`toRichlinkMessage`
branches from the iMessage mapper patch and update the fixture,
lockfile, and README accordingly.
Populate `reply_to_message_id`, `reply_to_text`, and
`reply_to_is_own_message` on reaction events so the gateway injects
`[Replying to your previous message: "..."]` when the agent receives
a tapback.

The sidecar now extracts a capped text preview from the hydrated
reaction target (plain text and mixed group messages; null for
attachment/voice-only targets), emitting it as `targetText` in the
NDJSON reaction payload. The Python adapter reads this field and sets
the reply correlation fields on the `MessageEvent`.
@underthestars-zhy
underthestars-zhy requested a review from a team June 26, 2026 23:51
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins labels Jun 27, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #53451. Your three commits were cherry-picked onto current main with your authorship preserved in git log (5636c22, 4345b3e, 8827300). Thanks for the clean SDK migration + tapback correlation work!

@teknium1 teknium1 closed this Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants