Skip to content

Commit

Permalink
Merge branch 'location' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
valgaze committed Feb 10, 2024
2 parents fdb5d0e + c435195 commit 9249247
Show file tree
Hide file tree
Showing 21 changed files with 1,401 additions and 15 deletions.
11 changes: 11 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default defineConfig({
title: "SpeedyBot",
description: "Rich conversation agents, the speedy and easy way",
themeConfig: {
footer: {
message: `<a href="https://github.com/valgaze/speedybot/blob/v2/LICENSE" target="_blank">MIT License</a> ${new Date().getFullYear()}`, // this'll be statically updated everytime redeploy
},
search: {
provider: "local",
},
Expand Down Expand Up @@ -51,6 +54,10 @@ export default defineConfig({
text: "📂 RAG with Voiceflow (file upload)",
link: "/examples/voiceflow-kb/README",
},
{
text: "🌎 Location Prompt",
link: "/examples/location/README.md",
},
{
text: "🔐 Secure Webhooks ",
link: "/webhooks",
Expand Down Expand Up @@ -115,6 +122,10 @@ export default defineConfig({
text: "📂 RAG with Voiceflow (file upload)",
link: "/examples/voiceflow-kb/README",
},
{
text: "🌎 Location Prompt",
link: "/examples/location/README.md",
},
],
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Grab an example and see the included README for instructions on how to get up an
| **[📲 LLM Stream](./examples/llm-stream/README.md)** |||
| **[🗣 Connect to Voiceflow](./examples/voiceflow/README.md)** |||
| **[📂 RAG with Voiceflow (File Uploads)](./examples/voiceflow-kb/README.md)** |||
| **[🌎 Location Prompt](./examples/location/README.md)** |||
1 change: 1 addition & 0 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Grab an example and see the included README for instructions on how to get up an
| **[📲 LLM Stream](./llm-stream/README.md)** |||
| **[🗣 Connect to Voiceflow](./voiceflow/README.md)** |||
| **[📂 RAG with Voiceflow (File Uploads)](./voiceflow-kb/README.md)** |||
| **[🌎 Location Prompt](./location/README.md)** |||
97 changes: 97 additions & 0 deletions docs/examples/location/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# [QUICKSTART] 🔥 Prompt your user for location information

- What if we could ask users for location in a respectful, privacy-protecting manner?

- This pattern already exists on mobile devices, it should exist on conversational interfaces too, ex:

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/location_iphone.png?raw=true" />

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/location_demo.gif?raw=true" />

Note: The steps below assume you have a working WebEx account + a Cloudflare account with permission to create Workers-- you can port this to any other infrastructure where you can expose a `/location` route that exposes privacy-respecting coarse-grained location information

## 1) Fetch repo & install deps

```
git clone https://github.com/valgaze/speedybot
cd speedybot/examples/location
npm i
```

## 2) Get + Set your bot access token

- Create a bot from scratch here + copy the token: **[https://developer.webex.com/my-apps/new/bot](https://developer.webex.com/my-apps/new/bot)**

- If you have an existing bot, get its token here (regenerate a new token): **[https://developer.webex.com/my-apps](https://developer.webex.com/my-apps)**

## 3) Get your bot's URL

- If you don't have one already, get a **[cloudflare account](https://dash.cloudflare.com/sign-up)**

- Authenticate your machine with `npx wrangler login`

- Run the command to deploy the code in this repo to your Worker and get your bot URL

```
npm run deploy
```

You'll be prompted to open your browser and you'll see an authorization screen like the following asking to enable **[wrangler (Worker's CLI tool)](https://developers.cloudflare.com/workers/wrangler/)** to take actions with your account, click **ALLOW**

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/worker_authorize_wrangler.png" />

The URL will look something like https://speedybot-worker-infra.your_username.workers.dev (you'll need it in a minute when we register webhooks)

## 4) Add your bot token

From the same directory as the repo run the following command to add a secret called `BOT_TOKEN` and enter your info using **[secrets manager](https://developers.cloudflare.com/workers/configuration/secrets/#secrets-on-deployed-workers)**

```sh
npx wrangler secret put BOT_TOKEN
```

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/worker_secret.gif" />

## 5) Deploy your agent

From the same directory as the repo run this command to deploy your agent (now bound with your `BOT_TOKEN` secret)

```
npm run deploy
```

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/worker_deploy.gif" />

## 6) Register your webhooks

- Right now if you try to interact with your "deployed" agent nothing happens, nobody is "home" to answer the knock at the door

- Make a note of the URL of the deployed function (ie https://speedybot-worker-infra.your_username.workers.dev)

- Hop on over to the **[SpeedyBot Garage (https://speedybot.js.org/garage)](https://speedybot.js.org/garage)**, enter your access token, select the Webhooks tab, and then **Add New Webhook** and add your Worker's URL and (optionally) a webhook secret

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/webhook_steps.gif" />

## 6a) Supply your Webhook "secret" to your Worker

Even though it's "optional", it's a really, really good idea to set a Webhook Secret too so you can make sure incoming requests are the real deal. For more detail, see **[https://speedybot.js.org/webhooks#securing-webhooks](https://speedybot.js.org/webhooks#securing-webhooks)**

To supply your Worker with a webhook secret, set a secret called WEBHOOK_SECRET which you'll need to supply to your Worker like you did with your `BOT_TOKEN` value

```sh
npx wrangler secret put WEBHOOK_SECRET
```

## 7) Take it for a spin

- After connecting webhooks, take it for a spin + say "location" or tap the Location Integration chip:

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/location_demo.gif?raw=true" />

## Some notes

- This is a proof of concept where the location-enriched functionality is broken out into a separate file

- We expose the messageId on the URL which in and of itself isn't a security issue, but depending on the platform you deploy to you could take advantage of encryption to scramble/unscramble the messageId

- The service used in this instance gives at best a very rough/coarse-grained amount of detail of a user's "location"-- the less detail you agent needs, the better
2 changes: 1 addition & 1 deletion docs/new.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ You can now customize this bot however you want by editing the file **[settings/

You can turn off your bot by holding down **CTRL-C** on your keyboard or exiting the terminal. To turn your bot back "on", open your terminal to your project directory and enter `npm run dev`

Whether you're just starting out on your conversation design journey or a seasoned pro, SpeedyBot has you covered for crafting bots that can do it all-- **[securely integrate w/ LLMs + content management systems](./examples/voiceflow/README)**, **[process file-uploads](./patterns.md#handle-file-uploads)**, **[segment content based on user data + behavior](./patterns.md#restrict-access-pattern)**, **[let users upload documents and then 'chat' with them using an LLM and a R.A.G. pattern](./examples/voiceflow-kb/README.md)**, create + manage **[SpeedyCards](./speedycard.md)**, ask for a user's location in a privacy-respecting way, and much more.
Whether you're just starting out on your conversation design journey or a seasoned pro, SpeedyBot has you covered for crafting bots that can do it all-- **[securely integrate w/ LLMs + content management systems](./examples/voiceflow/README)**, **[process file-uploads](./patterns.md#handle-file-uploads)**, **[segment content based on user data + behavior](./patterns.md#restrict-access-pattern)**, **[let users upload documents and then 'chat' with them using an LLM and a R.A.G. pattern](./examples/voiceflow-kb/README.md)**, create + manage **[SpeedyCards](./speedycard.md)**, **[ask for a user's location in a privacy-respecting way](./examples/location/README.md)**, and much more.

When you're ready to deploy it to a server, serverless function or virtually any infrastructure/device, **[check out the examples](./examples.md)**

Expand Down
55 changes: 44 additions & 11 deletions docs/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,54 @@ Below are some comon copy/paste'able step "snippets" or patterns which should co

### Prerequisites ​

SpeedyBot is super easy to use once you have building blocks in place. You'll need the following to get SpeedyBot up and running on your computer

- A "terminal" or command line interface-- if you don't have a lot of experience with it, see this guide here: **[terminal 101 ](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line)** and also this video: **[https://www.youtube.com/watch?v=5XgBd6rjuDQ](https://www.youtube.com/watch?v=5XgBd6rjuDQ)**

- NodeJS 18+ or equivalent runtime like Bun/Deno/Worker/friends w/ **[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)** available/polyfill
- Text editor

::: details Errhm, what's Node??

If you've never written code before or messed around with these tools you will need to a bit of setup.

If you open your **[terminal](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line)** type `npm -v` and see an error like `npm: command not found` you probably need to install node or a compatible runtime onto your system.

There are many ways to do this, but two easy ways:

**Option 1** Download + install Node from the official site: **[https://nodejs.org/en/download](https://nodejs.org/en/download)**

or

**Option 2** Download with **[Volta](https://docs.volta.sh/guide/)** in the terminal

```sh
curl https://get.volta.sh | bash

volta install node
```
npm install speedybot
```

**[https://www.npmjs.com/package/speedybot](https://www.npmjs.com/package/speedybot)**
However you set up your system, make sure to run `node -v` in your terminal to verify node is correctly installed and you're good to go
:::

- Text editor: There's a lot of text editors in the world these days, a real popular + free one (that works great with SpeedyBot) is called Visual Studio Code, see here for details: **[https://code.visualstudio.com](https://code.visualstudio.com)**

The developer-focused instructions are available here: **[https://www.npmjs.com/package/speedybot](https://www.npmjs.com/package/speedybot)**

See **[/new](./new.md)** for easy to follow instructions to go from zero to a bot you can extend and customize however you want. With SpeedyBot is all you need to focus on when building your bot is `bot.ts.` If you need to deploy it to a highly controlled server or a serverless function or any infra you want you just need to pop your `bot.ts` and you're good to go.
If you're new to bot development or not particularly technical, check out **[https://speedybot.js.org/new](https://speedybot.js.org/new)** for easy-to-follow instructions. These will take you from zero to a fully customizable bot in less than 3 minutes. With SpeedyBot, the main file you'll work with is bot.ts. All the patterns you'll see below would generally "live" inside your bot's `bot.ts` file.

When you're just starting, SpeedyBot runs your bot directly and securely from your computer. This allows you to focus on the essential aspects of your bot. However, if you need to deploy it to a highly controlled server, a serverless function, or any other infrastructure, simply transfer your bot.ts file, and you're all set.

## The basics

SpeedyBot simplifies the process of creating interactive conversations and makes it easy to deploy and manage bots. Anytime your SpeedyBot receives an event from a user (a message, card, file upload, etc) it operates through a series of "steps."
- SpeedyBot simplifies the process of creating interactive conversations and makes it easy to deploy and manage bots. Anytime your SpeedyBot receives an event from a user (a message, card, file upload, etc) it operates through a series of "steps."

- Each step is just a function which **must** return either $.next to proceed to the next step or $.end to terminate the chain. Each step can be synchronous or asynchronous depending on what you need to do

Each step is just a function which **must** return either $.next to proceed to the next step or $.end to terminate the chain. Each step can be synchronous or asynchronous depending on what you need to do.
- A step can do **whatever** you want (ex send the user a message or a **[SpeedyCard](./speedycard.md)**, call an API to interact with some external system, or do nothing at all)

A step can do **whatever** you want (send the user a message or a **[SpeedyCard](./speedycard.md)** or send/fetch data from some external system, do nothing at all) Whatever you're up to in a step, however, try not to take too long to do it because you probably don't want to keep your user waiting.
- Whatever you're up to in a step, however, try not to take too long to do it because you probably don't want to keep your user waiting

Here's a starter `bot.ts`:

```ts
import { SpeedyBot } from "speedybot";
Expand Down Expand Up @@ -84,9 +114,11 @@ Bot.addStep(async ($) => {

- The $ parameter provides a bunch of useful features, allowing you to reply to messages, send and check card data (see **[below for details on that](#simple-card-handler)**), and access information about the message and its author.

<img src="https://raw.githubusercontent.com/valgaze/speedybot-utils/main/assets/various/autocomplete.gif?raw=true" />

- Important: Avoid excessive usage of steps. If you find yourself writing a lot of "handlers" or checks in your steps you might be making things harder than they need to be. For a natural language "conversation", for example, focus on capturing user utterances (`$.text`) in your steps and then all you need to do is transmit back and forth to an external service and keep your steps short and sweet and simple

- Execution Order: Generally speaking, steps will fire in the order they are added to your `bot.ts`-- for convenience there is a `Bot.insertStepToFront` step which will slip the supplied to the front of the chain and `Bot.addStepSequence` to add a list of steps
- Execution Order: Generally speaking, steps will fire in the order they are added to your `bot.ts`-- for convenience there is a `Bot.insertStepToFront` step which will slip the supplied to the front of the chain and `Bot.addStepSequence` to add a bunch of steps all at once

## Send a message from a script

Expand Down Expand Up @@ -194,7 +226,7 @@ import { SpeedyBot } from "speedybot";

const Bot = new SpeedyBot();

// Will make sure
// Will make sure this step fires "first"
Bot.insertStepToFront(async ($) => {
const allowedDomains = ["allaboutfrogs.org", "geocities.com"];
if (!allowedDomains.includes($.author.domain) && !$.data) {
Expand Down Expand Up @@ -281,12 +313,13 @@ import { SpeedyBot } from "speedybot";
const Bot = new SpeedyBot();

Bot.addStep(async ($) => {
// set a random value on $.ctx.myValue
$.ctx.myValue = `${Bot.rando()}_${Bot.rando()}`;
return $.next;
});

Bot.addStep(async ($) => {
await $.send(`You said ${$.ctx.myValue}`);
await $.send(`You added this value to the context: ${$.ctx.myValue}`);
return $.next;
});
```
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Grab an example and see the included README for instructions on how to get up an
| **[📲 LLM Stream](./llm-stream/README.md)** |||
| **[🗣 Connect to Voiceflow](./voiceflow/README.md)** |||
| **[📂 RAG with Voiceflow (File Uploads)](./voiceflow-kb/README.md)** |||
| **[🌎 Location Prompt](./location/README.md)** |||
4 changes: 2 additions & 2 deletions examples/lambda/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"private": true,
"type": "module",
"scripts": {
"bot:dev": "npm run dev",
"dev": "sst dev",
"build": "sst build",
"deploy": "sst deploy",
"remove": "sst remove",
"console": "sst console",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"bot:dev": "echo Please see README.md to for instructions on how to boot"
},
"devDependencies": {
"@tsconfig/node16": "^16.1.0",
Expand Down
13 changes: 13 additions & 0 deletions examples/location/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# http://editorconfig.org
root = true

[*]
indent_style = tab
tab_width = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
Loading

0 comments on commit 9249247

Please sign in to comment.