Repository navigation
New file upload example - #237
mattieruth wants to merge 10 commits into
Conversation
517490a to
362e8f3
Compare
| conversation context. The LLM can then reason about the uploaded content and | ||
| respond with audio as it would for any other user turn. | ||
|
|
||
| Concepts this example is meant to demonstrate: |
| 4. **Run the bot**: | ||
|
|
||
| ```bash | ||
| uv run bot.py -u /tmp/uploads |
There was a problem hiding this comment.
Worth having a default temp location if one is not specified? Simplifies usage.
There was a problem hiding this comment.
you don't think that's a privacy/security issue? the runner will use this location to store and delete files. It felt a little presumptive to me to make a default.
There was a problem hiding this comment.
I meant just for this example, which exists only to show file uploading. Not proposing baking anything into the runner itself.
| # Edit .env.local if needed (defaults to localhost:7860) | ||
| ``` | ||
|
|
||
| > **Note:** Environment variables in Vite are bundled into the client and exposed in the browser. For production applications that require secret protection, consider implementing a backend proxy server to handle API requests and manage sensitive credentials securely. |
| user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()), | ||
| ) | ||
|
|
||
| rtvi = RTVIProcessor(uploads_folder=runner_args.cli_args.uploads_folder) |
There was a problem hiding this comment.
This is the only configuration needed on the bot server side? That's pretty sweet.
There was a problem hiding this comment.
correct. and even then it's only needed if you are supporting an endpoint for the client to upload files to. As @vipyne points out in her PR, PipecatCloud does not have an endpoint for this as of yet, so in that case, uploads_folder should be None and the client will only be able to upload either small files that can be sent wholesale over the transport message channel or urls.
There was a problem hiding this comment.
Since we have this (hopefully temporary) limitation today, we ought to mention it in the README, which presents Pipecat Cloud as a deployment option.
There was a problem hiding this comment.
i believe it is already 🤔
|
|
||
| This bot uses a cascade pipeline: Speech-to-Text → LLM → Text-to-Speech | ||
|
|
||
| Generated by Pipecat CLI |
There was a problem hiding this comment.
So there's also some new CLI affordances coming for configuring a bot to accept file uploads?
There was a problem hiding this comment.
i don't have any cli changes planned but maybe i should? When I started this example, I generated it using the CLI which adds this line (and 98% of the lines in this file). Maybe I should remove this comment?
There was a problem hiding this comment.
but maybe i should?
I'd have to refresh myself on the existing CLI options to see if something like "accept file uploads" would fit in...without going through them, I have no preference.
this line
I wonder if, if the intent of the CLI is to provide a starting point or scaffold that the user will then build on top of, this line should instead read "Bootstrapped by Pipecat CLI" or something. "Generated by" might lead the reader to believe this file is "managed" by a tool and shouldn't be edited. This is obviously an issue outside the scope of this PR. WDYT, @markbackman?
| * This file is auto-generated by pipecat-cli | ||
| */ | ||
|
|
||
| export const AVAILABLE_TRANSPORTS = [ |
There was a problem hiding this comment.
Should we add the websocket here ?
| "@pipecat-ai/client-js": "file:../../../pipecat-client-web/client-js", | ||
| "@pipecat-ai/daily-transport": "file:../../../pipecat-client-web-transports/transports/daily", | ||
| "@pipecat-ai/small-webrtc-transport": "file:../../../pipecat-client-web-transports/transports/small-webrtc-transport" |
There was a problem hiding this comment.
TODO: Remember to fix this before merging. 🙂
| option.textContent = 'SmallWebRTC'; | ||
| } else if (transport === 'daily') { | ||
| option.textContent = 'Daily'; | ||
| } else if (transport === 'websocket') { |
There was a problem hiding this comment.
Here we're mentioning websocket, but we don't have it in either the dependencies or AVAILABLE_TRANSPORTS. I think we just need to decide whether we want to support it or remove it.
There was a problem hiding this comment.
oh, i don't think i meant to support it. though, i should test that...
There was a problem hiding this comment.
actually. i went ahead and added support :)
| [tool.uv.sources] | ||
| pipecat-ai = { path = "/Users/mattieruth/src/pipecat/pipecat", editable=true } No newline at end of file |
There was a problem hiding this comment.
TODO: Remember to fix this before merging. 🙂
There was a problem hiding this comment.
I don't think any of the other examples have this. Are we planning to keep it?
There was a problem hiding this comment.
i can remove it. like i said, I generated this example using the CLI and so some of the stuff was just basic scaffolding. though, in chatting with @markbackman, it seemed like maybe i should leave it? i have no preference/opinion.
There was a problem hiding this comment.
Same here. I don't think any of the other examples have this. Are we planning to keep it?
| ) | ||
|
|
||
| # cli_args is only populated when running via the development runner (not on | ||
| # Pipecat Cloud, where there is no uploads endpoint and large-file upload is |
There was a problem hiding this comment.
Wait, so small-file upload is available even when uploads_folder is None?
There was a problem hiding this comment.
yes because those can fit in a basic message.
96435ea to
437f734
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| def create_file_storage() -> FileStorage: | ||
| """Storage backend for client uploads, discovered by the host alongside ``bot()``. | ||
|
|
||
| The host calls this at startup, serves its upload endpoint from the | ||
| returned backend, and injects it into the bot as | ||
| ``runner_args.file_storage``. | ||
| """ | ||
| return S3FileStorage(bucket=os.environ["S3_UPLOADS_BUCKET"], region=os.getenv("AWS_REGION")) |
New example showing how clients can upload local files or reference URLs as visual context during a voice conversation. Uses RTVIProcessor with uploads_folder on the server and client.sendFile via the RTVI protocol.
…/../../pipecat with a "remove before merge" TODO comment. - bot.py: guards cli_args/uploads_folder access so it won't crash on Pipecat Cloud. - app.js: URL format parsing uses new URL().pathname (handles query strings, rejects invalid URLs), the .catch().then() chains are reordered so success messages don't render after failures, and bot text is HTML-escaped before the innerHTML insertions. - README.md: added a note about Pipecat Cloud caveat that large-file upload needs a production /files endpoint.
7958504 to
284785a
Compare
The GCS/S3 variants now define create_file_storage() alongside bot() instead of calling set_runner_file_storage() (removed from pipecat): the host discovers the factory, backs its upload endpoint with the returned storage, and injects it into the bot as runner_args.file_storage, which bot.py hands to its FileResolver.
284785a to
6a7d477
Compare
| "@pipecat-ai/client-js": "file:../../../clients/web/client/client-js", | ||
| "@pipecat-ai/daily-transport": "file:../../../clients/web/transports/transports/daily", | ||
| "@pipecat-ai/livekit-transport": "file:../../../clients/web/transports/transports/livekit-transport", | ||
| "@pipecat-ai/small-webrtc-transport": "file:../../../clients/web/transports/transports/small-webrtc-transport/pipecat-ai-small-webrtc-transport-1.10.7.tgz", | ||
| "@pipecat-ai/websocket-transport": "file:../../../clients/web/transports/transports/websocket-transport" |
There was a problem hiding this comment.
We need to fix the dependencies here. 🙂
There was a problem hiding this comment.
Just saw that we still need to release all of them.
| description = "Voice AI bot built with Pipecat" | ||
| requires-python = ">=3.11" | ||
| dependencies = [ | ||
| "pipecat-ai[anthropic,aws,cartesia,daily,deepgram,google,livekit,openai,runner,silero,websocket,webrtc]>=1.4.0", |
There was a problem hiding this comment.
We also need to update to the latest version of Pipecat, which includes file upload support.
| # TODO: remove before merge — local override for testing against the sibling | ||
| # pipecat checkout (pipecat-ai/pipecat PR #3415) until the feature is released. | ||
| [tool.uv.sources] | ||
| pipecat-ai = { path = "../../../pipecat", editable=true } No newline at end of file |
There was a problem hiding this comment.
And implement this TODO. 😅
There was a problem hiding this comment.
yes. all of these I expect to do once the releases are actually available to link against.
|
Hi @mattieruth, I tried uploading a However, I can see the following errors in Pipecat: I believe this is the missing piece we discussed yesterday. Just sharing it here in case it’s worth addressing in the example. |
filipi87
left a comment
There was a problem hiding this comment.
Works great! I left just a couple of comments about remembering to update the libraries once we release, and whether we can improve error handling in case we push a failed or disallowed frame.
Other than that, it looks great. I've already approved it. 🚀
hmm. this looks expected to me. Anthropic is not accepting the file type you provided. What were you thinking should happen that didn't? |
I was thinking that it would be nice to reflect in the interface when an error occurs and we are not actually using the file. For example, we might not have added the file to the context in the first place, or we might have removed it from the context because of an error. In either case, it would be nice to send a specific message to RTVI so that the interface can indicate that the file we thought had been uploaded successfully was actually not accepted. But, this will probably require some changes to Pipecat as well. So, don't block this PR because of this. 🙂 |
No description provided.