Augment an existing Next.js 14 chatbot (built with the Vercel AI SDK) so it can answer questions using real‑time, trusted data from Tako and display rich Knowledge Cards right in the chat UI.

1 · Prerequisites

All steps below assume the canonical nextjs‑ai‑chatbot code base. If you started from scratch, follow Vercel’s Quickstart first, then return here.

2 · Install the Tako SDK

pnpm install tako-sdk

3 · Add a searchTakoKnowledge tool

import { tool } from 'ai';
import { z } from 'zod';
import { createTakoClient } from 'tako-sdk';

export const searchTakoKnowledge = tool({
  description: 'Search Tako for any knowledge or information-related questions, and get back answers and visual cards',
  parameters: z.object({
    query: z.string().describe('The search query to find relevant knowledge cards'),
  }),
  execute: async ({ query }) => {
    try {
      const tako = createTakoClient(process.env.TAKO_API_KEY!);
      const search = await tako.knowledgeSearch(query);
      return search.outputs.knowledge_cards;
    } catch (error: any) {
      throw new Error(`Failed to search Tako knowledge: ${error.message}`);
    }
  },
});

4 · Wire the tool into the Edge Route

Open app/(chat)/api/chat/route.ts and make three small edits:
  1. Add the import at the top
    import { searchTakoKnowledge } from '@/lib/ai/tools/tako';
    
  2. Register the executor in the tools map:
    tools: {
      searchTakoKnowledge,
      getWeather,
      // …other tools
    }
    
That’s it—no other middleware or route changes are necessary.

5 · Render Knowledge Cards in the Chat UI

Inside components/message.tsx, extend the preview switch so it recognises the new tool:
import { TakoCard } from './tako-card'; // add alongside other imports

// … inside the message renderer:

{toolName === 'searchTakoKnowledge' ? (
  <div className="flex flex-col gap-4">
    {result.map((c: any, i: number) => (
      <TakoCard key={i} card={c} />
    ))}
  </div>
) : toolName === 'getWeather' ? (
  // existing branches…
) : (
  <pre>{JSON.stringify(result, null, 2)}</pre>
)}
This simply maps the knowledge_cards array to a deck of responsive <TakoCard> components. With this in place, every time the model invokes searchTakoKnowledge, the returned array of cards is rendered as a deck of responsive iframes.

6 · Create the TakoCard component

import { Card } from './ui/card';
import { KnowledgeCard } from 'tako-sdk';
import { useEffect } from 'react';

export function TakoCard({ card }: { card: KnowledgeCard }) {
  useEffect(() => {
    const handleMessage = (e: MessageEvent) => {
      const d = e.data;
      if (d.type !== "tako::resize") return;
      
      for (let iframe of document.querySelectorAll("iframe")) {
        if (iframe.contentWindow !== e.source) continue;
        iframe.style.height = d.height + "px";
      }
    };

    window.addEventListener("message", handleMessage);
    return () => window.removeEventListener("message", handleMessage);
  }, []);

  return (
    <Card className="p-4 flex flex-col gap-3 max-w-2xl">
        <div className="relative w-full aspect-video">
          <iframe
            src={card.embed_url}
            title={card.title}
            className="w-full h-full rounded-lg"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            allowFullScreen
          />
        </div>
      <div className="flex flex-col gap-2">
        <h3 className="font-medium">{card.title}</h3>
      </div>
    </Card>
  );
}
This component embeds each Knowledge Card via Tako’s embed_url, responds to dynamic height messages for a seamless fit, and uses your existing Card UI primitive for consistent styling. With this in place, every time the model invokes searchTakoKnowledge, the returned array of cards is rendered as a deck of responsive iframes.

7 · Deploy

vercel --prod
Ensure TAKO_API_KEY is added to the Vercel Project’s Environment Variables (Production + Preview).