mirror of
https://github.com/ArthurDanjou/artagents.git
synced 2026-01-14 12:14:40 +01:00
175 lines
5.1 KiB
Vue
175 lines
5.1 KiB
Vue
<script setup lang="ts">
|
|
import { PROVIDERS, type Agent } from '~~/types'
|
|
import { useChat } from '@ai-sdk/vue'
|
|
import { onStartTyping } from '@vueuse/core'
|
|
import { AGENTS, MODELS } from '~~/types'
|
|
|
|
const toast = useToast()
|
|
const { agent } = useRoute().params
|
|
const currentAgent = ref(AGENTS.find(item => item.slug === agent) as Agent | undefined)
|
|
|
|
const model = ref<PROVIDERS>(currentAgent.value?.defaultModel || PROVIDERS.MISTRAL)
|
|
const selectedModel = computed(() => MODELS.find(item => item.model === model.value))
|
|
|
|
const { loadChat, deleteChat } = await useChatFile()
|
|
const initialMessages = await loadChat(currentAgent.value?.slug || '')
|
|
const { messages, input, handleSubmit, status, stop, error, reload } = useChat({
|
|
id: currentAgent.value?.slug,
|
|
initialMessages,
|
|
sendExtraMessageFields: true,
|
|
experimental_prepareRequestBody({ messages, id }) {
|
|
return { message: messages[messages.length - 1], id }
|
|
},
|
|
body: {
|
|
model: model.value,
|
|
agent: currentAgent.value,
|
|
},
|
|
})
|
|
|
|
const inputRef = shallowRef<HTMLInputElement | null>(null)
|
|
onStartTyping(() => { // TODO: fix focus
|
|
if (inputRef.value !== document.activeElement)
|
|
inputRef.value!.focus()
|
|
})
|
|
|
|
const isModalOpen = ref(false)
|
|
async function deleteConversation() {
|
|
await deleteChat(currentAgent.value!.slug)
|
|
window.location.reload()
|
|
isModalOpen.value = false
|
|
toast.add({
|
|
title: 'Conversation deleted',
|
|
description: `The conversation has been deleted`,
|
|
color: 'success',
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<main
|
|
v-if="currentAgent"
|
|
class="flex flex-col justify-between"
|
|
>
|
|
<ChatHeader :current-agent="currentAgent" />
|
|
<ChatMessages
|
|
:messages="messages"
|
|
:initial-messages="initialMessages"
|
|
:current-agent="currentAgent"
|
|
/>
|
|
<div
|
|
v-if="error"
|
|
class="flex items-center justify-center gap-2"
|
|
>
|
|
<div class="text-red-500">
|
|
{{ 'An error occurred' }}
|
|
</div>
|
|
<UButton
|
|
color="neutral"
|
|
variant="subtle"
|
|
size="xs"
|
|
@click="reload()"
|
|
>
|
|
retry
|
|
</UButton>
|
|
</div>
|
|
<ClientOnly>
|
|
<form
|
|
class="mt-4 shadow-md flex flex-col items-center w-full p-2 gap-2 bg-zinc-100 rounded-2xl dark:bg-neutral-800"
|
|
@submit.prevent="handleSubmit"
|
|
@keydown.enter.prevent="handleSubmit"
|
|
>
|
|
<div class="w-full flex gap-2">
|
|
<UTextarea
|
|
ref="inputRef"
|
|
v-model="input"
|
|
placeholder="Type what you want to ask..."
|
|
class="w-full min-h-8"
|
|
:ui="{
|
|
base: 'min-h-8',
|
|
}"
|
|
color="primary"
|
|
autoresize
|
|
:rows="1"
|
|
variant="soft"
|
|
:disabled="Boolean(error)"
|
|
/>
|
|
<div class="flex items-start">
|
|
<UButton
|
|
v-if="status !== 'ready'"
|
|
icon="i-heroicons-stop"
|
|
color="primary"
|
|
@click="stop"
|
|
/>
|
|
<UButton
|
|
v-else
|
|
icon="i-heroicons-arrow-long-up-16-solid"
|
|
type="submit"
|
|
class="rounded-xl duration-300"
|
|
:color="input.length === 0 ? 'neutral' : 'primary'"
|
|
:disabled="input.length === 0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="w-full flex items-center gap-2">
|
|
<UButton
|
|
icon="i-heroicons-paper-clip"
|
|
color="neutral"
|
|
variant="subtle"
|
|
class="rounded-xl"
|
|
@click="stop"
|
|
/>
|
|
<UTooltip text="Select model">
|
|
<USelect
|
|
v-model="model"
|
|
class="rounded-xl w-40"
|
|
color="neutral"
|
|
variant="subtle"
|
|
:items="MODELS"
|
|
label-key="name"
|
|
value-key="model"
|
|
:icon="selectedModel?.icon"
|
|
trailing-icon=""
|
|
leading-icon=""
|
|
/>
|
|
</UTooltip>
|
|
<UModal
|
|
v-model:open="isModalOpen"
|
|
title="Are you sure you want to delete this conversation?"
|
|
description="This action cannot be undone. The agent will lost all the conversation history and context."
|
|
:ui="{ footer: 'justify-end' }"
|
|
>
|
|
<UTooltip text="Clear conversation">
|
|
<UButton
|
|
:disabled="messages.length === 0"
|
|
icon="i-heroicons-trash"
|
|
color="neutral"
|
|
variant="subtle"
|
|
class="rounded-xl"
|
|
/>
|
|
</UTooltip>
|
|
<template #footer>
|
|
<div class="flex gap-2">
|
|
<UButton
|
|
color="neutral"
|
|
label="Dismiss"
|
|
@click.prevent="isModalOpen = false"
|
|
/>
|
|
<UButton
|
|
color="error"
|
|
label="Delete"
|
|
@click.prevent="deleteConversation"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</UModal>
|
|
</div>
|
|
</form>
|
|
</ClientOnly>
|
|
</main>
|
|
<main v-else>
|
|
<div class="flex items-center justify-center h-full">
|
|
Agent not found
|
|
</div>
|
|
</main>
|
|
</template>
|