diff --git a/apps/rowboat/app/projects/[projectId]/workflow/copilot.tsx b/apps/rowboat/app/projects/[projectId]/workflow/copilot.tsx
index 4d8e66b1..93019573 100644
--- a/apps/rowboat/app/projects/[projectId]/workflow/copilot.tsx
+++ b/apps/rowboat/app/projects/[projectId]/workflow/copilot.tsx
@@ -174,23 +174,35 @@ function App({
workflow,
dispatch,
chatContext=undefined,
+ messages,
+ setMessages,
+ loadingResponse,
+ setLoadingResponse,
+ loadingMessage,
+ setLoadingMessage,
+ responseError,
+ setResponseError,
}: {
projectId: string;
workflow: z.infer
;
dispatch: (action: WorkflowDispatch) => void;
chatContext?: z.infer;
+ messages: z.infer[];
+ setMessages: (messages: z.infer[]) => void;
+ loadingResponse: boolean;
+ setLoadingResponse: (loading: boolean) => void;
+ loadingMessage: string;
+ setLoadingMessage: (message: string) => void;
+ responseError: string | null;
+ setResponseError: (error: string | null) => void;
}) {
- const [messages, setMessages] = useState[]>([]);
- const [loadingResponse, setLoadingResponse] = useState(false);
- const [loadingMessage, setLoadingMessage] = useState("Thinking...");
- const [responseError, setResponseError] = useState(null);
const messagesEndRef = useRef(null);
const [appliedChanges, setAppliedChanges] = useState>({});
const [discardContext, setDiscardContext] = useState(false);
const [lastRequest, setLastRequest] = useState(null);
const [lastResponse, setLastResponse] = useState(null);
- // Cycle through loading messages until reaching the last one
+ // First useEffect for loading messages
useEffect(() => {
setLoadingMessage("Thinking");
if (!loadingResponse) return;
@@ -210,7 +222,7 @@ function App({
}, 4000);
return () => clearInterval(interval);
- }, [loadingResponse, messages]);
+ }, [loadingResponse, setLoadingMessage]);
// Reset discardContext when chatContext changes
useEffect(() => {
@@ -328,7 +340,7 @@ function App({
}
}, [dispatch, appliedChanges, messages]);
- // get copilot response
+ // Second useEffect for copilot response
useEffect(() => {
let ignore = false;
@@ -383,7 +395,16 @@ function App({
return () => {
ignore = true;
};
- }, [messages, projectId, responseError, workflow, effectiveContext]);
+ }, [
+ messages,
+ projectId,
+ responseError,
+ workflow,
+ effectiveContext,
+ setLoadingResponse,
+ setMessages,
+ setResponseError
+ ]);
function handleCopyChat() {
const jsonString = JSON.stringify({
@@ -483,40 +504,63 @@ export function Copilot({
workflow,
chatContext=undefined,
dispatch,
+ onNewChat,
+ messages,
+ setMessages,
+ loadingResponse,
+ setLoadingResponse,
+ loadingMessage,
+ setLoadingMessage,
+ responseError,
+ setResponseError,
}: {
projectId: string;
workflow: z.infer;
chatContext?: z.infer;
dispatch: (action: WorkflowDispatch) => void;
+ onNewChat: () => void;
+ messages: z.infer[];
+ setMessages: (messages: z.infer[]) => void;
+ loadingResponse: boolean;
+ setLoadingResponse: (loading: boolean) => void;
+ loadingMessage: string;
+ setLoadingMessage: (message: string) => void;
+ responseError: string | null;
+ setResponseError: (error: string | null) => void;
}) {
- const [key, setKey] = useState(0);
-
- function handleNewChat() {
- setKey(key + 1);
- }
-
return (
-
-
-
- }
- onClick={handleNewChat}
- >
- Ask
-
- ]}>
+
+
+
+ }
+ onClick={onNewChat}
+ >
+ New
+
+ ]}
+ >
);
diff --git a/apps/rowboat/app/projects/[projectId]/workflow/entity_list.tsx b/apps/rowboat/app/projects/[projectId]/workflow/entity_list.tsx
index b0ebfc03..02a8ba52 100644
--- a/apps/rowboat/app/projects/[projectId]/workflow/entity_list.tsx
+++ b/apps/rowboat/app/projects/[projectId]/workflow/entity_list.tsx
@@ -105,7 +105,10 @@ export function EntityList({
}, [selectedEntity]);
return (
-
+
{/* Agents Section */}
onAddAgent({})} />
diff --git a/apps/rowboat/app/projects/[projectId]/workflow/pane.tsx b/apps/rowboat/app/projects/[projectId]/workflow/pane.tsx
index a7ecd136..095349f2 100644
--- a/apps/rowboat/app/projects/[projectId]/workflow/pane.tsx
+++ b/apps/rowboat/app/projects/[projectId]/workflow/pane.tsx
@@ -1,26 +1,44 @@
import clsx from "clsx";
+import { InfoIcon } from "lucide-react";
+import { Tooltip } from "@nextui-org/react";
export function Pane({
title,
actions = null,
children,
fancy = false,
+ tooltip = null,
}: {
title: React.ReactNode;
actions?: React.ReactNode[] | null;
children: React.ReactNode;
fancy?: boolean;
+ tooltip?: string | null;
}) {
return
-
- {title}
+
+
+ {title}
+
+ {tooltip && (
+
+
+
+ )}
{!actions &&
}
{actions &&
[]>([]);
+ const [loadingResponse, setLoadingResponse] = useState(false);
+ const [loadingMessage, setLoadingMessage] = useState("Thinking...");
+ const [responseError, setResponseError] = useState(null);
console.log(`workflow editor chat key: ${state.present.chatKey}`);
@@ -752,7 +762,7 @@ export function WorkflowEditor({
}
{!isLive && <>
+
>}
@@ -792,7 +809,11 @@ export function WorkflowEditor({
/>
-
+
}
-
-
- 0 ? {
- type: 'chat',
- messages: chatMessages
- } : undefined
- }
- />
-
+ {showCopilot && <>
+
+ setCopilotWidth(size)}
+ >
+ 0 ? {
+ type: 'chat',
+ messages: chatMessages
+ } : undefined
+ }
+ onNewChat={() => {
+ setCopilotKey(prev => prev + 1);
+ setCopilotMessages([]);
+ setLoadingResponse(false);
+ setLoadingMessage("Thinking...");
+ setResponseError(null);
+ }}
+ messages={copilotMessages}
+ setMessages={setCopilotMessages}
+ loadingResponse={loadingResponse}
+ setLoadingResponse={setLoadingResponse}
+ loadingMessage={loadingMessage}
+ setLoadingMessage={setLoadingMessage}
+ responseError={responseError}
+ setResponseError={setResponseError}
+ />
+
+ >}
;
}