Skip to content

Migrate bot-ready-signalling example to Pipecat client SDK - #209

Open
jamsea wants to merge 9 commits into
mainfrom
migrate-bot-ready-signalling-to-pipecat-client-js
Open

Migrate bot-ready-signalling example to Pipecat client SDK#209
jamsea wants to merge 9 commits into
mainfrom
migrate-bot-ready-signalling-to-pipecat-client-js

Conversation

@jamsea

@jamsea jamsea commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the raw @daily-co/daily-js plumbing in the bot-ready-signalling example with the Pipecat client SDK, and rewire the bot to use the standard RTVI client-ready / bot-ready handshake instead of the custom sendAppMessage("playable") workaround.

RTVIProcessor is auto-attached to every PipelineTask, the JS/RN client SDKs signal client-ready automatically once the transport reaches the ready state, and the bot pushes its first TTSSpeakFrame from @task.rtvi.event_handler("on_client_ready"). The current example predates these defaults and was misleading new users.

What changed

Server

  • server/server.py: /connect now returns {url, token} (the shape DailyTransport.connect() expects).
  • server/signalling_bot.py: drop SilenceFrame workaround and on_app_message("playable") listener. Add transport.input() and audio_in_enabled=True so RTVI sees client messages. Queue the greeting from on_client_ready.

JS client (client/javascript/)

  • Swap @daily-co/daily-js for @pipecat-ai/client-js + @pipecat-ai/daily-transport.
  • src/app.js: rewrite around PipecatClient + DailyTransport. Use startBotAndConnect({ endpoint: '/connect' }). Render bot audio via the onTrackStarted callback.
  • index.html: drop the static <audio> element.

RN client (client/react-native/)

  • Swap @daily-co/react-native-daily-js (direct import) and @config-plugins/react-native-webrtc for @pipecat-ai/client-js + @pipecat-ai/react-native-daily-transport.
  • Bump Expo ^52~54.0.21 and RN 0.760.81.5 to satisfy the transport's @daily-co/react-native-webrtc@^124 peer dep. Matches the canonical pipecat-examples/simple-chatbot setup.
  • src/App.js: rewrite around PipecatClient + RNDailyTransport. Same UI shape (status bar, button, debug log).

Docs

  • Top-level + JS + RN READMEs describe the RTVI handshake and drop playable references.

Test plan

  • cd server && uv sync && cp env.example .env, fill DAILY_API_KEY + CARTESIA_API_KEY, then uv run server.py.
  • JS client: cd client/javascript && npm install && npm run dev. Visit http://localhost:5173, click Connect. Confirm transport state lands on ready, the full greeting plays with no clipping, the bot-ready log fires before audio, and Disconnect cleans up.
  • RN client: cd client/react-native && nvm i && npm install && npx expo prebuild --clean. Set API_BASE_URL in .env, then npm run ios (or npm run android). Tap Connect and run the same checks.

🤖 Generated with Claude Code

jamsea and others added 4 commits May 5, 2026 14:57
Replace raw @daily-co/daily-js plumbing with @pipecat-ai/client-js plus
@pipecat-ai/daily-transport (web) and @pipecat-ai/react-native-daily-transport
(RN). The custom sendAppMessage("playable") workaround is removed in favour of
the standard RTVI client-ready / bot-ready handshake: RTVIProcessor is
auto-attached to PipelineTask, and the bot pushes the first TTSSpeakFrame from
@task.rtvi.event_handler("on_client_ready").

- Server: /connect now returns {url, token} (the shape DailyTransport expects).
  signalling_bot.py drops the SilenceFrame workaround and on_app_message
  handler, adds transport.input(), and queues the greeting from on_client_ready.
- JS client: rewritten around PipecatClient + DailyTransport with
  startBotAndConnect; bot audio is rendered via the onTrackStarted callback.
- RN client: rewritten around PipecatClient + RNDailyTransport. Expo bumped
  from 52 to 54 and RN to 0.81 to satisfy the transport's webrtc peer dep
  (matches pipecat-examples/simple-chatbot).
- READMEs updated to describe the RTVI handshake.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add early-return in `connect()` so a second click while a client already
  exists does not orphan the previous PipecatClient and its listeners.
- Align `@pipecat-ai/client-js` and `@pipecat-ai/daily-transport` to ^1.6.0
  to match the React Native client.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…to ^1.6.1

Aligns both clients on the same client-js major and picks up the latest
daily-transport patch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pipecat-ai/daily-transport@1.6.1 requires @pipecat-ai/client-js@~1.7.0.
The previous bump to ^1.8.0 broke npm install with ERESOLVE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jamsea
jamsea requested a review from Copilot May 5, 2026 07:11
@jamsea
jamsea requested a review from filipi87 May 5, 2026 07:13
@jamsea

jamsea commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

@filipi87 could you run a sanity test for the react native client? I haven't ran react native in a long time so all my dependencies are out of date 🙏

@jamsea
jamsea marked this pull request as ready for review May 5, 2026 07:14
@jamsea
jamsea requested a review from markbackman May 5, 2026 07:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the bot-ready-signalling example by migrating both web and React Native clients from direct @daily-co/* usage to the Pipecat client SDK + Daily transports, and by switching the example to the standard RTVI client-ready / bot-ready handshake to avoid clipped initial TTS audio.

Changes:

  • Server: /connect response shape updated to {url, token} and bot updated to trigger greeting from on_client_ready.
  • Web client: rewritten around PipecatClient + DailyTransport, rendering bot audio via onTrackStarted.
  • RN client + docs: rewritten around PipecatClient + RNDailyTransport, with READMEs updated to describe the RTVI handshake.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
bot-ready-signalling/server/signalling_bot.py Rewires bot to RTVI on_client_ready, adds transport input stage and enables audio-in.
bot-ready-signalling/server/server.py Updates /connect return payload to {url, token} for Pipecat client SDK.
bot-ready-signalling/README.md Documents the standard RTVI handshake and removes playable workaround mention.
bot-ready-signalling/client/javascript/src/app.js Migrates browser client to PipecatClient + DailyTransport and plays audio via onTrackStarted.
bot-ready-signalling/client/javascript/index.html Removes static <audio> element (now created dynamically).
bot-ready-signalling/client/javascript/README.md Updates docs for Pipecat SDK + Daily transport and handshake explanation.
bot-ready-signalling/client/javascript/package.json Replaces @daily-co/daily-js dependency with Pipecat SDK + Daily transport.
bot-ready-signalling/client/javascript/package-lock.json Locks Pipecat SDK + Daily transport dependencies (brings in newer @daily-co/daily-js).
bot-ready-signalling/client/react-native/src/App.js Migrates RN client to PipecatClient + RNDailyTransport with updated callbacks/logging.
bot-ready-signalling/client/react-native/README.md Updates docs to explain RTVI bot-ready handshake.
bot-ready-signalling/client/react-native/package.json Updates Expo/RN versions and swaps dependencies to Pipecat SDK + RN Daily transport.
bot-ready-signalling/client/react-native/app.json Updates Expo config (plugins and new architecture flag).
Files not reviewed (1)
  • bot-ready-signalling/client/javascript/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bot-ready-signalling/server/signalling_bot.py Outdated
Comment thread bot-ready-signalling/client/javascript/src/app.js
Comment thread bot-ready-signalling/client/javascript/src/app.js
Comment thread bot-ready-signalling/client/react-native/src/App.js
Comment thread bot-ready-signalling/client/javascript/package-lock.json
Comment thread bot-ready-signalling/client/react-native/package.json Outdated
- server: thread the meeting token from server.py through runner.configure
  into DailyTransport, instead of generating a second token in the bot and
  discarding it
- js client: clear pcClient (and window.pcClient) on failed connect and on
  onDisconnected so reconnect works without a page reload
- js client: document Node 22 requirement in README and add .nvmrc
- rn client: clear clientRef.current on onDisconnected so remote disconnects
  don't wedge the Connect button
- rn client: replace Yarn-only "resolutions" with npm "overrides" for the
  @daily-co/react-native-webrtc/debug pin

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • bot-ready-signalling/client/javascript/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bot-ready-signalling/client/javascript/README.md Outdated
Comment thread bot-ready-signalling/client/javascript/.nvmrc Outdated
Comment thread bot-ready-signalling/client/javascript/src/app.js Outdated
Comment thread bot-ready-signalling/client/react-native/package.json
- .nvmrc: pin to 22.14.0 (the actual minimum @daily-co/daily-js requires)
  rather than the major version, so `nvm use` selects a compatible runtime
- README: tighten Node requirement text from "Node 22+" to ">=22.14.0"
- js client: extract a useful string from onError messages (data.message,
  string data, or JSON.stringify) so users don't see "[object Object]"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread bot-ready-signalling/server/server.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we could remove server.py and runner.py and just rely on the runner provided by Pipecat. In that case, we’d need to update signalling_bot.py to use it, like in other Pipecat examples. What do you think?

await callObject.join({ url: roomInfo.room_url });
log('Connecting to bot...');
await client.startBotAndConnect({
endpoint: `${API_BASE_URL}/connect`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the runner provided by Pipecat, this should be /start instead of /connect.

});

this.log('Connection complete');
await this.pcClient.startBotAndConnect({ endpoint: '/connect' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:
If we use the runner provided by Pipecat, this should be /start instead of /connect.

@filipi87

filipi87 commented May 5, 2026

Copy link
Copy Markdown
Contributor

@jamsea, We should probably update env.example and the README as well. What we previously referred to as DAILY_SAMPLE_ROOM_URL is now just DAILY_ROOM_URL.

@filipi87 filipi87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I’ve pushed a fix for both RN and the environment variable name to use DAILY_ROOM_URL.

The only thing missing is refactoring to use the runner provided by Pipecat, but feel free to do that in a follow-up PR.

🚀

Replace the hand-rolled server.py + runner.py with `pipecat.runner.run`,
matching the canonical pattern in travel-companion / daily-custom-tracks.
Server is now started via `uv run bot.py -t daily` and exposes the standard
`/start` endpoint (Pipecat Cloud compatible).

JS and RN clients call `/start` with `{createDailyRoom: true}`. The Vite dev
proxy is updated from `/connect` to `/start`. Smoke-tested locally: POST
/start returns {dailyRoom, dailyToken, sessionId} and the bot joins.

Addresses filipi87's review on PR #209.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants