Add streaming support and refactor Chat UI
- Add run_stream method to AgentCore for streaming output - Add base_url parameter to LLM clients for OpenRouter support - Add xbot module for new agent implementation - Refactor Chat.vue into composable + components (ChatHeader, ChatMessage, ChatInput, ChatSidebar, ChatAgentSelector) - Add ChatStream handler for SSE streaming in Go server - Add UseXBot field to chat request Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
72
web/src/components/chat/ChatInput.vue
Normal file
72
web/src/components/chat/ChatInput.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
modelValue: string
|
||||
loading: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void
|
||||
(e: 'send'): void
|
||||
}>()
|
||||
|
||||
const handleKeydown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault()
|
||||
emit('send')
|
||||
}
|
||||
}
|
||||
|
||||
const autoResize = (e: Event) => {
|
||||
const target = e.target as HTMLTextAreaElement
|
||||
target.style.height = 'auto'
|
||||
target.style.height = Math.min(target.scrollHeight, 160) + 'px'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-5 border-t border-white/[0.06] bg-[#0c0c0f]/60 backdrop-blur-xl">
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="relative bg-[#12121a] rounded-2xl border border-white/[0.08] focus-within:border-orange-500/40 focus-within:shadow-[0_0_30px_rgba(249,115,22,0.08)] transition-all duration-300">
|
||||
<!-- 附件按钮 -->
|
||||
<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/25 hover:text-orange-400 transition-colors p-1">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- 输入框 -->
|
||||
<textarea
|
||||
:value="modelValue"
|
||||
@input="emit('update:modelValue', ($event.target as HTMLTextAreaElement).value); autoResize($event)"
|
||||
@keydown="handleKeydown"
|
||||
placeholder="发送消息..."
|
||||
rows="1"
|
||||
class="w-full bg-transparent text-white placeholder-white/25 py-4 pl-12 pr-28 resize-none focus:outline-none text-[15px]"
|
||||
></textarea>
|
||||
|
||||
<!-- 发送按钮 -->
|
||||
<button
|
||||
@click="emit('send')"
|
||||
:disabled="!modelValue.trim() || loading"
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 w-9 h-9 rounded-lg flex items-center justify-center transition-all duration-200 disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
:class="modelValue.trim() && !loading
|
||||
? 'bg-orange-500 hover:bg-orange-400 shadow-lg shadow-orange-500/30 active:scale-90'
|
||||
: 'bg-white/10'"
|
||||
>
|
||||
<svg v-if="!loading" class="w-4 h-4 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
|
||||
</svg>
|
||||
<svg v-else class="w-4 h-4 text-white animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 提示 -->
|
||||
<div class="text-center mt-3">
|
||||
<span class="text-[10px] text-white/20 tracking-wide">AI 可能会产生错误信息,请核实重要内容</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user