mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-25 18:55:19 +02:00
Simplify playground chat component:
- remove unused system message - remove playgroundchat / simulation bits - general cleanup
This commit is contained in:
parent
64dba9a9f9
commit
ca3c80e96d
6 changed files with 14 additions and 105 deletions
|
|
@ -743,21 +743,20 @@ function ensureSystemMessage(logger: PrefixLogger, messages: z.infer<typeof Mess
|
||||||
logger = logger.child(`ensureSystemMessage`);
|
logger = logger.child(`ensureSystemMessage`);
|
||||||
|
|
||||||
// ensure that a system message is set
|
// ensure that a system message is set
|
||||||
if (messages.length > 0 && messages[0]?.role !== 'system') {
|
if (messages[0]?.role !== 'system') {
|
||||||
messages.unshift({
|
messages.unshift({
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: 'You are a helpful assistant.',
|
content: '',
|
||||||
});
|
});
|
||||||
logger.log(`added system message: ${messages[0]?.content}`);
|
logger.log(`added system message: ${messages[0]?.content}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that system message isn't blank
|
// ensure that system message isn't blank
|
||||||
if (messages.length > 0 && messages[0]?.role === 'system' && !messages[0].content) {
|
if (!messages[0].content) {
|
||||||
const defaultContext = `You are a helpful assistant.
|
const defaultContext = `You are a helpful assistant.
|
||||||
|
|
||||||
Basic context:
|
Basic context:
|
||||||
- Today's date is ${new Date().toLocaleDateString()}
|
- The date-time right now is ${new Date().toISOString()}`;
|
||||||
- Current time is ${new Date().toLocaleTimeString()}.`;
|
|
||||||
|
|
||||||
messages[0].content = defaultContext;
|
messages[0].content = defaultContext;
|
||||||
logger.log(`updated system message with default context: ${messages[0].content}`);
|
logger.log(`updated system message with default context: ${messages[0].content}`);
|
||||||
|
|
|
||||||
|
|
@ -129,18 +129,6 @@ export const User = z.object({
|
||||||
updatedAt: z.string().datetime(),
|
updatedAt: z.string().datetime(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PlaygroundChat = z.object({
|
|
||||||
createdAt: z.string().datetime(),
|
|
||||||
projectId: z.string(),
|
|
||||||
title: z.string().optional(),
|
|
||||||
messages: z.array(Message),
|
|
||||||
simulated: z.boolean().default(false).optional(),
|
|
||||||
simulationScenario: z.string().optional(),
|
|
||||||
simulationComplete: z.boolean().default(false).optional(),
|
|
||||||
agenticState: z.unknown().optional(),
|
|
||||||
systemMessage: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Webpage = z.object({
|
export const Webpage = z.object({
|
||||||
_id: z.string(),
|
_id: z.string(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,19 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { useState, useCallback, useRef } from "react";
|
import { useState, useCallback, useRef } from "react";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { MCPServer, Message, PlaygroundChat } from "@/app/lib/types/types";
|
import { Message } from "@/app/lib/types/types";
|
||||||
import { Workflow, WorkflowTool } from "@/app/lib/types/workflow_types";
|
import { Workflow } from "@/app/lib/types/workflow_types";
|
||||||
import { Chat } from "./components/chat";
|
import { Chat } from "./components/chat";
|
||||||
import { Panel } from "@/components/common/panel-common";
|
import { Panel } from "@/components/common/panel-common";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Tooltip } from "@heroui/react";
|
import { Tooltip } from "@heroui/react";
|
||||||
import { WithStringId } from "@/app/lib/types/types";
|
import { CheckIcon, CopyIcon, PlusIcon, InfoIcon, BugIcon, BugOffIcon } from "lucide-react";
|
||||||
import { CheckIcon, CopyIcon, PlusIcon, UserIcon, InfoIcon, BugIcon, BugOffIcon, CodeIcon } from "lucide-react";
|
|
||||||
import { clsx } from "clsx";
|
|
||||||
|
|
||||||
const defaultSystemMessage = '';
|
|
||||||
|
|
||||||
export function App({
|
export function App({
|
||||||
hidden = false,
|
hidden = false,
|
||||||
projectId,
|
projectId,
|
||||||
workflow,
|
workflow,
|
||||||
messageSubscriber,
|
messageSubscriber,
|
||||||
mcpServerUrls,
|
|
||||||
isInitialState = false,
|
|
||||||
onPanelClick,
|
onPanelClick,
|
||||||
triggerCopilotChat,
|
triggerCopilotChat,
|
||||||
}: {
|
}: {
|
||||||
|
|
@ -27,40 +21,16 @@ export function App({
|
||||||
projectId: string;
|
projectId: string;
|
||||||
workflow: z.infer<typeof Workflow>;
|
workflow: z.infer<typeof Workflow>;
|
||||||
messageSubscriber?: (messages: z.infer<typeof Message>[]) => void;
|
messageSubscriber?: (messages: z.infer<typeof Message>[]) => void;
|
||||||
mcpServerUrls: Array<z.infer<typeof MCPServer>>;
|
|
||||||
isInitialState?: boolean;
|
|
||||||
onPanelClick?: () => void;
|
onPanelClick?: () => void;
|
||||||
triggerCopilotChat?: (message: string) => void;
|
triggerCopilotChat?: (message: string) => void;
|
||||||
}) {
|
}) {
|
||||||
const [counter, setCounter] = useState<number>(0);
|
const [counter, setCounter] = useState<number>(0);
|
||||||
const [systemMessage, setSystemMessage] = useState<string>(defaultSystemMessage);
|
|
||||||
const [showDebugMessages, setShowDebugMessages] = useState<boolean>(true);
|
const [showDebugMessages, setShowDebugMessages] = useState<boolean>(true);
|
||||||
const [chat, setChat] = useState<z.infer<typeof PlaygroundChat>>({
|
|
||||||
projectId,
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
messages: [],
|
|
||||||
simulated: false,
|
|
||||||
systemMessage: defaultSystemMessage,
|
|
||||||
});
|
|
||||||
const [isProfileSelectorOpen, setIsProfileSelectorOpen] = useState(false);
|
|
||||||
const [showCopySuccess, setShowCopySuccess] = useState(false);
|
const [showCopySuccess, setShowCopySuccess] = useState(false);
|
||||||
const getCopyContentRef = useRef<(() => string) | null>(null);
|
const getCopyContentRef = useRef<(() => string) | null>(null);
|
||||||
|
|
||||||
function handleSystemMessageChange(message: string) {
|
|
||||||
setSystemMessage(message);
|
|
||||||
setCounter(counter + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleNewChatButtonClick() {
|
function handleNewChatButtonClick() {
|
||||||
setCounter(counter + 1);
|
setCounter(counter + 1);
|
||||||
setChat({
|
|
||||||
projectId,
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
messages: [],
|
|
||||||
simulated: false,
|
|
||||||
systemMessage: defaultSystemMessage,
|
|
||||||
});
|
|
||||||
setSystemMessage(defaultSystemMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCopyJson = useCallback(() => {
|
const handleCopyJson = useCallback(() => {
|
||||||
|
|
@ -142,13 +112,9 @@ export function App({
|
||||||
<div className="h-full overflow-auto px-4 py-4">
|
<div className="h-full overflow-auto px-4 py-4">
|
||||||
<Chat
|
<Chat
|
||||||
key={`chat-${counter}`}
|
key={`chat-${counter}`}
|
||||||
chat={chat}
|
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
workflow={workflow}
|
workflow={workflow}
|
||||||
messageSubscriber={messageSubscriber}
|
messageSubscriber={messageSubscriber}
|
||||||
systemMessage={systemMessage}
|
|
||||||
onSystemMessageChange={handleSystemMessageChange}
|
|
||||||
mcpServerUrls={mcpServerUrls}
|
|
||||||
onCopyClick={(fn) => { getCopyContentRef.current = fn; }}
|
onCopyClick={(fn) => { getCopyContentRef.current = fn; }}
|
||||||
showDebugMessages={showDebugMessages}
|
showDebugMessages={showDebugMessages}
|
||||||
triggerCopilotChat={triggerCopilotChat}
|
triggerCopilotChat={triggerCopilotChat}
|
||||||
|
|
|
||||||
|
|
@ -3,49 +3,39 @@ import { useEffect, useRef, useState, useCallback } from "react";
|
||||||
import { getAssistantResponseStreamId } from "@/app/actions/actions";
|
import { getAssistantResponseStreamId } from "@/app/actions/actions";
|
||||||
import { Messages } from "./messages";
|
import { Messages } from "./messages";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { MCPServer, Message, PlaygroundChat, ToolMessage } from "@/app/lib/types/types";
|
import { Message, ToolMessage } from "@/app/lib/types/types";
|
||||||
import { Workflow, WorkflowTool } from "@/app/lib/types/workflow_types";
|
import { Workflow } from "@/app/lib/types/workflow_types";
|
||||||
import { ComposeBoxPlayground } from "@/components/common/compose-box-playground";
|
import { ComposeBoxPlayground } from "@/components/common/compose-box-playground";
|
||||||
import { Button } from "@heroui/react";
|
import { Button } from "@heroui/react";
|
||||||
import { WithStringId } from "@/app/lib/types/types";
|
|
||||||
import { ProfileContextBox } from "./profile-context-box";
|
|
||||||
import { BillingUpgradeModal } from "@/components/common/billing-upgrade-modal";
|
import { BillingUpgradeModal } from "@/components/common/billing-upgrade-modal";
|
||||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||||
import { FeedbackModal } from "./feedback-modal";
|
import { FeedbackModal } from "./feedback-modal";
|
||||||
import { FIX_WORKFLOW_PROMPT, FIX_WORKFLOW_PROMPT_WITH_FEEDBACK, EXPLAIN_WORKFLOW_PROMPT_ASSISTANT, EXPLAIN_WORKFLOW_PROMPT_TOOL, EXPLAIN_WORKFLOW_PROMPT_TRANSITION } from "../copilot-prompts";
|
import { FIX_WORKFLOW_PROMPT, FIX_WORKFLOW_PROMPT_WITH_FEEDBACK, EXPLAIN_WORKFLOW_PROMPT_ASSISTANT, EXPLAIN_WORKFLOW_PROMPT_TOOL, EXPLAIN_WORKFLOW_PROMPT_TRANSITION } from "../copilot-prompts";
|
||||||
|
|
||||||
export function Chat({
|
export function Chat({
|
||||||
chat,
|
|
||||||
projectId,
|
projectId,
|
||||||
workflow,
|
workflow,
|
||||||
messageSubscriber,
|
messageSubscriber,
|
||||||
systemMessage,
|
|
||||||
onSystemMessageChange,
|
|
||||||
mcpServerUrls,
|
|
||||||
onCopyClick,
|
onCopyClick,
|
||||||
showDebugMessages = true,
|
showDebugMessages = true,
|
||||||
showJsonMode = false,
|
showJsonMode = false,
|
||||||
triggerCopilotChat,
|
triggerCopilotChat,
|
||||||
}: {
|
}: {
|
||||||
chat: z.infer<typeof PlaygroundChat>;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
workflow: z.infer<typeof Workflow>;
|
workflow: z.infer<typeof Workflow>;
|
||||||
messageSubscriber?: (messages: z.infer<typeof Message>[]) => void;
|
messageSubscriber?: (messages: z.infer<typeof Message>[]) => void;
|
||||||
systemMessage: string;
|
|
||||||
onSystemMessageChange: (message: string) => void;
|
|
||||||
mcpServerUrls: Array<z.infer<typeof MCPServer>>;
|
|
||||||
onCopyClick: (fn: () => string) => void;
|
onCopyClick: (fn: () => string) => void;
|
||||||
showDebugMessages?: boolean;
|
showDebugMessages?: boolean;
|
||||||
showJsonMode?: boolean;
|
showJsonMode?: boolean;
|
||||||
triggerCopilotChat?: (message: string) => void;
|
triggerCopilotChat?: (message: string) => void;
|
||||||
}) {
|
}) {
|
||||||
const [messages, setMessages] = useState<z.infer<typeof Message>[]>(chat.messages);
|
const [messages, setMessages] = useState<z.infer<typeof Message>[]>([]);
|
||||||
const [loadingAssistantResponse, setLoadingAssistantResponse] = useState<boolean>(false);
|
const [loadingAssistantResponse, setLoadingAssistantResponse] = useState<boolean>(false);
|
||||||
const [fetchResponseError, setFetchResponseError] = useState<string | null>(null);
|
const [fetchResponseError, setFetchResponseError] = useState<string | null>(null);
|
||||||
const [billingError, setBillingError] = useState<string | null>(null);
|
const [billingError, setBillingError] = useState<string | null>(null);
|
||||||
const [lastAgenticRequest, setLastAgenticRequest] = useState<unknown | null>(null);
|
const [lastAgenticRequest, setLastAgenticRequest] = useState<unknown | null>(null);
|
||||||
const [lastAgenticResponse, setLastAgenticResponse] = useState<unknown | null>(null);
|
const [lastAgenticResponse, setLastAgenticResponse] = useState<unknown | null>(null);
|
||||||
const [optimisticMessages, setOptimisticMessages] = useState<z.infer<typeof Message>[]>(chat.messages);
|
const [optimisticMessages, setOptimisticMessages] = useState<z.infer<typeof Message>[]>([]);
|
||||||
const [isLastInteracted, setIsLastInteracted] = useState(false);
|
const [isLastInteracted, setIsLastInteracted] = useState(false);
|
||||||
const [showFeedbackModal, setShowFeedbackModal] = useState(false);
|
const [showFeedbackModal, setShowFeedbackModal] = useState(false);
|
||||||
const [pendingFixMessage, setPendingFixMessage] = useState<string | null>(null);
|
const [pendingFixMessage, setPendingFixMessage] = useState<string | null>(null);
|
||||||
|
|
@ -82,14 +72,11 @@ export function Chat({
|
||||||
|
|
||||||
const getCopyContent = useCallback(() => {
|
const getCopyContent = useCallback(() => {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
messages: [{
|
messages,
|
||||||
role: 'system',
|
|
||||||
content: systemMessage,
|
|
||||||
}, ...messages],
|
|
||||||
lastRequest: lastAgenticRequest,
|
lastRequest: lastAgenticRequest,
|
||||||
lastResponse: lastAgenticResponse,
|
lastResponse: lastAgenticResponse,
|
||||||
}, null, 2);
|
}, null, 2);
|
||||||
}, [messages, systemMessage, lastAgenticRequest, lastAgenticResponse]);
|
}, [messages, lastAgenticRequest, lastAgenticResponse]);
|
||||||
|
|
||||||
// Expose copy function to parent
|
// Expose copy function to parent
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -206,13 +193,7 @@ export function Chat({
|
||||||
const response = await getAssistantResponseStreamId(
|
const response = await getAssistantResponseStreamId(
|
||||||
projectId,
|
projectId,
|
||||||
workflow,
|
workflow,
|
||||||
[
|
messages,
|
||||||
{
|
|
||||||
role: 'system',
|
|
||||||
content: systemMessage || '',
|
|
||||||
},
|
|
||||||
...messages,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
if (ignore) {
|
if (ignore) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -329,8 +310,6 @@ export function Chat({
|
||||||
messages,
|
messages,
|
||||||
projectId,
|
projectId,
|
||||||
workflow,
|
workflow,
|
||||||
systemMessage,
|
|
||||||
mcpServerUrls,
|
|
||||||
fetchResponseError,
|
fetchResponseError,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -362,9 +341,6 @@ export function Chat({
|
||||||
toolCallResults={toolCallResults}
|
toolCallResults={toolCallResults}
|
||||||
loadingAssistantResponse={loadingAssistantResponse}
|
loadingAssistantResponse={loadingAssistantResponse}
|
||||||
workflow={workflow}
|
workflow={workflow}
|
||||||
systemMessage={systemMessage}
|
|
||||||
onSystemMessageChange={onSystemMessageChange}
|
|
||||||
showSystemMessage={false}
|
|
||||||
showDebugMessages={showDebugMessages}
|
showDebugMessages={showDebugMessages}
|
||||||
showJsonMode={showJsonMode}
|
showJsonMode={showJsonMode}
|
||||||
onFix={handleFix}
|
onFix={handleFix}
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,6 @@ function ToolCalls({
|
||||||
messages,
|
messages,
|
||||||
sender,
|
sender,
|
||||||
workflow,
|
workflow,
|
||||||
systemMessage,
|
|
||||||
delta,
|
delta,
|
||||||
onFix,
|
onFix,
|
||||||
onExplain,
|
onExplain,
|
||||||
|
|
@ -226,7 +225,6 @@ function ToolCalls({
|
||||||
messages: z.infer<typeof Message>[];
|
messages: z.infer<typeof Message>[];
|
||||||
sender: string | null | undefined;
|
sender: string | null | undefined;
|
||||||
workflow: z.infer<typeof Workflow>;
|
workflow: z.infer<typeof Workflow>;
|
||||||
systemMessage: string | undefined;
|
|
||||||
delta: number;
|
delta: number;
|
||||||
onFix?: (message: string, index: number) => void;
|
onFix?: (message: string, index: number) => void;
|
||||||
onExplain?: (type: 'tool' | 'transition', message: string, index: number) => void;
|
onExplain?: (type: 'tool' | 'transition', message: string, index: number) => void;
|
||||||
|
|
@ -672,9 +670,6 @@ export function Messages({
|
||||||
toolCallResults,
|
toolCallResults,
|
||||||
loadingAssistantResponse,
|
loadingAssistantResponse,
|
||||||
workflow,
|
workflow,
|
||||||
systemMessage,
|
|
||||||
onSystemMessageChange,
|
|
||||||
showSystemMessage,
|
|
||||||
showDebugMessages = true,
|
showDebugMessages = true,
|
||||||
showJsonMode = false,
|
showJsonMode = false,
|
||||||
onFix,
|
onFix,
|
||||||
|
|
@ -685,9 +680,6 @@ export function Messages({
|
||||||
toolCallResults: Record<string, z.infer<typeof ToolMessage>>;
|
toolCallResults: Record<string, z.infer<typeof ToolMessage>>;
|
||||||
loadingAssistantResponse: boolean;
|
loadingAssistantResponse: boolean;
|
||||||
workflow: z.infer<typeof Workflow>;
|
workflow: z.infer<typeof Workflow>;
|
||||||
systemMessage: string | undefined;
|
|
||||||
onSystemMessageChange: (message: string) => void;
|
|
||||||
showSystemMessage: boolean;
|
|
||||||
showDebugMessages?: boolean;
|
showDebugMessages?: boolean;
|
||||||
showJsonMode?: boolean;
|
showJsonMode?: boolean;
|
||||||
onFix?: (message: string, index: number) => void;
|
onFix?: (message: string, index: number) => void;
|
||||||
|
|
@ -726,7 +718,6 @@ export function Messages({
|
||||||
messages={messages}
|
messages={messages}
|
||||||
sender={message.agentName ?? ''}
|
sender={message.agentName ?? ''}
|
||||||
workflow={workflow}
|
workflow={workflow}
|
||||||
systemMessage={systemMessage}
|
|
||||||
delta={latency}
|
delta={latency}
|
||||||
onFix={onFix}
|
onFix={onFix}
|
||||||
onExplain={onExplain}
|
onExplain={onExplain}
|
||||||
|
|
@ -792,15 +783,6 @@ export function Messages({
|
||||||
return message.role === 'assistant' && (!('toolCalls' in message) || !Array.isArray(message.toolCalls) || !message.toolCalls.some(tc => tc.function.name.startsWith('transfer_to_')));
|
return message.role === 'assistant' && (!('toolCalls' in message) || !Array.isArray(message.toolCalls) || !message.toolCalls.some(tc => tc.function.name.startsWith('transfer_to_')));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (showSystemMessage) {
|
|
||||||
return (
|
|
||||||
<ProfileContextBox
|
|
||||||
content={systemMessage || ''}
|
|
||||||
onChange={onSystemMessageChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just render the messages, no scroll container or unread bubble
|
// Just render the messages, no scroll container or unread bubble
|
||||||
return (
|
return (
|
||||||
<div className="max-w-7xl mx-auto px-2 sm:px-8 relative">
|
<div className="max-w-7xl mx-auto px-2 sm:px-8 relative">
|
||||||
|
|
|
||||||
|
|
@ -1158,8 +1158,6 @@ export function WorkflowEditor({
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
workflow={state.present.workflow}
|
workflow={state.present.workflow}
|
||||||
messageSubscriber={updateChatMessages}
|
messageSubscriber={updateChatMessages}
|
||||||
mcpServerUrls={mcpServerUrls}
|
|
||||||
isInitialState={isInitialState}
|
|
||||||
onPanelClick={handlePlaygroundClick}
|
onPanelClick={handlePlaygroundClick}
|
||||||
triggerCopilotChat={triggerCopilotChat}
|
triggerCopilotChat={triggerCopilotChat}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue