Put Bash inside your app
Your user talks to Bash without leaving your app. Your server opens a session for them, and your page shows it.
Open a session
On your server, for the user signed in to your app. Its token lasts 15 minutes and reaches only that user (embed).
What happens Bash answers with a url for this user, and session.started reaches your webhooks.
// On your server, for the user signed in to your app.const session = await vestra.user('traveller-42').embed(); // Hand session.url to your page, for its iframe.console.log(session.url, session.expires_at);# On your server, for the user signed in to your app.session = vestra.user("traveller-42").embed() # Hand session.url to your page, for its iframe.print(session.url, session.expires_at)# A preview of what your user sees. In your app, your server opens one per visit.vestra embed --user traveller-42# On your server, for the user signed in to your app.curl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "chat": true, "screen": "view", "voice": true }'{ "method": "tools/call", "params": { "name": "embed", "arguments": { "user": "traveller-42" } }}Show it in your page
Put the url in an iframe with allow="microphone", so voice works. Name the pages that may frame it in allowed_embed_origins, with PATCH /v1/org.
What happens Your user chats, approves in place and watches Bash work, with no Vestra sign-in.
<!-- In your page: the url your server opened for this user. --><iframe src="{{ session.url }}" allow="microphone" title="Travel help" style="width: 100%; height: 640px; border: 0"></iframe>Or show just its screen
For the screen alone, in a tab or a support console, opened in the user's conversation. With control, a person can take the wheel and give it back (watch).
What happens The page shows Bash's computer, live, and screen.control on the conversation's stream says who is driving.
// Its screen alone, in the user's conversation.// With control, a person may take the wheel.const traveller = vestra.user('traveller-42');const screen = await traveller.watch({ conversation: 'conv_8f2k', control: true,});console.log(screen.url);# Its screen alone, in the user's conversation.# With control, a person may take the wheel.screen = vestra.user("traveller-42").watch( conversation="conv_8f2k", control=True)print(screen.url)# Its screen alone, in the user's conversation. With --control, whoever opens it may take the wheel.vestra watch --user traveller-42 --conversation conv_8f2k --control# Its screen alone, in the user's conversation. With "control", a person may take the wheel.curl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "screen": "control" }'{ "method": "tools/call", "params": { "name": "watch", "arguments": { "user": "traveller-42", "conversation": "conv_8f2k", "control": true } }}Or start a voice call
A call in the user's conversation (talk).
What happens The page joins the call, and what is said lands in the conversation as text. When it ends, session.ended carries the transcript.
// A call in the user's conversation.const traveller = vestra.user('traveller-42');const call = await traveller.talk({ conversation: 'conv_8f2k' });console.log(call.url);# A call in the user's conversation.call = vestra.user("traveller-42").talk(conversation="conv_8f2k")print(call.url)# A call in the user's conversation.vestra talk --user traveller-42 --conversation conv_8f2k# A call in the user's conversation.curl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "voice": true }'{ "method": "tools/call", "params": { "name": "talk", "arguments": { "user": "traveller-42", "conversation": "conv_8f2k" } }}End it
When your user signs out, end their session by its id.
What happens Its token stops working at once, its streams close, and session.ended says so.
// When your user signs out, by the id you kept.await vestra.sessions.end('ses_8h2');# When your user signs out, by the id you kept.vestra.sessions.end("ses_8h2")The CLI's sessions are previews, good for 15 minutes. End one from your server, with an SDK or HTTP.
# When your user signs out, by the id you kept.curl -X DELETE "$VESTRA_BASE_URL/v1/sessions/ses_8h2" \ -H "Authorization: Bearer $VESTRA_API_KEY"# When your user signs out, by the id you kept.curl -X DELETE "$VESTRA_BASE_URL/v1/sessions/ses_8h2" \ -H "Authorization: Bearer $VESTRA_API_KEY"Sessions end from your server, with an SDK or HTTP.
# When your user signs out, by the id you kept.curl -X DELETE "$VESTRA_BASE_URL/v1/sessions/ses_8h2" \ -H "Authorization: Bearer $VESTRA_API_KEY"The whole thing
Open, show, call and end, in one program.
What happens One session per visit, and your user never leaves your app.
import { Vestra } from '@vestra/sdk'; const vestra = new Vestra();const traveller = vestra.user('traveller-42'); // Open a sessionconst session = await traveller.embed();console.log(session.url); // Or show just its screenconst screen = await traveller.watch({ conversation: 'conv_8f2k', control: true,}); // Or start a voice callconst call = await traveller.talk({ conversation: 'conv_8f2k' });console.log(screen.url, call.url); // End itawait vestra.sessions.end(session.id);from vestra import Vestra vestra = Vestra()traveller = vestra.user("traveller-42") # Open a sessionsession = traveller.embed()print(session.url) # Or show just its screenscreen = traveller.watch(conversation="conv_8f2k", control=True) # Or start a voice callcall = traveller.talk(conversation="conv_8f2k")print(screen.url, call.url) # End itvestra.sessions.end(session.id)# Open a session: a preview of what your user seesvestra embed --user traveller-42 # Or show just its screenvestra watch --user traveller-42 --conversation conv_8f2k --control # Or start a voice callvestra talk --user traveller-42 --conversation conv_8f2k# Open a sessioncurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "chat": true, "screen": "view", "voice": true }' # Or show just its screencurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "screen": "control" }' # Or start a voice callcurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "voice": true }' # End itcurl -X DELETE "$VESTRA_BASE_URL/v1/sessions/ses_8h2" \ -H "Authorization: Bearer $VESTRA_API_KEY"An agent opens each with the embed, watch and talk tools. Ending one stays with your server.
# Open a sessioncurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "chat": true, "screen": "view", "voice": true }' # Or show just its screencurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "screen": "control" }' # Or start a voice callcurl "$VESTRA_BASE_URL/v1/sessions" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "conversation_id": "conv_8f2k", "voice": true }' # End itcurl -X DELETE "$VESTRA_BASE_URL/v1/sessions/ses_8h2" \ -H "Authorization: Bearer $VESTRA_API_KEY"