Fix the copy button not working

Fix copy button not working
This commit is contained in:
akhisud3195 2025-04-10 13:22:16 +05:30
parent 0d775003bf
commit 767584dbbc
2 changed files with 53 additions and 35 deletions

View file

@ -1,5 +1,5 @@
'use client';
import { useState } from "react";
import { useState, useCallback, useRef } from "react";
import { z } from "zod";
import { MCPServer, PlaygroundChat } from "@/app/lib/types/types";
import { Workflow } from "@/app/lib/types/workflow_types";
@ -30,7 +30,6 @@ export function App({
mcpServerUrls: Array<z.infer<typeof MCPServer>>;
toolWebhookUrl: string;
}) {
const [counter, setCounter] = useState<number>(0);
const [testProfile, setTestProfile] = useState<WithStringId<z.infer<typeof TestProfile>> | null>(null);
const [systemMessage, setSystemMessage] = useState<string>(defaultSystemMessage);
const [chat, setChat] = useState<z.infer<typeof PlaygroundChat>>({
@ -42,19 +41,17 @@ export function App({
});
const [isProfileSelectorOpen, setIsProfileSelectorOpen] = useState(false);
const [showCopySuccess, setShowCopySuccess] = useState(false);
const getCopyContentRef = useRef<(() => string) | null>(null);
function handleSystemMessageChange(message: string) {
setSystemMessage(message);
setCounter(counter + 1);
}
function handleTestProfileChange(profile: WithStringId<z.infer<typeof TestProfile>> | null) {
setTestProfile(profile);
setCounter(counter + 1);
}
function handleNewChatButtonClick() {
setCounter(counter + 1);
setChat({
projectId,
createdAt: new Date().toISOString(),
@ -62,21 +59,23 @@ export function App({
simulated: false,
systemMessage: defaultSystemMessage,
});
setSystemMessage(defaultSystemMessage);
}
const handleCopyJson = () => {
const jsonString = JSON.stringify({
messages: [{
role: 'system',
content: systemMessage,
}, ...chat.messages],
}, null, 2);
navigator.clipboard.writeText(jsonString);
setShowCopySuccess(true);
setTimeout(() => {
setShowCopySuccess(false);
}, 2000);
};
const handleCopyJson = useCallback(() => {
if (getCopyContentRef.current) {
try {
const data = getCopyContentRef.current();
navigator.clipboard.writeText(data);
setShowCopySuccess(true);
setTimeout(() => {
setShowCopySuccess(false);
}, 2000);
} catch (error) {
console.error('Error copying:', error);
}
}
}, []);
if (hidden) {
return <></>;
@ -140,7 +139,6 @@ export function App({
/>
<div className="h-full overflow-auto px-4 py-4">
<Chat
key={`chat-${counter}`}
chat={chat}
projectId={projectId}
workflow={workflow}
@ -151,6 +149,7 @@ export function App({
onSystemMessageChange={handleSystemMessageChange}
mcpServerUrls={mcpServerUrls}
toolWebhookUrl={toolWebhookUrl}
onCopyClick={(fn) => { getCopyContentRef.current = fn; }}
/>
</div>
</Panel>

View file

@ -1,5 +1,5 @@
'use client';
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState, useCallback } from "react";
import { getAssistantResponseStreamId } from "@/app/actions/actions";
import { Messages } from "./messages";
import z from "zod";
@ -27,6 +27,7 @@ export function Chat({
onSystemMessageChange,
mcpServerUrls,
toolWebhookUrl,
onCopyClick,
}: {
chat: z.infer<typeof PlaygroundChat>;
projectId: string;
@ -38,6 +39,7 @@ export function Chat({
onSystemMessageChange: (message: string) => void;
mcpServerUrls: Array<z.infer<typeof MCPServer>>;
toolWebhookUrl: string;
onCopyClick: (fn: () => string) => void;
}) {
const [messages, setMessages] = useState<z.infer<typeof apiV1.ChatMessage>[]>(chat.messages);
const [loadingAssistantResponse, setLoadingAssistantResponse] = useState<boolean>(false);
@ -47,9 +49,23 @@ export function Chat({
const [fetchResponseError, setFetchResponseError] = useState<string | null>(null);
const [lastAgenticRequest, setLastAgenticRequest] = useState<unknown | null>(null);
const [lastAgenticResponse, setLastAgenticResponse] = useState<unknown | null>(null);
const [isProfileSelectorOpen, setIsProfileSelectorOpen] = useState(false);
const [optimisticMessages, setOptimisticMessages] = useState<z.infer<typeof apiV1.ChatMessage>[]>(chat.messages);
const messagesEndRef = useRef<HTMLDivElement>(null);
const getCopyContent = useCallback(() => {
return JSON.stringify({
messages: [{
role: 'system',
content: systemMessage,
}, ...messages],
lastRequest: lastAgenticRequest,
lastResponse: lastAgenticResponse,
}, null, 2);
}, [messages, systemMessage, lastAgenticRequest, lastAgenticResponse]);
// Expose copy function to parent
useEffect(() => {
onCopyClick(getCopyContent);
}, [getCopyContent, onCopyClick]);
// reset optimistic messages when messages change
useEffect(() => {
@ -63,7 +79,6 @@ export function Chat({
.forEach((message) => {
toolCallResults[message.tool_call_id] = message;
});
console.log('toolCallResults', toolCallResults);
function handleUserMessage(prompt: string) {
const updatedMessages: z.infer<typeof apiV1.ChatMessage>[] = [...messages, {
@ -94,7 +109,6 @@ export function Chat({
// get assistant response
useEffect(() => {
console.log('stream useEffect called');
let ignore = false;
let eventSource: EventSource | null = null;
let msgs: z.infer<typeof apiV1.ChatMessage>[] = [];
@ -102,6 +116,11 @@ export function Chat({
async function process() {
setLoadingAssistantResponse(true);
setFetchResponseError(null);
// Reset request/response state before making new request
setLastAgenticRequest(null);
setLastAgenticResponse(null);
const { agents, tools, prompts, startAgent } = convertWorkflowToAgenticAPI(workflow);
const request: z.infer<typeof AgenticAPIChatRequest> = {
projectId,
@ -121,8 +140,9 @@ export function Chat({
toolWebhookUrl: toolWebhookUrl,
testProfile: testProfile ?? undefined,
};
setLastAgenticRequest(null);
setLastAgenticResponse(null);
// Store the full request object
setLastAgenticRequest(request);
let streamId: string | null = null;
try {
@ -139,14 +159,9 @@ export function Chat({
}
if (ignore || !streamId) {
console.log('almost there', ignore, streamId);
return;
}
// log the stream id
console.log('🔄 got assistant response', streamId);
// read from SSE stream
eventSource = new EventSource(`/api/v1/stream-response/${streamId}`);
eventSource.addEventListener("message", (event) => {
@ -158,7 +173,6 @@ export function Chat({
const data = JSON.parse(event.data);
const msg = AgenticAPIChatMessage.parse(data);
const parsedMsg = convertFromAgenticAPIChatMessages([msg])[0];
console.log('🔄 got assistant response chunk', parsedMsg);
msgs.push(parsedMsg);
setOptimisticMessages(prev => [...prev, parsedMsg]);
} catch (err) {
@ -173,9 +187,15 @@ export function Chat({
eventSource.close();
}
console.log('🔄 got assistant response done', event.data);
const parsed: {state: unknown} = JSON.parse(event.data);
const parsed = JSON.parse(event.data);
setAgenticState(parsed.state);
// Combine state and collected messages in the response
setLastAgenticResponse({
...parsed,
messages: msgs
});
setMessages([...messages, ...msgs]);
setLoadingAssistantResponse(false);
});
@ -207,7 +227,6 @@ export function Chat({
return () => {
ignore = true;
console.log('stream useEffect cleanup called');
if (eventSource) {
eventSource.close();
}