Chatraisonnement

Afficher un raisonnement ou un processus de réflexion d'IA pliable.

Utilisation

Le composant ChatReasoning rend un bloc pliable qui affiche le contenu du raisonnement ou de la pensée de l'IA. Il s'ouvre automatiquement pendant le streaming et se ferme automatiquement après.

<script setup lang="ts">
const streaming = ref(false)
const text = ref('')

async function simulateStreaming() {
  streaming.value = true
  text.value = ''

  const content =
    'The user is asking about Vue components. I should explain the Composition API pattern and how it relates to their question about reactive state management. Let me think about the best way to structure this response.\n\nFirst, I need to consider the key differences between the Options API and Composition API. The Composition API was introduced in Vue 3 to address limitations of the Options API when building large-scale applications.\n\nFor reactive state management specifically, the Composition API offers ref() for primitive values and reactive() for objects.'

  for (const char of content) {
    text.value += char
    await new Promise((resolve) => setTimeout(resolve, 10))
  }

  streaming.value = false
}

onMounted(simulateStreaming)
</script>

<template>
  <UChatReasoning :text="text" :streaming="streaming" class="w-60" />
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'

const streaming = ref(false)
const text = ref('')

async function simulateStreaming() {
  streaming.value = true
  text.value = ''

  const content =
    'The user is asking about Vue components. I should explain the Composition API pattern and how it relates to their question about reactive state management. Let me think about the best way to structure this response.\n\nFirst, I need to consider the key differences between the Options API and Composition API. The Composition API was introduced in Vue 3 to address limitations of the Options API when building large-scale applications.\n\nFor reactive state management specifically, the Composition API offers ref() for primitive values and reactive() for objects.'

  for (const char of content) {
    text.value += char
    await new Promise((resolve) => setTimeout(resolve, 10))
  }

  streaming.value = false
}

onMounted(simulateStreaming)
</script>

<template>
  <UChatReasoning :text="text" :streaming="streaming" class="w-60" />
</template>
Le contenu du corps utilise le composable useScrollShadow pour appliquer des ombres de fondu lors du débordement.

Texte écrit

Utilisez le prop text pour définir le contenu du raisonnement. Le texte s'affiche à l'intérieur du corps pliable.

<template>
  <UChatReasoning text="The user is asking about Vue components..." />
</template>

Streaming

Utilisez la prop streaming pour indiquer un raisonnement actif. Le composant s'ouvre automatiquement lorsque le streaming démarre et se ferme automatiquement lorsqu 'il se termine.

The user is asking about Vue components...
<template>
  <UChatReasoning streaming text="The user is asking about Vue components..." />
</template>
Utilisez l'utilitaire isPartStreaming de @nuxt/ui/utils/ai pour déterminer si une partie est en cours de diffusion.

écran

Lors de la diffusion en continu, l'étiquette de déclenchement utilise le composant ChatShimmer. Utilisez la prop shimmer pour personnaliser ses duration et spread.

The user is asking about Vue components...
<template>
  <UChatReasoning
    streaming
    text="The user is asking about Vue components..."
    :shimmer="{
      duration: 2,
      spread: 2
    }"
  />
</template>

Icône

Utilisez la prop icon pour afficher un composant Icon à côté du déclencheur.

<template>
  <UChatReasoning icon="i-lucide-brain" text="The user is asking about Vue components..." />
</template>

Chevron

Utilisez le prop chevron pour changer la position de l'icône du chevron.

Lorsque chevron est réglé sur leading avec un icon, l'icône change avec le chevron en survol et lorsqu 'elle est ouverte.
<template>
  <UChatReasoning
    chevron="leading"
    icon="i-lucide-brain"
    text="The user is asking about Vue components..."
  />
</template>

Chevron Icône

Utilisez la prop chevron-icon pour personnaliser le chevron Icon.

<template>
  <UChatReasoning
    chevron-icon="i-lucide-arrow-down"
    text="The user is asking about Vue components..."
  />
</template>
Vous pouvez personnaliser cette icône globalement dans votre app.config.ts sous la touche ui.icons.chevronDown.
Vous pouvez personnaliser cette icône globalement dans votre vite.config.ts sous la touche ui.icons.chevronDown.

exemples

Consultez la page d'aperçu Chat pour les instructions d'installation, la configuration du serveur et les exemples d'utilisation.

API

Props équipements

Prop Default Type
text
string

The reasoning text content to display.

streaming
false
boolean

Whether the reasoning content is currently streaming.

duration
number

The duration in seconds that the AI spent reasoning. If not provided, it will be calculated automatically based on streaming time.

icon
any

The icon displayed next to the trigger.

chevron
'trailing'
"leading" | "trailing"

The position of the chevron icon.

chevronIcon
appConfig.ui.icons.chevronDown
any

The icon displayed as the chevron.

autoCloseDelay
500
number

The delay in milliseconds before auto-closing when streaming ends. Set to 0 to disable auto-close.

shimmer
Partial<Omit<ChatShimmerProps, "text">>

Customize the ChatShimmer component when streaming.

disabled
boolean

When true, prevents the user from interacting with the collapsible.

open
undefined
boolean

The controlled open state of the collapsible. Can be binded with v-model.

defaultOpen
boolean

The open state of the collapsible when it is initially rendered.
Use when you do not need to control its open state.

unmountOnHide
false
boolean

When true, the element will be unmounted on closed state.

ui
{ root?: SlotClass; trigger?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; chevronIcon?: SlotClass; label?: SlotClass; trailingIcon?: SlotClass; content?: SlotClass; body?: SlotClass; }

Slots

Slot Type
default
{ open: boolean; }

Emis

Event Type
update:open
[value: boolean]

thème

app.config.ts
export default defineAppConfig({
  ui: {
    chatReasoning: {
      slots: {
        root: '',
        trigger: [
          'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
          'transition-colors'
        ],
        leading: 'relative size-4 shrink-0',
        leadingIcon: 'size-4 shrink-0',
        chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
        label: 'truncate',
        trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
        content: 'data-[state=open]:animate-[collapsible-down_200ms_var(--ease-out)] data-[state=closed]:animate-[collapsible-up_200ms_var(--ease-out)] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
        body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
      },
      variants: {
        chevron: {
          leading: {
            leadingIcon: 'group-hover:opacity-0'
          },
          trailing: ''
        },
        alone: {
          false: {
            leadingIcon: [
              'absolute inset-0 group-data-[state=open]:opacity-0',
              'transition-opacity duration-200 ease-out'
            ],
            chevronIcon: [
              'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
              'transition-[rotate,opacity] duration-200 ease-out motion-reduce:transition-none'
            ]
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        chatReasoning: {
          slots: {
            root: '',
            trigger: [
              'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
              'transition-colors'
            ],
            leading: 'relative size-4 shrink-0',
            leadingIcon: 'size-4 shrink-0',
            chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
            label: 'truncate',
            trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
            content: 'data-[state=open]:animate-[collapsible-down_200ms_var(--ease-out)] data-[state=closed]:animate-[collapsible-up_200ms_var(--ease-out)] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
            body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
          },
          variants: {
            chevron: {
              leading: {
                leadingIcon: 'group-hover:opacity-0'
              },
              trailing: ''
            },
            alone: {
              false: {
                leadingIcon: [
                  'absolute inset-0 group-data-[state=open]:opacity-0',
                  'transition-opacity duration-200 ease-out'
                ],
                chevronIcon: [
                  'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
                  'transition-[rotate,opacity] duration-200 ease-out motion-reduce:transition-none'
                ]
              }
            }
          }
        }
      }
    })
  ]
})

Changelog écrit

No recent changes