Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 38 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,59 @@
# BELL

<img width="512" height="512" alt="pixel-bell-512" src="https://github.com/user-attachments/assets/f4c9363d-2ab0-4205-a3c7-7d7ad61ec6c6" />
<img width="128" height="128" alt="BELL" src="https://github.com/user-attachments/assets/f4c9363d-2ab0-4205-a3c7-7d7ad61ec6c6" />

**BELL is a reference architecture and sample app for developers building personal assistants. Developers should have a practical starting point for building their own versions that are truly performant on execution.**
BELL is a reference architecture and sample app for building personal AI assistants that execute tasks on your behalf.

Browserbase, Eve by Vercel, Linq, Link by Stripe, 1Password, Baselayer power assistants that execute tasks on your behalf.

Bell pairs an Eve agent with browser
automation powered by Browserbase and a compact web interface. This standalone repository owns
Bell's agent, interface, configuration, and merchant integration.
Bell directly owns Stagehand/Browserbase session management, browser tools,
Contexts, human handoff, and optional 1Password access. Bell adds Linq iMessage/SMS messaging
with a signed webhook and a private sender list.
Eve by Vercel runs the agent; Browserbase and Stagehand power browser automation. A web interface provides chat, screenshots, and human handoff. Integrations with Linq, Link by Stripe, 1Password, and Baselayer add messaging, payments, credential access, and merchant verification.

## Run locally

Use Node.js 24 and pnpm 10.33.4. Clone Bell and install its dependencies:
Requires Node.js 24, pnpm 10.33.4, and OpenAI and Browserbase API keys.

```sh
git clone https://github.com/browserbase/bell-stack.git
cd bell-stack
pnpm install --frozen-lockfile
cp .env.example .env
# Set OPENAI_API_KEY and BROWSERBASE_API_KEY in .env.
```

Set `OPENAI_API_KEY` and `BROWSERBASE_API_KEY` in `.env`. For ordinary browsing, set `BELL_DEMO_URL` to your target website. The default protected demo requires [Baselayer setup](docs/baselayer.md).

```sh
pnpm dev
```

Open `http://127.0.0.1:4320` and select **Open demo site**. Bell opens the configured `BELL_DEMO_URL`
(the protected Baselayer demo in `.env.example`) in one persistent Browserbase session. Configure
Baselayer as described below for that demo, or set the URL to an ordinary website for browsing.
Ask for a screenshot to update the capture panel. Follow-up
messages at the same `/s/...` address reuse the conversation and browser. Stop cancels active work.
The panel is a screenshot viewer; use `human_handoff` when you need to interact with the browser.

Browser tools, hooks, and runtime code live directly in Bell. One Next.js app and one Eve agent
use the root `package.json` and lockfile. Restart Bell after runtime edits. See
[repository layout](docs/repository.md) and
[browser configuration and credential handling](docs/browser-runtime.md).

For phone use, point Linq directly at Bell's HTTPS deployment and use the same origin
for handoff links. Hosted browser launches keep `browserSettings.verified: true` and
managed proxies enabled. See [Linq setup](docs/linq.md).

## Baselayer merchant access

Bell can mint a short-lived L2 credential, bind it to a merchant nonce, and present it on one
approved browser request using `merchant_access`. Configure the sandbox API key, verified
principal, and exact merchant origin in `.env.local`.
[Follow the Baselayer setup and verification guide](docs/baselayer.md).

The protected demo is `https://bell-stack-demo-site.vercel.app/protected`. Ordinary navigation
should be denied; successful `merchant_access` should return HTTP 200. Sandbox credentials
usually expire after about one hour; check the returned expiry. Live access requires a current
verified principal from the same sandbox organization as the API key.
Best Buy browsing does not require Baselayer and does not demonstrate merchant verification.

## Optional integrations

- Link sandbox: test purchases with an operator-injected token, no database or saved wallet
credentials. Real Link: connect a wallet from an allowlisted Linq conversation using OAuth. Bell sends a
consent URL and resumes in the same chat. PostgreSQL stores encrypted per-sender grants;
spend requests retain Eve confirmation and Link approval. Approved payment entry uses the server-side checkout tool;
card details and payment tokens are not returned to the model. Follow [Link setup](docs/link.md).
- 1Password: for local desktop access, set `OP_ACCOUNT="Your account name"` in `.env.local`,
using the account name shown in the 1Password sidebar. In the desktop app, enable
**Settings > Developer > Integrate with other apps** under the SDK options, then approve
the request when prompted. Bell must run on the same computer as the desktop app.
For hosted access, set `OP_SERVICE_ACCOUNT_TOKEN` instead; it takes precedence over `OP_ACCOUNT`.
Existing CLI setups can select `BELL_ONEPASSWORD_BACKEND=cli` with an explicit account or
service token; see the [credential setup and limits](docs/browser-runtime.md#credentials-and-otp).
Save a Login item with the destination website, username, and password before asking Bell to log in.
Add a one-time password field if the site uses TOTP. The vault tools enforce the saved
website host and HTTPS before filling credentials. Credentials are resolved on the server; a URL alone does not
provide a login.
These vault tools are for the trusted operator and are unavailable over Linq.
Personal iMessage [1Password Agentic Autofill](docs/onepassword.md) is staged and disabled by default.
Stagehand 4.3.0 and 1Password currently compete for the hosted session's extension slot.
Keep `ONEPASSWORD_ENABLED=false` and `BROWSERBASE_1PASSWORD_EXTENSION_ID` unset until that
launch path is fixed and the live flow passes verification. Ordinary browsing remains available.
- Local vault: existing encrypted files remain readable using `BELL_VAULT_FILE` and
`BELL_VAULT_MASTER_KEY`. No vault administration UI or writing API is included. Protect the
file and its website mappings as trusted operator configuration.
- Linq: configure your own Linq receiving line, API key, webhook signing secret, and allowed
personal sending number, then text that line. Follow the [Linq setup and phone demo](docs/linq.md).
Each Linq chat keeps its own conversation and browser. Baselayer is not required for browsing.
- Handoff: set a random `BELL_HANDOFF_SECRET` of at least 32 characters and
`BELL_PUBLIC_URL` to the app's reachable origin. Configure this before asking for a handoff.

Browser logging and recording are disabled for hosted sessions. Context and vault tools run
directly in Bell. Visa is not integrated. Before updating an existing deployment, follow the
[configuration and session migration notes](docs/browser-runtime.md#updating-an-existing-deployment).

## Check the code
Open [localhost:4320](http://127.0.0.1:4320), select **Open demo site**, and give Bell a task. Follow-up messages in the same conversation reuse the browser session. Ask for a screenshot to see progress or a handoff to interact with the browser. Handoff requires the [public URL and secret settings](docs/browser-runtime.md#configuration).

## Start here

| Integration | What it does | Guide |
| --- | --- | --- |
| Browserbase + Stagehand | Browser sessions, automation, saved Contexts, and human handoff | [Browser runtime](docs/browser-runtime.md) |
| Eve by Vercel | Agent configuration, tools, conversation state, and channels | [Eve in Bell](docs/repository.md#eve-by-vercel) |
| Linq | iMessage and SMS through a signed webhook and sender allowlist | [Messaging setup](docs/linq.md) |
| Link by Stripe | Wallet authorization, spend approval, and checkout through Linq | [Sandbox and wallet setup](docs/link.md) |
| 1Password | Operator credentials and OTP; personal Agentic Autofill is disabled by default | [Operator access](docs/browser-runtime.md#credentials-and-otp) · [Personal access status](docs/onepassword.md) |
| Baselayer | Verified access to approved merchants using short-lived credentials | [Merchant access](docs/baselayer.md) |

Personal 1Password Agentic Autofill must remain disabled until hosted extension support and live verification are complete. Operator SDK/CLI access is separate and unavailable over Linq.

See the [repository layout and implementation map](docs/repository.md) to extend Bell.

## Development

```sh
pnpm check
```

This runs tests, TypeScript, lint, and the Bell production build. Browser runtime tests live in
`tests/browser`; live provider tests remain opt-in and skip without their required configuration.
The default suite makes no live provider calls. Set `TEST_LINK_DATABASE_URL` to a disposable
PostgreSQL database to include Link persistence tests; CI runs these automatically. A successful build verifies compilation only.
Keep this demo local until you configure application authentication and durable storage. Bell's
HTTP channel rejects unauthenticated production traffic. Context metadata and optional local
vault files are scoped to one trusted operator; Context writes are serialized within one process.
See the [browser runtime guide](docs/browser-runtime.md)
for storage, authentication, and credential boundaries and [provider checks](docs/provider-tests.md)
for live regression commands.
Runs tests, type checking, lint, and the production build. [Live provider checks](docs/provider-tests.md) are opt-in.

Bell is a sample app for one trusted operator. Before deploying, configure application authentication and durable storage using the [browser runtime guide](docs/browser-runtime.md).

## Acknowledgments

Special thanks to Visa.

## License

[MIT](LICENSE).
2 changes: 1 addition & 1 deletion docs/baselayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ cancellation, redacted results, and bounded retry. They do not establish live sa

Live verification also needs the actual sandbox API key, a current principal, and the deployed
merchant's working registry checks. Run the full denial/access/denial sequence after configuring
those services. [Link wallet OAuth and checkout](link.md) are configured separately. Visa is not integrated.
those services. [Link by Stripe wallet OAuth and checkout](link.md) are configured separately.

Protocol references: [minting credentials](https://docs.baselayer.com/docs/minting-credentials),
[presentation and verification](https://docs.baselayer.com/docs/presenting-and-verifying-a-credential),
Expand Down
6 changes: 4 additions & 2 deletions docs/browser-runtime.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Browser runtime

Bell's Eve agent owns conversation history and tool execution. Browser tools share one in-process
Bell's Eve by Vercel agent owns conversation history and tool execution. Browser tools share one in-process
Stagehand runtime per Eve session. Follow-up turns reuse the browser; saved Browserbase session
metadata supports reconnecting after a worker restart. Hosted launches request managed proxies,
Verified Browsers, and keep-alive on every attempt, including retries.
Expand Down Expand Up @@ -82,7 +82,9 @@ The SDK honors 1Password's Never-autofill policy. CLI access enforces saved webs
cannot enforce autofill policies that the CLI does not expose; use the default SDK when those
policies are required. Both modes keep credential values out of model-visible results.

Personal iMessage accounts use [Agentic Autofill](onepassword.md), with per-sender encrypted
Personal iMessage [1Password Agentic Autofill](onepassword.md) is disabled by default pending
hosted extension support and live verification. Keep `ONEPASSWORD_ENABLED=false` and
`BROWSERBASE_1PASSWORD_EXTENSION_ID` unset. The staged implementation uses per-sender encrypted
OAuth connections and explicit approval in the 1Password app. Operator SDK/CLI vault tools
are not available over Linq. Personal mode disables reusable Contexts; each conversation
keeps a private browser, and failed fills require a new conversation.
Expand Down
5 changes: 4 additions & 1 deletion docs/link.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Link sandbox and wallet OAuth over Linq
# Link by Stripe: sandbox and wallet OAuth over Linq

Link by Stripe provides wallet authorization, spend approval, and checkout. Linq carries the
messages; Eve by Vercel runs the agent and authorization flow. These are separate integrations.

## Sandbox: no database or saved wallet credentials

Expand Down
18 changes: 10 additions & 8 deletions docs/linq.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Text Bell through Linq

Configure Bell with a receiving phone number from your own Linq account.
Linq carries iMessage and SMS. [Link wallet OAuth and checkout](link.md) use this channel's
Linq carries iMessage and SMS. [Link by Stripe wallet OAuth and checkout](link.md) use this channel's
verified sender identity and require separate configuration.

```text
Expand Down Expand Up @@ -76,9 +76,10 @@ still need a reachable HTTPS application host. See

5. Use persistent storage for Bell's Context metadata and any existing local vault file on a single-instance
host, or configure durable shared storage before a multi-instance/serverless deployment.
Personal 1Password access uses [Agentic Autofill](onepassword.md), per-sender OAuth, and
private browsers without reusable Contexts. Operator service-account and desktop vaults
are not exposed to Linq senders. Keep provider credentials in the server secret store.
Personal [1Password Agentic Autofill](onepassword.md) is disabled by default pending hosted
extension support and live verification. Its implementation uses per-sender OAuth and private
browsers without reusable Contexts. Operator service-account and desktop vaults are not
exposed to Linq senders. Keep provider credentials in the server secret store.

## Demo from your phone

Expand All @@ -92,10 +93,11 @@ Bell should visit the site in Browserbase and reply in the same Linq chat. Follo
that chat's browser. Report what the browser actually sees; merchant pages can vary by region
or present a challenge. This demo does not log in, add items to a cart, or purchase anything.

For a personal saved login, configure [1Password Agentic Autofill](onepassword.md), connect
from the private conversation, and approve the website in the 1Password desktop app.
The initial flow supports single-step sign-in; OTP and passkey flows need separate handling.
Do not send passwords or OTPs as chat messages.
Personal saved logins are unavailable while [1Password Agentic Autofill](onepassword.md) is disabled.
Keep `ONEPASSWORD_ENABLED=false` and `BROWSERBASE_1PASSWORD_EXTENSION_ID` unset until the guide's
hosted extension and live verification requirements are met. The staged personal flow supports
single-step sign-in only; OTP and passkeys are not implemented. Do not send passwords or OTPs
as chat messages.

## Verification boundary

Expand Down
26 changes: 25 additions & 1 deletion docs/repository.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Bell repository

Bell lives in [browserbase/bell-stack](https://github.com/browserbase/bell-stack).
One Next.js application serves the web interface and integrations. One Eve agent owns the web
One Next.js application serves the web interface and integrations. One Eve by Vercel agent owns the web
and Linq conversations; both channels use Bell's browser runtime directly.

```text
Expand All @@ -14,6 +14,30 @@ package.json Application dependencies and commands
pnpm-lock.yaml One dependency resolution tree
```

## Eve by Vercel

[Eve by Vercel](https://eve.dev/docs) runs Bell's agent, conversation state, tools, and channels.
Configure the model and session limits in [`agent/agent.ts`](../agent/agent.ts), behavior in
[`agent/instructions.md`](../agent/instructions.md), and tools in [`agent/tools/`](../agent/tools/).
The [web channel](../agent/channels/eve.ts) and [Linq channel](../agent/channels/linq.ts) use the
same agent with separate conversations. [Hooks](../agent/hooks/) maintain task state and browser
lifecycle; channel callbacks also handle terminal-session cleanup. Restart Bell after runtime edits.

## Integration implementation

| Integration | Implementation | Guide |
| --- | --- | --- |
| Browserbase + Stagehand | [Browser runtime](../agent/lib/browser-runtime.ts), [session management](../server/browser/browser-session.ts) | [Browser configuration](browser-runtime.md) |
| Eve by Vercel | [Agent](../agent/agent.ts), [channels](../agent/channels/), [hooks](../agent/hooks/) | [Eve in Bell](#eve-by-vercel) |
| Linq | [Channel and sender policy](../agent/channels/linq.ts) | [Messaging setup](linq.md) |
| Link by Stripe | [Eve extension and tools](../agent/extensions/link/), [authorization](../agent/lib/link-auth.ts), [server implementation](../server/link/) | [Sandbox and wallet setup](link.md) |
| 1Password | [Operator SDK/CLI access](../server/browser/vault/onepassword.ts), [personal authorization](../agent/lib/onepassword-auth.ts), [personal server implementation](../server/onepassword/) | [Operator credentials](browser-runtime.md#credentials-and-otp), [personal access status](onepassword.md) |
| Baselayer | [Agent tool](../agent/tools/merchant_access.ts), [credential minting](../server/baselayer.ts), [merchant verification](../server/verified-merchant.ts) | [Merchant access](baselayer.md) |

Personal 1Password Agentic Autofill is implemented but disabled by default pending hosted extension
support and live verification. Keep `ONEPASSWORD_ENABLED=false` and the extension ID unset as
described in its guide. Operator SDK/CLI access remains separate and is unavailable over Linq.

## Development

Use Node.js 24 and pnpm 10.33.4:
Expand Down
Loading