# Build your first Web Agent

At the end of this tutorial, Nimbus CRM has a chat on every page. When you ask it to create a contact, the contact appears in the app. When you ask it to change or delete one, it shows a confirmation card and waits for you.

Nimbus CRM is a small example CRM with contacts, companies and deals, built with React, Express and SQLite. Its code is public at [github.com/faustine-ai/example-nimbus-crm](https://github.com/faustine-ai/example-nimbus-crm).

In this tutorial, you:

- [Create the agent](#create-the-agent)
- [Connect the repository](#connect-the-repository)
- [Run the analysis](#run-the-analysis)
- [Pick the modules](#pick-the-modules)
- [Set up and launch the agent](#set-up-and-launch-the-agent)
- [Review the actions](#review-the-actions)
- [Make the agent ask before updating](#make-the-agent-ask-before-updating)
- [Install the snippet](#install-the-snippet)
- [Ask the agent to create a contact](#ask-the-agent-to-create-a-contact)
- [Read the log of the conversation](#read-the-log-of-the-conversation)

## Before you begin

- A Faustine workspace with a model provider set up. The analysis in this tutorial uses tokens from that provider. See [Connect your model provider](https://docs.faustine.ai/get-started/connect-your-ai-provider/).
- A GitHub account, with a fork of `faustine-ai/example-nimbus-crm` in it.
- Docker, to run Nimbus CRM on your machine, and a clone of your fork.

## Create the agent

1. In the portal, go to [**Web Agents**](https://auth.faustine.ai/go?to=%2Fweb-assistants) and select **New Web Agent**. The **Quick start** wizard opens.
2. Under **Choose your app type**, select **React.js**. Under **What is your agent for?**, select **Get the work done for them**.
3. Under **Details**, enter `Support agent` as the **Assistant name**.
4. Under **Environments**, clear **Staging** and select **Production**. With Production as the only environment, the version you publish later is the one the snippet loads.
5. Select **Continue**.

The wizard shows the name with a **Production** badge and opens **Connect your code**.

## Connect the repository

1. Select **GitHub**.
2. Select **Connect GitHub**. GitHub asks you to install the Faustine GitHub App. Choose your account, give the app access to your fork only, and install it.
3. GitHub sends you back to the wizard with the new connection selected.
4. In **Repository**, select your fork of `example-nimbus-crm`. **Branch** fills in with `main`.
5. In **Frontend path**, select `app/frontend`. The repository also holds the backend, and the agent is built from the front end.
6. Select **Continue**.
7. Under **Keep the assistant up to date**, leave **Automatic** selected and select **Continue**.
8. Under **Extra resources**, select **Skip for now**.
9. Under **Review & create**, select **Create & start analysis**.

The analysis page opens with the title **Analyzing your code base to create your assistant.**

## Run the analysis

The first two stages run without input.

1. **Clone the repository** downloads your fork.
2. **Analyze the architecture & modules** reads the structure of the app. A log shows what the analysis is doing. The stage takes 3 to 10 minutes.

You can leave the page while it runs. To come back, select the agent in **Web Agents**.

> **Checkpoint:** The second stage shows how many modules and insights it found, and **Choose what to analyze** opens with a list of modules.

## Pick the modules

The list has one module for each feature area the analysis found in Nimbus CRM: contacts, companies, deals and the rest. The names and descriptions are written by the analysis, so yours can differ from another run's.

1. Select **None** to clear the selection.
2. Select the module that covers contacts.
3. Select **Analyze selected**.

One module keeps the first run short. You can analyze the others later with a re-analysis.

![The Choose what to analyze step with the two insights included and only the contacts module selected.](https://docs.faustine.ai/images/web-agents/tutorial-choose-modules.png)

The module shows its progress while Faustine writes its actions. When it finishes, the **Summary** stage reads **Analysis complete** with the number of modules, actions and insights. **Key findings** lists the Authentication and Navigation insights, and **Analysis breakdown** shows the time and the estimated cost of each part.

![The analysis summary: one module, five actions and two insights, with the time and estimated cost of each part.](https://docs.faustine.ai/images/web-agents/analysis-summary-light.png)

## Set up and launch the agent

1. In the summary, select **Continue to setup**. The **Set up your assistant** wizard opens.
2. In **Get to know your assistant**, read the three texts the analysis drafted about the app, then select **Continue**.
3. In **Actions**, leave every action on and select **Continue**.
4. Select **Continue** in **Web search**, **Knowledge base**, **Look & feel** and **AI model** to keep what they show.
5. In **Install the assistant**, select **Copy** to copy the snippet. Keep it for a later step.
6. Select **Launch**.

**Launch** publishes the draft as the first version and opens the agent's page. The header shows Production with the version it serves.

## Review the actions

1. Select the **Actions** tab.
2. Find the group for the contacts module. Its row shows how many of its actions are enabled.
3. Read the rows. Each one has the HTTP method of its request, a display name and a function name. Nimbus CRM's contacts API has five endpoints, and the analysis writes one action for each: `createContact`, `deleteContact`, `getContact`, `listContacts` and `updateContact`.
4. Select the action that creates a contact. Its **Parameters** include a first name and a last name, which Nimbus CRM requires, and optional fields such as the email.
5. Select **Back to actions**.

The JSDoc you saw is what the model reads to decide when to run the action. The code under it is the request Nimbus CRM itself makes when you save the contact form.

## Make the agent ask before updating

The analysis turns on confirmation for every action that sends a `DELETE` request, so the agent already asks before it deletes a contact. In the row of the action that deletes a contact, the switch in the **Confirmation** column is on.

To make the agent ask before it changes a contact too:

1. In the row of the action that updates a contact, turn on the switch in the **Confirmation** column.
2. In the save bar, select **Save changes**.
3. In the header, select **Publish**.

The header shows the new version on Production. The widget loads it the next time the page loads.

![The Actions tab with the five contact actions. Ask to confirm is on for deleteContact and updateContact.](https://docs.faustine.ai/images/web-agents/actions-tab-light.png)

## Install the snippet

1. In your clone of the fork, open `app/frontend/index.html`.
2. Add the snippet you copied inside `<head>`. It has this form, with your agent's ID.

```html filename="app/frontend/index.html"
<script src="https://webagent.faustine.ai/embed?wid=<AGENT_ID>" async></script>
```

3. Start Nimbus CRM.

```bash
cd app
docker compose up
```

4. Open `http://localhost:5173` and sign in with `admin@crm.test` and the password `admin123`.

If you did not keep the snippet, it is in the agent's **Overview** tab, in the **Install the assistant** card, under **JS / Auto**.

> **Checkpoint:** The agent's launcher is on the page. It stays there as you move between Contacts, Companies and Deals.

## Ask the agent to create a contact

1. Open **Contacts** in Nimbus CRM, so you can watch the list.
2. Select the launcher and send this message.

```text
Create a contact named Ada Lovelace with the email ada@example.com
```

The agent runs the create action as the user you are signed in as. It replies that the contact was created and shows a card for her, and Ada Lovelace appears in the Contacts list.

![Nimbus CRM with the widget open. The agent answers that Ada Lovelace is created and shows her contact card.](https://docs.faustine.ai/images/web-agents/tutorial-contact-created.png)

3. Now send this message.

```text
Delete the contact Ada Lovelace
```

The agent finds the contact, then replaces the message box with a confirmation card that names what it is about to delete. Nothing is deleted yet.

![The confirmation card in the widget. It names the contact, lists the one operation it will run, and has Cancel and Delete buttons.](https://docs.faustine.ai/images/web-agents/tutorial-confirmation-card.png)

4. Select **Delete** on the card.

The agent reports that the contact was deleted, and the row disappears from the list.

## Read the log of the conversation

1. In the portal, open the agent's **Monitoring** tab.
2. Under **Conversations**, select the conversation you just had.
3. Go through the turns. Each one has your message and the agent's reply. Where the agent ran an action, the turn shows the call with its **Input** and its **Output**.

The create call's input has the first name, the last name and the email the model took from your sentence. Its output is what Nimbus CRM returned.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| No launcher on the page | The snippet is not in the page, or the page was not reloaded. | Check that `app/frontend/index.html` has your snippet inside `<head>` and reload. |

## What you built

Your fork of Nimbus CRM has a Web Agent with one module of actions, generated from its front-end code and served on Production. The agent, its actions, its versions and its conversations are under [**Web Agents**](https://auth.faustine.ai/go?to=%2Fweb-assistants) in the portal.

## Next steps

- [Choose what to analyze](https://docs.faustine.ai/web-agents/choose-what-to-analyze/): add the companies and deals modules.
- [Turn an action on or off and test it](https://docs.faustine.ai/web-agents/test-an-action/): run one action without the chat.
- [Write the agent's persona](https://docs.faustine.ai/web-agents/persona/): make the agent talk about the CRM in your words.
- [Verify your users with a signed token](https://docs.faustine.ai/web-agents/verify-users/): tell the agent which user is signed in.
- [Appearance](https://docs.faustine.ai/web-agents/appearance/): change how the widget looks.
