mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-25 00:16:29 +02:00
fix copilot bugs
This commit is contained in:
parent
18812a4887
commit
64cfe43135
3 changed files with 39 additions and 114 deletions
|
|
@ -15,7 +15,7 @@ import clsx from "clsx";
|
|||
import { Action as WorkflowDispatch } from "./workflow_editor";
|
||||
import MarkdownContent from "../../../lib/components/markdown-content";
|
||||
import { CopyAsJsonButton } from "../playground/copy-as-json-button";
|
||||
import { CornerDownLeftIcon, SendIcon } from "lucide-react";
|
||||
import { CornerDownLeftIcon, PlusIcon, SendIcon } from "lucide-react";
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ const CopilotContext = createContext<{
|
|||
workflow: z.infer<typeof Workflow> | null;
|
||||
handleApplyChange: (messageIndex: number, actionIndex: number, field?: string) => void;
|
||||
appliedChanges: Record<string, boolean>;
|
||||
}>({ workflow: null, handleApplyChange: () => {}, appliedChanges: {} });
|
||||
}>({ workflow: null, handleApplyChange: () => { }, appliedChanges: {} });
|
||||
|
||||
export function getAppliedChangeKey(messageIndex: number, actionIndex: number, field: string) {
|
||||
return `${messageIndex}-${actionIndex}-${field}`;
|
||||
|
|
@ -174,35 +174,35 @@ function App({
|
|||
projectId,
|
||||
workflow,
|
||||
dispatch,
|
||||
chatContext=undefined,
|
||||
messages,
|
||||
setMessages,
|
||||
loadingResponse,
|
||||
setLoadingResponse,
|
||||
loadingMessage,
|
||||
setLoadingMessage,
|
||||
responseError,
|
||||
setResponseError,
|
||||
chatContext = undefined,
|
||||
}: {
|
||||
projectId: string;
|
||||
workflow: z.infer<typeof Workflow>;
|
||||
dispatch: (action: WorkflowDispatch) => void;
|
||||
chatContext?: z.infer<typeof CopilotChatContext>;
|
||||
messages: z.infer<typeof CopilotMessage>[];
|
||||
setMessages: (messages: z.infer<typeof CopilotMessage>[]) => void;
|
||||
loadingResponse: boolean;
|
||||
setLoadingResponse: (loading: boolean) => void;
|
||||
loadingMessage: string;
|
||||
setLoadingMessage: (message: string) => void;
|
||||
responseError: string | null;
|
||||
setResponseError: (error: string | null) => void;
|
||||
}) {
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const [messages, setMessages] = useState<z.infer<typeof CopilotMessage>[]>([]);
|
||||
const [loadingResponse, setLoadingResponse] = useState(false);
|
||||
const [loadingMessage, setLoadingMessage] = useState("Thinking");
|
||||
const [responseError, setResponseError] = useState<string | null>(null);
|
||||
const [appliedChanges, setAppliedChanges] = useState<Record<string, boolean>>({});
|
||||
const [discardContext, setDiscardContext] = useState(false);
|
||||
const [lastRequest, setLastRequest] = useState<unknown | null>(null);
|
||||
const [lastResponse, setLastResponse] = useState<unknown | null>(null);
|
||||
|
||||
// Check for initial prompt in local storage and send it
|
||||
useEffect(() => {
|
||||
const prompt = localStorage.getItem(`project_prompt_${projectId}`);
|
||||
if (prompt && messages.length === 0) {
|
||||
localStorage.removeItem(`project_prompt_${projectId}`);
|
||||
setMessages([{
|
||||
role: 'user',
|
||||
content: prompt
|
||||
}]);
|
||||
}
|
||||
}, [projectId, messages.length, setMessages]);
|
||||
|
||||
// First useEffect for loading messages
|
||||
useEffect(() => {
|
||||
setLoadingMessage("Thinking");
|
||||
|
|
@ -481,8 +481,8 @@ function App({
|
|||
{effectiveContext.type === 'tool' && `Tool: ${effectiveContext.name}`}
|
||||
{effectiveContext.type === 'prompt' && `Prompt: ${effectiveContext.name}`}
|
||||
</div>
|
||||
<button
|
||||
className="text-gray-500 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
<button
|
||||
className="text-gray-500 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
onClick={() => setDiscardContext(true)}
|
||||
>
|
||||
<svg className="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
|
||||
|
|
@ -503,83 +503,42 @@ function App({
|
|||
export function Copilot({
|
||||
projectId,
|
||||
workflow,
|
||||
chatContext=undefined,
|
||||
chatContext = undefined,
|
||||
dispatch,
|
||||
onNewChat,
|
||||
messages,
|
||||
setMessages,
|
||||
loadingResponse,
|
||||
setLoadingResponse,
|
||||
loadingMessage,
|
||||
setLoadingMessage,
|
||||
responseError,
|
||||
setResponseError,
|
||||
}: {
|
||||
projectId: string;
|
||||
workflow: z.infer<typeof Workflow>;
|
||||
chatContext?: z.infer<typeof CopilotChatContext>;
|
||||
dispatch: (action: WorkflowDispatch) => void;
|
||||
onNewChat: () => void;
|
||||
messages: z.infer<typeof CopilotMessage>[];
|
||||
setMessages: (messages: z.infer<typeof CopilotMessage>[]) => void;
|
||||
loadingResponse: boolean;
|
||||
setLoadingResponse: (loading: boolean) => void;
|
||||
loadingMessage: string;
|
||||
setLoadingMessage: (message: string) => void;
|
||||
responseError: string | null;
|
||||
setResponseError: (error: string | null) => void;
|
||||
}) {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
// Check for initial prompt in URL and send it
|
||||
useEffect(() => {
|
||||
const prompt = searchParams.get('prompt');
|
||||
if (prompt && messages.length === 0) {
|
||||
setMessages([{
|
||||
role: 'user',
|
||||
content: prompt
|
||||
}]);
|
||||
|
||||
// Clean up the URL
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete('prompt');
|
||||
window.history.replaceState({}, '', url);
|
||||
}
|
||||
}, [searchParams, messages.length, setMessages]);
|
||||
const [copilotKey, setCopilotKey] = useState(0);
|
||||
|
||||
function handleNewChat() {
|
||||
setCopilotKey(prev => prev + 1);
|
||||
}
|
||||
|
||||
return (
|
||||
<StructuredPanel
|
||||
fancy
|
||||
title="COPILOT"
|
||||
<StructuredPanel
|
||||
fancy
|
||||
title="COPILOT"
|
||||
tooltip="Get AI assistance for creating and improving your multi-agent system"
|
||||
actions={[
|
||||
<ActionButton
|
||||
key="ask"
|
||||
primary
|
||||
icon={
|
||||
<svg className="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 12h14m-7 7V5" />
|
||||
</svg>
|
||||
}
|
||||
onClick={onNewChat}
|
||||
icon={<PlusIcon className="w-4 h-4" />}
|
||||
onClick={handleNewChat}
|
||||
>
|
||||
New
|
||||
</ActionButton>
|
||||
]}
|
||||
>
|
||||
<App
|
||||
key={copilotKey}
|
||||
projectId={projectId}
|
||||
workflow={workflow}
|
||||
dispatch={dispatch}
|
||||
chatContext={chatContext}
|
||||
messages={messages}
|
||||
setMessages={setMessages}
|
||||
loadingResponse={loadingResponse}
|
||||
setLoadingResponse={setLoadingResponse}
|
||||
loadingMessage={loadingMessage}
|
||||
setLoadingMessage={setLoadingMessage}
|
||||
responseError={responseError}
|
||||
setResponseError={setResponseError}
|
||||
/>
|
||||
</StructuredPanel>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ import { PublishedBadge } from "./published_badge";
|
|||
import { BackIcon, HamburgerIcon, WorkflowIcon } from "../../../lib/components/icons";
|
||||
import { CopyIcon, ImportIcon, Layers2Icon, RadioIcon, RedoIcon, ServerIcon, Sparkles, UndoIcon } from "lucide-react";
|
||||
import { EntityList } from "./entity_list";
|
||||
import { CopilotMessage } from "../../../lib/types/copilot_types";
|
||||
import { McpImportTools } from "./mcp_imports";
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
|
||||
enablePatches();
|
||||
|
||||
|
|
@ -598,29 +596,18 @@ export function WorkflowEditor({
|
|||
const [showCopySuccess, setShowCopySuccess] = useState(false);
|
||||
const [showCopilot, setShowCopilot] = useState(false);
|
||||
const [copilotWidth, setCopilotWidth] = useState(25);
|
||||
const [copilotKey, setCopilotKey] = useState(0);
|
||||
const [copilotMessages, setCopilotMessages] = useState<z.infer<typeof CopilotMessage>[]>([]);
|
||||
const [loadingResponse, setLoadingResponse] = useState(false);
|
||||
const [loadingMessage, setLoadingMessage] = useState("Thinking...");
|
||||
const [responseError, setResponseError] = useState<string | null>(null);
|
||||
const searchParams = useSearchParams();
|
||||
const [isMcpImportModalOpen, setIsMcpImportModalOpen] = useState(false);
|
||||
|
||||
console.log(`workflow editor chat key: ${state.present.chatKey}`);
|
||||
|
||||
// Auto-show copilot and increment key when prompt is present
|
||||
useEffect(() => {
|
||||
const prompt = searchParams.get('prompt');
|
||||
const prompt = localStorage.getItem(`project_prompt_${state.present.workflow.projectId}`);
|
||||
console.log('init project prompt', prompt);
|
||||
if (prompt) {
|
||||
setShowCopilot(true);
|
||||
setCopilotKey(prev => prev + 1); // Force copilot to reset
|
||||
|
||||
// Clean up the URL
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete('prompt');
|
||||
window.history.replaceState({}, '', url);
|
||||
}
|
||||
}, [searchParams]);
|
||||
}, [state.present.workflow.projectId]);
|
||||
|
||||
function handleSelectAgent(name: string) {
|
||||
dispatch({ type: "select_agent", name });
|
||||
|
|
@ -958,7 +945,6 @@ export function WorkflowEditor({
|
|||
onResize={(size) => setCopilotWidth(size)}
|
||||
>
|
||||
<Copilot
|
||||
key={copilotKey}
|
||||
projectId={state.present.workflow.projectId}
|
||||
workflow={state.present.workflow}
|
||||
dispatch={dispatch}
|
||||
|
|
@ -971,21 +957,6 @@ export function WorkflowEditor({
|
|||
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}
|
||||
/>
|
||||
</ResizablePanel>
|
||||
</>}
|
||||
|
|
|
|||
|
|
@ -206,14 +206,9 @@ export default function App() {
|
|||
throw new Error('Project creation failed - no project ID returned');
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
prompt: promptText,
|
||||
autostart: 'true'
|
||||
});
|
||||
const url = `/projects/${response.id}/workflow?${params.toString()}`;
|
||||
|
||||
console.log('Navigating to:', url);
|
||||
window.location.href = url;
|
||||
// write prompt to local storage
|
||||
localStorage.setItem(`project_prompt_${response.id}`, promptText);
|
||||
router.push(`/projects/${response.id}/workflow`);
|
||||
} catch (error) {
|
||||
console.error('Error creating project:', error);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue