Skip to content

Instantly share code, notes, and snippets.

@bookercodes
Created November 16, 2025 20:19
Show Gist options
  • Select an option

  • Save bookercodes/8ffa355c0a6eeaf7d840511afdb15e90 to your computer and use it in GitHub Desktop.

Select an option

Save bookercodes/8ffa355c0a6eeaf7d840511afdb15e90 to your computer and use it in GitHub Desktop.
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";
export default function Chat() {
const [input, setInput] = useState("");
const [imageUrl, setImageUrl] = useState("");
const [imageFile, setImageFile] = useState<File | null>(null);
const { messages, setMessages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: "/api/chat",
}),
});
const handleImageChange = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const file = event.target.files?.[0];
if (file) {
setImageFile(file);
const reader = new FileReader();
reader.onloadend = () => {
setImageUrl(reader.result as string);
};
reader.readAsDataURL(file);
}
};
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
sendMessage({
role: "user",
parts: [
...(imageUrl.trim().length > 0
? [
{
type: "file" as const,
mediaType: imageFile?.type || "image/png",
url: imageUrl,
},
]
: []),
{ type: "text" as const, text: input },
],
});
setInput("");
setImageUrl("");
setImageFile(null);
};
return (
<div>
{imageUrl}
<div>
{messages.map((m) => (
<div key={m.id}>
<span>{m.role === "user" ? "User: " : "AI: "}</span>
<div>
{m.parts.map((part, i) => {
switch (part.type) {
case "text":
return part.text;
case "file":
return (
<img
key={(part.filename || "image") + i}
src={part.url}
alt={part.filename ?? "image"}
/>
);
default:
return null;
}
})}
</div>
</div>
))}
</div>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="image-upload">Upload Image:</label>
<input
id="image-upload"
type="file"
accept="image/*"
onChange={handleImageChange}
/>
{imageUrl && (
<img
src={imageUrl}
alt="Preview"
style={{ maxWidth: "200px", marginTop: "10px" }}
/>
)}
</div>
<div>
<label htmlFor="image-description">Prompt:</label>
<input
id="image-description"
value={input}
placeholder="What dog is this?"
onChange={(e) => setInput(e.currentTarget.value)}
/>
</div>
<button type="submit">Send Message</button>
</form>
</div>
);
}
import { mastra } from "@/mastra";
import { toAISdkFormat } from "@mastra/ai-sdk";
import { createUIMessageStreamResponse } from "ai";
const dogAgent = mastra.getAgent("dogAgent");
export async function POST(req: Request) {
const { messages } = await req.json();
const stream = await dogAgent.stream(messages, {
memory: {
thread: "example-user-id",
resource: "weather-chat", // change
},
});
return createUIMessageStreamResponse({
stream: toAISdkFormat(stream, { from: "agent" }),
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment