import { metadata, task } from "@trigger.dev/sdk"; import { streamText, type CoreMessage, tool } from "ai"; import { z } from "zod"; import { openai } from "@ai-sdk/openai"; import { logger } from "~/services/logger.service"; import { getOrCreatePersonalAccessToken } from "../utils/utils"; import axios from "axios"; export const ExtensionSearchBodyRequest = z.object({ userInput: z.string().min(1, "User input is required"), userId: z.string().min(1, "User ID is required"), context: z .string() .optional() .describe("Additional context about the user's current work"), }); // Export a singleton instance export const extensionSearch = task({ id: "extensionSearch", maxDuration: 3000, run: async (body: z.infer) => { const { userInput, userId, context } = ExtensionSearchBodyRequest.parse(body); const pat = await getOrCreatePersonalAccessToken({ name: "extensionSearch", userId: userId as string, }); // Define the searchMemory tool that actually calls the search service const searchMemoryTool = tool({ description: "Search the user's memory for relevant facts and episodes based on a query", parameters: z.object({ query: z.string().describe("Search query to find relevant information"), }), execute: async ({ query }) => { try { const response = await axios.post( `${process.env.API_BASE_URL}/api/v1/search`, { query }, { headers: { Authorization: `Bearer ${pat.token}`, }, }, ); const searchResult = response.data; return { facts: searchResult.facts || [], episodes: searchResult.episodes || [], }; } catch (error) { logger.error(`SearchMemory tool error: ${error}`); return { facts: [], episodes: [], }; } }, }); const messages: CoreMessage[] = [ { role: "system", content: `You are a specialized memory search and summarization agent. Your job is to: 1. First, use the searchMemory tool to find relevant information from the user's memory based on their input 2. Then, analyze the retrieved facts and episodes to create a concise, relevant summary You have access to a searchMemory tool that can search the user's knowledge base. Use this tool with relevant search queries to find information that would help answer their question. After retrieving the information, provide a concise summary (2-4 sentences) that highlights the most relevant context for answering their question. Focus on: - Key facts that directly relate to their question - Important background information or decisions - Relevant examples or past experiences - Critical context that would help provide a good answer If no relevant information is found, provide a brief statement indicating that.`, }, { role: "user", content: `User input: "${userInput}"${context ? `\n\nAdditional context: ${context}` : ""}\n\nPlease search my memory for relevant information and provide a concise summary of the most important context for this question.`, }, ]; try { const result = streamText({ model: openai(process.env.MODEL as string), messages, tools: { searchMemory: searchMemoryTool, }, maxSteps: 5, temperature: 0.3, maxTokens: 600, }); const stream = await metadata.stream("messages", result.textStream); let finalText: string = ""; for await (const chunk of stream) { finalText = finalText + chunk; } return finalText; } catch (error) { logger.error(`SearchMemoryAgent error: ${error}`); return `Context related to: ${userInput}. Looking for relevant background information, previous discussions, and related concepts that would help provide a comprehensive answer.`; } }, });