Skip to content

apps/cli: Route studio_mobile_* bot replies to studio-mobile-client endpoint (PoC)#3493

Open
gcsecsey wants to merge 4 commits into
trunkfrom
gcsecsey/cli-mobile-respond-routing
Open

apps/cli: Route studio_mobile_* bot replies to studio-mobile-client endpoint (PoC)#3493
gcsecsey wants to merge 4 commits into
trunkfrom
gcsecsey/cli-mobile-respond-routing

Conversation

@gcsecsey
Copy link
Copy Markdown
Member

@gcsecsey gcsecsey commented May 14, 2026

Related issues

How AI was used in this PR

Used Claude Code to implement the flow described in the SPEC. Reviewed the diff manually, and tested end-to-end against a local daemon talking to mobile app through wpcom.

Proposed Changes

The Studio CLI's remote-session loop currently posts every reply to /wpcom/v2/telegram-bot/local-agent-respond regardless of which client originated the message. That endpoint only knows how to forward to Telegram, so replies destined for the studio-mobile PoC client (polled with bot: "studio_mobile_<machine_id>") get rejected with rest_missing_callback_param. The wpcom side now exposes a parallel /wpcom/v2/studio-mobile-client/respond endpoint that accepts an agent_message envelope; this PR teaches the CLI to use it.

  • Forks the outbound URL in respondMessage(): when the effective bot starts with studio_mobile_, hit /wpcom/v2/studio-mobile-client/respond (derived by swapping the trailing telegram-bot segment in base_url so dev hosts still resolve). Other bots keep using /local-agent-respond unchanged.
  • Forks the body builder. Mobile path sends { chat_id, bot, machine_id, envelope: { type: "agent_message", id, text } }. chat_id and bot are the queue routing keys today; machine_id is forward-compat for when wpcom switches the queue key in Phase 2 of the SPEC; envelope.text is what the server reads instead of the old top-level text field. Telegram path is unchanged.
  • Photos are out of scope for the studio-mobile v1 surface, so when a media.share event lands on a studio_mobile_* bot the photo bytes are dropped and the caption (or a placeholder) is promoted to the envelope text, with a warning logged. Telegram still gets the multipart sendPhoto path.

Testing Instructions

  • Follow the testing steps on 217387-ghe-Automattic/wpcom
  • Pull this branch and rebuild the CLI: npm run cli:build.
  • Apply the env var to enable remote sessions: export STUDIO_ENABLE_REMOTE_SESSION=true
  • Stop any running remote-session daemon: node apps/cli/dist/cli/main.mjs code remote-session stop.
  • Start a fresh daemon: node apps/cli/dist/cli/main.mjs code remote-session start.
  • Send a message from your Telegram bot to verify the existing path is unchanged. The reply should land in Telegram and ~/.studio/remote-session.log should show a successful Posting reply followed by no Respond 4xx.
  • Send a message from the studio-mobile PoC client (which polls with a studio_mobile_* bot suffix). The reply should land in the mobile app, and the log should again show a successful Posting reply with no 4xx.
  • Optional: run npm test -- apps/cli/remote-session to exercise the unit tests covering the routing and body shape.
Scenario Log tail Reply visible in client
Telegram bot reply (regression) CleanShot 2026-05-14 at 15 30 35@2x CleanShot 2026-05-14 at 15 29 56@2x
studio_mobile_* bot reply (new path) CleanShot 2026-05-14 at 15 35 13@2x CleanShot 2026-05-14 at 15 35 26@2x

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

…ndpoint

When the polled message comes from a bot whose name starts with
studio_mobile_, the remote-session controller now POSTs the reply to
/wpcom/v2/studio-mobile-client/respond with an agent_message envelope
alongside the existing chat_id and bot routing keys. Other bots keep
hitting /local-agent-respond unchanged.
@gcsecsey gcsecsey requested a review from epeicher May 14, 2026 14:25
@gcsecsey gcsecsey changed the title apps/cli: Route studio_mobile_* bot replies to studio-mobile-client endpoint apps/cli: Route studio_mobile_* bot replies to studio-mobile-client endpoint (PoC) May 14, 2026
@gcsecsey gcsecsey marked this pull request as ready for review May 14, 2026 14:36
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented May 14, 2026

📊 Performance Test Results

Comparing 98dee4c vs trunk

app-size

Metric trunk 98dee4c Diff Change
App Size (Mac) 1354.53 MB 1428.77 MB +74.24 MB 🔴 5.5%

site-editor

Metric trunk 98dee4c Diff Change
load 1502 ms 1497 ms 5 ms ⚪ 0.0%

site-startup

Metric trunk 98dee4c Diff Change
siteCreation 8586 ms 8579 ms 7 ms ⚪ 0.0%
siteStartup 4934 ms 4927 ms 7 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

gcsecsey added 2 commits May 19, 2026 15:51
…ing fork

Move machine_id into the remote-session config schema with a sanitized
os.hostname() default and a STUDIO_REMOTE_MACHINE_ID env override. Removes
the MobileTarget struct, the empty-suffix throw in the NDJSON reader path,
and the silent base_url misroute when /telegram-bot is missing.
…pond router

The mobile and Telegram message shapes were both living inside telegram-client.ts
alongside the dispatch logic, which made the file the de-facto home for the
entire wire protocol. Move the studio-mobile shape into its own
studio-mobile-client.ts, the Telegram-only code stays in telegram-client.ts,
and introduce respond-router.ts as the dispatcher (fork + retry loop). Shared
HTTP primitives (errors, URL helpers, backoff) move to remote-http.ts; the
Telegram-flavored error class names become Remote*Error to reflect that they're
transport-layer concerns shared by both clients.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants