检查点

一个简单的组件,用于标记对话历史点并将聊天恢复到之前的状态。

Checkpoint 组件提供了一种方法来标记对话历史中的特定点并将聊天恢复到该状态。受 VSCode 的 Copilot 检查点功能启发,它允许用户恢复到更早的对话状态,同时在不同对话段之间保持清晰的可视化分离。

使用 CLI 安装

AI Elements Vue
shadcn-vue CLI
npx ai-elements-vue@latest add checkpoint

手动安装

将以下代码复制并粘贴到同一文件夹中。

Checkpoint.vue
CheckpointIcon.vue
CheckpointTrigger.vue
index.ts
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue'
import { Separator } from '@repo/shadcn-vue/components/ui/separator'
import { cn } from '@repo/shadcn-vue/lib/utils'

const props = defineProps<{
  class?: HTMLAttributes['class']
}>()
</script>

<template>
  <div
    :class="cn('flex items-center gap-0.5 text-muted-foreground', props.class)"
    v-bind="$attrs"
  >
    <slot />
    <Separator />
  </div>
</template>

特性

  • 简单的 flex 布局,带有图标、触发器和分隔符
  • 可视化分隔线,用于清晰的对话中断
  • 可点击的恢复按钮,用于恢复到检查点
  • 可自定义图标(默认为 BookmarkIcon)
  • 键盘可访问,具有适当的 ARIA 标签
  • 响应式设计,适应不同的屏幕尺寸
  • 无缝的浅色/深色主题集成

与 AI SDK 一起使用

构建一个带有对话检查点的聊天界面,允许用户恢复到之前的状态。

将以下组件添加到你的前端:

pages/index.vue
<script setup lang="ts">
import { useChat } from '@ai-sdk/vue'
import { nanoid } from 'nanoid'
import { computed, ref } from 'vue'
import {
  Checkpoint,
  CheckpointIcon,
  CheckpointTrigger,
} from '@/components/ai-elements/checkpoint'
import {
  Conversation,
  ConversationContent,
} from '@/components/ai-elements/conversation'
import {
  Message,
  MessageContent,
  MessageResponse,
} from '@/components/ai-elements/message'

interface CheckpointType {
  id: string
  messageIndex: number
  timestamp: Date
  messageCount: number
}

const { messages, setMessages } = useChat()
const checkpoints = ref<CheckpointType[]>([])

const messagesWithCheckpoints = computed(() => {
  return messages.value.map((message, index) => {
    const checkpoint = checkpoints.value.find(
      cp => cp.messageIndex === index
    )
    return { message, index, checkpoint }
  })
})

function createCheckpoint(messageIndex: number) {
  const checkpoint: CheckpointType = {
    id: nanoid(),
    messageIndex,
    timestamp: new Date(),
    messageCount: messageIndex + 1,
  }
  checkpoints.value.push(checkpoint)
}

function restoreToCheckpoint(messageIndex: number) {
  // Restore messages to checkpoint state (assuming setMessages API is the same)
  setMessages(messages.value.slice(0, messageIndex + 1))
  // Remove checkpoints after this point
  checkpoints.value = checkpoints.value.filter(
    cp => cp.messageIndex <= messageIndex
  )
}
</script>

<template>
  <div
    class="max-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px]"
  >
    <Conversation>
      <ConversationContent>
        <template
          v-for="{ message, checkpoint } in messagesWithCheckpoints"
          :key="message.id"
        >
          <Message :from="message.role">
            <MessageContent>
              <MessageResponse>{{ message.content }}</MessageResponse>
            </MessageContent>
          </Message>

          <Checkpoint v-if="checkpoint">
            <CheckpointIcon />
            <CheckpointTrigger
              @click="restoreToCheckpoint(checkpoint.messageIndex)"
            >
              Restore checkpoint
            </CheckpointTrigger>
          </Checkpoint>
        </template>
      </ConversationContent>
    </Conversation>
  </div>
</template>

使用场景

手动检查点

允许用户在重要的对话点手动创建检查点:

<Button @click="createCheckpoint(messages.length - 1)">
  Create Checkpoint
</Button>

自动检查点

在重要的对话里程碑后自动创建检查点:

watch(
  () => messages.value.length,
  (length) => {
    // Create checkpoint every 5 messages
    if (length > 0 && length % 5 === 0) {
      createCheckpoint(length - 1)
    }
  }
)

分支对话

使用检查点启用对话分支,用户可以探索不同的对话路径:

function restoreAndBranch(messageIndex: number) {
  // Save current branch
  const currentBranch = messages.value.slice(messageIndex + 1)
  saveBranch(currentBranch)

  // Restore to checkpoint
  restoreToCheckpoint(messageIndex)
}

Props

<Checkpoint />

classstring
''
应用于组件的类名。

<CheckpointIcon />

classstring
''
应用于组件的类名。

<CheckpointTrigger />

tooltipstring
''
悬停触发器时显示的工具提示文本。
variantstring
'ghost'
按钮的变体(例如,'ghost'、'outline'、'solid')。
sizestring
'sm'
按钮的大小(例如,'sm'、'md'、'lg')。