2026-05-01 11:31:48 +08:00
|
|
|
|
<template>
|
2026-05-01 22:30:46 +08:00
|
|
|
|
<MainLayout>
|
|
|
|
|
|
<div class="page-header">
|
|
|
|
|
|
<div class="page-header-left">
|
|
|
|
|
|
<h3>{{ chatMode === 'single' ? (agent ? agent.name : 'AI Agent 对话') : '多 Agent 编排' }}</h3>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
2026-05-01 22:30:46 +08:00
|
|
|
|
<div class="page-header-actions">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<el-switch
|
|
|
|
|
|
v-model="chatMode"
|
|
|
|
|
|
active-value="orchestrate"
|
|
|
|
|
|
inactive-value="single"
|
|
|
|
|
|
active-text="编排"
|
|
|
|
|
|
inactive-text="单 Agent"
|
|
|
|
|
|
style="margin-right: 12px"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- 单 Agent 模式 -->
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<template v-if="chatMode === 'single'">
|
|
|
|
|
|
<el-select v-model="currentAgentId" placeholder="选择 Agent" @change="switchAgent" style="width: 180px" clearable>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-option v-for="a in agents" :key="a.id" :label="a.name" :value="a.id" />
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</el-select>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- Session selector with rename -->
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<el-select
|
|
|
|
|
|
v-model="currentSessionId"
|
|
|
|
|
|
placeholder="对话记录"
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
style="width: 220px"
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
:disabled="!currentAgentId"
|
|
|
|
|
|
@change="switchSession"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-option label="+ 新对话" value="__new__">
|
|
|
|
|
|
<span style="color: var(--el-color-primary); font-weight: 500">+ 新对话</span>
|
|
|
|
|
|
</el-option>
|
|
|
|
|
|
<el-option
|
2026-07-26 20:57:11 +08:00
|
|
|
|
v-for="s in sortedSessions"
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
:key="s.session_id"
|
|
|
|
|
|
:label="s.title || '未命名对话'"
|
|
|
|
|
|
:value="s.session_id"
|
|
|
|
|
|
>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<div class="session-option-row">
|
|
|
|
|
|
<div style="display:flex;flex-direction:column;flex:1;min-width:0">
|
|
|
|
|
|
<span class="session-option-title">
|
|
|
|
|
|
<el-icon v-if="s.is_pinned" :size="12" style="color:var(--el-color-warning);vertical-align:-1px"><Top /></el-icon>
|
|
|
|
|
|
{{ s.title || '未命名对话' }}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span class="session-option-meta">{{ s.message_count }} 条消息 · {{ relativeTimeText(s.updated_at) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="session-option-actions">
|
|
|
|
|
|
<el-icon
|
|
|
|
|
|
:size="14"
|
|
|
|
|
|
:style="{ color: s.is_pinned ? 'var(--el-color-warning)' : 'var(--el-text-color-placeholder)' }"
|
|
|
|
|
|
:title="s.is_pinned ? '取消置顶' : '置顶'"
|
|
|
|
|
|
@click.stop.prevent="togglePinSession(s)"
|
|
|
|
|
|
><Top /></el-icon>
|
|
|
|
|
|
<el-icon
|
|
|
|
|
|
:size="14"
|
|
|
|
|
|
style="color:var(--el-color-danger)"
|
|
|
|
|
|
title="删除会话"
|
|
|
|
|
|
@click.stop.prevent="deleteSession(s)"
|
|
|
|
|
|
><Delete /></el-icon>
|
|
|
|
|
|
</span>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</el-option>
|
|
|
|
|
|
</el-select>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Session rename button -->
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
v-if="currentSessionId && currentSessionId !== '__new__'"
|
|
|
|
|
|
text
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
@click="showRenameDialog = true"
|
|
|
|
|
|
title="重命名会话"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-icon :size="16"><Edit /></el-icon>
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Export button -->
|
|
|
|
|
|
<el-dropdown trigger="click" v-if="displayMessages.length > 0">
|
|
|
|
|
|
<el-button text size="small" title="导出对话">
|
|
|
|
|
|
<el-icon :size="16"><Download /></el-icon>
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<template #dropdown>
|
|
|
|
|
|
<el-dropdown-menu>
|
|
|
|
|
|
<el-dropdown-item @click="exportSession('markdown')">导出 Markdown</el-dropdown-item>
|
|
|
|
|
|
<el-dropdown-item @click="exportSession('json')">导出 JSON</el-dropdown-item>
|
|
|
|
|
|
</el-dropdown-menu>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-dropdown>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Branches button -->
|
|
|
|
|
|
<el-button text size="small" @click="showBranchesPanel = true" title="对话分支">
|
|
|
|
|
|
<el-icon :size="16"><Share /></el-icon>
|
|
|
|
|
|
</el-button>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- 编排模式 -->
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<template v-if="chatMode === 'orchestrate'">
|
2026-05-02 11:03:51 +08:00
|
|
|
|
<el-select v-model="orchestrateMode" style="width: 140px">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<el-option label="辩论模式" value="debate" />
|
|
|
|
|
|
<el-option label="路由模式" value="route" />
|
|
|
|
|
|
<el-option label="顺序模式" value="sequential" />
|
2026-05-02 11:03:51 +08:00
|
|
|
|
<el-option label="流水线模式" value="pipeline" />
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</el-select>
|
|
|
|
|
|
<el-button @click="showOrchestrateEditor = true" style="margin-left: 8px">
|
|
|
|
|
|
配置 Agent ({{ orchestrateAgents.length }})
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- 搜索 -->
|
|
|
|
|
|
<el-popover placement="bottom" :width="400" trigger="click" @show="searchInputRef?.focus()">
|
|
|
|
|
|
<template #reference>
|
|
|
|
|
|
<el-button text size="small" title="搜索消息 (Ctrl+F)">
|
|
|
|
|
|
<el-icon :size="16"><Search /></el-icon>
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<div class="search-panel">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
ref="searchInputRef"
|
|
|
|
|
|
v-model="searchKeyword"
|
|
|
|
|
|
placeholder="搜索消息内容..."
|
|
|
|
|
|
clearable
|
|
|
|
|
|
@input="handleSearchMessages"
|
|
|
|
|
|
@keyup.enter="handleSearchMessages"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #prefix><el-icon><Search /></el-icon></template>
|
|
|
|
|
|
</el-input>
|
|
|
|
|
|
<div class="search-results" v-if="searchResults.length > 0">
|
|
|
|
|
|
<div class="search-count">找到 {{ searchTotal }} 条匹配</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-for="r in searchResults"
|
|
|
|
|
|
:key="r.id"
|
|
|
|
|
|
class="search-result-item"
|
|
|
|
|
|
@click="jumpToSearchResult(r)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="search-result-header">
|
|
|
|
|
|
<el-tag size="small" :type="r.role === 'user' ? 'info' : 'success'">{{ r.role === 'user' ? '用户' : 'AI' }}</el-tag>
|
|
|
|
|
|
<span class="search-result-session">{{ r.session_title || r.session_id?.slice(0, 8) }}</span>
|
|
|
|
|
|
<span class="search-result-time">{{ relativeTimeText(r.created_at) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="search-result-content" v-html="highlightSearchMatch(r.content)"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-pagination
|
|
|
|
|
|
v-if="searchTotal > 10"
|
|
|
|
|
|
v-model:current-page="searchPage"
|
|
|
|
|
|
:page-size="10"
|
|
|
|
|
|
:total="searchTotal"
|
|
|
|
|
|
layout="prev, next"
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
@current-change="handleSearchMessages"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-empty v-else-if="searchKeyword && searchKeyword.length >= 1 && searchDone" description="无匹配消息" :image-size="40" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-popover>
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
<el-button @click="clearChat" :disabled="displayMessages.length === 0">清空</el-button>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="chat-messages" ref="messagesRef">
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- Empty state -->
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<div v-if="displayMessages.length === 0 && !loading" class="chat-empty">
|
|
|
|
|
|
<template v-if="chatMode === 'single' && agent">
|
|
|
|
|
|
<el-avatar :size="56" icon="Promotion" style="background:var(--el-color-primary-light-5);margin-bottom:8px" />
|
|
|
|
|
|
<h3 class="welcome-title">{{ agent.name }}</h3>
|
|
|
|
|
|
<p v-if="agent.description" class="welcome-desc">{{ agent.description }}</p>
|
|
|
|
|
|
<div class="welcome-tags">
|
|
|
|
|
|
<el-tag size="small" type="info" v-if="agent.version">v{{ agent.version }}</el-tag>
|
|
|
|
|
|
<el-tag size="small" :type="agent.status === 'published' ? 'success' : 'warning'">{{ agent.status === 'published' ? '已发布' : agent.status }}</el-tag>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p class="hint">可以问我任何问题,或者试试下面的示例:</p>
|
2026-07-26 20:26:15 +08:00
|
|
|
|
<div class="preset-questions" v-loading="presetLoading" element-loading-text="正在生成示例问题...">
|
|
|
|
|
|
<div class="preset-q" v-for="(q, qi) in presetQuestions" :key="qi" @click="sendPresetQuestion(q)">{{ q }}</div>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else-if="chatMode === 'single'">
|
|
|
|
|
|
<el-icon :size="48"><ChatLineSquare /></el-icon>
|
|
|
|
|
|
<p>选择一个智能体开始对话</p>
|
|
|
|
|
|
<p class="hint">从上方下拉框中选择已创建的 Agent</p>
|
|
|
|
|
|
<div class="agent-quick-list" v-if="agents.length > 0">
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-button v-for="a in agents.slice(0, 6)" :key="a.id" size="small" @click="currentAgentId = a.id; switchAgent()" style="margin:4px">{{ a.name }}</el-button>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<el-icon :size="48"><ChatLineSquare /></el-icon>
|
|
|
|
|
|
<p>配置多个 Agent 后发送消息进行编排对话</p>
|
|
|
|
|
|
<p class="hint">支持辩论、路由、顺序、流水线四种编排模式</p>
|
|
|
|
|
|
</template>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<template v-for="item in displayItems" :key="item.key">
|
|
|
|
|
|
<div v-if="item._divider" class="date-divider"><span class="date-divider-text">{{ item.label }}</span></div>
|
|
|
|
|
|
<ChatMessageBubble
|
|
|
|
|
|
v-else
|
|
|
|
|
|
:role="item.msg.role"
|
|
|
|
|
|
:content-html="renderMarkdown(item.msg.orchestrateResult?.final_answer || item.msg.content)"
|
|
|
|
|
|
:timestamp="item.msg.timestamp"
|
|
|
|
|
|
:status="item.msg.status"
|
|
|
|
|
|
:iterations="item.msg.iterations"
|
|
|
|
|
|
:tool-calls-made="item.msg.tool_calls_made"
|
|
|
|
|
|
:token-usage="item.msg.token_usage"
|
2026-07-26 23:48:29 +08:00
|
|
|
|
:attachments="item.msg.attachments"
|
2026-07-26 20:57:11 +08:00
|
|
|
|
>
|
|
|
|
|
|
<template v-if="item.msg.orchestrateResult" #extra>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<div class="orchestrate-result">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div class="orch-header">
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<el-tag size="small" type="info">{{ item.msg.orchestrateResult.mode }}</el-tag>
|
|
|
|
|
|
<span class="orch-agent-count">{{ item.msg.orchestrateResult.steps.length }} 个 Agent</span>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="orch-steps">
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<div v-for="(step, si) in item.msg.orchestrateResult.steps" :key="si" class="orch-step" :class="{ expanded: step._open }">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div class="orch-step-header" @click="step._open = !step._open">
|
|
|
|
|
|
<el-icon><CaretRight :style="{ transform: step._open ? 'rotate(90deg)' : '' }" /></el-icon>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-tag size="small" :type="step.error ? 'danger' : 'success'" round>{{ step.agent_name }}</el-tag>
|
|
|
|
|
|
<span class="orch-step-meta">{{ step.iterations_used }} 步 · {{ step.tool_calls_made }} 次工具</span>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div v-show="step._open" class="orch-step-body">
|
|
|
|
|
|
<div class="message-text" v-html="renderMarkdown(step.output)"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</template>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<template v-if="!item.msg.orchestrateResult" #extra>
|
|
|
|
|
|
<div v-if="item.msg.tool_calls && item.msg.tool_calls.length > 0" class="tool-calls">
|
|
|
|
|
|
<div class="tool-calls-header"><el-icon><Tools /></el-icon> 工具调用 ({{ item.msg.tool_calls.length }})</div>
|
|
|
|
|
|
<div v-for="(tc, j) in item.msg.tool_calls" :key="j" class="tool-call-item">
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<span class="tool-name">{{ tc.function?.name || '?' }}</span>
|
|
|
|
|
|
<el-tag size="small" type="info">{{ safeParseArgCount(tc.function?.arguments) }} 个参数</el-tag>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<div v-if="item.msg.steps && item.msg.steps.length > 0" class="thinking-trace">
|
|
|
|
|
|
<div class="trace-header" @click="toggleTrace(item.msg)">
|
|
|
|
|
|
<el-icon><CaretRight :style="{ transform: item.msg._traceOpen ? 'rotate(90deg)' : '' }" /></el-icon>
|
|
|
|
|
|
<span>思考链 ({{ item.msg.steps.length }} 步)</span>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<div v-show="item.msg._traceOpen" class="trace-steps">
|
|
|
|
|
|
<div v-for="(step, si) in item.msg.steps" :key="si" class="trace-step" :class="'step-' + step.type">
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<div class="step-icon">
|
|
|
|
|
|
<el-icon v-if="step.type === 'think'"><ChatDotSquare /></el-icon>
|
|
|
|
|
|
<el-icon v-else-if="step.type === 'tool_result'"><Tools /></el-icon>
|
|
|
|
|
|
<el-icon v-else><Select /></el-icon>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="step-body">
|
|
|
|
|
|
<div class="step-header">
|
|
|
|
|
|
<span class="step-tag" :class="'tag-' + step.type">{{ {think:'思考',tool_result:'工具结果',final:'最终回答'}[step.type] || step.type }}</span>
|
|
|
|
|
|
<span class="step-iter">#{{ step.iteration }}</span>
|
|
|
|
|
|
<span v-if="step.tool_name" class="step-tool-name">{{ step.tool_name }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="step.content" class="step-content" v-html="renderMarkdown(step.content)"></div>
|
|
|
|
|
|
<div v-if="step.reasoning" class="step-reasoning">
|
|
|
|
|
|
<div class="reasoning-header">推理过程</div>
|
|
|
|
|
|
<div class="reasoning-text">{{ step.reasoning }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="step.tool_input && Object.keys(step.tool_input).length" class="step-tool-input">
|
|
|
|
|
|
<div class="reasoning-header">参数</div>
|
|
|
|
|
|
<pre>{{ JSON.stringify(step.tool_input, null, 2) }}</pre>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<div v-if="step.tool_result" class="step-tool-result">
|
|
|
|
|
|
<div class="reasoning-header">结果</div>
|
|
|
|
|
|
<pre>{{ step.tool_result }}</pre>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template #actions>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<el-button v-if="item.msg.role === 'assistant' && item.msg.content" link size="small" @click="isSpeaking ? stopSpeak() : speakMessage(item.msg.orchestrateResult?.final_answer || item.msg.content)" :title="isSpeaking ? '停止朗读' : '朗读'">
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<el-icon><Headset v-if="!isSpeaking" /><VideoPause v-else /></el-icon>
|
|
|
|
|
|
</el-button>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
<el-button v-if="item.msg.role === 'user'" link size="small" @click="editMessage(item.idx)" title="编辑"><el-icon><Edit /></el-icon></el-button>
|
|
|
|
|
|
<el-button v-if="item.msg.role === 'assistant'" link size="small" @click="copyMessage(item.msg)" title="复制"><el-icon><DocumentCopy /></el-icon></el-button>
|
|
|
|
|
|
<el-button link size="small" @click="createBranch(item.idx)" title="从此分支"><el-icon><Share /></el-icon></el-button>
|
|
|
|
|
|
<el-button v-if="item.msg.role === 'assistant' && !loading" link :type="item.msg.status === 'error' ? 'danger' : undefined" size="small" @click="retryMessage(item.idx)" :title="item.msg.status === 'error' ? '重试' : '重新生成'"><el-icon><Refresh /></el-icon></el-button>
|
|
|
|
|
|
<el-button link size="small" @click="deleteMessage(item.idx)" title="删除"><el-icon style="color:var(--el-color-danger)"><Delete /></el-icon></el-button>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</template>
|
2026-07-26 20:57:11 +08:00
|
|
|
|
</ChatMessageBubble>
|
|
|
|
|
|
</template>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
<div v-if="loading && !streamingActive" class="message assistant">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div class="message-avatar"><el-avatar :size="36" icon="Promotion" /></div>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
<div class="message-bubble">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div class="thinking"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<ChatInputArea
|
|
|
|
|
|
ref="inputAreaRef"
|
|
|
|
|
|
v-model="inputMessage"
|
|
|
|
|
|
:loading="loading"
|
|
|
|
|
|
:disabled="loading || (chatMode === 'single' && !currentAgentId)"
|
|
|
|
|
|
:attachments="pendingAttachments"
|
|
|
|
|
|
:drag-over="inputDragOver"
|
|
|
|
|
|
:show-stop="loading"
|
|
|
|
|
|
:is-listening="isListening"
|
|
|
|
|
|
:voice-supported="voiceSupported"
|
|
|
|
|
|
placeholder="输入你的问题... Enter 发送,Shift+Enter 换行 支持拖拽或粘贴图片/文件"
|
|
|
|
|
|
@send="sendMessage"
|
|
|
|
|
|
@stop="stopGeneration"
|
|
|
|
|
|
@attach-file="handleAttachFile"
|
|
|
|
|
|
@start-voice="startListening"
|
|
|
|
|
|
@stop-voice="stopListening"
|
|
|
|
|
|
@files-selected="onFilesSelected"
|
|
|
|
|
|
@remove-attachment="removeAttachment"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #extraActions>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-popover v-if="chatMode === 'single'" placement="top" :width="280" trigger="click">
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
<template #reference>
|
|
|
|
|
|
<el-button text size="small" title="对话设置"><el-icon :size="18"><Setting /></el-icon></el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<div class="chat-settings-popover">
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<div style="margin-bottom:8px;font-size:13px;font-weight:500">模型配置</div>
|
|
|
|
|
|
<el-select v-model="chatModelConfigId" size="small" style="width:100%" clearable placeholder="默认模型">
|
|
|
|
|
|
<el-option-group
|
|
|
|
|
|
v-for="group in modelConfigGroups"
|
|
|
|
|
|
:key="group.label"
|
|
|
|
|
|
:label="group.label"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="mc in group.configs"
|
|
|
|
|
|
:key="mc.id"
|
|
|
|
|
|
:label="mc.name || `${group.label} ${mc.model_name}`"
|
|
|
|
|
|
:value="mc.id"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>{{ mc.name || mc.model_name }}</span>
|
|
|
|
|
|
<span style="float:right;color:#909399;font-size:11px">{{ mc.model_name }}</span>
|
|
|
|
|
|
</el-option>
|
|
|
|
|
|
</el-option-group>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</el-select>
|
|
|
|
|
|
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">Temperature: {{ chatTemperature.toFixed(1) }}</div>
|
|
|
|
|
|
<el-slider v-model="chatTemperature" :min="0" :max="2" :step="0.1" size="small" show-stops />
|
|
|
|
|
|
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">最大迭代</div>
|
|
|
|
|
|
<el-input-number v-model="chatMaxIterations" :min="1" :max="50" size="small" style="width:100%" />
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">最大 Token 数</div>
|
|
|
|
|
|
<el-select v-model="chatMaxTokens" size="small" style="width:100%" clearable placeholder="默认">
|
|
|
|
|
|
<el-option v-for="t in tokenOptions" :key="t.value" :label="t.label" :value="t.value" />
|
|
|
|
|
|
</el-select>
|
2026-07-04 17:06:51 +08:00
|
|
|
|
<div style="margin:10px 0 4px;font-size:13px;font-weight:500">朗读语音</div>
|
|
|
|
|
|
<el-select v-model="chatVoice" size="small" style="width:100%">
|
|
|
|
|
|
<el-option-group label="── 教师女声 ──">
|
|
|
|
|
|
<el-option label="晓晓老师 · 温柔教导" value="teacher1" />
|
|
|
|
|
|
<el-option label="晓怡老师 · 活泼教学" value="teacher2" />
|
|
|
|
|
|
</el-option-group>
|
|
|
|
|
|
<el-option-group label="── 女声 ──">
|
|
|
|
|
|
<el-option label="晓晓 · 温柔" value="xiaoxiao" />
|
|
|
|
|
|
<el-option label="晓怡 · 活泼" value="xiaoyi" />
|
|
|
|
|
|
<el-option label="晓辰 · 温和" value="xiaochen" />
|
|
|
|
|
|
<el-option label="晓涵 · 知性" value="xiaohan" />
|
|
|
|
|
|
</el-option-group>
|
|
|
|
|
|
<el-option-group label="── 男声 ──">
|
|
|
|
|
|
<el-option label="云希 · 阳光" value="yunxi" />
|
|
|
|
|
|
<el-option label="云扬 · 专业" value="yunyang" />
|
|
|
|
|
|
<el-option label="云健 · 激情" value="yunjian" />
|
|
|
|
|
|
<el-option label="云夏 · 可爱" value="yunxia" />
|
|
|
|
|
|
</el-option-group>
|
|
|
|
|
|
</el-select>
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</el-popover>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</ChatInputArea>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 编排 Agent 编辑器 -->
|
2026-05-01 22:30:46 +08:00
|
|
|
|
<el-dialog v-model="showOrchestrateEditor" title="编排 Agent 配置" width="700px" @closed="saveState">
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div class="orch-editor">
|
2026-05-02 11:03:51 +08:00
|
|
|
|
<div v-if="orchestrateMode === 'pipeline'" class="orch-mode-hint">
|
|
|
|
|
|
<el-alert type="info" :closable="false" show-icon>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<template #title>流水线模式:仅使用第一个 Agent 作为执行器,系统自动创建 Planner(规划)和 Reviewer(审查)角色</template>
|
2026-05-02 11:03:51 +08:00
|
|
|
|
</el-alert>
|
|
|
|
|
|
</div>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
<div v-for="(agt, i) in orchestrateAgents" :key="i" class="orch-agent-card">
|
|
|
|
|
|
<div class="orch-agent-header">
|
|
|
|
|
|
<span class="orch-agent-num">#{{ i + 1 }}</span>
|
|
|
|
|
|
<el-input v-model="agt.name" placeholder="名称" style="width: 140px" size="small" />
|
|
|
|
|
|
<el-input v-model="agt.id" placeholder="ID" style="width: 120px" size="small" />
|
|
|
|
|
|
<el-button size="small" type="danger" link @click="orchestrateAgents.splice(i, 1)">删除</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-input v-model="agt.system_prompt" type="textarea" :rows="3" placeholder="System Prompt" size="small" />
|
|
|
|
|
|
<div class="orch-agent-params">
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-select v-model="agt.model_config_id" size="small" style="width: 180px" clearable placeholder="模型(可选)">
|
|
|
|
|
|
<el-option-group
|
|
|
|
|
|
v-for="group in modelConfigGroups"
|
|
|
|
|
|
:key="group.label"
|
|
|
|
|
|
:label="group.label"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="mc in group.configs"
|
|
|
|
|
|
:key="mc.id"
|
|
|
|
|
|
:label="mc.name || mc.model_name"
|
|
|
|
|
|
:value="mc.id"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-option-group>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</el-select>
|
|
|
|
|
|
<el-input-number v-model="agt.temperature" :min="0" :max="2" :step="0.1" size="small" style="width: 110px" />
|
|
|
|
|
|
<el-input-number v-model="agt.max_iterations" :min="1" :max="50" size="small" style="width: 110px" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<el-button @click="addOrchestrateAgent" style="width: 100%; margin-top: 8px">+ 添加 Agent</el-button>
|
2026-05-01 19:32:59 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<el-button @click="showOrchestrateEditor = false">关闭</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-dialog>
|
2026-05-04 23:17:59 +08:00
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
<!-- 会话重命名对话框 -->
|
|
|
|
|
|
<el-dialog v-model="showRenameDialog" title="重命名会话" width="420px">
|
|
|
|
|
|
<el-input v-model="renameTitle" placeholder="输入新标题" @keyup.enter="handleRenameSession" />
|
|
|
|
|
|
<el-button link type="primary" size="small" style="margin-top:8px" @click="autoGenerateTitle" :loading="autoTitleLoading">
|
|
|
|
|
|
<el-icon><MagicStick /></el-icon> AI 自动生成标题
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<el-button @click="showRenameDialog = false">取消</el-button>
|
|
|
|
|
|
<el-button type="primary" @click="handleRenameSession">确定</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 对话分支面板 -->
|
|
|
|
|
|
<el-drawer v-model="showBranchesPanel" title="对话分支" size="380px" direction="rtl">
|
|
|
|
|
|
<div class="branches-panel">
|
|
|
|
|
|
<div class="branches-actions">
|
|
|
|
|
|
<el-button size="small" type="primary" @click="createBranch(-1)" :disabled="displayMessages.length === 0">
|
|
|
|
|
|
从当前位置创建分支
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="branches.length > 0" class="branches-list">
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-for="b in branches"
|
|
|
|
|
|
:key="b.id"
|
|
|
|
|
|
class="branch-item"
|
|
|
|
|
|
:class="{ active: currentBranchId === b.id }"
|
|
|
|
|
|
@click="switchToBranch(b)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="branch-title">{{ b.title || '未命名分支' }}</div>
|
|
|
|
|
|
<div class="branch-meta">
|
|
|
|
|
|
<span>{{ b.agent_name || 'Agent' }}</span>
|
|
|
|
|
|
<span>{{ b.message_count }} 条消息</span>
|
|
|
|
|
|
<span>{{ relativeTimeText(b.created_at) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="branch-actions">
|
|
|
|
|
|
<el-button link size="small" type="danger" @click.stop="deleteBranch(b.id)">删除</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<el-empty v-else description="暂无分支" :image-size="48" />
|
|
|
|
|
|
<el-button style="width:100%;margin-top:12px" @click="loadBranches()">刷新</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-drawer>
|
|
|
|
|
|
|
2026-05-04 23:17:59 +08:00
|
|
|
|
<!-- 工具审批对话框 -->
|
|
|
|
|
|
<el-dialog v-model="showApprovalDialog" title="工具执行审批" width="480px" :close-on-click-modal="false">
|
|
|
|
|
|
<div style="margin-bottom: 12px">
|
|
|
|
|
|
<el-tag type="warning" size="large">{{ approvalToolName }}</el-tag>
|
|
|
|
|
|
<span style="margin-left: 8px; color: #666">需要人工审批才能执行</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="Object.keys(approvalArgs).length > 0" style="background: #f5f7fa; padding: 12px; border-radius: 6px; max-height: 200px; overflow-y: auto">
|
|
|
|
|
|
<pre style="margin: 0; font-size: 13px; white-space: pre-wrap; word-break: break-all">{{ JSON.stringify(approvalArgs, null, 2) }}</pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<el-button @click="resolveApproval('denied')">拒绝</el-button>
|
|
|
|
|
|
<el-button @click="resolveApproval('skip')">跳过</el-button>
|
|
|
|
|
|
<el-button type="primary" @click="resolveApproval('approved')">批准执行</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-dialog>
|
2026-05-01 22:30:46 +08:00
|
|
|
|
</MainLayout>
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
|
2026-05-01 11:31:48 +08:00
|
|
|
|
import { useRoute } from 'vue-router'
|
2026-07-26 20:26:15 +08:00
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
2026-07-26 20:57:11 +08:00
|
|
|
|
import { ChatLineSquare, UserFilled, Promotion, Tools, CaretRight, ChatDotSquare, Select, DocumentCopy, Refresh, VideoPause, Edit, Delete, Headset, Setting, Search, Download, Share, MagicStick, Top } from '@element-plus/icons-vue'
|
2026-05-01 22:30:46 +08:00
|
|
|
|
import MainLayout from '@/components/MainLayout.vue'
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
import ChatMessageBubble from '@/components/ChatMessageBubble.vue'
|
|
|
|
|
|
import ChatInputArea from '@/components/ChatInputArea.vue'
|
2026-05-01 11:31:48 +08:00
|
|
|
|
import api from '@/api'
|
|
|
|
|
|
import type { Agent } from '@/stores/agent'
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
import { useModelConfigStore } from '@/stores/modelConfig'
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
import { useMarkdown } from '@/composables/useMarkdown'
|
|
|
|
|
|
import { useFileUpload } from '@/composables/useFileUpload'
|
2026-07-26 23:48:29 +08:00
|
|
|
|
import type { MessageAttachment } from '@/composables/useFileUpload'
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
import { useTTS } from '@/composables/useTTS'
|
|
|
|
|
|
import { useSpeechRecognition } from '@/composables/useSpeechRecognition'
|
|
|
|
|
|
|
2026-07-04 17:06:51 +08:00
|
|
|
|
const { renderMarkdown, stripMarkdownForTTS } = useMarkdown()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const { pendingAttachments, inputDragOver, uploadFiles, removeAttachment, clearAttachments, buildAttachmentContext, onFilesSelected, handleAttachFile } = useFileUpload()
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
const { isSpeaking, speak: ttsSpeak, stop: ttsStop } = useTTS()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const { isListening, transcript, error: voiceError, supported: voiceSupported, start: voiceStart, stop: voiceStop } = useSpeechRecognition()
|
|
|
|
|
|
const modelConfigStore = useModelConfigStore()
|
2026-05-01 11:31:48 +08:00
|
|
|
|
|
2026-05-01 19:32:59 +08:00
|
|
|
|
interface AgentStep {
|
|
|
|
|
|
iteration: number; type: string; content: string
|
|
|
|
|
|
tool_name?: string; tool_input?: Record<string, any>; tool_result?: string; reasoning?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
interface OrchestrateStep {
|
|
|
|
|
|
agent_id: string; agent_name: string; input: string; output: string
|
|
|
|
|
|
iterations_used: number; tool_calls_made: number; error?: string; _open?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
interface OrchestrateResult {
|
|
|
|
|
|
mode: string; final_answer: string; steps: OrchestrateStep[]; agent_results: any[]
|
|
|
|
|
|
}
|
2026-05-01 11:31:48 +08:00
|
|
|
|
interface ChatMessage {
|
2026-05-01 19:32:59 +08:00
|
|
|
|
role: 'user' | 'assistant'; content: string; tool_calls?: any[]; timestamp: number
|
|
|
|
|
|
iterations?: number; tool_calls_made?: number; status?: string; steps?: AgentStep[]
|
2026-07-26 23:48:29 +08:00
|
|
|
|
token_usage?: any; attachments?: MessageAttachment[]
|
2026-05-01 19:32:59 +08:00
|
|
|
|
_traceOpen?: boolean; orchestrateResult?: OrchestrateResult
|
|
|
|
|
|
}
|
|
|
|
|
|
interface OrchestrateAgentForm {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
id: string; name: string; system_prompt: string; model: string; model_config_id: string
|
2026-05-01 19:32:59 +08:00
|
|
|
|
temperature: number; max_iterations: number; description: string
|
2026-05-01 11:31:48 +08:00
|
|
|
|
}
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
interface BranchInfo {
|
|
|
|
|
|
id: string; title: string; agent_name?: string; parent_session_id: string
|
|
|
|
|
|
branch_session_id: string; message_count: number; first_user_message?: string; created_at: string
|
|
|
|
|
|
}
|
2026-05-01 11:31:48 +08:00
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const STORAGE_KEY = 'agent_chat_state'
|
|
|
|
|
|
interface ChatState {
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
messages: Record<string, ChatMessage[]>
|
2026-05-01 22:30:46 +08:00
|
|
|
|
sessionId: Record<string, string>
|
|
|
|
|
|
currentAgentId: string
|
|
|
|
|
|
chatMode: 'single' | 'orchestrate'
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
chatModelConfigId: string
|
|
|
|
|
|
chatTemperature: number
|
|
|
|
|
|
chatMaxIterations: number
|
|
|
|
|
|
chatMaxTokens: number | null
|
|
|
|
|
|
chatVoice: string
|
2026-05-01 22:30:46 +08:00
|
|
|
|
orchestrateMode: string
|
|
|
|
|
|
orchestrateAgents: OrchestrateAgentForm[]
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_savedAt?: number
|
2026-05-04 23:17:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
function saveState() {
|
|
|
|
|
|
try {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const state: any = {
|
2026-05-01 22:30:46 +08:00
|
|
|
|
messages: messages.value,
|
|
|
|
|
|
sessionId: sessionId.value,
|
|
|
|
|
|
currentAgentId: currentAgentId.value,
|
|
|
|
|
|
chatMode: chatMode.value,
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
chatModelConfigId: chatModelConfigId.value,
|
|
|
|
|
|
chatTemperature: chatTemperature.value,
|
|
|
|
|
|
chatMaxIterations: chatMaxIterations.value,
|
|
|
|
|
|
chatMaxTokens: chatMaxTokens.value,
|
|
|
|
|
|
chatVoice: chatVoice.value,
|
2026-05-01 22:30:46 +08:00
|
|
|
|
orchestrateMode: orchestrateMode.value,
|
|
|
|
|
|
orchestrateAgents: orchestrateAgents.value,
|
2026-05-10 19:50:20 +08:00
|
|
|
|
_savedAt: Date.now(),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
}
|
2026-05-01 22:30:46 +08:00
|
|
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
} catch { /* ignore */ }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function loadState(): ChatState | null {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const raw = localStorage.getItem(STORAGE_KEY)
|
|
|
|
|
|
if (!raw) return null
|
|
|
|
|
|
const parsed = JSON.parse(raw)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (parsed._savedAt && Date.now() - parsed._savedAt > 24 * 3600 * 1000) { localStorage.removeItem(STORAGE_KEY); return null }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
if (Array.isArray(parsed.messages)) {
|
|
|
|
|
|
parsed.messages = { '__bare__': parsed.messages }
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
parsed.sessionId = { '__bare__': parsed.sessionId || '' }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
return parsed
|
|
|
|
|
|
} catch { return null }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 11:31:48 +08:00
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
const agents = ref<Agent[]>([])
|
|
|
|
|
|
const currentAgentId = ref('')
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const messages = ref<Record<string, ChatMessage[]>>({})
|
2026-05-01 11:31:48 +08:00
|
|
|
|
const inputMessage = ref('')
|
|
|
|
|
|
const loading = ref(false)
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const streamingActive = ref(false)
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
const abortController = ref<AbortController | null>(null)
|
|
|
|
|
|
const inputAreaRef = ref<InstanceType<typeof ChatInputArea> | null>(null)
|
2026-05-04 23:17:59 +08:00
|
|
|
|
const showApprovalDialog = ref(false)
|
|
|
|
|
|
const approvalId = ref('')
|
|
|
|
|
|
const approvalToolName = ref('')
|
|
|
|
|
|
const approvalArgs = ref<Record<string, any>>({})
|
2026-05-01 11:31:48 +08:00
|
|
|
|
const messagesRef = ref<HTMLElement | null>(null)
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
const isNearBottom = ref(true)
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const sessionId = ref<Record<string, string>>({})
|
2026-05-01 11:31:48 +08:00
|
|
|
|
const agent = ref<Agent | null>(null)
|
|
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
interface SessionInfo {
|
|
|
|
|
|
session_id: string; title?: string; last_message?: string
|
|
|
|
|
|
message_count: number; is_pinned: boolean
|
|
|
|
|
|
created_at?: string; updated_at?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
const sessions = ref<SessionInfo[]>([])
|
|
|
|
|
|
const currentSessionId = ref('')
|
|
|
|
|
|
const sessionsLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
// 对话设置
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const chatModelConfigId = ref('')
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
const chatTemperature = ref(0.8)
|
|
|
|
|
|
const chatMaxIterations = ref(15)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const chatMaxTokens = ref<number | null>(null)
|
|
|
|
|
|
const tokenOptions = [
|
|
|
|
|
|
{ label: '512', value: 512 },
|
|
|
|
|
|
{ label: '1024', value: 1024 },
|
|
|
|
|
|
{ label: '2048', value: 2048 },
|
|
|
|
|
|
{ label: '4096', value: 4096 },
|
|
|
|
|
|
{ label: '8192', value: 8192 },
|
|
|
|
|
|
{ label: '16384', value: 16384 },
|
|
|
|
|
|
]
|
|
|
|
|
|
const chatVoice = ref('xiaoxiao')
|
|
|
|
|
|
|
|
|
|
|
|
// 模型配置下拉分组
|
|
|
|
|
|
interface ModelConfigGroup { label: string; configs: { id: string; name: string; model_name: string }[] }
|
|
|
|
|
|
const modelConfigGroups = ref<ModelConfigGroup[]>([])
|
|
|
|
|
|
|
|
|
|
|
|
// 会话重命名
|
|
|
|
|
|
const showRenameDialog = ref(false)
|
|
|
|
|
|
const renameTitle = ref('')
|
|
|
|
|
|
const autoTitleLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
// 消息搜索
|
|
|
|
|
|
const searchKeyword = ref('')
|
|
|
|
|
|
const searchResults = ref<any[]>([])
|
|
|
|
|
|
const searchTotal = ref(0)
|
|
|
|
|
|
const searchPage = ref(1)
|
|
|
|
|
|
const searchDone = ref(false)
|
|
|
|
|
|
const searchInputRef = ref<any>(null)
|
|
|
|
|
|
|
|
|
|
|
|
// 对话分支
|
|
|
|
|
|
const showBranchesPanel = ref(false)
|
|
|
|
|
|
const branches = ref<BranchInfo[]>([])
|
|
|
|
|
|
const currentBranchId = ref('')
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const currentAgentKey = computed(() => {
|
|
|
|
|
|
if (chatMode.value === 'orchestrate') return '__orchestrate__'
|
|
|
|
|
|
return currentAgentId.value || '__bare__'
|
|
|
|
|
|
})
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const displayMessages = computed(() => messages.value[currentAgentKey.value] || [])
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
2026-07-26 20:57:11 +08:00
|
|
|
|
// 日期分割线:消息列表中跨天时插入分隔项
|
|
|
|
|
|
interface DisplayItem {
|
|
|
|
|
|
_divider?: boolean; label?: string; key: string
|
|
|
|
|
|
msg?: ChatMessage; idx?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
function _dayStart(ts: number): number { const d = new Date(ts); d.setHours(0, 0, 0, 0); return d.getTime() }
|
|
|
|
|
|
function dayLabelText(ts: number): string {
|
|
|
|
|
|
const days = Math.round((_dayStart(Date.now()) - _dayStart(ts)) / 86400000)
|
|
|
|
|
|
if (days <= 0) return '今天'
|
|
|
|
|
|
if (days === 1) return '昨天'
|
|
|
|
|
|
if (days < 7) return `${days} 天前`
|
|
|
|
|
|
return new Date(ts).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
|
|
|
|
|
|
}
|
|
|
|
|
|
const displayItems = computed<DisplayItem[]>(() => {
|
|
|
|
|
|
const items: DisplayItem[] = []
|
|
|
|
|
|
let lastDay = -1
|
|
|
|
|
|
displayMessages.value.forEach((msg, idx) => {
|
|
|
|
|
|
const day = _dayStart(msg.timestamp || Date.now())
|
|
|
|
|
|
if (day !== lastDay) {
|
|
|
|
|
|
lastDay = day
|
|
|
|
|
|
items.push({ _divider: true, label: dayLabelText(msg.timestamp || Date.now()), key: `divider-${day}` })
|
|
|
|
|
|
}
|
|
|
|
|
|
items.push({ key: `msg-${idx}-${msg.timestamp}`, msg, idx })
|
|
|
|
|
|
})
|
|
|
|
|
|
return items
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-05-01 19:32:59 +08:00
|
|
|
|
// 编排模式
|
|
|
|
|
|
const chatMode = ref<'single' | 'orchestrate'>('single')
|
|
|
|
|
|
const orchestrateMode = ref('debate')
|
|
|
|
|
|
const showOrchestrateEditor = ref(false)
|
|
|
|
|
|
const orchestrateAgents = ref<OrchestrateAgentForm[]>([
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
{ id: 'agent-a', name: 'Agent A', system_prompt: '你是一个有用的AI助手。', model: 'deepseek-v4-flash', model_config_id: '', temperature: 0.7, max_iterations: 10, description: '' },
|
|
|
|
|
|
{ id: 'agent-b', name: 'Agent B', system_prompt: '你是一个专业的分析助手。', model: 'deepseek-v4-flash', model_config_id: '', temperature: 0.7, max_iterations: 10, description: '' },
|
2026-05-01 19:32:59 +08:00
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
function addOrchestrateAgent() {
|
|
|
|
|
|
const n = orchestrateAgents.value.length + 1
|
|
|
|
|
|
orchestrateAgents.value.push({
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
id: `agent-${String.fromCharCode(96 + n)}`, name: `Agent ${String.fromCharCode(64 + n)}`,
|
|
|
|
|
|
system_prompt: '你是一个有用的AI助手。', model: 'deepseek-v4-flash', model_config_id: '',
|
|
|
|
|
|
temperature: 0.7, max_iterations: 10, description: '',
|
2026-05-01 19:32:59 +08:00
|
|
|
|
})
|
2026-05-01 22:30:46 +08:00
|
|
|
|
saveState()
|
2026-05-01 19:32:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
async function fetchModelConfigs() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const configs = await modelConfigStore.fetchModelConfigs({ limit: 100 })
|
|
|
|
|
|
const groups: Record<string, ModelConfigGroup> = {}
|
|
|
|
|
|
const displayMap: Record<string, string> = {
|
|
|
|
|
|
deepseek: 'DeepSeek', openai: 'OpenAI', anthropic: 'Anthropic',
|
|
|
|
|
|
qwen: '阿里通义千问', zhipu: '智谱 GLM', baidu: '百度文心一言',
|
|
|
|
|
|
moonshot: '月之暗面 Kimi', bytedance: '字节豆包', minimax: 'MiniMax',
|
|
|
|
|
|
openrouter: 'OpenRouter', siliconflow: '硅基流动', xunfei: '讯飞星火',
|
|
|
|
|
|
hunyuan: '腾讯混元', yi: '零一万物', baichuan: '百川',
|
|
|
|
|
|
cohere: 'Cohere', xai: 'xAI', together: 'Together', fireworks: 'Fireworks',
|
|
|
|
|
|
perplexity: 'Perplexity', deepinfra: 'DeepInfra', groq: 'Groq',
|
|
|
|
|
|
google: 'Google Gemini', mistral: 'Mistral AI', local: '本地/其他',
|
|
|
|
|
|
}
|
|
|
|
|
|
for (const c of (Array.isArray(configs) ? configs : [])) {
|
|
|
|
|
|
const label = displayMap[c.provider] || c.provider?.toUpperCase() || '未知'
|
|
|
|
|
|
if (!groups[label]) groups[label] = { label, configs: [] }
|
|
|
|
|
|
groups[label].configs.push({ id: c.id, name: c.name, model_name: c.model_name })
|
|
|
|
|
|
}
|
|
|
|
|
|
modelConfigGroups.value = Object.values(groups)
|
|
|
|
|
|
} catch { /* 静默失败 */ }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 分支管理 ──
|
|
|
|
|
|
async function loadBranches() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.get('/api/v1/agent-chat/branches', {
|
|
|
|
|
|
params: { agent_id: currentAgentId.value || undefined, limit: 50 },
|
|
|
|
|
|
})
|
|
|
|
|
|
branches.value = resp.data.branches || []
|
|
|
|
|
|
} catch { branches.value = [] }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function createBranch(msgIdx: number) {
|
|
|
|
|
|
const key = currentAgentKey.value
|
|
|
|
|
|
if (!sessionId.value[key]) { ElMessage.warning('请先发送消息创建会话'); return }
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.post('/api/v1/agent-chat/branches', {
|
|
|
|
|
|
session_id: sessionId.value[key],
|
|
|
|
|
|
agent_id: currentAgentId.value || undefined,
|
|
|
|
|
|
})
|
|
|
|
|
|
ElMessage.success('分支已创建')
|
|
|
|
|
|
currentBranchId.value = resp.data.id
|
|
|
|
|
|
await loadBranches()
|
|
|
|
|
|
showBranchesPanel.value = true
|
|
|
|
|
|
} catch (e: any) { ElMessage.error(e.response?.data?.detail || '创建分支失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function switchToBranch(b: BranchInfo) {
|
|
|
|
|
|
if (!b.branch_session_id) return
|
|
|
|
|
|
currentBranchId.value = b.id
|
|
|
|
|
|
const key = currentAgentKey.value
|
|
|
|
|
|
sessionId.value[key] = b.branch_session_id
|
|
|
|
|
|
currentSessionId.value = b.branch_session_id
|
|
|
|
|
|
// Load branch messages from parent session
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.get(`/api/v1/agent-chat/branches/${b.id}`)
|
|
|
|
|
|
if (resp.data.messages) {
|
|
|
|
|
|
messages.value[key] = resp.data.messages
|
|
|
|
|
|
.filter((m: any) => m.role === 'user' || m.role === 'assistant')
|
|
|
|
|
|
.map((m: any) => ({
|
|
|
|
|
|
role: m.role, content: m.content || '',
|
|
|
|
|
|
timestamp: m.created_at ? new Date(m.created_at).getTime() : Date.now(),
|
|
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch { /* ignore */ }
|
|
|
|
|
|
await loadSessions()
|
|
|
|
|
|
saveState()
|
|
|
|
|
|
showBranchesPanel.value = false
|
|
|
|
|
|
nextTick(scrollToBottom)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function deleteBranch(id: string) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await api.delete(`/api/v1/agent-chat/branches/${id}`)
|
|
|
|
|
|
if (currentBranchId.value === id) currentBranchId.value = ''
|
|
|
|
|
|
ElMessage.success('分支已删除')
|
|
|
|
|
|
await loadBranches()
|
|
|
|
|
|
} catch (e: any) { ElMessage.error(e.response?.data?.detail || '删除失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 会话重命名 ──
|
|
|
|
|
|
async function handleRenameSession() {
|
|
|
|
|
|
if (!currentAgentId.value || !currentSessionId.value || currentSessionId.value === '__new__') return
|
|
|
|
|
|
try {
|
|
|
|
|
|
await api.patch(`/api/v1/agent-chat/${currentAgentId.value}/sessions/${currentSessionId.value}`, { title: renameTitle.value })
|
|
|
|
|
|
ElMessage.success('标题已更新')
|
|
|
|
|
|
showRenameDialog.value = false
|
|
|
|
|
|
await loadSessions()
|
|
|
|
|
|
saveState()
|
|
|
|
|
|
} catch (e: any) { ElMessage.error(e.response?.data?.detail || '重命名失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function autoGenerateTitle() {
|
|
|
|
|
|
if (displayMessages.value.length === 0) { ElMessage.warning('没有消息可生成标题'); return }
|
|
|
|
|
|
autoTitleLoading.value = true
|
|
|
|
|
|
const recentMsgs = displayMessages.value.slice(0, 6).map(m => `${m.role === 'user' ? '用户' : 'AI'}: ${(m.content || '').slice(0, 200)}`).join('\n')
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.post('/api/v1/agent-chat/bare', {
|
|
|
|
|
|
message: `请给以下对话生成一个简短的标题(不超过20个字,只返回标题文本不要其他内容):\n${recentMsgs}`,
|
|
|
|
|
|
model: 'deepseek-v4-flash', max_iterations: 1, temperature: 0.3,
|
|
|
|
|
|
})
|
|
|
|
|
|
renameTitle.value = (resp.data.content || '').trim().slice(0, 50)
|
|
|
|
|
|
} catch { ElMessage.warning('自动生成失败') }
|
|
|
|
|
|
finally { autoTitleLoading.value = false }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 消息搜索 ──
|
|
|
|
|
|
async function handleSearchMessages() {
|
|
|
|
|
|
if (!searchKeyword.value || searchKeyword.value.length < 1) { searchResults.value = []; searchDone.value = false; return }
|
|
|
|
|
|
if (!currentAgentId.value) return
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.get(`/api/v1/agent-chat/${currentAgentId.value}/search-messages`, {
|
|
|
|
|
|
params: { q: searchKeyword.value, skip: (searchPage.value - 1) * 10, limit: 10 },
|
|
|
|
|
|
})
|
|
|
|
|
|
searchResults.value = resp.data.messages || []
|
|
|
|
|
|
searchTotal.value = resp.data.total || 0
|
|
|
|
|
|
searchDone.value = true
|
|
|
|
|
|
} catch { searchResults.value = []; searchDone.value = true }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function highlightSearchMatch(text: string) {
|
|
|
|
|
|
if (!text || !searchKeyword.value) return text || ''
|
|
|
|
|
|
const escaped = searchKeyword.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
|
|
|
|
return text.replace(new RegExp(`(${escaped})`, 'gi'), '<mark class="search-highlight">$1</mark>')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function jumpToSearchResult(r: any) {
|
|
|
|
|
|
if (r.session_id) {
|
|
|
|
|
|
sessionId.value[currentAgentKey.value] = r.session_id
|
|
|
|
|
|
currentSessionId.value = r.session_id
|
|
|
|
|
|
await switchSession(r.session_id)
|
|
|
|
|
|
}
|
|
|
|
|
|
// Close popover by removing focus
|
|
|
|
|
|
document.activeElement && (document.activeElement as HTMLElement).blur()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 导出 ──
|
|
|
|
|
|
async function exportSession(format: string) {
|
|
|
|
|
|
if (!currentAgentId.value || !currentSessionId.value) { ElMessage.warning('请先开始对话'); return }
|
|
|
|
|
|
try {
|
|
|
|
|
|
const token = localStorage.getItem('access_token') || localStorage.getItem('token') || ''
|
|
|
|
|
|
const resp = await fetch(`/api/v1/agent-chat/${currentAgentId.value}/sessions/${currentSessionId.value}/export?format=${format}`, {
|
|
|
|
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
|
|
|
|
})
|
|
|
|
|
|
if (!resp.ok) throw new Error('Export failed')
|
|
|
|
|
|
const ext = format === 'markdown' ? 'md' : 'json'
|
|
|
|
|
|
const mime = format === 'markdown' ? 'text/markdown' : 'application/json'
|
|
|
|
|
|
const blob = await resp.blob()
|
|
|
|
|
|
const url = URL.createObjectURL(blob)
|
|
|
|
|
|
const a = document.createElement('a')
|
|
|
|
|
|
a.href = url; a.download = `chat_export.${ext}`
|
|
|
|
|
|
a.click()
|
|
|
|
|
|
URL.revokeObjectURL(url)
|
|
|
|
|
|
ElMessage.success('导出成功')
|
|
|
|
|
|
} catch { ElMessage.error('导出失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function resolveApproval(decision: string) {
|
|
|
|
|
|
try { await api.post(`/api/v1/approval/${approvalId.value}/resolve`, { decision }) } catch { /* ignore */ }
|
|
|
|
|
|
showApprovalDialog.value = false; approvalId.value = ''; approvalToolName.value = ''; approvalArgs.value = {}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
watch(chatMode, saveState)
|
|
|
|
|
|
watch(orchestrateMode, saveState)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
watch(voiceError, (err) => { if (err) ElMessage.warning(err) })
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
function handleScroll() {
|
|
|
|
|
|
if (!messagesRef.value) return
|
|
|
|
|
|
const el = messagesRef.value
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
isNearBottom.value = (el.scrollHeight - el.scrollTop - el.clientHeight) < 60
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 11:31:48 +08:00
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
await loadAgents()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
await fetchModelConfigs()
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
|
|
|
|
|
const saved = loadState()
|
|
|
|
|
|
if (saved) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
messages.value = saved.messages; sessionId.value = saved.sessionId
|
|
|
|
|
|
chatMode.value = saved.chatMode; orchestrateMode.value = saved.orchestrateMode
|
2026-05-01 22:30:46 +08:00
|
|
|
|
orchestrateAgents.value = saved.orchestrateAgents
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (saved.chatModelConfigId) chatModelConfigId.value = saved.chatModelConfigId
|
|
|
|
|
|
if (saved.chatTemperature != null) chatTemperature.value = saved.chatTemperature
|
|
|
|
|
|
if (saved.chatMaxIterations != null) chatMaxIterations.value = saved.chatMaxIterations
|
|
|
|
|
|
if (saved.chatMaxTokens != null) chatMaxTokens.value = saved.chatMaxTokens
|
|
|
|
|
|
if (saved.chatVoice) chatVoice.value = saved.chatVoice === 'teacher1' ? 'xiaoxiao' : saved.chatVoice
|
|
|
|
|
|
for (const arr of Object.values(messages.value)) arr.forEach(m => { if (m.steps?.length) m._traceOpen = false })
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (route.params.id) { currentAgentId.value = route.params.id as string; await switchAgent() }
|
|
|
|
|
|
else if (saved?.currentAgentId) { currentAgentId.value = saved.currentAgentId; await switchAgent() }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
messagesRef.value?.addEventListener('scroll', handleScroll, { passive: true })
|
|
|
|
|
|
scrollToBottom()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
// Ctrl+F for search
|
|
|
|
|
|
const handleKeydown = (e: KeyboardEvent) => {
|
|
|
|
|
|
if ((e.ctrlKey || e.metaKey) && e.key === 'f' && document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {
|
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
|
searchInputRef.value?.focus()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
document.addEventListener('keydown', handleKeydown)
|
|
|
|
|
|
onUnmounted(() => document.removeEventListener('keydown', handleKeydown))
|
2026-05-01 11:31:48 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
onUnmounted(() => { messagesRef.value?.removeEventListener('scroll', handleScroll) })
|
|
|
|
|
|
|
2026-05-01 11:31:48 +08:00
|
|
|
|
async function loadAgents() {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
try { const resp = await api.get('/api/v1/agents'); agents.value = resp.data || [] } catch { /* ignore */ }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function switchAgent() {
|
2026-07-26 20:26:15 +08:00
|
|
|
|
if (!currentAgentId.value) { agent.value = null; currentSessionId.value = ''; sessions.value = []; presetQuestions.value = []; saveState(); nextTick(scrollToBottom); return }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.get(`/api/v1/agents/${currentAgentId.value}`)
|
|
|
|
|
|
agent.value = resp.data
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
await loadSessions()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
await loadBranches()
|
2026-07-26 20:26:15 +08:00
|
|
|
|
loadPresetQuestions()
|
2026-05-01 22:30:46 +08:00
|
|
|
|
saveState()
|
|
|
|
|
|
nextTick(scrollToBottom)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
} catch { ElMessage.error('加载 Agent 失败'); agent.value = null }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
async function loadSessions() {
|
|
|
|
|
|
if (!currentAgentId.value) return
|
|
|
|
|
|
sessionsLoading.value = true
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
try { const resp = await api.get(`/api/v1/agent-chat/${currentAgentId.value}/sessions?limit=50`); sessions.value = resp.data.sessions || [] } catch { /* ignore */ }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
finally { sessionsLoading.value = false }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function switchSession(sid: string) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (sid === '__new__') { newSession(); return }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
currentSessionId.value = sid
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; sessionId.value[key] = sid
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
sessionsLoading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await api.get(`/api/v1/agent-chat/${currentAgentId.value}/sessions/${sid}/messages?limit=200`)
|
|
|
|
|
|
const serverMessages = resp.data.messages || []
|
|
|
|
|
|
messages.value[key] = serverMessages.map((m: any) => ({
|
|
|
|
|
|
role: m.role === 'user' ? 'user' : 'assistant',
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
content: m.content || '', timestamp: m.created_at ? new Date(m.created_at).getTime() : Date.now(),
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
tool_calls: m.tool_name ? [{ function: { name: m.tool_name, arguments: m.tool_input } }] : [],
|
|
|
|
|
|
}))
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
hasMoreHistory.value = resp.data.has_more || false
|
|
|
|
|
|
} catch { ElMessage.warning('加载对话历史失败') }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
finally { sessionsLoading.value = false; saveState(); nextTick(scrollToBottom) }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function newSession() {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; messages.value[key] = []; sessionId.value[key] = ''
|
|
|
|
|
|
currentSessionId.value = ''; currentBranchId.value = '';
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
saveState()
|
|
|
|
|
|
nextTick(scrollToBottom)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-26 20:57:11 +08:00
|
|
|
|
// 置顶优先,其余按更新时间倒序
|
|
|
|
|
|
const sortedSessions = computed(() =>
|
|
|
|
|
|
[...sessions.value].sort((a, b) => {
|
|
|
|
|
|
if (!!a.is_pinned !== !!b.is_pinned) return a.is_pinned ? -1 : 1
|
|
|
|
|
|
return new Date(b.updated_at || 0).getTime() - new Date(a.updated_at || 0).getTime()
|
|
|
|
|
|
})
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
async function togglePinSession(s: SessionInfo) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await api.patch(`/api/v1/agent-chat/${currentAgentId.value}/sessions/${s.session_id}`, { is_pinned: !s.is_pinned })
|
|
|
|
|
|
s.is_pinned = !s.is_pinned
|
|
|
|
|
|
ElMessage.success(s.is_pinned ? '已置顶' : '已取消置顶')
|
|
|
|
|
|
} catch { ElMessage.error('操作失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function deleteSession(s: SessionInfo) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await ElMessageBox.confirm(
|
|
|
|
|
|
`确定删除会话「${s.title || '未命名对话'}」吗?该操作不可恢复。`,
|
|
|
|
|
|
'删除会话',
|
|
|
|
|
|
{ type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消' }
|
|
|
|
|
|
)
|
|
|
|
|
|
} catch { return }
|
|
|
|
|
|
try {
|
|
|
|
|
|
await api.delete(`/api/v1/agent-chat/${currentAgentId.value}/sessions/${s.session_id}`)
|
|
|
|
|
|
sessions.value = sessions.value.filter(x => x.session_id !== s.session_id)
|
|
|
|
|
|
if (currentSessionId.value === s.session_id) newSession()
|
|
|
|
|
|
ElMessage.success('会话已删除')
|
|
|
|
|
|
} catch { ElMessage.error('删除失败') }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-26 20:26:15 +08:00
|
|
|
|
// ── 预设问题:LLM 按 Agent 描述生成,localStorage 缓存(Agent 更新后自动失效)──
|
|
|
|
|
|
const presetQuestions = ref<string[]>([])
|
|
|
|
|
|
const presetLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
function fallbackPresetQuestions(): string[] {
|
|
|
|
|
|
const name = agent.value?.name || '这个 Agent'
|
|
|
|
|
|
return [
|
|
|
|
|
|
`作为${name},你能帮我解决什么问题?`,
|
|
|
|
|
|
'给我一个你能处理的具体例子',
|
|
|
|
|
|
'我们从哪里开始比较好?',
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function loadPresetQuestions() {
|
|
|
|
|
|
const a = agent.value
|
|
|
|
|
|
if (!a) { presetQuestions.value = []; return }
|
|
|
|
|
|
const cacheKey = `agent_preset_qs:${a.id}:${a.updated_at || ''}`
|
|
|
|
|
|
try {
|
|
|
|
|
|
const cached = localStorage.getItem(cacheKey)
|
|
|
|
|
|
if (cached) {
|
|
|
|
|
|
const qs = JSON.parse(cached)
|
|
|
|
|
|
if (Array.isArray(qs) && qs.length) { presetQuestions.value = qs; return }
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch { /* ignore */ }
|
|
|
|
|
|
presetLoading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const body: any = {
|
|
|
|
|
|
message: `你是「${a.name}」。简介:${a.description || '无'}。\n请生成 3 个用户最可能向你提问的示例问题(每个不超过 30 字)。只返回 JSON 数组,例如 ["问题1","问题2","问题3"],不要输出任何其他内容。`,
|
|
|
|
|
|
model: 'deepseek-v4-flash', max_iterations: 1, temperature: 0.7,
|
|
|
|
|
|
}
|
|
|
|
|
|
if (chatModelConfigId.value) body.model_config_id = chatModelConfigId.value
|
|
|
|
|
|
const resp = await api.post('/api/v1/agent-chat/bare', body)
|
|
|
|
|
|
const content = resp.data?.content || ''
|
|
|
|
|
|
const m = content.match(/\[[\s\S]*\]/)
|
|
|
|
|
|
const qs = m ? JSON.parse(m[0]) : []
|
|
|
|
|
|
const valid = Array.isArray(qs) ? qs.filter(q => typeof q === 'string' && q.trim()).map(q => q.trim()).slice(0, 3) : []
|
|
|
|
|
|
presetQuestions.value = valid.length ? valid : fallbackPresetQuestions()
|
|
|
|
|
|
if (valid.length) localStorage.setItem(cacheKey, JSON.stringify(valid))
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
presetQuestions.value = fallbackPresetQuestions()
|
|
|
|
|
|
} finally { presetLoading.value = false }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
function sendPresetQuestion(q: string) { inputMessage.value = q; nextTick(() => sendMessage()) }
|
|
|
|
|
|
function speakMessage(text: string) { if (!text) return; ttsSpeak(stripMarkdownForTTS(text), { voice: chatVoice.value }) }
|
|
|
|
|
|
function stopSpeak() { ttsStop() }
|
|
|
|
|
|
function startListening() { voiceStart('zh-CN') }
|
|
|
|
|
|
function stopListening() { voiceStop(); if (transcript.value) { inputMessage.value = (inputMessage.value + ' ' + transcript.value).trim(); transcript.value = '' } }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
|
|
|
|
|
|
function relativeTimeText(isoStr?: string): string {
|
|
|
|
|
|
if (!isoStr) return ''
|
|
|
|
|
|
const diff = Date.now() - new Date(isoStr).getTime()
|
|
|
|
|
|
if (diff < 60000) return '刚刚'
|
|
|
|
|
|
if (diff < 3600000) return `${Math.floor(diff / 60000)} 分钟前`
|
|
|
|
|
|
if (diff < 86400000) return `${Math.floor(diff / 3600000)} 小时前`
|
|
|
|
|
|
return `${Math.floor(diff / 86400000)} 天前`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onInputDragEnter(e: DragEvent) {
|
|
|
|
|
|
if (loading.value || (chatMode.value === 'single' && !currentAgentId.value)) return
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
e.preventDefault(); if (e.dataTransfer) e.dataTransfer.dropEffect = 'copy'
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
inputDragOver.value = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function onInputDrop(e: DragEvent) {
|
|
|
|
|
|
inputDragOver.value = false
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (chatMode.value === 'single' && !currentAgentId.value) { ElMessage.warning('请先选择智能体再上传文件'); return }
|
|
|
|
|
|
const files = e.dataTransfer?.files; if (files?.length) await uploadFiles(Array.from(files))
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 11:31:48 +08:00
|
|
|
|
async function sendMessage() {
|
|
|
|
|
|
const text = inputMessage.value.trim()
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
const hasAttachments = pendingAttachments.value.length > 0
|
|
|
|
|
|
if (!text && !hasAttachments) return
|
|
|
|
|
|
if (loading.value) return
|
|
|
|
|
|
|
|
|
|
|
|
const attachCtx = buildAttachmentContext()
|
|
|
|
|
|
const fullText = text + attachCtx
|
2026-05-01 11:31:48 +08:00
|
|
|
|
|
2026-07-26 23:48:29 +08:00
|
|
|
|
// 快照附件:图片走多模态消息,非图片仍走文本上下文
|
|
|
|
|
|
const sentAttachments = pendingAttachments.value.map(a => ({
|
|
|
|
|
|
relative_path: a.relative_path,
|
|
|
|
|
|
filename: a.filename,
|
|
|
|
|
|
content_type: a.content_type,
|
|
|
|
|
|
is_image: !!a.thumbUrl || (a.content_type || '').startsWith('image/'),
|
|
|
|
|
|
}))
|
|
|
|
|
|
const msgAttachments: MessageAttachment[] = pendingAttachments.value.map(a => ({
|
|
|
|
|
|
relative_path: a.relative_path,
|
|
|
|
|
|
filename: a.filename,
|
|
|
|
|
|
thumbUrl: a.thumbUrl,
|
|
|
|
|
|
isImage: !!a.thumbUrl || (a.content_type || '').startsWith('image/'),
|
|
|
|
|
|
content_type: a.content_type,
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const key = currentAgentKey.value
|
|
|
|
|
|
if (!messages.value[key]) messages.value[key] = []
|
2026-07-26 23:48:29 +08:00
|
|
|
|
messages.value[key].push({ role: 'user', content: fullText, timestamp: Date.now(), attachments: msgAttachments.length ? msgAttachments : undefined })
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
inputMessage.value = ''; pendingAttachments.value = []; inputDragOver.value = false
|
|
|
|
|
|
loading.value = true; scrollToBottom()
|
2026-05-01 11:31:48 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
2026-05-01 19:32:59 +08:00
|
|
|
|
if (chatMode.value === 'orchestrate') {
|
|
|
|
|
|
const resp = await api.post('/api/v1/agent-chat/orchestrate', {
|
2026-07-26 23:48:29 +08:00
|
|
|
|
message: fullText, mode: orchestrateMode.value,
|
2026-05-01 19:32:59 +08:00
|
|
|
|
agents: orchestrateAgents.value.map(a => ({
|
|
|
|
|
|
id: a.id, name: a.name, system_prompt: a.system_prompt,
|
|
|
|
|
|
model: a.model, temperature: a.temperature, max_iterations: a.max_iterations,
|
|
|
|
|
|
tools: [], description: a.description,
|
|
|
|
|
|
})),
|
|
|
|
|
|
})
|
|
|
|
|
|
const data = resp.data as OrchestrateResult
|
|
|
|
|
|
data.steps.forEach(s => { s._open = false })
|
2026-05-01 22:30:46 +08:00
|
|
|
|
messages.value[key].push({
|
2026-05-01 19:32:59 +08:00
|
|
|
|
role: 'assistant', content: data.final_answer, timestamp: Date.now(),
|
|
|
|
|
|
orchestrateResult: data, _traceOpen: true,
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const sessId = sessionId.value[key] || ''
|
|
|
|
|
|
const streamEndpoint = currentAgentId.value
|
|
|
|
|
|
? `/api/v1/agent-chat/${currentAgentId.value}/stream`
|
|
|
|
|
|
: '/api/v1/agent-chat/bare/stream'
|
|
|
|
|
|
|
|
|
|
|
|
let usedStreaming = false
|
2026-05-05 00:00:51 +08:00
|
|
|
|
let placeholderIdx = -1
|
2026-05-01 22:30:46 +08:00
|
|
|
|
streamingActive.value = false
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
abortController.value = new AbortController()
|
|
|
|
|
|
const streamTimeout = setTimeout(() => abortController.value?.abort(), 300000)
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
try {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const authToken = localStorage.getItem('access_token') || localStorage.getItem('token') || ''
|
|
|
|
|
|
const body: any = {
|
2026-07-26 23:48:29 +08:00
|
|
|
|
message: fullText,
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
session_id: sessId || undefined,
|
|
|
|
|
|
temperature: chatTemperature.value,
|
|
|
|
|
|
max_iterations: chatMaxIterations.value,
|
|
|
|
|
|
}
|
2026-07-26 23:48:29 +08:00
|
|
|
|
if (sentAttachments.length) body.attachments = sentAttachments
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (chatMaxTokens.value) body.max_tokens = chatMaxTokens.value
|
|
|
|
|
|
if (chatModelConfigId.value) body.model_config_id = chatModelConfigId.value
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const resp = await fetch(streamEndpoint, {
|
|
|
|
|
|
method: 'POST',
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
headers: { 'Content-Type': 'application/json', ...(authToken ? { 'Authorization': `Bearer ${authToken}` } : {}) },
|
|
|
|
|
|
body: JSON.stringify(body),
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
signal: abortController.value.signal,
|
2026-05-01 22:30:46 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (resp.ok && resp.body) {
|
|
|
|
|
|
usedStreaming = true
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const msg: ChatMessage = { role: 'assistant', content: '', timestamp: Date.now(), steps: [], _traceOpen: true, iterations: 0, tool_calls_made: 0 }
|
2026-05-05 00:00:51 +08:00
|
|
|
|
placeholderIdx = messages.value[key].push(msg) - 1
|
|
|
|
|
|
const currentMsg = messages.value[key][placeholderIdx]
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
|
|
|
|
|
const reader = resp.body.getReader()
|
|
|
|
|
|
const decoder = new TextDecoder()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
let buffer = ''; let receivedFirstEvent = false
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
const { done, value } = await reader.read()
|
|
|
|
|
|
if (done) break
|
|
|
|
|
|
buffer += decoder.decode(value, { stream: true })
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const parts = buffer.split('\n\n'); buffer = parts.pop() || ''
|
2026-05-01 22:30:46 +08:00
|
|
|
|
for (const part of parts) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const lines = part.split('\n'); let eventType = ''; let dataStr = ''
|
|
|
|
|
|
for (const line of lines) { if (line.startsWith('event: ')) eventType = line.slice(7); else if (line.startsWith('data: ')) dataStr = line.slice(6) }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
if (!dataStr) continue
|
|
|
|
|
|
try {
|
|
|
|
|
|
const data = JSON.parse(dataStr)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (!receivedFirstEvent) { receivedFirstEvent = true; streamingActive.value = true }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
if (eventType === 'think') {
|
2026-07-26 20:57:11 +08:00
|
|
|
|
currentMsg.content = ''
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
currentMsg.steps!.push({ iteration: data.iteration, type: 'think', content: data.content || '思考中...', reasoning: data.reasoning, tool_name: data.tool_names?.[0] })
|
2026-07-26 20:57:11 +08:00
|
|
|
|
} else if (eventType === 'answer_chunk') {
|
|
|
|
|
|
currentMsg.content = (currentMsg.content || '') + (data.content || '')
|
|
|
|
|
|
scrollToBottom()
|
2026-05-01 22:30:46 +08:00
|
|
|
|
} else if (eventType === 'tool_call') {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
currentMsg.steps!.push({ iteration: data.iteration, type: 'tool_call', content: `调用工具: ${data.name}`, tool_name: data.name, tool_input: data.input })
|
2026-05-01 22:30:46 +08:00
|
|
|
|
} else if (eventType === 'tool_result') {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
currentMsg.steps!.push({ iteration: data.iteration, type: 'tool_result', content: `工具 ${data.name} 返回结果`, tool_name: data.name, tool_result: data.result })
|
2026-05-04 23:17:59 +08:00
|
|
|
|
} else if (eventType === 'approval_required') {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
approvalId.value = data.approval_id || ''; approvalToolName.value = data.tool_name || ''; approvalArgs.value = data.args || {}
|
2026-05-04 23:17:59 +08:00
|
|
|
|
showApprovalDialog.value = true
|
2026-05-01 22:30:46 +08:00
|
|
|
|
} else if (eventType === 'final') {
|
2026-05-10 19:50:20 +08:00
|
|
|
|
clearTimeout(streamTimeout)
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
currentMsg.content = data.content || ''; currentMsg.iterations = data.iterations_used || 0; currentMsg.tool_calls_made = data.tool_calls_made || 0
|
2026-07-26 20:57:11 +08:00
|
|
|
|
if (data.token_usage) currentMsg.token_usage = data.token_usage
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (data.session_id) { sessionId.value[key] = data.session_id; if (!currentSessionId.value) { currentSessionId.value = data.session_id; loadSessions() } }
|
|
|
|
|
|
streamingActive.value = false; loading.value = false
|
2026-05-01 22:30:46 +08:00
|
|
|
|
} else if (eventType === 'error') {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
clearTimeout(streamTimeout); currentMsg.content = data.content || ''; currentMsg.status = 'error'
|
|
|
|
|
|
streamingActive.value = false; loading.value = false
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
} catch { /* skip */ }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-05 00:00:51 +08:00
|
|
|
|
clearTimeout(streamTimeout)
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
2026-07-26 20:57:11 +08:00
|
|
|
|
} catch {
|
|
|
|
|
|
clearTimeout(streamTimeout); streamingActive.value = false
|
|
|
|
|
|
if (abortController.value?.signal.aborted) {
|
|
|
|
|
|
// 用户主动停止:标记「已停止」,阻止非流式 fallback 重复请求
|
|
|
|
|
|
if (placeholderIdx >= 0 && placeholderIdx < messages.value[key].length) {
|
|
|
|
|
|
const m = messages.value[key][placeholderIdx]
|
|
|
|
|
|
if (m.content || (m.steps && m.steps.length)) { m.status = 'stopped' } else { messages.value[key].splice(placeholderIdx, 1) }
|
|
|
|
|
|
}
|
|
|
|
|
|
loading.value = false; saveState(); nextTick(scrollToBottom)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
usedStreaming = false
|
|
|
|
|
|
}
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
|
|
|
|
|
if (!usedStreaming) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (placeholderIdx >= 0 && placeholderIdx < messages.value[key].length) messages.value[key].splice(placeholderIdx, 1)
|
|
|
|
|
|
const fallbackEndpoint = currentAgentId.value ? `/api/v1/agent-chat/${currentAgentId.value}` : '/api/v1/agent-chat/bare'
|
2026-07-26 23:48:29 +08:00
|
|
|
|
const body: any = { message: fullText, session_id: sessId || undefined, temperature: chatTemperature.value, max_iterations: chatMaxIterations.value }
|
|
|
|
|
|
if (sentAttachments.length) body.attachments = sentAttachments
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (chatMaxTokens.value) body.max_tokens = chatMaxTokens.value
|
|
|
|
|
|
if (chatModelConfigId.value) body.model_config_id = chatModelConfigId.value
|
|
|
|
|
|
const resp = await api.post(fallbackEndpoint, body)
|
2026-05-01 22:30:46 +08:00
|
|
|
|
const data = resp.data
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
sessionId.value[key] = data.session_id; if (!currentSessionId.value) { currentSessionId.value = data.session_id; loadSessions() }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
messages.value[key].push({
|
|
|
|
|
|
role: 'assistant', content: data.content, timestamp: Date.now(),
|
|
|
|
|
|
iterations: data.iterations_used, tool_calls_made: data.tool_calls_made,
|
|
|
|
|
|
status: data.truncated ? 'error' : 'success', steps: data.steps || [],
|
|
|
|
|
|
_traceOpen: data.steps && data.steps.length > 0,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2026-05-01 19:32:59 +08:00
|
|
|
|
}
|
2026-05-01 22:30:46 +08:00
|
|
|
|
saveState()
|
2026-05-01 11:31:48 +08:00
|
|
|
|
} catch (e: any) {
|
2026-05-01 22:30:46 +08:00
|
|
|
|
messages.value[key].push({
|
2026-05-01 19:32:59 +08:00
|
|
|
|
role: 'assistant', content: `错误:${e.response?.data?.detail || e.message || '请求失败'}`,
|
|
|
|
|
|
timestamp: Date.now(), status: 'error',
|
2026-05-01 11:31:48 +08:00
|
|
|
|
})
|
2026-05-01 22:30:46 +08:00
|
|
|
|
saveState()
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
} finally { loading.value = false; scrollToBottom() }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 19:32:59 +08:00
|
|
|
|
function toggleTrace(msg: ChatMessage) { msg._traceOpen = !msg._traceOpen }
|
2026-07-26 20:26:15 +08:00
|
|
|
|
async function clearChat() {
|
|
|
|
|
|
if (displayMessages.value.length === 0) return
|
|
|
|
|
|
try {
|
|
|
|
|
|
await ElMessageBox.confirm(
|
|
|
|
|
|
'清空后将开始新对话(历史会话仍保留在「对话记录」中)。',
|
|
|
|
|
|
'确认清空',
|
|
|
|
|
|
{ type: 'warning', confirmButtonText: '清空', cancelButtonText: '取消' }
|
|
|
|
|
|
)
|
|
|
|
|
|
} catch { return }
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; messages.value[key] = []
|
|
|
|
|
|
if (chatMode.value === 'single') { sessionId.value[key] = ''; currentSessionId.value = '' }
|
|
|
|
|
|
currentBranchId.value = ''
|
|
|
|
|
|
saveState(); nextTick(scrollToBottom)
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
function scrollToBottom() { nextTick(() => { if (messagesRef.value && isNearBottom.value) messagesRef.value.scrollTop = messagesRef.value.scrollHeight }) }
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
function stopGeneration() { abortController.value?.abort(); loading.value = false; streamingActive.value = false; saveState() }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
function safeParseArgCount(args?: string): number { if (!args) return 0; try { return Object.keys(JSON.parse(args)).length } catch { return 0 } }
|
2026-05-01 22:30:46 +08:00
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
function editMessage(idx: number) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; const msgs = messages.value[key]
|
|
|
|
|
|
if (!msgs || !msgs[idx] || msgs[idx].role !== 'user') return
|
|
|
|
|
|
inputMessage.value = msgs[idx].content; msgs.splice(idx, 1); saveState(); nextTick(scrollToBottom)
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function deleteMessage(idx: number) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; const msgs = messages.value[key]
|
|
|
|
|
|
if (!msgs || !msgs[idx]) return; msgs.splice(idx, 1); saveState(); nextTick(scrollToBottom)
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-01 22:30:46 +08:00
|
|
|
|
function copyMessage(msg: ChatMessage) {
|
|
|
|
|
|
const text = msg.orchestrateResult?.final_answer || msg.content
|
|
|
|
|
|
if (!text) return
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
navigator.clipboard.writeText(text).then(() => ElMessage.success('已复制')).catch(() => ElMessage.warning('复制失败'))
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function retryMessage(idx: number) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
const key = currentAgentKey.value; const msgs = messages.value[key]
|
2026-05-01 22:30:46 +08:00
|
|
|
|
if (!msgs) return
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
let userMsg = ''; let userIdx = -1
|
|
|
|
|
|
for (let i = idx - 1; i >= 0; i--) { if (msgs[i].role === 'user') { userMsg = msgs[i].content; userIdx = i; break } }
|
|
|
|
|
|
if (!userMsg) { ElMessage.warning('未找到可重试的消息'); return }
|
2026-05-05 00:00:51 +08:00
|
|
|
|
const removeIndices: number[] = [userIdx, idx]
|
|
|
|
|
|
for (let i = userIdx + 1; i < idx; i++) {
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
if (msgs[i].role === 'assistant' && (!msgs[i].content || msgs[i].content === '') && (msgs[i].steps?.length || 0) > 0) removeIndices.push(i)
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
removeIndices.sort((a, b) => b - a); for (const ri of removeIndices) msgs.splice(ri, 1)
|
|
|
|
|
|
saveState(); inputMessage.value = userMsg; nextTick(() => sendMessage())
|
2026-05-01 22:30:46 +08:00
|
|
|
|
}
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
|
|
|
|
|
|
// 分页加载更多历史
|
|
|
|
|
|
const hasMoreHistory = ref(false)
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
2026-05-01 22:30:46 +08:00
|
|
|
|
.agent-chat-page { display: flex; flex-direction: column; height: 100%; max-width: 960px; margin: 0 auto; }
|
|
|
|
|
|
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--el-border-color-light); }
|
|
|
|
|
|
.page-header-left { display: flex; align-items: center; gap: 8px; }
|
|
|
|
|
|
.page-header-left h3 { margin: 0; font-size: 16px; font-weight: 600; }
|
|
|
|
|
|
.page-header-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
|
|
|
|
|
.chat-messages { flex: 1; overflow-y: auto; padding: 8px 0; display: flex; flex-direction: column; gap: 12px; min-height: 0; }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
.chat-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: var(--el-text-color-secondary); gap: 12px; padding: 40px 20px; text-align: center; }
|
|
|
|
|
|
.chat-empty .hint { font-size: 13px; color: var(--el-text-color-placeholder); margin-top: 8px; }
|
|
|
|
|
|
.welcome-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--el-text-color-primary); }
|
|
|
|
|
|
.welcome-desc { margin: 0; font-size: 14px; color: var(--el-text-color-secondary); max-width: 480px; line-height: 1.6; }
|
|
|
|
|
|
.welcome-tags { display: flex; gap: 6px; }
|
|
|
|
|
|
.preset-questions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; max-width: 520px; margin-top: 4px; }
|
|
|
|
|
|
.preset-q { padding: 8px 16px; background: var(--el-fill-color); border: 1px solid var(--el-border-color-light); border-radius: 20px; font-size: 13px; cursor: pointer; transition: all 0.15s; color: var(--el-text-color-regular); }
|
|
|
|
|
|
.preset-q:hover { background: var(--el-color-primary-light-9); border-color: var(--el-color-primary-light-5); color: var(--el-color-primary); }
|
|
|
|
|
|
.agent-quick-list { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; max-width: 480px; }
|
|
|
|
|
|
|
|
|
|
|
|
/* Chat settings popover */
|
|
|
|
|
|
.chat-settings-popover { padding: 4px 0; }
|
2026-05-01 19:32:59 +08:00
|
|
|
|
.message { display: flex; gap: 12px; max-width: 88%; }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
.message.user { align-self: flex-end; flex-direction: row-reverse; }
|
|
|
|
|
|
.message.assistant { align-self: flex-start; }
|
2026-05-01 19:32:59 +08:00
|
|
|
|
.message-bubble { padding: 10px 14px; border-radius: 12px; background: var(--el-fill-color-light); line-height: 1.6; font-size: 14px; }
|
|
|
|
|
|
.message.user .message-bubble { background: var(--el-color-primary-light-8); }
|
|
|
|
|
|
.message.error .message-bubble { border: 1px solid var(--el-color-danger-light-5); }
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
.message-text :deep(pre) { background: #1e1e2e; color: #cdd6f4; padding: 14px; border-radius: 8px; overflow-x: auto; font-size: 13px; line-height: 1.55; margin: 8px 0; }
|
|
|
|
|
|
.message-text :deep(pre code) { background: none; padding: 0; border-radius: 0; font-size: inherit; color: inherit; }
|
|
|
|
|
|
.message-text :deep(code) { background: var(--el-fill-color-darker); padding: 2px 6px; border-radius: 4px; font-size: 13px; font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', monospace; }
|
|
|
|
|
|
.message-text :deep(h1) { font-size: 1.4em; font-weight: 700; margin: 12px 0 6px; }
|
|
|
|
|
|
.message-text :deep(h2) { font-size: 1.2em; font-weight: 700; margin: 10px 0 4px; }
|
|
|
|
|
|
.message-text :deep(h3) { font-size: 1.1em; font-weight: 600; margin: 8px 0 4px; }
|
|
|
|
|
|
.message-text :deep(ul), .message-text :deep(ol) { padding-left: 20px; margin: 4px 0; }
|
|
|
|
|
|
.message-text :deep(li) { margin: 2px 0; }
|
|
|
|
|
|
.message-text :deep(blockquote) { border-left: 3px solid var(--el-color-primary); margin: 8px 0; padding: 4px 12px; color: var(--el-text-color-secondary); background: var(--el-fill-color-lighter); border-radius: 0 6px 6px 0; }
|
|
|
|
|
|
.message-text :deep(table) { border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 13px; }
|
|
|
|
|
|
.message-text :deep(th), .message-text :deep(td) { border: 1px solid var(--el-border-color); padding: 6px 10px; text-align: left; }
|
|
|
|
|
|
.message-text :deep(th) { background: var(--el-fill-color); font-weight: 600; }
|
|
|
|
|
|
.message-text :deep(a) { color: var(--el-color-primary); text-decoration: underline; }
|
|
|
|
|
|
.message-text :deep(hr) { border: none; border-top: 1px solid var(--el-border-color-light); margin: 12px 0; }
|
|
|
|
|
|
.message-text :deep(p) { margin: 4px 0; }
|
|
|
|
|
|
.message-text :deep(img) { max-width: 100%; border-radius: 8px; margin: 6px 0; }
|
2026-05-01 19:32:59 +08:00
|
|
|
|
|
|
|
|
|
|
/* Tool calls */
|
|
|
|
|
|
.tool-calls { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--el-border-color-light); }
|
|
|
|
|
|
.tool-calls-header { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--el-text-color-secondary); margin-bottom: 4px; }
|
|
|
|
|
|
.tool-call-item { display: flex; align-items: center; gap: 8px; padding: 4px 8px; font-size: 12px; }
|
|
|
|
|
|
.tool-name { font-weight: 500; color: var(--el-color-primary); }
|
|
|
|
|
|
|
|
|
|
|
|
/* Thinking trace */
|
|
|
|
|
|
.thinking-trace { margin-top: 10px; border-top: 1px solid var(--el-border-color-light); padding-top: 8px; }
|
|
|
|
|
|
.trace-header { display: flex; align-items: center; gap: 4px; cursor: pointer; font-size: 12px; color: var(--el-color-primary); user-select: none; padding: 4px 0; }
|
|
|
|
|
|
.trace-steps { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
|
|
|
|
|
|
.trace-step { display: flex; gap: 8px; padding: 8px 10px; border-radius: 8px; background: var(--el-fill-color-lighter); border-left: 3px solid var(--el-border-color); }
|
|
|
|
|
|
.trace-step.step-think { border-left-color: var(--el-color-primary); }
|
|
|
|
|
|
.trace-step.step-tool_result { border-left-color: var(--el-color-warning); }
|
|
|
|
|
|
.trace-step.step-final { border-left-color: var(--el-color-success); }
|
|
|
|
|
|
.step-icon { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-size: 14px; color: var(--el-text-color-secondary); }
|
|
|
|
|
|
.step-body { flex: 1; min-width: 0; font-size: 13px; }
|
|
|
|
|
|
.step-header { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
|
|
|
|
|
|
.step-tag { font-size: 11px; padding: 1px 6px; border-radius: 4px; font-weight: 500; }
|
|
|
|
|
|
.tag-think { background: var(--el-color-primary-light-9); color: var(--el-color-primary); }
|
|
|
|
|
|
.tag-tool_result { background: var(--el-color-warning-light-9); color: var(--el-color-warning); }
|
|
|
|
|
|
.tag-final { background: var(--el-color-success-light-9); color: var(--el-color-success); }
|
|
|
|
|
|
.step-iter { font-size: 11px; color: var(--el-text-color-placeholder); }
|
|
|
|
|
|
.step-tool-name { font-size: 11px; background: var(--el-color-info-light-9); color: var(--el-color-info); padding: 0 6px; border-radius: 4px; font-family: monospace; }
|
|
|
|
|
|
.step-content { line-height: 1.5; }
|
|
|
|
|
|
.step-content :deep(pre) { background: var(--el-fill-color); padding: 8px; border-radius: 6px; overflow-x: auto; font-size: 12px; margin: 4px 0; }
|
|
|
|
|
|
.step-reasoning, .step-tool-input, .step-tool-result { margin-top: 6px; }
|
|
|
|
|
|
.reasoning-header { font-size: 11px; color: var(--el-text-color-secondary); margin-bottom: 2px; font-weight: 500; }
|
|
|
|
|
|
.reasoning-text { font-size: 12px; color: var(--el-text-color-secondary); line-height: 1.5; font-style: italic; }
|
|
|
|
|
|
.step-tool-input pre, .step-tool-result pre { background: var(--el-fill-color-darker); padding: 6px 8px; border-radius: 4px; font-size: 11px; overflow-x: auto; max-height: 200px; margin: 0; }
|
|
|
|
|
|
|
|
|
|
|
|
/* Thinking dots */
|
|
|
|
|
|
.thinking { display: flex; gap: 4px; padding: 8px 0; }
|
|
|
|
|
|
.dot { width: 8px; height: 8px; background: var(--el-text-color-placeholder); border-radius: 50%; animation: bounce 1.4s infinite ease-in-out; }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
.dot:nth-child(2) { animation-delay: 0.16s; }
|
|
|
|
|
|
.dot:nth-child(3) { animation-delay: 0.32s; }
|
2026-05-01 19:32:59 +08:00
|
|
|
|
@keyframes bounce { 0%,80%,100% { transform: scale(0); } 40% { transform: scale(1); } }
|
|
|
|
|
|
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
/* Session selector */
|
|
|
|
|
|
.session-option-title { font-size: 13px; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 260px; }
|
2026-07-26 20:57:11 +08:00
|
|
|
|
.session-option-row { display: flex; align-items: center; width: 100%; gap: 8px; }
|
|
|
|
|
|
.session-option-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
|
|
|
|
|
|
.session-option-actions .el-icon { cursor: pointer; padding: 2px; }
|
|
|
|
|
|
.session-option-actions .el-icon:hover { transform: scale(1.15); }
|
|
|
|
|
|
.date-divider {
|
|
|
|
|
|
display: flex; align-items: center; justify-content: center;
|
|
|
|
|
|
margin: 16px 0 8px; width: 100%;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
.date-divider::before {
|
|
|
|
|
|
content: ''; position: absolute; left: 0; right: 0; top: 50%;
|
|
|
|
|
|
border-top: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
|
}
|
|
|
|
|
|
.date-divider-text {
|
|
|
|
|
|
position: relative; z-index: 1;
|
|
|
|
|
|
background: var(--el-bg-color);
|
|
|
|
|
|
padding: 2px 12px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: var(--el-text-color-placeholder);
|
|
|
|
|
|
}
|
fix: Android null-safety Gson crash + AgentChat full UX overhaul (Round 1-4)
Android:
- Add NullSafeStringAdapter to GsonBuilder globally to prevent null String injection into non-nullable Kotlin fields
- Add defensive null-safe mappings in AgentRepository and all UI Text() calls
Frontend AgentChat (4 rounds):
- Round 1: Stop generation button, server-side session history sync, smart scroll
- Round 2: Full markdown rendering (marked), file/image upload with drag-drop, message edit/delete
- Round 3: TTS speech (browser SpeechSynthesis), voice input (SpeechRecognition), empty state guidance, model/temperature selector
- Round 4: Extract shared chat core — useMarkdown, useFileUpload, ChatMessageBubble, ChatInputArea modules — merge AgentChat.vue and AgentChatPreview.vue divergent code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 14:45:55 +08:00
|
|
|
|
.session-option-meta { font-size: 11px; color: var(--el-text-color-placeholder); }
|
2026-05-01 19:32:59 +08:00
|
|
|
|
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
/* Orchestrate */
|
2026-05-01 19:32:59 +08:00
|
|
|
|
.orchestrate-result { font-size: 14px; }
|
|
|
|
|
|
.orch-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
|
|
|
|
|
.orch-agent-count { font-size: 12px; color: var(--el-text-color-secondary); }
|
|
|
|
|
|
.orch-final { margin-bottom: 12px; }
|
|
|
|
|
|
.orch-section-title { font-size: 13px; font-weight: 600; color: var(--el-text-color-primary); margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--el-border-color-light); }
|
|
|
|
|
|
.orch-steps { display: flex; flex-direction: column; gap: 4px; }
|
|
|
|
|
|
.orch-step { border: 1px solid var(--el-border-color-lighter); border-radius: 8px; overflow: hidden; }
|
|
|
|
|
|
.orch-step-header { display: flex; align-items: center; gap: 6px; padding: 6px 10px; cursor: pointer; background: var(--el-fill-color-lighter); font-size: 13px; }
|
|
|
|
|
|
.orch-step-header:hover { background: var(--el-fill-color-light); }
|
|
|
|
|
|
.orch-step-meta { font-size: 11px; color: var(--el-text-color-placeholder); margin-left: auto; }
|
|
|
|
|
|
.orch-step-body { padding: 8px 12px; font-size: 13px; background: var(--el-bg-color); }
|
|
|
|
|
|
.orch-editor { display: flex; flex-direction: column; gap: 12px; max-height: 500px; overflow-y: auto; }
|
|
|
|
|
|
.orch-agent-card { border: 1px solid var(--el-border-color-light); border-radius: 8px; padding: 12px; }
|
|
|
|
|
|
.orch-agent-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
|
|
|
|
|
.orch-agent-num { font-weight: 600; color: var(--el-color-primary); font-size: 14px; }
|
|
|
|
|
|
.orch-agent-params { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
|
|
|
|
|
|
/* Search panel */
|
|
|
|
|
|
.search-panel { max-height: 420px; display: flex; flex-direction: column; }
|
|
|
|
|
|
.search-results { flex: 1; overflow-y: auto; margin-top: 10px; }
|
|
|
|
|
|
.search-count { font-size: 12px; color: var(--el-text-color-secondary); margin-bottom: 8px; }
|
|
|
|
|
|
.search-result-item { padding: 8px; border-radius: 6px; cursor: pointer; border: 1px solid var(--el-border-color-lighter); margin-bottom: 6px; transition: all 0.15s; }
|
|
|
|
|
|
.search-result-item:hover { background: var(--el-fill-color-light); border-color: var(--el-color-primary-light-5); }
|
|
|
|
|
|
.search-result-header { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
|
|
|
|
|
|
.search-result-session { font-size: 11px; color: var(--el-text-color-placeholder); margin-left: auto; }
|
|
|
|
|
|
.search-result-time { font-size: 11px; color: var(--el-text-color-placeholder); }
|
|
|
|
|
|
.search-result-content { font-size: 13px; color: var(--el-text-color-regular); line-height: 1.4; max-height: 60px; overflow: hidden; }
|
|
|
|
|
|
.search-result-content :deep(.search-highlight) { background: #fde047; color: #1e293b; padding: 0 2px; border-radius: 2px; }
|
|
|
|
|
|
|
|
|
|
|
|
/* Branches panel */
|
|
|
|
|
|
.branches-panel { display: flex; flex-direction: column; gap: 12px; }
|
|
|
|
|
|
.branches-actions { margin-bottom: 4px; }
|
|
|
|
|
|
.branches-list { display: flex; flex-direction: column; gap: 8px; }
|
|
|
|
|
|
.branch-item { padding: 10px 12px; border: 1px solid var(--el-border-color-lighter); border-radius: 8px; cursor: pointer; transition: all 0.15s; }
|
|
|
|
|
|
.branch-item:hover { border-color: var(--el-color-primary-light-5); background: var(--el-fill-color-light); }
|
|
|
|
|
|
.branch-item.active { border-color: var(--el-color-primary); background: var(--el-color-primary-light-9); }
|
|
|
|
|
|
.branch-title { font-size: 14px; font-weight: 500; margin-bottom: 4px; }
|
|
|
|
|
|
.branch-meta { display: flex; gap: 10px; font-size: 11px; color: var(--el-text-color-placeholder); }
|
|
|
|
|
|
.branch-actions { margin-top: 6px; display: flex; justify-content: flex-end; }
|
2026-05-01 11:31:48 +08:00
|
|
|
|
</style>
|