WIP - initial AI assistant chat working creating records

This commit is contained in:
Francisco Gaona
2026-01-12 23:55:57 +01:00
parent ca11c8cbe7
commit d2b3fce4eb
10 changed files with 1551 additions and 6 deletions

View File

@@ -8,26 +8,90 @@ import {
} from '@/components/ui/input-group'
import { Separator } from '@/components/ui/separator'
import { ArrowUp } from 'lucide-vue-next'
import { useRoute } from 'vue-router'
import { useApi } from '@/composables/useApi'
const chatInput = ref('')
const messages = ref<{ role: 'user' | 'assistant'; text: string }[]>([])
const sending = ref(false)
const route = useRoute()
const { api } = useApi()
const handleSend = () => {
const buildContext = () => {
const recordId = route.params.recordId ? String(route.params.recordId) : undefined
const viewParam = route.params.view ? String(route.params.view) : undefined
const view = viewParam || (recordId ? (recordId === 'new' ? 'edit' : 'detail') : 'list')
const objectApiName = route.params.objectName
? String(route.params.objectName)
: undefined
return {
objectApiName,
view,
recordId,
route: route.fullPath,
}
}
const handleSend = async () => {
if (!chatInput.value.trim()) return
// TODO: Implement AI chat send functionality
console.log('Sending message:', chatInput.value)
const message = chatInput.value.trim()
messages.value.push({ role: 'user', text: message })
chatInput.value = ''
sending.value = true
try {
const history = messages.value.slice(0, -1).slice(-6)
const response = await api.post('/ai/chat', {
message,
history,
context: buildContext(),
})
messages.value.push({
role: 'assistant',
text: response.reply || 'Let me know what else you need.',
})
} catch (error: any) {
console.error('Failed to send AI chat message:', error)
messages.value.push({
role: 'assistant',
text: error.message || 'Sorry, I ran into an error. Please try again.',
})
} finally {
sending.value = false
}
}
</script>
<template>
<div class="ai-chat-area w-full border-t border-border p-4 bg-neutral-50">
<div class="ai-chat-messages mb-4 space-y-3">
<div
v-for="(message, index) in messages"
:key="`${message.role}-${index}`"
class="flex"
:class="message.role === 'user' ? 'justify-end' : 'justify-start'"
>
<div
class="max-w-[80%] rounded-lg px-3 py-2 text-sm"
:class="message.role === 'user' ? 'bg-primary text-primary-foreground' : 'bg-white border border-border text-foreground'"
>
{{ message.text }}
</div>
</div>
<p v-if="messages.length === 0" class="text-sm text-muted-foreground">
Ask the assistant to add records, filter lists, or summarize the page.
</p>
</div>
<InputGroup>
<InputGroupTextarea
v-model="chatInput"
placeholder="Ask, Search or Chat..."
class="min-h-[60px] rounded-lg"
@keydown.enter.exact.prevent="handleSend"
:disabled="sending"
/>
<InputGroupAddon>
<InputGroupText class="ml-auto">
@@ -37,7 +101,7 @@ const handleSend = () => {
<InputGroupButton
variant="default"
class="rounded-full"
:disabled="!chatInput.trim()"
:disabled="!chatInput.trim() || sending"
@click="handleSend"
>
<ArrowUp class="size-4" />