7eaf4d9dca
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
57 lines
1.9 KiB
Vue
57 lines
1.9 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useChatStore } from '@/stores/chat'
|
|
import { useSettingsStore } from '@/stores/settings'
|
|
import { renderMarkdown } from '@/utils/markdown'
|
|
import ToolCallCard from '@/components/ToolCallCard.vue'
|
|
import ToolConfirmCard from '@/components/ToolConfirmCard.vue'
|
|
|
|
const store = useChatStore()
|
|
const settingsStore = useSettingsStore()
|
|
|
|
const streamingRendered = computed(() => {
|
|
if (!store.streamingContent) return ''
|
|
return renderMarkdown(store.streamingContent)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="chat-message role-assistant">
|
|
<div class="message-bubble streaming-bubble">
|
|
<div class="message-header">
|
|
<span class="role-label">{{ settingsStore.assistantName }}</span>
|
|
</div>
|
|
<div v-if="store.streamingToolCalls.length" class="streaming-tool-calls">
|
|
<ToolCallCard
|
|
v-for="(tc, i) in store.streamingToolCalls"
|
|
:key="i"
|
|
:tool-call="tc"
|
|
/>
|
|
</div>
|
|
<ToolConfirmCard
|
|
v-if="store.streamingPendingTool"
|
|
:pending-tool="store.streamingPendingTool"
|
|
@accept="store.confirmTool(true)"
|
|
@decline="store.confirmTool(false)"
|
|
/>
|
|
<div v-if="store.streamingStatus" class="streaming-status-line">
|
|
<span class="streaming-status-dot"></span>
|
|
{{ store.streamingStatus }}
|
|
</div>
|
|
<details
|
|
v-if="store.streamingThinking"
|
|
class="thinking-block"
|
|
:open="!store.streamingContent"
|
|
>
|
|
<summary class="thinking-summary">Reasoning</summary>
|
|
<pre class="thinking-text">{{ store.streamingThinking }}</pre>
|
|
</details>
|
|
<div class="message-content prose" v-html="streamingRendered"></div>
|
|
<span
|
|
v-if="!store.streamingStatus && !store.streamingThinking && !store.streamingContent"
|
|
class="typing-indicator"
|
|
></span>
|
|
</div>
|
|
</div>
|
|
</template>
|