Aller au contenu principal

Intégrer Mastra à votre projet Astro

Dans ce guide, vous allez créer avec Mastra un Agent d’IA capable d’appeler des Tools, puis le connecter à Astro en l’important et en l’appelant directement depuis vos routes.

Vous utiliserez AI SDK UI et AI Elements pour créer une expérience de chat élégante et interactive.

remarque

Ce guide montre comment utiliser Astro avec React et un rendu complet côté serveur (SSR), mais Astro peut être associé à Mastra de nombreuses manières. Vous pouvez activer le SSR fichier par fichier et utiliser d’autres frameworks comme Svelte, Vue, Solid ou Preact. Vous pouvez également créer une interface de chat avec Astro et appeler des endpoints nativement dans Astro.

Avant de commencer
Lien direct vers Avant de commencer

  • Vous aurez besoin d’une clé d’API fournie par un Provider de modèle pris en charge. Si vous n’avez pas de préférence, utilisez OpenAI.
  • Installez Node.js v22.13.0 ou une version ultérieure

Créer une nouvelle application Astro (facultatif)
Lien direct vers Créer une nouvelle application Astro (facultatif)

Si vous disposez déjà d’une application Astro, passez à l’étape suivante. Votre application Astro doit être configurée comme suit :

  • Utiliser le SSR (output: "server" dans astro.config.mjs)
  • Utiliser l’intégration React
  • Installer Tailwind

Pour prendre en charge le rendu à la demande, ce guide utilise l’adaptateur Node.js, mais n’importe quel adaptateur de serveur pris en charge convient.

npm create astro@latest mastra-astro -- --add node --add react --add tailwind --install --skip-houston --template minimal --git

Cette commande crée un projet nommé mastra-astro, mais vous pouvez choisir un autre nom.

Accédez à votre projet avec cd, puis modifiez le fichier astro.config.mjs pour définir le paramètre output sur "server" :

// @ts-check
import { defineConfig } from 'astro/config'

import node from '@astrojs/node'
import react from '@astrojs/react'
import tailwindcss from '@tailwindcss/vite'

// https://astro.build/config
export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone',
}),

integrations: [react()],

vite: {
plugins: [tailwindcss()],
},
})

Modifiez le fichier tsconfig.json pour résoudre les chemins :

tsconfig.json
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
},
// ...
},
}

Initialiser Mastra
Lien direct vers Initialiser Mastra

Exécutez mastra init. Lorsque vous y êtes invité, choisissez un Provider, par exemple OpenAI, puis saisissez votre clé :

npx mastra@latest init

Cette commande crée un dossier src/mastra contenant un exemple d’Agent météo et les fichiers suivants :

  • index.ts : configuration de Mastra, notamment la Memory
  • tools/weather-tool.ts : Tool permettant de récupérer la météo d’un lieu donné
  • agents/weather-agent.ts : Agent météo dont le prompt utilise le Tool

Vous appellerez weather-agent.ts depuis vos routes Astro au cours des étapes suivantes.

Installer AI SDK UI et AI Elements
Lien direct vers Installer AI SDK UI et AI Elements

Installez AI SDK UI avec l’adaptateur Mastra :

npm install @mastra/ai-sdk@latest @ai-sdk/react ai

Initialisez ensuite AI Elements. Lorsque vous y êtes invité, sélectionnez les options par défaut :

npx ai-elements@latest

Cette commande télécharge toute la bibliothèque de composants UI d’AI Elements dans un dossier @/components/ai-elements.

Créer une route de chat
Lien direct vers Créer une route de chat

Créez src/pages/api/chat.ts :

src/pages/api/chat.ts
import type { APIRoute } from 'astro'
import { handleChatStream } from '@mastra/ai-sdk'
import { toAISdkV5Messages } from '@mastra/ai-sdk/ui'
import { createUIMessageStreamResponse } from 'ai'
import { mastra } from '@/mastra'

const THREAD_ID = 'example-user-id'
const RESOURCE_ID = 'weather-chat'

export const POST: APIRoute = async ({ request }) => {
const params = await request.json()
const stream = await handleChatStream({
mastra,
agentId: 'weather-agent',
params: {
...params,
memory: {
...params.memory,
thread: THREAD_ID,
resource: RESOURCE_ID,
},
},
})

return createUIMessageStreamResponse({ stream })
}

export const GET: APIRoute = async () => {
const memory = await mastra.getAgentById('weather-agent').getMemory()
let response = null

try {
response = await memory?.recall({
threadId: THREAD_ID,
resourceId: RESOURCE_ID,
})
} catch {
console.log('No previous messages found.')
}

const uiMessages = toAISdkV5Messages(response?.messages || [])

return Response.json(uiMessages)
}

La route POST accepte un prompt et renvoie la réponse diffusée de l’Agent au format AI SDK, tandis que la route GET récupère l’historique des messages depuis la Memory afin que l’UI puisse être hydratée lorsque le client recharge la page.

Créer un composant de chat
Lien direct vers Créer un composant de chat

Créez src/components/chat.tsx :

src/components/chat.tsx
import '@/styles/global.css'
import { useEffect, useState } from 'react'
import { DefaultChatTransport, type ToolUIPart } from 'ai'
import { useChat } from '@ai-sdk/react'

import {
PromptInput,
PromptInputBody,
PromptInputTextarea,
} from '@/components/ai-elements/prompt-input'

import {
Conversation,
ConversationContent,
ConversationScrollButton,
} from '@/components/ai-elements/conversation'

import { Message, MessageContent, MessageResponse } from '@/components/ai-elements/message'

import { Tool, ToolHeader, ToolContent, ToolInput, ToolOutput } from '@/components/ai-elements/tool'

function Chat() {
const [input, setInput] = useState<string>('')

const { messages, setMessages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
}),
})

useEffect(() => {
const fetchMessages = async () => {
const res = await fetch('/api/chat')
const data = await res.json()
setMessages([...data])
}
fetchMessages()
}, [setMessages])

const handleSubmit = async () => {
if (!input.trim()) return

sendMessage({ text: input })
setInput('')
}

return (
<div className="relative size-full h-screen w-full p-6">
<div className="flex h-full flex-col">
<Conversation className="h-full">
<ConversationContent>
{messages.map(message => (
<div key={message.id}>
{message.parts?.map((part, i) => {
if (part.type === 'text') {
return (
<Message key={`${message.id}-${i}`} from={message.role}>
<MessageContent>
<MessageResponse>{part.text}</MessageResponse>
</MessageContent>
</Message>
)
}

if (part.type?.startsWith('tool-')) {
return (
<Tool key={`${message.id}-${i}`}>
<ToolHeader
type={(part as ToolUIPart).type}
state={(part as ToolUIPart).state || 'output-available'}
className="cursor-pointer"
/>
<ToolContent>
<ToolInput input={(part as ToolUIPart).input || {}} />
<ToolOutput
output={(part as ToolUIPart).output}
errorText={(part as ToolUIPart).errorText}
/>
</ToolContent>
</Tool>
)
}

return null
})}
</div>
))}
<ConversationScrollButton />
</ConversationContent>
</Conversation>

<PromptInput onSubmit={handleSubmit} className="mt-20">
<PromptInputBody>
<PromptInputTextarea
onChange={e => setInput(e.target.value)}
className="md:leading-10"
value={input}
placeholder="Type your message..."
disabled={status !== 'ready'}
/>
</PromptInputBody>
</PromptInput>
</div>
</div>
)
}

export default Chat

Ce composant connecte useChat() à l’endpoint api/chat, auquel il envoie les prompts et dont il reçoit la réponse sous forme de fragments diffusés.

Il affiche le texte de la réponse à l’aide du composant <MessageResponse> et les appels de Tools avec le composant <Tool>.

Afficher le composant de chat
Lien direct vers Afficher le composant de chat

La dernière étape consiste à afficher le composant de chat sur votre page d’index. Modifiez src/pages/index.astro :

src/pages/index.astro
---
import Chat from '@/components/chat';
---

<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content="{Astro.generator}" />
<title>Astro</title>
</head>
<body>
<Chat client:load />
</body>
</html>

Importez le composant Chat et ajoutez-le au corps de la page avec la directive client:load afin qu’il s’exécute côté client.

Tester votre Agent
Lien direct vers Tester votre Agent

  1. Lancez votre application Astro avec npm run dev
  2. Ouvrez le chat à l’adresse http://localhost:4321
  3. Posez une question sur la météo. Si votre clé d’API est correctement configurée, vous recevrez une réponse

Étapes suivantes
Lien direct vers Étapes suivantes

Félicitations, vous avez créé votre Agent Mastra avec Astro ! 🎉

Vous pouvez maintenant enrichir le projet avec vos propres Tools et votre propre logique :

  • En savoir plus sur les Agents
  • Ajouter des Tools à votre Agent
  • Ajouter une Memory similaire à la mémoire humaine à votre Agent

Lorsque vous serez prêt, découvrez comment Mastra s’intègre à AI SDK UI et comment déployer votre Agent où vous le souhaitez :