diff --git a/apps/server/src/routes/agent/index.ts b/apps/server/src/routes/agent/index.ts index 49ddb59fd..e31dfc20a 100644 --- a/apps/server/src/routes/agent/index.ts +++ b/apps/server/src/routes/agent/index.ts @@ -1371,21 +1371,29 @@ export class ZeroDriver extends Agent { }).then((r) => r.threads.map((t) => t.id)), ).pipe(Effect.catchAll(() => Effect.succeed([]))); + const effects: Effect.Effect[] = [rawEffect]; + if (this.env.AUTORAG_ID) effects.unshift(ragEffect as Effect.Effect); + // Run both in parallel and wait for results - const results = await Effect.runPromise( - Effect.all([ragEffect, rawEffect], { concurrency: 'unbounded' }), - ); + const results = await Effect.runPromise(Effect.all(effects, { concurrency: 'unbounded' })); + if (this.env.AUTORAG_ID) { + const [ragIds, rawIds] = results; - const [ragIds, rawIds] = results; + // Return InboxRag results if found, otherwise fallback to raw + if (ragIds.length > 0) { + return { + threadIds: ragIds, + source: 'autorag' as const, + }; + } - // Return InboxRag results if found, otherwise fallback to raw - if (ragIds.length > 0) { return { - threadIds: ragIds, - source: 'autorag' as const, + threadIds: rawIds, + source: 'raw' as const, + nextPageToken: pageToken, }; } - + const [rawIds] = results; return { threadIds: rawIds, source: 'raw' as const, diff --git a/apps/server/src/routes/agent/tools.ts b/apps/server/src/routes/agent/tools.ts index 36edbcb7a..85f67f076 100644 --- a/apps/server/src/routes/agent/tools.ts +++ b/apps/server/src/routes/agent/tools.ts @@ -136,7 +136,9 @@ const getThreadSummary = (connectionId: string) => const thread = await driver.getThread(id); if (response.length && response?.[0]?.metadata?.['summary'] && thread?.latest?.subject) { const result = response[0].metadata as { summary: string; connection: string }; - if (result.connection !== connectionId) return null; + if (result.connection !== connectionId) { + return null; + } const shortResponse = await env.AI.run('@cf/facebook/bart-large-cnn', { input_text: result.summary, }); @@ -147,7 +149,11 @@ const getThreadSummary = (connectionId: string) => date: thread.latest?.receivedOn, }; } - return null; + return { + subject: thread.latest?.subject, + sender: thread.latest?.sender, + date: thread.latest?.receivedOn, + }; }, }); @@ -448,8 +454,8 @@ export const webSearch = () => }, }); -export const tools = async (connectionId: string) => { - return { +export const tools = async (connectionId: string, ragEffect: boolean = false) => { + const _tools = { [Tools.GetThread]: getEmail(), [Tools.GetThreadSummary]: getThreadSummary(connectionId), [Tools.ComposeEmail]: composeEmailTool(connectionId), @@ -464,6 +470,23 @@ export const tools = async (connectionId: string) => { [Tools.DeleteLabel]: deleteLabel(connectionId), [Tools.BuildGmailSearchQuery]: buildGmailSearchQuery(), [Tools.GetCurrentDate]: getCurrentDate(), + [Tools.InboxRag]: tool({ + description: + 'Search the inbox for emails using natural language. Returns only an array of threadIds.', + parameters: z.object({ + query: z.string().describe('The query to search the inbox for'), + maxResults: z.number().describe('The maximum number of results to return').default(10), + }), + execute: async ({ query, maxResults }) => { + const agent = await getZeroAgent(connectionId); + const res = await agent.searchThreads({ query, maxResults }); + return res.threadIds; + }, + }), + }; + if (ragEffect) return _tools; + return { + ..._tools, [Tools.InboxRag]: tool({ description: 'Search the inbox for emails using natural language. Returns only an array of threadIds.', diff --git a/apps/server/src/routes/ai.ts b/apps/server/src/routes/ai.ts index bffacb26c..aee6ae61f 100644 --- a/apps/server/src/routes/ai.ts +++ b/apps/server/src/routes/ai.ts @@ -2,6 +2,7 @@ import { systemPrompt } from '../services/call-service/system-prompt'; import { openai } from '@ai-sdk/openai'; import { tools } from './agent/tools'; import { generateText } from 'ai'; +import { Tools } from '../types'; import { createDb } from '../db'; import { env } from '../env'; import { Hono } from 'hono'; @@ -28,11 +29,12 @@ aiRouter.post('/do/:action', async (c) => { // if (env.DISABLE_CALLS) return c.json({ success: false, error: 'Not implemented' }, 400); if (env.VOICE_SECRET !== c.req.header('X-Voice-Secret')) return c.json({ success: false, error: 'Unauthorized' }, 401); - if (!c.req.header('X-Caller')) return c.json({ success: false, error: 'Unauthorized' }, 401); + const caller = c.req.header('X-Caller'); + if (!caller) return c.json({ success: false, error: 'Unauthorized' }, 401); const { db, conn } = createDb(env.HYPERDRIVE.connectionString); const user = await db.query.user.findFirst({ where: (user, { eq, and }) => - and(eq(user.phoneNumber, c.req.header('X-Caller')!), eq(user.phoneNumberVerified, true)), + and(eq(user.phoneNumber, caller), eq(user.phoneNumberVerified, true)), }); if (!user) return c.json({ success: false, error: 'Unauthorized' }, 401); @@ -44,12 +46,12 @@ aiRouter.post('/do/:action', async (c) => { if (!connection) return c.json({ success: false, error: 'Unauthorized' }, 401); try { - const action = c.req.param('action'); + const action = c.req.param('action') as keyof ToolsReturnType; const body = await c.req.json(); console.log('[DEBUG] action', action, body); // Get all tools for this connection - const toolset: ToolsReturnType = await tools(connection.id); + const toolset: ToolsReturnType = await tools(connection.id, action === Tools.InboxRag); const tool = toolset[action as keyof ToolsReturnType]; if (!tool) { diff --git a/scripts/register-elevenlabs-tools.ts b/scripts/register-elevenlabs-tools.ts index 65ad8bc79..b4e4041c3 100644 --- a/scripts/register-elevenlabs-tools.ts +++ b/scripts/register-elevenlabs-tools.ts @@ -40,7 +40,7 @@ export const toolDefinitions: ToolDefinition[] = [ name: Tools.GetThreadSummary, description: 'Get the summary of a specific email thread', parameters: z.object({ - id: z.string().describe('The ID of the email thread to get the summary of'), + id: z.string().describe('The threadId of the email thread to get the summary of'), }), }, { @@ -189,6 +189,7 @@ export const toolDefinitions: ToolDefinition[] = [ 'Search the inbox for emails using natural language. Returns only an array of threadIds.', parameters: z.object({ query: z.string().describe('The query to search the inbox for'), + maxResults: z.number().describe('The maximum number of results to return').default(10), }), }, ]; @@ -206,7 +207,7 @@ interface ElevenLabsToolRequest { properties: any; required?: string[]; }; - request_headers: Record; + request_headers: Record; }; }; } @@ -477,7 +478,7 @@ async function updateAgent(apiKey: string, agentId: string, toolIds: string[]): async function main() { const apiKey = process.env.ELEVENLABS_API_KEY; - const serverUrl = process.env.SERVER_URL || 'https://staging.0.email'; + const serverUrl = process.env.SERVER_URL; const voiceSecret = process.env.VOICE_SECRET; const agentId = process.env.ELEVENLABS_AGENT_ID; @@ -557,7 +558,9 @@ async function main() { request_headers: { 'Content-Type': 'application/json', 'X-Voice-Secret': voiceSecret, - 'X-Caller': 'system__caller_id', + 'X-Caller': { + variable_name: 'system__caller_id', + }, }, }, },