Files
veridian/app/pages/agent/[id]/index.vue
T
2026-01-11 05:04:29 -06:00

93 lines
2.7 KiB
Vue

<script setup lang="ts">
import type { Message } from '~~/types'
const { createTopic, activeTopic } = await useTopics()
const { activeAgent } = await useAgents()
const loading = ref(false)
const messages = useState<Message[]>('messages', () => [])
const generatingMessage = ref('')
if (activeTopic.value !== undefined) {
const topicData = await useFetch(`/api/topics/${activeTopic.value.id}`)
if (topicData.error.value) throw topicData.error
messages.value = topicData.data.value!.messages
console.log(messages.value)
}
const handleSubmit = async (message: string) => {
loading.value = true
let topic;
if (activeTopic.value) {
topic = activeTopic.value
} else {
topic = await createTopic('New Topic', activeAgent.value!.id)
}
console.log(topic.id)
const generation = await $fetch(`/api/chat/generate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
topicId: topic.id,
messages: [{
type: 'user',
message
}]
})
})
const response = await $fetch<ReadableStream>(`/api/chat/stream/${generation.generationId}`, {
method: 'get',
responseType: 'stream',
})
// Create a new ReadableStream from the response with TextDecoderStream to get the data as text
const reader = response.pipeThrough(new TextDecoderStream()).getReader()
generatingMessage.value = ''
// Read the data from the stream and update the UI
while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
const { type, data } = JSON.parse(value)
if (type === 'token') {
generatingMessage.value += data
continue
}
if (type === 'complete') {
if (generatingMessage.value !== data) {
generatingMessage.value = data
}
break
}
}
loading.value = false
}
</script>
<template>
<div class="flex h-full w-full pb-4 justify-center">
<div class="max-w-4xl h-full w-full flex flex-col">
<!-- chat pane -->
<div class="flex h-full flex-col gap-6">
<p v-if="activeTopic !== undefined" v-for="message in messages" :key="message.id">
{{ message.content }}
</p>
<p v-else>No messages yet</p>
<p v-if="generatingMessage" class="text-sm text-gray-500">{{ generatingMessage }}</p>
</div>
<ChatInput @submit="handleSubmit" :loading="loading" />
</div>
</div>
</template>