streaming, markdown, model selecting, and lots more
This commit is contained in:
@@ -1,33 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
const { agents, createAgent } = await useAgents()
|
||||
const agentsListRef = ref<HTMLElement | null>(null)
|
||||
const agentsOpen = ref(true)
|
||||
const agentsListHeight = ref('auto')
|
||||
const agentsListOpacity = ref(1)
|
||||
const agentsListScale = ref(1)
|
||||
const creatingAgent = ref(false)
|
||||
const { agents } = await useAgents();
|
||||
const agentsListRef = ref<HTMLElement | null>(null);
|
||||
const agentsOpen = ref(true);
|
||||
const agentsListHeight = ref('auto');
|
||||
const agentsListOpacity = ref(1);
|
||||
const agentsListScale = ref(1);
|
||||
const creatingAgent = ref(false);
|
||||
|
||||
function easeInOutQuad(x: number): number {
|
||||
return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
|
||||
return x < 0.5 ? 2 * x * x : 1 - (-2 * x + 2) ** 2 / 2;
|
||||
}
|
||||
|
||||
const toggleAgentsList = () => {
|
||||
if (!agentsListRef.value) return;
|
||||
let animationLength = 200;
|
||||
const animationLength = 200;
|
||||
let animationStart: number | null = null;
|
||||
|
||||
let startHeight: number;
|
||||
let startOpacity = agentsListOpacity.value;
|
||||
let startScale = agentsListScale.value;
|
||||
const startOpacity = agentsListOpacity.value;
|
||||
const startScale = agentsListScale.value;
|
||||
if (agentsListHeight.value === 'auto') {
|
||||
startHeight = agentsListRef.value.clientHeight;
|
||||
} else {
|
||||
startHeight = Number(agentsListHeight.value.replace('px', ''));
|
||||
}
|
||||
|
||||
let targetHeight = agentsOpen.value ? 0 : agentsListRef.value.scrollHeight;
|
||||
let targetOpacity = agentsOpen.value ? 0 : 1;
|
||||
let targetScale = agentsOpen.value ? 0.95 : 1;
|
||||
const targetHeight = agentsOpen.value ? 0 : agentsListRef.value.scrollHeight;
|
||||
const targetOpacity = agentsOpen.value ? 0 : 1;
|
||||
const targetScale = agentsOpen.value ? 0.95 : 1;
|
||||
agentsOpen.value = !agentsOpen.value;
|
||||
|
||||
const animate = (timestamp: number) => {
|
||||
@@ -54,36 +54,59 @@ const toggleAgentsList = () => {
|
||||
};
|
||||
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
};
|
||||
|
||||
const newAgent = async () => {
|
||||
creatingAgent.value = true;
|
||||
const agent = await createAgent();
|
||||
creatingAgent.value = false;
|
||||
navigateTo(`/agent/${agent!.id}`);
|
||||
}
|
||||
const triplit = useTriplitClient();
|
||||
const { user } = useAuth();
|
||||
|
||||
if (!user.value) throw new Error('User not logged in');
|
||||
|
||||
const agent = await triplit.insert('agents', {
|
||||
name: 'New Agent',
|
||||
userId: user.value.id,
|
||||
systemPrompt: 'You are a helpful assistant.',
|
||||
imageUrl: null,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
|
||||
console.log(agents.value, agent);
|
||||
if (!agent) throw new Error('Failed to create agent');
|
||||
|
||||
let agentExists: () => void;
|
||||
const agentExistsPromise = new Promise<void>((resolve) => {
|
||||
agentExists = resolve;
|
||||
});
|
||||
|
||||
watch(agents, () => {
|
||||
agentExists();
|
||||
});
|
||||
|
||||
await agentExistsPromise;
|
||||
|
||||
navigateTo(`/agent/${agent.id}`);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="flex flex-col gap-1">
|
||||
<SidenavItem name="Search" icon="mynaui:search" />
|
||||
<NuxtLink to="/" class="decoration-none text-[var(--color-text)]">
|
||||
<SidenavItem class="bg-[var(--color-highlight)]" name="Home" icon="mynaui:home" />
|
||||
</NuxtLink>
|
||||
<SidenavItem to="/" :active="true" name="Home" icon="mynaui:home" />
|
||||
|
||||
<!-- Agents Section -->
|
||||
<div class="flex items-center justify-between gap-2 px-2 py-2 rounded-lg bg-transparent hover:bg-[var(--color-highlight)] transition-colors w-full text-left"
|
||||
<button
|
||||
class="flex items-center justify-between gap-2 px-2 py-2 rounded-lg bg-transparent hover:bg-[var(--color-highlight)] focus-visible:bg-[var(--color-highlight)] transition-colors w-full text-left"
|
||||
@click="toggleAgentsList()">
|
||||
<span class="text-sm">Agents</span>
|
||||
<Icon name="mynaui:chevron-down"
|
||||
:class="['w-4 h-4 transition-transform duration-250 ease-[cubic-bezier(0.5,_1,_0.89,_1)] transform-origin-center', agentsOpen ? '' : '-rotate-90']" />
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div ref="agentsListRef"
|
||||
<div ref="agentsListRef" :inert="!agentsOpen"
|
||||
:style="{ height: agentsListHeight, opacity: agentsListOpacity, transform: `scale(${agentsListScale})` }"
|
||||
class="mt-1 gap-1 flex flex-col overflow-hidden transform-origin-center-top">
|
||||
class="mt-1 gap-1 flex flex-col transform-origin-center-top overflow-y-hidden">
|
||||
<button @click="newAgent" :disabled="creatingAgent"
|
||||
class="flex items-center gap-2 px-1 h-9 shrink-0 rounded-lg text-sm text-[var(--color-subtle)] bg-transparent hover:bg-[var(--color-highlight)] transition-colors disabled:opacity-50 w-full">
|
||||
class="flex items-center gap-2 px-1 h-9 shrink-0 rounded-lg text-sm text-[var(--color-muted)] bg-transparent hover:bg-[var(--color-highlight)] focus-visible:bg-[var(--color-highlight)] transition-colors disabled:opacity-50 w-full">
|
||||
<div class="h-7 w-7 flex items-center justify-center">
|
||||
<Icon v-if="creatingAgent" class="text-4.5" name="svg-spinners:ring-resize" />
|
||||
<Icon v-else class="text-4.5" name="mynaui:plus" />
|
||||
@@ -91,10 +114,9 @@ const newAgent = async () => {
|
||||
<span>New Agent</span>
|
||||
</button>
|
||||
|
||||
<NuxtLink v-for="agent in agents" :to="`/agent/${agent.id}`" :key="agent.id"
|
||||
class="decoration-none text-[var(--color-subtle)]">
|
||||
<SidenavItem :name="agent.name" icon="mynaui:check-hexagon" />
|
||||
</NuxtLink>
|
||||
<SidenavItem
|
||||
v-for="agent in agents?.map((agent) => agent)?.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())"
|
||||
:to="`/agent/${agent.id}`" :key="agent.id" :name="agent.name" icon="mynaui:check-hexagon" />
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
Reference in New Issue
Block a user