Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 5 additions & 16 deletions docs/app/components/content/AssistantDemo.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { Chat } from '@ai-sdk/vue'
import { DefaultChatTransport, isToolUIPart, isTextUIPart, getToolName } from 'ai'
import { DefaultChatTransport, isToolUIPart, isTextUIPart } from 'ai'
import { isToolStreaming } from '@nuxt/ui/utils/ai'

const config = useRuntimeConfig()
Expand Down Expand Up @@ -36,18 +36,6 @@ const chat = isEnabled.value
})
: null

function getToolText(part: Parameters<typeof getToolName>[0]) {
const toolName = getToolName(part)
const input = (part as { input?: Record<string, string> }).input
const verb = part.state === 'output-available' ? 'Searched' : 'Searching'
const readVerb = part.state === 'output-available' ? 'Read' : 'Reading'

return {
'list-pages': `${verb} pages`,
'get-page': `${readVerb} ${input?.path || '...'}`,
}[toolName] || `${verb} ${toolName}`
}

function handleSubmit() {
if (!input.value.trim() || !chat) return

Expand Down Expand Up @@ -111,7 +99,7 @@ function resetChat() {
<template #indicator>
<UChatTool
icon="i-lucide-brain"
text="Thinking..."
:text="t('assistant.loading.thinking')"
streaming
/>
</template>
Expand All @@ -128,8 +116,9 @@ function resetChat() {

<UChatTool
v-else-if="isToolUIPart(part)"
:text="getToolText(part)"
:icon="getToolName(part) === 'get-page' ? 'i-lucide-file-text' : 'i-lucide-search'"
:text="getToolText(part, t)"
:suffix="getToolSuffix(part)"
:icon="getToolIcon(part)"
:streaming="isToolStreaming(part)"
/>
</template>
Expand Down
88 changes: 88 additions & 0 deletions layer/app/utils/assistantTools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { getToolName } from 'ai'
import type { ToolUIPart, DynamicToolUIPart } from 'ai'

export type AssistantToolPart = ToolUIPart | DynamicToolUIPart

type Translator = (key: string) => string

const VERB_KEYS: Record<string, [active: string, done: string]> = {
list: ['searching', 'searched'],
search: ['searching', 'searched'],
find: ['searching', 'searched'],
query: ['searching', 'searched'],
get: ['reading', 'read'],
read: ['reading', 'read'],
fetch: ['reading', 'read'],
show: ['finding', 'found'],
open: ['opening', 'opened'],
generate: ['generating', 'generated'],
create: ['creating', 'created'],
}

const SUFFIX_KEYS = [
'search',
'query',
'q',
'term',
'path',
'slug',
'templateName',
'componentName',
'composableName',
'name',
'repo',
'section',
'id',
]

function parseToolName(toolName: string): { verbKey?: [string, string], label: string } {
const parts = toolName.split(/[-_\s]+/).filter(Boolean)
const head = parts[0]?.toLowerCase()

if (head && VERB_KEYS[head] && parts.length > 1) {
return { verbKey: VERB_KEYS[head], label: parts.slice(1).join(' ') }
}

return { label: parts.join(' ') || toolName }
}

export function getToolText(part: AssistantToolPart, t: Translator): string {
const done = part.state === 'output-available'
const { verbKey, label } = parseToolName(getToolName(part))
const key = verbKey ? verbKey[done ? 1 : 0] : (done ? 'searched' : 'searching')

return `${t(`assistant.tools.${key}`)} ${label}`.trim()
}

export function getToolSuffix(part: AssistantToolPart): string | undefined {
const input = (part.input || {}) as Record<string, unknown>

for (const key of SUFFIX_KEYS) {
const value = input[key]
if (typeof value === 'string' && value.trim()) return value
}

return undefined
}

export function getToolIcon(part: AssistantToolPart): string {
const name = getToolName(part).toLowerCase()

if (/icon/.test(name)) return 'i-lucide-smile'
if (/component/.test(name)) return 'i-lucide-box'
if (/composable/.test(name)) return 'i-lucide-square-function'
if (/template/.test(name)) return 'i-lucide-layout-template'
if (/example|snippet/.test(name)) return 'i-lucide-code'
if (/module|package/.test(name)) return 'i-lucide-box'
if (/blog|post|news/.test(name)) return 'i-lucide-newspaper'
if (/changelog|release/.test(name)) return 'i-lucide-history'
if (/deploy|hosting|provider/.test(name)) return 'i-lucide-cloud'
if (/getting.?started|guide/.test(name)) return 'i-lucide-rocket'
if (/issue|github/.test(name)) return 'i-simple-icons-github'
if (/page|doc/.test(name)) {
const isList = /^(?:list|search|find|query)[-_]/.test(name)
return isList ? 'i-lucide-book-open' : 'i-lucide-file-text'
}

return 'i-lucide-search'
}
16 changes: 15 additions & 1 deletion layer/i18n/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "إغلاق",
"expand": "توسيع",
"collapse": "طي",
"thinking": "التفكير...",
"askMeAnything": "اسأل عن أي شيء",
"askMeAnythingDescription": "احصل على المساعدة في التنقل بين الوثائق وفهم المفاهيم والعثور على الإجابات.",
"faq": "الأسئلة الشائعة",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "اشرح باستخدام الذكاء الاصطناعي",
"toolListPages": "صفحات الوثائق المدرجة",
"toolReadPage": "قراءة",
"tools": {
"searching": "جارٍ البحث",
"searched": "تم البحث",
"reading": "جارٍ القراءة",
"read": "تمت القراءة",
"finding": "جارٍ البحث",
"found": "تم العثور",
"opening": "جارٍ الفتح",
"opened": "تم الفتح",
"generating": "جارٍ التوليد",
"generated": "تم التوليد",
"creating": "جارٍ الإنشاء",
"created": "تم الإنشاء"
},
"loading": {
"thinking": "التفكير...",
"searching": "البحث في الوثائق",
"reading": "قراءة المستندات",
"analyzing": "تحليل المحتوى",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "Закрыць",
"expand": "Пашырыць",
"collapse": "Згарнуць",
"thinking": "Мысленне...",
"askMeAnything": "Спытаць што-небудзь",
"askMeAnythingDescription": "Атрымаць дапамогу ў навігацыі па дакументацыі, разуменні канцэпцый і пошуку адказаў.",
"faq": "Пытанні і адказы",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "Растлумачыць ІІ",
"toolListPages": "Старонкі дакументацыі",
"toolReadPage": "Чытаць",
"tools": {
"searching": "Пошук",
"searched": "Знойдзена",
"reading": "Чытанне",
"read": "Прачытана",
"finding": "Пошук",
"found": "Знойдзена",
"opening": "Адкрыццё",
"opened": "Адкрыта",
"generating": "Генерацыя",
"generated": "Згенеравана",
"creating": "Стварэнне",
"created": "Створана"
},
"loading": {
"thinking": "Мысленне...",
"searching": "Пошук дакументацыі",
"reading": "Чытанне праз дакументы",
"analyzing": "Аналіз зместу",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "Затваряне",
"expand": "Разширяване",
"collapse": "Свиване",
"thinking": "Мисля си...",
"askMeAnything": "Попитайте за всичко",
"askMeAnythingDescription": "Потърсете помощ за навигация в документацията, разбиране на концепциите и намиране на отговори.",
"faq": "Често задавани въпроси",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "Обяснете с ИИ",
"toolListPages": "Изброени страници от документацията",
"toolReadPage": "Четене",
"tools": {
"searching": "Търсене",
"searched": "Намерено",
"reading": "Четене",
"read": "Прочетено",
"finding": "Търсене",
"found": "Намерено",
"opening": "Отваряне",
"opened": "Отворено",
"generating": "Генериране",
"generated": "Генерирано",
"creating": "Създаване",
"created": "Създадено"
},
"loading": {
"thinking": "Мисля си...",
"searching": "Търсене в документацията",
"reading": "Четене на документите",
"analyzing": "Анализиране на съдържанието",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "বন্ধ করুন",
"expand": "প্রসারিত করুন",
"collapse": "সঙ্কুচিত",
"thinking": "চিন্তা করা হচ্ছে...",
"askMeAnything": "যেকোনো কিছু জিজ্ঞাসা করুন",
"askMeAnythingDescription": "ডকুমেন্টেশন নেভিগেট করতে, ধারণাগুলি বুঝতে এবং উত্তর খুঁজে পেতে সহায়তা পান ।",
"faq": "প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "AI এর সাথে ব্যাখ্যা করুন",
"toolListPages": "তালিকাভুক্ত ডকুমেন্টেশন পৃষ্ঠাগুলি",
"toolReadPage": "পড়ুন",
"tools": {
"searching": "খুঁজছে",
"searched": "খুঁজেছে",
"reading": "পড়ছে",
"read": "পড়েছে",
"finding": "খুঁজছে",
"found": "পাওয়া গেছে",
"opening": "খুলছে",
"opened": "খুলেছে",
"generating": "উৎপন্ন করছে",
"generated": "উৎপন্ন করেছে",
"creating": "তৈরি করছে",
"created": "তৈরি করেছে"
},
"loading": {
"thinking": "চিন্তা করা হচ্ছে...",
"searching": "ডকুমেন্টেশন অনুসন্ধান করা হচ্ছে",
"reading": "ডকুমেন্টের মাধ্যমে পড়া",
"analyzing": "বিষয়বস্তু বিশ্লেষণ করা হচ্ছে",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "Tanca",
"expand": "Amplia",
"collapse": "Contraure",
"thinking": "Pensant...",
"askMeAnything": "Pregunta el que vulguis",
"askMeAnythingDescription": "Rep ajuda per navegar per la documentació, entendre els conceptes i trobar respostes.",
"faq": "Preguntes freqüents",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "Explica-ho amb IA",
"toolListPages": "Pàgines de documentació llistades",
"toolReadPage": "Llegir",
"tools": {
"searching": "Cercant",
"searched": "Cercat",
"reading": "Llegint",
"read": "Llegit",
"finding": "Cercant",
"found": "Trobat",
"opening": "Obrint",
"opened": "Obert",
"generating": "Generant",
"generated": "Generat",
"creating": "Creant",
"created": "Creat"
},
"loading": {
"thinking": "Pensant...",
"searching": "Cerca a la documentació",
"reading": "Llegir els documents",
"analyzing": "Analitzar el contingut",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/ckb.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "دابخە",
"expand": "فراوانتر بکە",
"collapse": "داڕمان",
"thinking": "بیرکردنەوە...",
"askMeAnything": "هەر شتێک بپرسە",
"askMeAnythingDescription": "یارمەتی وەربگرە لە گەشتکردن بە بەڵگەنامەکان، تێگەیشتن لە چەمکەکان و دۆزینەوەی وەڵامەکان.",
"faq": "پرسیارە بەردەوامەکان",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "بە AI ڕوونی بکەرەوە",
"toolListPages": "لاپەڕەکانی بەڵگەنامەی ڕیزبەندی",
"toolReadPage": "خوێندنەوە",
"tools": {
"searching": "گەڕان",
"searched": "گەڕا",
"reading": "خوێندنەوە",
"read": "خوێندرایەوە",
"finding": "گەڕان",
"found": "دۆزرایەوە",
"opening": "کردنەوە",
"opened": "کرایەوە",
"generating": "دروستکردن",
"generated": "دروستکرا",
"creating": "دروستکردن",
"created": "دروستکرا"
},
"loading": {
"thinking": "بیرکردنەوە...",
"searching": "گەڕان بەدوای بەڵگەنامەکاندا",
"reading": "خوێندنەوە لە ڕێگەی دۆکیۆمێنتەکانەوە",
"analyzing": "شیکردنەوەی ناوەڕۆک",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "Zavřít",
"expand": "Rozbalit",
"collapse": "Sbalit",
"thinking": "Přemýšlím...",
"askMeAnything": "Zeptej se na cokoliv",
"askMeAnythingDescription": "Získejte pomoc s orientací v dokumentaci, porozuměním konceptům a nalezením odpovědí.",
"faq": "Často kladené otázky",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "Vysvětlete pomocí AI",
"toolListPages": "Uvedené stránky dokumentace",
"toolReadPage": "Číst",
"tools": {
"searching": "Hledání",
"searched": "Nalezeno",
"reading": "Čtení",
"read": "Přečteno",
"finding": "Hledání",
"found": "Nalezeno",
"opening": "Otevírání",
"opened": "Otevřeno",
"generating": "Generování",
"generated": "Vygenerováno",
"creating": "Vytváření",
"created": "Vytvořeno"
},
"loading": {
"thinking": "Přemýšlím...",
"searching": "Vyhledávání v dokumentaci",
"reading": "Čtení dokumentů",
"analyzing": "Analýza obsahu",
Expand Down
16 changes: 15 additions & 1 deletion layer/i18n/locales/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"close": "Luk",
"expand": "Udvid",
"collapse": "Skjul",
"thinking": "Tænker...",
"askMeAnything": "Spørg om hvad som helst",
"askMeAnythingDescription": "Få hjælp til at navigere i dokumentationen, forstå begreber og finde svar.",
"faq": "FAQ",
Expand All @@ -52,7 +51,22 @@
"explainWithAi": "Forklar med AI",
"toolListPages": "Opførte dokumentationssider",
"toolReadPage": "Læs",
"tools": {
"searching": "Søger",
"searched": "Søgt",
"reading": "Læser",
"read": "Læst",
"finding": "Søger",
"found": "Fundet",
"opening": "Åbner",
"opened": "Åbnet",
"generating": "Genererer",
"generated": "Genereret",
"creating": "Opretter",
"created": "Oprettet"
},
"loading": {
"thinking": "Tænker...",
"searching": "Søgning i dokumentationen",
"reading": "Gennemlæsning af dokumenterne",
"analyzing": "Analyse af indholdet",
Expand Down
Loading
Loading