Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
ponderingdemocritus committed Jan 26, 2025
2 parents 56cb092 + f0e0bc6 commit 2326efc
Show file tree
Hide file tree
Showing 20 changed files with 815 additions and 266 deletions.
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
# VSCode settings
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local history for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

# Logs

Expand Down Expand Up @@ -177,3 +190,11 @@ dist
# Logs

logs/app-*.log

# Environment files
.env
.env.local
.env.*.local

# But keep examples
!.env.example
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"prettier.singleQuote": false,
"typescript.tsdk": "node_modules/typescript/lib"
}
1 change: 1 addition & 0 deletions clients/example-ui/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_WEBSOCKET_URL=ws://localhost:8080
1 change: 1 addition & 0 deletions clients/example-ui/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_WEBSOCKET_URL=wss://your-production-url.com
6 changes: 6 additions & 0 deletions clients/example-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Chat with your Agent

1. Run the server: `pnpm run server`
2. Run the UI: `pnpm run ui`
3. Start chatting with your agent!

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
Expand Down
168 changes: 109 additions & 59 deletions clients/example-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,122 @@
import { useState, useEffect } from "react";
import { MessagesList } from "@/components/message-list";
import { useDaydreamsWs } from "@/hooks/use-daydreams";
import { AppSidebar } from "@/components/app-sidebar";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
import { useState } from "react";

import { ThemeProvider } from "@/components/theme-provider";
import { ModeToggle } from "./components/mode-toggle";

interface MessageType {
type: "user" | "assistant" | "system" | "error" | "other";
message?: string;
error?: string;
}

function App() {
const [message, setMessage] = useState("");
const [message, setMessage] = useState("");
const [allMessages, setAllMessages] = useState<MessageType[]>([]);
const { messages, sendGoal } = useDaydreamsWs();

// Synchronise les messages du hook dans allMessages
useEffect(() => {
if (messages.length === 0) return;
const lastMessage = messages[messages.length - 1];
setAllMessages((prev: any) => {
// On évite les doublons si le dernier message est identique
if (
prev.length > 0 &&
JSON.stringify(prev[prev.length - 1]) ===
JSON.stringify(lastMessage)
) {
return prev;
}
return [...prev, lastMessage];
});
}, [messages]);

const handleSubmit = () => {
if (!message.trim()) return;
setAllMessages((prev) => [...prev, { type: "user", message: message }]);
sendGoal(message);
setMessage("");
};

return (
<ThemeProvider>
<SidebarProvider className="font-body">
<AppSidebar />
<SidebarInset>
{/* Header */}
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
<div className="flex items-center gap-2 px-4">
<ModeToggle />
<SidebarTrigger className="-ml-1" />
<Separator
orientation="vertical"
className="mr-2 h-4"
/>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
<BreadcrumbLink href="#">
Home
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</div>
</header>

const handleSubmit = () => {
// Handle message submission here
console.log("Message submitted:", message);
setMessage(""); // Clear input after submit
};
{/* Main content area */}
<div className="flex flex-col flex-1 gap-4 p-4 pt-0">
{/* Zone conversation */}
<div className="relative flex flex-col h-[calc(100vh-5rem)] rounded-lg border bg-muted/50 md:min-h-min">
{/* Liste des messages */}
<div className="flex-1 p-4 overflow-auto">
<MessagesList messages={allMessages} />
</div>

return (
<SidebarProvider className="font-body">
<AppSidebar />
<SidebarInset>
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
<div className="flex items-center gap-2 px-4">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
{/* <BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
</BreadcrumbItem> */}
</BreadcrumbList>
</Breadcrumb>
</div>
</header>
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min p-4">
<div className="flex gap-2 max-w-2xl mx-auto">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type your message here..."
className="flex-1 px-4 py-2 rounded-lg border border-border bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
/>
<button
onClick={handleSubmit}
className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary"
>
Send
</button>
</div>
</div>
</div>
</SidebarInset>
</SidebarProvider>
);
{/* Barre d'input en bas */}
<div className="px-4 py-3 border-t border-gray-300 bg-background flex items-center gap-2">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
handleSubmit();
}
}}
placeholder="Type your message..."
className="flex-1 px-4 py-2 rounded-lg border border-border bg-background text-foreground
focus:outline-none focus:ring-2 focus:ring-primary"
/>
<button
onClick={handleSubmit}
className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90
focus:outline-none focus:ring-2 focus:ring-primary"
>
Send
</button>
</div>
</div>
</div>
</SidebarInset>
</SidebarProvider>
</ThemeProvider>
);
}

export default App;
135 changes: 68 additions & 67 deletions clients/example-ui/src/components/app-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,85 +5,86 @@ import { NavProjects } from "@/components/nav-projects";
import { NavUser } from "@/components/nav-user";
import { TeamSwitcher } from "@/components/team-switcher";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarRail,
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarRail,
} from "@/components/ui/sidebar";
import { ModeToggle } from "./mode-toggle";

// This is sample data.
const data = {
user: {
name: "sleever",
email: "[email protected]",
avatar: "/avatars/shadcn.jpg",
},
teams: [
{
name: "sleever",
logo: Bot,
plan: "Enterprise",
user: {
name: "sleever",
email: "[email protected]",
avatar: "/avatars/shadcn.jpg",
},
],
navMain: [
{
title: "Agents",
url: "#",
icon: Bot,
isActive: true,
items: [
teams: [
{
title: "My Agents",
url: "#",
name: "sleever",
logo: Bot,
plan: "Enterprise",
},
],
navMain: [
{
title: "Create Agent",
url: "#",
title: "Agents",
url: "#",
icon: Bot,
isActive: true,
items: [
{
title: "My Agents",
url: "#",
},
{
title: "Create Agent",
url: "#",
},
{
title: "Settings",
url: "#",
},
],
},
{
title: "Settings",
url: "#",
title: "Chats",
url: "#",
icon: MessageSquare,
items: [
{
title: "History",
url: "#",
},
{
title: "Saved",
url: "#",
},
{
title: "Settings",
url: "#",
},
],
},
],
},
{
title: "Chats",
url: "#",
icon: MessageSquare,
items: [
{
title: "History",
url: "#",
},
{
title: "Saved",
url: "#",
},
{
title: "Settings",
url: "#",
},
],
},
],
projects: [],
],
projects: [],
};

export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
return (
<Sidebar collapsible="icon" {...props}>
<SidebarHeader>
<TeamSwitcher teams={data.teams} />
</SidebarHeader>
<SidebarContent>
<NavMain items={data.navMain} />
<NavProjects projects={data.projects} />
</SidebarContent>
<SidebarFooter>
<NavUser user={data.user} />
</SidebarFooter>
<SidebarRail />
</Sidebar>
);
return (
<Sidebar collapsible="icon" {...props}>
<SidebarHeader>
<TeamSwitcher teams={data.teams} />
</SidebarHeader>
<SidebarContent>
<NavMain items={data.navMain} />
<NavProjects projects={data.projects} />
</SidebarContent>
<SidebarFooter>
<NavUser user={data.user} />
</SidebarFooter>
<SidebarRail />
</Sidebar>
);
}
Loading

0 comments on commit 2326efc

Please sign in to comment.