feat(photon): upgrade sidecar to spectrum-ts v8 and correlate tapbacks (salvage #53333) - #53451
Conversation
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`.
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:3002: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
✅ Fixed issues (1):
| Rule | Count |
|---|---|
invalid-assignment |
1 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`
Unchanged: 6031 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Thorough upgrade of the Photon sidecar to spectrum-ts v8. The test rewrite is extensive but well-structured — the _tabify helper converts fixture indentation to match real spectrum-ts output, and the _SPECTRUM_IMESSAGE_FIXTURE provides a faithful executable slice of the upstream code. Runtime assertion tests verify both rebuild and inbound mapper behavior.
Looks Good:
- Tab-indented fixtures match real
@spectrum-ts/imessage/distoutput - Idempotency test confirms the patcher can run multiple times safely
- Runtime test covers single-attachment, multi-attachment, text-only, and no-text cases
- Clear fixture structure mirrors the published code shape
Reviewed by Hermes Agent
Summary
Restores the Photon (iMessage) sidecar on the current
spectrum-tsSDK (3.1.0 → 8.0.0) and makes tapbacks carry the text of the message they reacted to, so the agent knows what was tapped back instead of a barereaction:added:❤️.Salvage of #53333 by @underthestars-zhy — cherry-picked onto current
mainwith authorship preserved.Changes
sidecar/package.json/package-lock.json: bump exact pin tospectrum-ts@8.0.0.sidecar/patch-spectrum-mixed-attachments.mjs: retarget the postinstall patch at@spectrum-ts/imessage/dist/index.js(v5 package split); drop therichlinkmapper branches (v8 made richlink outbound-only — inbound rich links now arrive as plaintext).sidecar/index.mjs: addreactionTargetText()(capped ≤2000-char preview of the already-hydrated reaction target) and emittargetTextin the reaction NDJSON payload — no extra round trip.adapter.py: populatereply_to_message_id/reply_to_text/reply_to_is_own_messageon reactionMessageEvents, reusing the gateway's existing[Replying to your previous message: "…"]injection.README.md/cli.py: document the v5 package split, the v8 richlink change, and the postinstall patch-validation step.Plugin-only — touches
plugins/platforms/photon/and its tests. Zero core surface.Validation
pytest tests/plugins/platforms/photon/on current mainis_oursguard →reply_to_is_own_message=TrueInfographic