-
Notifications
You must be signed in to change notification settings - Fork 147
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Bug Description
The Streamdown package works as expected for general rendering, but it fails to correctly display mathematical equations. Other functionalities are working fine.
Steps to Reproduce
You can just try it out. This is what I have facing problem in.
This is the code for my API:-
import { auth } from "@clerk/nextjs/server";
import { createOpenAI } from "@ai-sdk/openai";
import { streamText } from "ai";
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY as string,
});
export async function POST(request: Request) {
try {
const { userId } = await auth();
if (!userId) {
console.log("❌ Unauthorized request - no userId");
return new Response(
JSON.stringify({
error: "Unauthorized - Please sign in to use this service",
}),
{ status: 401, headers: { "Content-Type": "application/json" } }
);
}
const body = await request.json();
let { messages, model, system, prompt } = body || {};
if ((!messages || !Array.isArray(messages) || messages.length === 0) && typeof prompt === "string" && prompt.trim().length > 0) {
messages = [{ role: "user", content: prompt }];
}
if (!messages || !Array.isArray(messages) || messages.length === 0) {
return new Response(JSON.stringify({ error: "Messages are required" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
}
const formattedMessages = messages.map((msg: any) => ({
role: msg.role,
content: msg.content,
}));
const selectedModel = typeof model === "string" && model.trim().length > 0
? openai(model)
: openai("gpt-4o-mini");
const systemPrompt =
typeof system === "string" && system.trim().length > 0
? system
: "You are a helpful AI assistant. You can help with various tasks including text processing, answering questions, and general conversation. Be friendly and informative.";
const streaming = streamText({
model: selectedModel,
system: systemPrompt,
messages: formattedMessages,
maxOutputTokens: 1024,
});
return streaming.toTextStreamResponse();
} catch (error) {
console.error("Chat API error:", error);
return new Response(JSON.stringify({ error: "Internal server error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}And this is the code for the client side(Not fancy but yeah testing right now):-
"use client";
import { useEffect } from "react";
import { useCompletion } from "@ai-sdk/react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Streamdown } from "streamdown";
export default function AIDashboard() {
const { completion, input, setInput, handleSubmit, isLoading, error } =
useCompletion({
api: "/api/cipher",
streamProtocol: "text",
});
useEffect(() => {
if (error) {
// eslint-disable-next-line no-console
console.error("Chat error:", error);
}
}, [error]);
return (
<div className="space-y-4 p-4 max-w-4xl mx-auto">
<div className="space-y-4 min-h-[300px] max-h-[500px] overflow-y-auto border rounded-lg p-4">
{!completion && (
<div className="text-center text-muted-foreground py-8">
<p>Start a conversation with the AI assistant!</p>
<p className="text-sm">
Ask questions, request help, or just chat.
</p>
</div>
)}
{completion && (
<div className="p-4 rounded-lg bg-gray-50 dark:bg-gray-900/20 border border-gray-200 dark:border-gray-800 mr-12">
<div className="flex items-start space-x-2">
<div className="font-semibold text-sm text-gray-800 dark:text-gray-200">
AI Assistant
</div>
</div>
<div className="mt-2 whitespace-pre-wrap text-gray-800 dark:text-gray-200">
<Streamdown>{completion}</Streamdown>
</div>
</div>
)}
{isLoading && (
<div className="bg-gray-50 dark:bg-gray-900/20 border border-gray-200 dark:border-gray-800 mr-12 p-4 rounded-lg">
<div className="flex items-center space-x-2">
<div className="font-semibold text-sm text-gray-800 dark:text-gray-200">
AI Assistant
</div>
<div className="text-sm text-gray-500">typing...</div>
</div>
<div className="mt-2 flex space-x-1">
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
<div
className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"
style={{ animationDelay: "0.1s" }}
></div>
<div
className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"
style={{ animationDelay: "0.2s" }}
></div>
</div>
</div>
)}
</div>
{/* Error Display */}
{!!error && (
<div className="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800">
<p className="text-red-800 dark:text-red-200">
Error: {String((error as any)?.message ?? "Something went wrong")}
</p>
</div>
)}
<form onSubmit={handleSubmit} className="space-y-3">
<div>
<label
htmlFor="chat-input"
className="block text-sm font-medium mb-2"
>
Message the AI Assistant:
</label>
<Textarea
id="chat-input"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Ask the AI assistant anything! Try: 'Hello!' or 'Tell me a joke' or 'Explain React'"
className="min-h-24"
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmit(e as any);
}
}}
/>
<p className="text-xs text-muted-foreground mt-1">
Press Enter to send, Shift+Enter for new line
</p>
</div>
<Button
type="submit"
disabled={!input.trim() || isLoading}
className="w-full"
>
{isLoading ? (
<div className="flex items-center space-x-2">
<div className="w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"></div>
<span>Sending...</span>
</div>
) : (
"Send Message"
)}
</Button>
</form>
</div>
);
}Expected Behavior
Just to render out the mathematical equations in the output that's all.
Actual Behavior
The Mathematical Equations is just throwing out the syntax and looking quite weird.
Code Sample
Streamdown Version
^1.3.0
React Version
19.1.1
Node.js Version
24.4.1
Browser(s)
Safari
Operating System
macOS
Additional Context
No response
koskeller
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working