Skip to content

Commit

Permalink
Chat backend for recieving messages (#607)
Browse files Browse the repository at this point in the history
* Chat log sveltekit backend

* update on the chatlog backend

* displaying the responses in the chat log frontend

* fix little bug on the frontend of the chatlog

* updated chatlog backend

* addeded the ui and some of the functionality of the replay

* making few updates to the replay

* fixup prompt improver

* correct writing errors

* more typo fixes

* fix bug on the chat  backend

* update for the replay

* add condition to trigger the chat when the run button clicked

* added changes to the meave , the run button triggers the chat

* latest update on the chatlog

* self orientation

* sessions page

* work on session page

* chat backend somewhat working

---------

Co-authored-by: Minilik94 <minilzeru@gmail.com>
  • Loading branch information
eksno and Minilik94 authored Feb 27, 2024
1 parent 950bc5e commit ec3917a
Show file tree
Hide file tree
Showing 16 changed files with 866 additions and 170 deletions.
40 changes: 36 additions & 4 deletions apps/aitino/src/app.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,38 @@
@tailwind utilities;

@layer base {
/* Universal */
--md-sys-color-primary: 69 223 164;
--md-sys-color-on-primary: 0 56 37;
--md-sys-color-primary-container: 0 81 55;
--md-sys-color-on-primary-container: 104 252 191;
--md-sys-color-secondary: 60 221 199;
--md-sys-color-on-secondary: 0 55 49;
--md-sys-color-secondary-container: 0 80 71;
--md-sys-color-on-secondary-container: 98 250 227;
--md-sys-color-tertiary: 255 175 211;
--md-sys-color-on-tertiary: 98 0 64;
--md-sys-color-tertiary-container: 133 20 90;
--md-sys-color-on-tertiary-container: 255 216 231;
--md-sys-color-error: 255 180 171;
--md-sys-color-error-container: 147 0 10;
--md-sys-color-on-error: 105 0 5;
--md-sys-color-on-error-container: 255 218 214;
--md-sys-color-background: 23 25 25;
--md-sys-color-on-background: 225 227 223;
--md-sys-color-surface: 30 30 30;
--md-sys-color-on-surface: 225 227 223;
--md-sys-color-surface-variant: 64 73 67;
--md-sys-color-on-surface-variant: 191 201 193;
--md-sys-color-outline: 138 147 140;
--md-sys-color-inverse-on-surface: 25 28 26;
--md-sys-color-inverse-surface: 225 227 223;
--md-sys-color-inverse-primary: 0 108 75;
--md-sys-color-shadow: 0 0 0;
--md-sys-color-surface-tint: 69 223 164;
--md-sys-color-outline-variant: 64 73 67;
--md-sys-color-scrim: 0 0 0;

:root {
--background: 255 255 255;
--foreground: 13 13 13;
Expand All @@ -26,7 +58,7 @@
--radius: 0.5rem;
}
.dark {
--background: 9 16 16;
--background: 23 25 25;
--foreground: 248 250 252;
--card: 13 13 13;
--card-foreground: 249 249 249;
Expand All @@ -35,16 +67,16 @@
--primary: 69 223 164;
--primary-foreground: 0 56 37;
--secondary: 60 221 199;
--secondary-foreground: 249 249 249;
--secondary-foreground: 0 55 49;
--muted: 45 45 45;
--muted-foreground: 166 166 166;
--accent: 255 175 211;
--accent-foreground: 98 0 64;
--destructive: 251 113 133;
--destructive-foreground: 249 249 249;
--border: 45 45 45;
--input: 30 41 59;
--ring: 123 123 123;
--input: 0 81 55;
--ring: 69 223 164;
--radius: 0.5rem;
}
}
Expand Down
1 change: 1 addition & 0 deletions apps/aitino/src/lib/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { supabase } from "$lib/supabase";
import type { TablesInsert } from "$lib/supabase.types";

export async function saveMaeveNodes(data: TablesInsert<"maeve_nodes">) {
localStorage.setItem("currentMeaveId", data.id);
return supabase.from("maeve_nodes").upsert(data);
}

Expand Down
194 changes: 129 additions & 65 deletions apps/aitino/src/lib/components/ChatRoom.svelte
Original file line number Diff line number Diff line change
@@ -1,44 +1,25 @@
<script lang="ts">
import { ArrowDown, Loader, Send, User } from "lucide-svelte";
import { ArrowDown, ChevronDown, Loader, Loader2, Send, User } from "lucide-svelte";
import { Input } from "./ui/input";
import { Button } from "./ui/button";
import * as Card from "$lib/components/ui/card";
import { afterUpdate, onMount } from "svelte";
import SvelteMarkdown from "svelte-markdown";
let messages = [
{
unique_id: "0004",
content:
"Aitino will be the ultimate business partner and business tool. Aitino will be able to help both entrepreneurs and larger corporations by harnessing the power of multi-LLM-agent environments and advanced integration with other business systems.",
time: "10:46:45 pm",
fromUser: false,
instance_id: "4",
full_name: "Michael",
job_title: "Graphic Designer",
model: "model-b"
},
{
unique_id: "0004",
content: "The waitlist for aitino is live go check it out at aiti.no 😀",
time: "10:46:45 pm",
fromUser: false,
instance_id: "4",
full_name: "Michael",
job_title: "Graphic Designer",
model: "model-b"
},
{
content: "Generate a 1 min video with a short description about Aitino.",
time: "11:20:45 pm",
fromUser: true,
unique_id: "0001",
instance_id: "1",
full_name: "Alice Johnson",
job_title: "Content Creator",
model: "model-a"
let maeveId: string;
onMount(() => {
const _id: string | null = localStorage.getItem("currentMeaveId");
if (_id == null) {
console.error("No maeve id found");
return;
}
];
maeveId = _id;
console.log(maeveId, "maeveId");
});
let messages: any[] = [];
function handleKeyDown(event: { key: string }) {
if (event.key === "Enter") {
Expand All @@ -55,40 +36,119 @@
if (newMessageContent.trim() !== "") {
const newMessage = {
id: messages.length + 1,
name: "User",
role: "User Role",
content: newMessageContent,
time: new Date().toLocaleTimeString(),
fromUser: true
status: "success",
data: {
content: newMessageContent,
role: "not user",
name: "new user",
created_at: new Date().toLocaleTimeString()
}
};
messages = [...messages, newMessage];
newMessageContent = "";
}
};
let showReplyField = false;
const toggleReplyField = () => {
showReplyField = !showReplyField;
};
function formatDate(dateString: string) {
const date = new Date(dateString);
return date.toLocaleDateString("en-US");
}
let chatContainerElement: HTMLDivElement;
afterUpdate(() => {
if (chatContainerElement) {
chatContainerElement.scrollTop = chatContainerElement.scrollHeight;
}
});
let replyMessage = "";
let state: "loading" | "success" | "error" | "idle" = "idle";
function handleInputChangeReply(event: { target: { value: string } }) {
replyMessage = event.target.value;
}
const handleReply = async () => {
state = "loading";
const id = messages[0].data.session_id;
const reply = replyMessage;
const queryParams = new URLSearchParams({
meave_id: "dfb9ede1-3c08-462f-af73-94cf6aa9185a",
session_id: id,
reply
}).toString();
try {
const response = await fetch(`/api/v1/reply?${queryParams}`);
const data = await response.json();
const jsonResponseString = data.content;
const jsonStrings = jsonResponseString
.split("}}\n")
.map((str: string) => (str.endsWith("}") ? str : str + "}}"));
// Parsing each string to JSON, filtering out the 'done' message or any non-JSON strings
const jsonObjects = jsonStrings
.filter((str: string) => str.trim() && !str.includes('"status": "success", "data": "done"'))
.map((str: string) => JSON.parse(str));
// Adding parsed objects to the messages array
messages = [...messages, ...jsonObjects];
state = "success";
replyMessage = "";
showReplyField = false;
} catch (error) {
state = "error";
replyMessage = "";
showReplyField = false;
console.error("Error fetching chat maeave:", error);
}
};
</script>

<div class="container -mb-6 flex h-screen max-w-6xl flex-col justify-end p-6">
<div class="no-scrollbar max-h-full overflow-y-auto" bind:this={chatContainerElement}>
<!-- add scroll to the bottom of the chat -->
{#each messages as message}
<div>
{#if !message.fromUser}
{#if message.data && "content" in message.data && message.data.role === "user"}
<div class="space-y-2 border-none">
<Card.Root class=" max-w-2xl">
<Card.Content class="grid gap-4 p-6">
{#if message.content.startsWith("```") || message.content.includes("<")}
<SvelteMarkdown source={message.content} />
{#if message.data && "content" in message.data && message.data.content === "CONTINUE"}
{#if !showReplyField}
{message.data.content}
<Button on:click={toggleReplyField} class="flex items-center justify-center">
reply
</Button>{/if}
{#if showReplyField}
<form class="mt-2 flex flex-col gap-y-6" on:submit={handleReply}>
<Input
on:input={handleInputChangeReply}
placeholder="Type your reply..."
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-6 text-sm shadow-sm ring-offset-0 transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
/>
<div class="align-center mx-auto flex justify-between gap-2">
<Button variant="primary" type="submit">Send Reply</Button>
{#if state !== "idle"}
<Loader2 class="ml-2 w-4 animate-spin" />
{/if}
<Button variant="primary" on:click={toggleReplyField}>Cancel</Button>
</div>
</form>
{/if}
{:else if message.data.content.startsWith("```") || message.data.content.includes("<")}
<SvelteMarkdown source={message.data.content} />
{:else}
<p class="prose text-sm font-medium leading-5 tracking-widest">
{message.content}
<p
class="prose max-w-2xl break-words text-sm font-medium leading-5 tracking-widest"
>
{message.data.content}
</p>
{/if}
</Card.Content>
Expand All @@ -103,36 +163,40 @@
<p
class="prose text-xs font-medium leading-none tracking-widest dark:text-blue-950"
>
{message.full_name} - Agent
{message.data.name} - Agent
</p>
</div>
<p class="prose text-sm font-medium dark:text-blue-950">
sent: {message.time}
sent: {formatDate(message.data.created_at)}
</p>
</Card.Content>
</Card.Root>
</div>
{:else}
<div class="space-y-2">
<Card.Root class=" ml-auto flex max-w-2xl flex-wrap rounded-bl-3xl border">
<Card.Content class="prose grid gap-4 p-6">
{#if message.content.startsWith("```") || message.content.includes("<")}
<SvelteMarkdown source={message.content} />
{:else}
<p class="prose text-sm font-medium leading-5 tracking-widest">
{message.content}
{#if message.data && "content" in message.data}
<Card.Root class=" ml-auto flex max-w-2xl flex-wrap rounded-bl-3xl border">
<Card.Content class="prose grid gap-4 p-6">
{#if message.data && "content" in message.data && message.data.content !== "undefined" && message.data.content.startsWith("```")}
<SvelteMarkdown source={message.data.content} />
{:else}
<p class="max-2xl prose text-sm font-medium leading-5 tracking-widest">
{message.data.content}
</p>
{/if}
</Card.Content>
</Card.Root>
{/if}
{#if message.data && "created_at" in message.data}
<Card.Root class="ml-auto max-w-2xl border-none bg-transparent">
<Card.Content class="grid w-full grid-cols-2 items-center justify-between gap-4">
<p class="prose text-xs font-medium leading-8 dark:text-green-300">you</p>
<p class="prose text-xs font-medium leading-8 dark:text-green-300">
sent: {message.data.created_at}
</p>
{/if}
</Card.Content>
</Card.Root>
<Card.Root class="ml-auto max-w-2xl border-none bg-transparent">
<Card.Content class="grid w-full grid-cols-2 items-center justify-between gap-4">
<p class="prose text-xs font-medium leading-8 dark:text-green-300">you</p>
<p class="prose text-xs font-medium leading-8 dark:text-green-300">
sent: {message.time}
</p>
</Card.Content>
</Card.Root>
</Card.Content>
</Card.Root>
{/if}
</div>
{/if}
</div>
Expand All @@ -151,7 +215,7 @@
</Card.Content>
</Card.Root>

<div class="relative flex w-full max-w-full items-center">
<form class="relative flex w-full max-w-full items-center">
<Input
bind:value={newMessageContent}
on:input={handleInputChange}
Expand All @@ -167,6 +231,6 @@
>
<Send class="hover:text-primary" />
</Button>
</div>
</form>
</div>
</div>
8 changes: 7 additions & 1 deletion apps/aitino/src/lib/components/ui/textarea/textarea.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
<script lang="ts">
import type { HTMLTextareaAttributes } from "svelte/elements";
import { cn } from "$lib/utils";
export let minRows = 1;
export let maxRows: number;
type $$Props = HTMLTextareaAttributes;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"] = undefined;
export { className as class };
$: minHeight = `${1 + minRows * 1.5}em`;
$: maxHeight = maxRows ? `${1 + maxRows * 1.5}em` : `auto`;
</script>

<textarea
class={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
style="min-height: {minHeight}; max-height: {maxHeight}"
bind:value
on:blur
on:change
Expand Down
2 changes: 1 addition & 1 deletion apps/aitino/src/routes/(marketing)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
setContext("splitTestIdentifier", data?.splitTestIdentifier);
</script>

<Shell class="">
<Shell>
<svelte:fragment slot="header">
<Header />
</svelte:fragment>
Expand Down
5 changes: 4 additions & 1 deletion apps/aitino/src/routes/api/v1/prompt/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import { API_BASE_URL } from "$lib/config";
export const GET = async ({ url }) => {
const prompt = url.searchParams.get("prompt");
const wordLimit = url.searchParams.get("word_limit") || "300"; // Default to 300 if not provided
const temperature = url.searchParams.get("temperature") || "0"; // Default to 0.8 if not provided
const prompt_type = url.searchParams.get("prompt_type") || "generic"; // Default to generic if not provided

if (!prompt) {
return json({ error: "No prompt provided" }, { status: 400 });
}

const apiUrl = `${API_BASE_URL}/improve?word_limit=${wordLimit}&prompt=${encodeURIComponent(prompt)}`;
const apiUrl = `${API_BASE_URL}/improve?word_limit=${wordLimit}&prompt=${encodeURIComponent(prompt)}&temperature=${temperature}&prompt_type=${prompt_type}`;

try {
const response = await fetch(apiUrl);
Expand Down
Loading

0 comments on commit ec3917a

Please sign in to comment.