Build an email agent with Langbase & Unified
In this guide, you will build an AI-powered email agent with Langbase SDK, using the Unified.to messaging API as a tool call to fetch emails from Gmail accounts.
Let’s get started!
Step #0Prerequisites
Before you begin, go ahead and create a free personal account on Langbase and Unified.to.
Step #1Setup your project
Create a new directory for your project and navigate to it.
1mkdir email-agent && cd email-agentStep #2Initialize the project
Initialize Node.js project and create an email-agent.ts file.
1npm init -y && touch email-agent.tsStep #3Install dependencies
You will use the Langbase SDK to connect to the AI agent pipes, dotenv to manage environment variables and Unified SDK to fetch emails. Install them with:
1npm i langbase dotenv @unified-api/typescript-sdk
Step #4Get Langbase and Unified API key
Every request you send to Langbase needs an API key. To generate your Langbase API key follow these steps.
Create an .env file in the root of your project and add your Langbase API key.
1// Replace xxxxxxxxx with your Langbase API key.
2LANGBASE_API_KEY=xxxxxxxxxYou also need the Unified API key to work with its messaging API. Follow this quickstart guide to learn more about how you can generate one. Once you have the key, add it to the '.env' file.
1LANGBASE_API_KEY=xxxxxxxxx
2UNIFIED_API_KEY=xxxxxxxxxStep #5Add LLM API keys
If you have set up LLM API keys in your profile, the pipe agent will automatically use them. If not, navigate to the LLM API keys page and add keys for different providers like OpenAI, TogetherAI, Anthropic, etc.
Step #6Fork the AI agent pipe
On Langbase, fork this public email agent pipe. This agent pipe analyzes user prompts to fetch emails, process them, and respond accordingly. If the user asks any question other than emails, it responds back with a predefined message.
The pipe agent contains the following tool definition. The agent calls the tool when the user provides a prompt like fetch the latest email from my inbox. The tool uses Unified API to fetch the latest email from the user's Gmail account.
1{
2 "type": "function",
3 "function": {
4 "name": "fetchEmails",
5 "description": "Fetch number of emails from user inbox.",
6 "parameters": {
7 "type": "object",
8 "required": ["num"],
9 "properties": {
10 "num": {
11 "type": "string",
12 "description": "The number of emails to fetch from the user inbox. Default value is 1."
13 }
14 }
15 }
16 }
17}Step #7Setup Unified OAuth 2 credentials for Gmail
To access Google services such as Gmail with the Unified API, you will need to generate and retrieve your OAuth 2 credentials in the Google Cloud Console.
You can follow this guide to quickly set it up.
Step #8Create Gmail connection
Lastly, navigate to the “Connections” inside the Unified dashboard and create a new Gmail connection.
Step #9Setting up the email agent
In this step, you will call the forked email agent pipe to analyze user prompts. To fetch emails from a user's inbox using Langbase, we'll break this process into two steps. Go ahead and add the following code to your email-agent.ts file:
1import 'dotenv/config';
2import { Langbase, Tools } from 'langbase';
3
4// Initialize Langbase SDK
5const langbase = new Langbase({
6 apiKey: process.env.LANGBASE_API_KEY!
7});
8
9// Tool definition to fetch emails from user inbox
10const fetchEmailToolDefinition: Tools = {
11 type: 'function',
12 function: {
13 name: 'fetchEmails',
14 description: 'Fetch number of emails from user inbox.',
15 parameters: {
16 type: 'object',
17 required: ['num'],
18 properties: {
19 num: {
20 type: 'string',
21 description:
22 'The number of emails to fetch from the user inbox. Default value is 1.'
23 }
24 }
25 }
26 }
27};Here's whats happening in the above code:
- Initialize the Langbase SDK with an API key from the environment variables.
- Define the
fetchEmailToolDefinitionobject that contains the tool definition to fetch emails from the user's inbox.
Now, let's implement the email agent and handle the response stream. For that add the following code in the same email-agent.ts file:
1import { Langbase, Tools, getRunner, getToolsFromRunStream } from 'langbase';
2
3async function userEmailAgent(prompt: string) {
4 // Call the email agent pipe
5 const { stream } = await langbase.pipes.run({
6 stream: true,
7 name: 'email-agent',
8 messages: [
9 {
10 role: 'system',
11 content: `You are an AI email agent that fetches emails from user inbox.
12 If user asks anything other than fetching emails,
13 you should respond that you can only process prompts related to emails.`
14 },
15 {
16 role: 'user',
17 content: prompt
18 }
19 ],
20 tools: [fetchEmailToolDefinition]
21 });
22
23 // Split the stream into two parts to check for tool calls and print on screen
24 const [streamForTools, streamForResponse] = stream.tee();
25 const toolCalls = await getToolsFromRunStream(streamForTools);
26
27 // Check if any tool calls are present
28 const hasToolCalls = toolCalls.length > 0;
29
30 // If tool calls are present, handle them
31 if (hasToolCalls) {
32 // Handle tool calls (to be implemented)
33 } else {
34 // If no tool calls are present, get the runner and listen for content
35 const runner = getRunner(streamForResponse);
36 runner.on('content', content => {
37 process.stdout.write(content);
38 });
39 }
40}
41
42// Execute the email agent with a test prompt
43(async () => {
44 const userPrompt = 'Fetch latest email from my inbox.';
45 await userEmailAgent(userPrompt);
46})();Let's take a look at what is happening in this code:
- Define
userEmailAgent, which sends a request to the Langbase agent with a system prompt and user input. - Split the response stream into two:
- One checks if tool calls exist.
- The other prints the response on the screen if no tools are needed.
- If a tool call is detected, it will be handled in the next step. Otherwise, you will print the stream on the console.
- Define an immediately invoked function expression (IIFE) where you have called
userEmailAgentfunction. This will call the function when you run the file.
Step #10Implement tool calls
Now you will handle the case when agent pipes make a tool call. Go ahead and add the following code in email-agent.ts file:
1import { Langbase, Tools, getRunner, getToolsFromRunStream } from 'langbase';
2import { UnifiedTo } from '@unified-api/typescript-sdk';
3import 'dotenv/config';
4
5// Initialize Langbase SDK
6const langbase = new Langbase({
7 apiKey: process.env.LANGBASE_API_KEY!
8});
9
10// Initialize Unified API SDK
11const unified = new UnifiedTo({
12 security: {
13 jwt: process.env.UNIFIED_API_KEY!
14 }
15});
16
17// Function to fetch emails from user inbox
18async function fetchEmails(args: { num: string }) {
19 const num = args.num || '1';
20
21 // use unified messaging API to fetch x number of emails
22 const emails = await unified.messaging.listMessagingMessages({
23 connectionId: 'REPLACE_WITH_CONNECTION_ID',
24 channelId: 'inbox',
25 limit: parseInt(num)
26 });
27
28 for (const email of emails) {
29 const emailContent = email.message;
30 console.log('Email:', emailContent);
31 }
32}
33
34// All tools available in the agent
35const allTools: Record<string, Function> = {
36 fetchEmails
37};
38
39// Tool definition to fetch emails from user inbox
40const fetchEmailToolDefinition: Tools = {
41 type: 'function',
42 function: {
43 name: 'fetchEmails',
44 description: 'Fetch number of emails from user inbox.',
45 parameters: {
46 type: 'object',
47 required: ['num'],
48 properties: {
49 num: {
50 type: 'string',
51 description:
52 'The number of emails to fetch from the user inbox. Default value is 1.'
53 }
54 }
55 }
56 }
57};
58
59async function userEmailAgent(prompt: string) {
60 // Call the email agent pipe
61 const { stream } = await langbase.pipes.run({
62 stream: true,
63 name: 'email-agent',
64 messages: [
65 {
66 role: 'system',
67 content: `You are an AI email agent that fetches emails from user inbox.
68 If user asks anything other than fetching emails,
69 you should respond that you can only process prompts related to emails.`
70 },
71 {
72 role: 'user',
73 content: prompt
74 }
75 ],
76 tools: [fetchEmailToolDefinition]
77 });
78
79 // Split the stream into two parts to check for tool calls and print on screen
80 const [streamForTools, streamForResponse] = stream.tee();
81 const toolCalls = await getToolsFromRunStream(streamForTools);
82
83 // Check if any tool calls are present
84 const hasToolCalls = toolCalls.length > 0;
85
86 // If tool calls are present, handle them
87 if (hasToolCalls) {
88 toolCalls.map(async tool => {
89 const fnName = tool.function.name;
90 const fnArgs = JSON.parse(tool.function.arguments);
91
92 if (allTools[fnName]) {
93 await allTools[fnName](fnArgs);
94 } else {
95 console.error(`Function "${fnName}" not found.`);
96 }
97 });
98 } else {
99 // If no tool calls are present, get the runner and listen for content
100 const runner = getRunner(streamForResponse);
101 runner.on('content', content => {
102 process.stdout.write(content);
103 });
104 }
105}
106
107(async () => {
108 const userPrompt = 'Fetch latest email from my inbox.';
109 await userEmailAgent(userPrompt);
110})();Let's take a look at the above code:
- Initialize the Unified API SDK with the API key from the environment variables.
- Define a
fetchEmailsfunction that takes anumas an argument. Thenumdefines how many emails the function needs to fetch and uses Unified SDK to fetch emails. fetchEmailsfunction then logs the email content on the console- Create an object that contains the
fetchEmailsfunction tool. - Inside
userEmailAgentfunction, map over the tools array to call every tool the agent called.
You can find the connection id inside connections in the Unified dashboard.
Step #11Run the agent
Run the email agent by running the following command in terminal:
1npx tsx email-agent.tsYou should see the response in your terminal. Here’s an example output you’ll see in the console:
1Hi folks,
2
3I just wanted to share how impressed I am with the service I received yesterday!
4The product worked perfectly, and customer support was incredibly helpful and efficient.
5
6Great job to the team!
7John.This is how you can build an AI email agent using Langbase pipe agents and Unified messaging API.
Next steps
We have also written a guide to help you build a fully functional AI email response generator workflow. This composable multi-agent AI workflow takes user email, analyzes its sentiment, summarizes it, decides whether to respond, and generates the response email if needed.
You can pass the emails you get from the above pipe agent we created through this composable multi-agent AI email agent workflow and generate response emails as well.
Build your own composable multi-agent email AI workflow
This composable multi-agent workflow analyzes, summarizes, and responds to emails when needed.
