vercel / ai-chatbot

A full-featured, hackable Next.js AI chatbot built by Vercel
https://chat.vercel.ai
Other
5.51k stars 1.62k forks source link

tools : File_search #351

Open babakhalid opened 1 month ago

babakhalid commented 1 month ago

Hello,

Please, how can I add file search in the actions.tsx file and retrieve data from the vector I have in the assistant? I tried this code:


fileSearchTool: {
    description: 'Search and retrieve answers from files based on user queries using vector search.',
    parameters: z.object({
      query: z.string().describe('The search query to find relevant answers from files.')
    }),
    generate: async function* ({ query }) {
      const results = await fetchFileSearchResults(query);

      yield (
        <BotCard>
          <div>Searching for answers related to "{query}"...</div>
        </BotCard>
      );

      await sleep(1000); // Simulate async operation

      return (
        <BotCard>
          <ul>
            {results.map((result, index) => (
              <li key={index}>
                <div><strong>Answer:</strong> {result.answer}</div>
                <div><strong>File:</strong> {result.file}</div>
              </li>
            ))}
          </ul>
        </BotCard>
      );
    }
  },

const fetchFileSearchResults = async (query: string): Promise<FileSearchResult[]> => {
  // Create a new thread with the user's query
  const thread = await openai2.beta.threads.create({
    messages: [
      {
        role: "user",
        content: query,
        // Attach the relevant vector store for file search
        attachments: [{ file_id: "my_vector_store_id", tools: [{ type: "file_search" }] }],
      },
    ],
  });

  const threadId = thread.id;

  // Stream the run results
  const stream = openai2.beta.threads.runs.stream(threadId, {
    assistant_id: "my_assistant_id",
  });

  const results: FileSearchResult[] = [];

  return new Promise((resolve, reject) => {
    stream.on("textDelta", (delta) => {
      if (delta.annotations && delta.annotations.length > 0) {
        delta.annotations.forEach((annotation) => {
          if (annotation.type === "file_path") {
            results.push({
              answer: delta.value,
              file: annotation.text,
            });
          }
        });
      }
    });

    stream.on("end", () => resolve(results));
    stream.on("error", (err) => reject(err));
  });
};