mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-02 22:32:27 +08:00
feat: update tool names and descriptions for diagram handling, add clear messages functionality in ChatInput
This commit is contained in:
@@ -21,22 +21,23 @@ export async function POST(req: Request) {
|
|||||||
You are a helpful assistant that can create, edit, and display diagram using draw.io through xml strings.
|
You are a helpful assistant that can create, edit, and display diagram using draw.io through xml strings.
|
||||||
You can use the following tools:
|
You can use the following tools:
|
||||||
---Tool1---
|
---Tool1---
|
||||||
tool name: display_flow_chart
|
tool name: display_diagram
|
||||||
description: write a xml and display it on draw.io
|
description: Display a diagram on draw.io
|
||||||
parameters: {
|
parameters: {
|
||||||
xml: string
|
xml: string
|
||||||
}
|
}
|
||||||
---Tool2---
|
|
||||||
tool name: fetch_flow_chart
|
|
||||||
description: Get the current diagram XML from draw.io
|
|
||||||
parameters: {}
|
|
||||||
---End of tools---
|
---End of tools---
|
||||||
|
|
||||||
When you need to modify the diagram, you need fetch the current diagram XML from draw.io and then modify it and display it again.
|
Here is a guide for the XML format:
|
||||||
here is a guide for the XML format: ${guide}
|
"""md
|
||||||
You can use the tools to create and manipulate diagram.
|
${guide}
|
||||||
|
"""
|
||||||
|
You can use the tools to create and manipulate diagrams.
|
||||||
You can also answer questions and provide explanations.
|
You can also answer questions and provide explanations.
|
||||||
If user want you to draw something rather than diagram, you can use the combination of the shape to draw it.
|
Note that:
|
||||||
|
- If the user wants you to draw something rather than a diagram, you can use the combination of the shapes to draw it.
|
||||||
|
- Consider the layout of the diagram and the shapes used to avoid overlapping.
|
||||||
|
- Ensure that the XML strings are well-formed and valid.
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Add system message if only user message is provided
|
// Add system message if only user message is provided
|
||||||
@@ -50,17 +51,12 @@ If user want you to draw something rather than diagram, you can use the combinat
|
|||||||
messages: enhancedMessages,
|
messages: enhancedMessages,
|
||||||
tools: {
|
tools: {
|
||||||
// Client-side tool that will be executed on the client
|
// Client-side tool that will be executed on the client
|
||||||
display_flow_chart: {
|
display_diagram: {
|
||||||
description: "Display a flowchart on draw.io",
|
description: "Display a diagram on draw.io",
|
||||||
parameters: z.object({
|
parameters: z.object({
|
||||||
xml: z.string().describe("XML string to be displayed on draw.io")
|
xml: z.string().describe("XML string to be displayed on draw.io")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// Client-side tool that will be executed on the client
|
|
||||||
fetch_flow_chart: {
|
|
||||||
description: "Get the current flowchart XML from draw.io",
|
|
||||||
parameters: z.object({})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
import React, { useCallback, useRef, useEffect } from "react"
|
import React, { useCallback, useRef, useEffect } from "react"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
import { Loader2, Send } from "lucide-react"
|
import { Loader2, Send, Trash } from "lucide-react"
|
||||||
|
|
||||||
interface ChatInputProps {
|
interface ChatInputProps {
|
||||||
input: string
|
input: string
|
||||||
status: "submitted" | "streaming" | "ready" | "error"
|
status: "submitted" | "streaming" | "ready" | "error"
|
||||||
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void
|
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void
|
||||||
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void
|
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void
|
||||||
|
setMessages: (messages: any[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ChatInput({ input, status, onSubmit, onChange }: ChatInputProps) {
|
export function ChatInput({ input, status, onSubmit, onChange, setMessages }: ChatInputProps) {
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||||
|
|
||||||
// Auto-resize textarea based on content
|
// Auto-resize textarea based on content
|
||||||
@@ -51,7 +52,17 @@ export function ChatInput({ input, status, onSubmit, onChange }: ChatInputProps)
|
|||||||
aria-label="Chat input"
|
aria-label="Chat input"
|
||||||
className="min-h-[80px] resize-none transition-all duration-200"
|
className="min-h-[80px] resize-none transition-all duration-200"
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-between gap-2">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="default"
|
||||||
|
onClick={() => setMessages([])}
|
||||||
|
title="Clear messages"
|
||||||
|
>
|
||||||
|
<Trash className="mr-2 h-4 w-4" />
|
||||||
|
Start a new conversation
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={status === "streaming" || !input.trim()}
|
disabled={status === "streaming" || !input.trim()}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useRef, useEffect } from "react"
|
|||||||
|
|
||||||
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
import { useChat } from '@ai-sdk/react';
|
import { useChat } from '@ai-sdk/react';
|
||||||
import { ChatInput } from "@/components/chat-input"
|
import { ChatInput } from "@/components/chat-input"
|
||||||
|
|
||||||
@@ -14,20 +15,16 @@ interface ChatPanelProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ChatPanel({ onDisplayChart, onFetchChart }: ChatPanelProps) {
|
export default function ChatPanel({ onDisplayChart, onFetchChart }: ChatPanelProps) {
|
||||||
const { messages, input, handleInputChange, handleSubmit, status, error, addToolResult } = useChat({
|
const { messages, input, handleInputChange, handleSubmit, status, error, setInput, setMessages } = useChat({
|
||||||
|
maxSteps: 5,
|
||||||
async onToolCall({ toolCall }) {
|
async onToolCall({ toolCall }) {
|
||||||
console.log("Tool call:", toolCall);
|
console.log("Tool call:", toolCall);
|
||||||
console.log("Tool call name:", toolCall.toolName);
|
console.log("Tool call name:", toolCall.toolName);
|
||||||
console.log("Tool call arguments:", toolCall.args);
|
console.log("Tool call arguments:", toolCall.args);
|
||||||
|
if (toolCall.toolName === "display_diagram") {
|
||||||
if (toolCall.toolName === "display_flow_chart") {
|
|
||||||
const { xml } = toolCall.args as { xml: string };
|
const { xml } = toolCall.args as { xml: string };
|
||||||
onDisplayChart(xml);
|
onDisplayChart(xml);
|
||||||
return "Successfully displayed the flowchart.";
|
return "Successfully displayed the flowchart.";
|
||||||
} else if (toolCall.toolName === "fetch_flow_chart") {
|
|
||||||
const currentXML = await onFetchChart();
|
|
||||||
console.log("Current XML:", currentXML);
|
|
||||||
return currentXML;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@@ -41,11 +38,24 @@ export default function ChatPanel({ onDisplayChart, onFetchChart }: ChatPanelPro
|
|||||||
if (messagesEndRef.current) {
|
if (messagesEndRef.current) {
|
||||||
messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
|
messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
|
||||||
}
|
}
|
||||||
|
console.log("Messages updated:", messages);
|
||||||
}, [messages])
|
}, [messages])
|
||||||
|
|
||||||
const onFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const onFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (input.trim() && status !== "streaming") {
|
if (input.trim() && status !== "streaming") {
|
||||||
|
setInput(
|
||||||
|
`
|
||||||
|
Current diagram XML:
|
||||||
|
"""xml
|
||||||
|
${onFetchChart()}
|
||||||
|
"""
|
||||||
|
User input:
|
||||||
|
"""md
|
||||||
|
${input}
|
||||||
|
"""
|
||||||
|
`
|
||||||
|
)
|
||||||
handleSubmit(e)
|
handleSubmit(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,6 +179,7 @@ export default function ChatPanel({ onDisplayChart, onFetchChart }: ChatPanelPro
|
|||||||
status={status}
|
status={status}
|
||||||
onSubmit={onFormSubmit}
|
onSubmit={onFormSubmit}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
|
setMessages={setMessages}
|
||||||
/>
|
/>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user