Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { TestProfile } from "@/app/lib/types/testing_types";
import { WithStringId } from "@/app/lib/types/types";
import { ProfileContextBox } from "./profile-context-box";
import { USE_TESTING_FEATURE } from "@/app/lib/feature_flags";
import { toast } from 'sonner'

export function Chat({
chat,
Expand Down Expand Up @@ -120,11 +121,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,
Expand All @@ -144,7 +145,7 @@ export function Chat({
toolWebhookUrl: toolWebhookUrl,
testProfile: testProfile ?? undefined,
};

// Store the full request object
setLastAgenticRequest(request);

Expand All @@ -157,7 +158,17 @@ export function Chat({
streamId = response.streamId;
} catch (err) {
if (!ignore) {
setFetchResponseError(`Failed to get assistant response: ${err instanceof Error ? err.message : 'Unknown error'}`);
// setFetchResponseError(`Failed to get assistant response: ${err instanceof Error ? err.message : 'Unknown error'}`);

if (err instanceof Error && err.message.includes('quota')) {
toast.error('API Quota Exceeded', {
description: 'Please check your billing settings or upgrade your plan.'
});
} else {
toast.error('Failed to start conversation', {
description: err instanceof Error ? err.message : 'Unknown error occurred'
});
}
setLoadingAssistantResponse(false);
}
}
Expand All @@ -181,7 +192,9 @@ export function Chat({
setOptimisticMessages(prev => [...prev, parsedMsg]);
} catch (err) {
console.error('Failed to parse SSE message:', err);
setFetchResponseError(`Failed to parse SSE message: ${err instanceof Error ? err.message : 'Unknown error'}`);
toast.error('Message Parse Error', {
description: 'Received invalid message format from server'
});
setOptimisticMessages(messages);
}
});
Expand All @@ -193,13 +206,11 @@ export function Chat({

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);
});
Expand All @@ -211,8 +222,11 @@ export function Chat({

console.error('SSE Error:', event);
if (!ignore) {
const errorData = JSON.parse(event.data);
toast.error('Stream Error', {
description: errorData.error || 'An error occurred during streaming'
});
setLoadingAssistantResponse(false);
setFetchResponseError('Error: ' + JSON.parse(event.data).error);
setOptimisticMessages(messages);
}
});
Expand All @@ -221,7 +235,9 @@ export function Chat({
console.error('SSE Error:', error);
if (!ignore) {
setLoadingAssistantResponse(false);
setFetchResponseError('Stream connection failed');
toast.error('Connection Lost', {
description: 'Stream connection failed. Please try sending your message again.'
});
setOptimisticMessages(messages);
}
};
Expand Down Expand Up @@ -270,7 +286,7 @@ export function Chat({
/>
)}
</div>

<div className="flex-1 overflow-auto pr-1
[&::-webkit-scrollbar]{width:4px}
[&::-webkit-scrollbar-track]{background:transparent}
Expand Down Expand Up @@ -306,7 +322,7 @@ export function Chat({
</Button>
</div>
)}

<ComposeBoxPlayground
handleUserMessage={handleUserMessage}
messages={messages.filter(msg => msg.content !== undefined) as any}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RelativeTime } from "@primer/react";
import { Pagination, Spinner } from "@heroui/react";
import { DownloadIcon } from "lucide-react";
import { Section } from "./section";
import { toast } from "sonner";

function FileListItem({
projectId,
Expand Down Expand Up @@ -41,6 +42,9 @@ function FileListItem({
} catch (error) {
console.error('Download failed:', error);
// TODO: Add error handling
toast.error('Download failed:', {
description: 'Connection interrupted. Please retry the download.'
});
} finally {
setIsDownloading(false);
}
Expand Down Expand Up @@ -125,6 +129,9 @@ function PaginatedFileList({
}
} catch (error) {
console.error('Error fetching files:', error);
toast.error('Error fetching files:', {
description: 'Unable to load files. Please try again.'
});
} finally {
setLoading(false);
}
Expand Down Expand Up @@ -252,6 +259,9 @@ export function FilesSource({
} catch (error) {
console.error('Upload failed:', error);
// TODO: Add error handling
toast.error('Upload failed:', {
description: 'Unable to upload file. Please try again.'
});
} finally {
setUploading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { FormStatusButton } from "../../../../lib/components/form-status-button"
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Section } from "./section";
import { toast } from "sonner";

function UrlListItem({ file, onDelete }: {
file: WithStringId<z.infer<typeof DataSourceDoc>>,
Expand Down Expand Up @@ -76,6 +77,9 @@ function UrlList({ projectId, sourceId, onDelete }: {
}
} catch (error) {
console.error('Error fetching files:', error);
toast.error('Error fetching files:', {
description: 'Unable to load files. Please try again.'
});
} finally {
setLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FormStatusButton } from "../../../../lib/components/form-status-button"
import { Spinner } from "@heroui/react";
import { addDocsToDataSource, deleteDocsFromDataSource, listDocsInDataSource } from "../../../../actions/datasource_actions";
import { Section } from "./section";
import { toast } from "sonner";

export function TextSource({
projectId,
Expand Down Expand Up @@ -46,6 +47,9 @@ export function TextSource({
}
} catch (error) {
console.error('Error fetching content:', error);
toast.error('Error fetching content:', {
description: 'Unable to fetch content. Please try again.'
});
} finally {
setIsLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { fetchWorkflow } from "@/app/actions/workflow_actions";
import { StructuredPanel, ActionButton } from "@/app/lib/components/structured-panel"
import { DataTable } from "./components/table"
import { isValidDate } from './utils/date';
import { toast } from "sonner";

function ViewRun({
projectId,
Expand Down Expand Up @@ -81,13 +82,19 @@ function ViewRun({
const result = await getSimulationResult(projectId, runId, simulationId);
if (!result) {
console.error("No result found for simulation");
toast.error('Result not found:', {
description: 'No simulation results available. Please run the simulation first.'
});
return;
}

// Get simulation name from simulations array
const simulation = simulations.find(s => s._id === simulationId);
if (!simulation) {
console.error("Simulation not found");
toast.error('Simulation not found:', {
description: 'The requested simulation does not exist or has been deleted.'
});
return;
}

Expand Down Expand Up @@ -118,6 +125,9 @@ function ViewRun({
document.body.removeChild(a);
} catch (error) {
console.error("Failed to download result:", error);
toast.error('Download failed:', {
description: 'Unable to download results. Please try again.'
});
}
};

Expand Down
50 changes: 27 additions & 23 deletions apps/rowboat/app/projects/layout/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { Tooltip } from "@heroui/react";
import { UserButton } from "@/app/lib/components/user_button";
import {
DatabaseIcon,
SettingsIcon,
WorkflowIcon,
import {
DatabaseIcon,
SettingsIcon,
WorkflowIcon,
PlayIcon,
FolderOpenIcon,
ChevronLeftIcon,
Expand All @@ -20,6 +20,7 @@ import { getProjectConfig } from "@/app/actions/project_actions";
import { useTheme } from "@/app/providers/theme-provider";
import { USE_TESTING_FEATURE, USE_PRODUCT_TOUR } from '@/app/lib/feature_flags';
import { useHelpModal } from "@/app/providers/help-modal-provider";
import { toast } from 'sonner';

interface SidebarProps {
projectId: string;
Expand Down Expand Up @@ -47,6 +48,9 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
setProjectName(project.name);
} catch (error) {
console.error('Failed to fetch project name:', error);
toast.error('Failed to load project:', {
description: 'Unable to retrieve project information. Please refresh the page.'
});
setProjectName("Select Project");
}
}
Expand Down Expand Up @@ -95,16 +99,16 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
{/* Project Selector */}
<div className="p-3 border-b border-zinc-100 dark:border-zinc-800">
<Tooltip content={collapsed ? projectName : "Change project"} showArrow placement="right">
<Link
<Link
href="/projects"
className={`
flex items-center rounded-md hover:bg-zinc-100 dark:hover:bg-zinc-800/50 transition-all
${collapsed ? 'justify-center py-4' : 'gap-3 px-4 py-2.5'}
`}
>
<FolderOpenIcon
size={collapsed ? COLLAPSED_ICON_SIZE : EXPANDED_ICON_SIZE}
className="text-zinc-500 dark:text-zinc-400 transition-all duration-200"
<FolderOpenIcon
size={collapsed ? COLLAPSED_ICON_SIZE : EXPANDED_ICON_SIZE}
className="text-zinc-500 dark:text-zinc-400 transition-all duration-200"
/>
{!collapsed && (
<span className="text-sm font-medium truncate">
Expand All @@ -122,25 +126,25 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
const fullPath = `/projects/${projectId}/${item.href}`;
const isActive = pathname.startsWith(fullPath);
const isDisabled = isProjectsRoute && item.requiresProject;

return (
<Tooltip
<Tooltip
key={item.href}
content={collapsed ? item.label : ""}
showArrow
showArrow
placement="right"
>
<Link
<Link
href={isDisabled ? '#' : fullPath}
className={isDisabled ? 'pointer-events-none' : ''}
>
<button
<button
className={`
relative w-full rounded-md flex items-center
text-[15px] font-medium transition-all duration-200
${collapsed ? 'justify-center py-4' : 'px-4 py-4 gap-3'}
${isActive
? 'bg-indigo-50 dark:bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 border-l-2 border-indigo-600 dark:border-indigo-400'
${isActive
? 'bg-indigo-50 dark:bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 border-l-2 border-indigo-600 dark:border-indigo-400'
: isDisabled
? 'text-zinc-300 dark:text-zinc-600 cursor-not-allowed'
: 'text-zinc-600 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800/50 hover:text-zinc-900 dark:hover:text-zinc-300'
Expand All @@ -149,12 +153,12 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
disabled={isDisabled}
data-tour-target={item.href === 'config' ? 'settings' : item.href === 'sources' ? 'entity-data-sources' : undefined}
>
<Icon
size={collapsed ? COLLAPSED_ICON_SIZE : EXPANDED_ICON_SIZE}
<Icon
size={collapsed ? COLLAPSED_ICON_SIZE : EXPANDED_ICON_SIZE}
className={`
transition-all duration-200
${isDisabled
? 'text-zinc-300 dark:text-zinc-600'
${isDisabled
? 'text-zinc-300 dark:text-zinc-600'
: isActive
? 'text-indigo-600 dark:text-indigo-400'
: 'text-zinc-500 dark:text-zinc-400'
Expand Down Expand Up @@ -192,7 +196,7 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
<div className="p-3 border-t border-zinc-100 dark:border-zinc-800 space-y-2">
{USE_PRODUCT_TOUR && !isProjectsRoute && (
<Tooltip content={collapsed ? "Help" : ""} showArrow placement="right">
<button
<button
onClick={showHelpModal}
className={`
w-full rounded-md flex items-center
Expand All @@ -210,7 +214,7 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
)}

<Tooltip content={collapsed ? "Appearance" : ""} showArrow placement="right">
<button
<button
onClick={toggleTheme}
className={`
w-full rounded-md flex items-center
Expand All @@ -220,14 +224,14 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false,
text-zinc-600 dark:text-zinc-400
`}
>
{ theme == "light" ? <Moon size={COLLAPSED_ICON_SIZE} /> : <Sun size={COLLAPSED_ICON_SIZE} /> }
{theme == "light" ? <Moon size={COLLAPSED_ICON_SIZE} /> : <Sun size={COLLAPSED_ICON_SIZE} />}
{!collapsed && <span>Appearance</span>}
</button>
</Tooltip>

{useAuth && (
<Tooltip content={collapsed ? "Account" : ""} showArrow placement="right">
<div
<div
className={`
w-full rounded-md flex items-center
text-[15px] font-medium transition-all duration-200
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { FolderOpenIcon, InformationCircleIcon } from "@heroicons/react/24/outli
import { USE_MULTIPLE_PROJECTS } from "@/app/lib/feature_flags";
import { HorizontalDivider } from "@/components/ui/horizontal-divider";
import { Tooltip } from "@heroui/react";
import { toast } from "sonner";

// Add glow animation styles
const glowStyles = `
Expand Down Expand Up @@ -226,6 +227,9 @@ export function CreateProject({ defaultName, onOpenProjectPane, isProjectPaneOpe
router.push(`/projects/${response.id}/workflow`);
} catch (error) {
console.error('Error creating project:', error);
toast.error('Failed to create project:', {
description: 'Unable to create new project. Please try again.'
});
}
}

Expand Down
4 changes: 2 additions & 2 deletions apps/rowboat/app/scripts/setup_qdrant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const EMBEDDING_VECTOR_SIZE = Number(process.env.EMBEDDING_VECTOR_SIZE) || 1536;
distance: 'Dot',
},
});
console.log(`Create qdrant collection 'embeddings' completed with result: ${result}`);
console.log(`Create qdrant collection 'embeddings' completed with result : ${result}`);
} catch (error) {
console.error(`Unable to create qdrant collection 'embeddings': ${error}`);
console.error(`Unable to create qdrant collection 'embeddings ': ${error}`);
}
})();
Loading