主要改进: - 新增 REST API 任务管理接口 (/api/tasks) - 实现 150ms 轮询机制,提供流畅的流式输出体验 - 支持页面刷新后自动恢复任务状态 - WebSocket 断开时检测 REST API 任务,避免误停止 - 修复堆叠块融合问题,刷新后内容正确合并 - 修复思考块展开/折叠逻辑,只展开正在流式输出的块 - 修复工具块重复显示问题,通过注册机制实现状态更新 - 修复历史不完整导致内容丢失的问题 - 新增 tool_intent 事件处理,支持打字机效果显示 - 修复对话列表排序时 None 值比较错误 技术细节: - 前端:新增 taskPolling.ts 和 task store 处理轮询逻辑 - 后端:TaskManager 管理任务生命周期和事件存储 - 状态恢复:智能判断是否需要从头重建,避免内容重复 - 工具块注册:恢复时注册到 toolActionIndex,支持状态更新 - Intent 显示:0.5-1秒打字机效果,历史加载直接显示 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
199 lines
9.7 KiB
TypeScript
199 lines
9.7 KiB
TypeScript
// @ts-nocheck
|
||
// static/app-enhanced.js - 修复版,正确实现Token实时更新
|
||
import { mapActions } from 'pinia';
|
||
import { useUiStore } from './stores/ui';
|
||
import { useChatStore } from './stores/chat';
|
||
import { useInputStore } from './stores/input';
|
||
import { useToolStore } from './stores/tool';
|
||
import { useResourceStore } from './stores/resource';
|
||
import { useUploadStore } from './stores/upload';
|
||
import { useFileStore } from './stores/file';
|
||
import { useSubAgentStore } from './stores/subAgent';
|
||
import { useFocusStore } from './stores/focus';
|
||
import { usePersonalizationStore } from './stores/personalization';
|
||
import { useModelStore } from './stores/model';
|
||
import { useMonitorStore } from './stores/monitor';
|
||
import { appComponents } from './app/components';
|
||
import { dataState } from './app/state';
|
||
import { computed } from './app/computed';
|
||
import { watchers } from './app/watchers';
|
||
import { created, mounted, beforeUnmount } from './app/lifecycle';
|
||
import { conversationMethods } from './app/methods/conversation';
|
||
import { historyMethods } from './app/methods/history';
|
||
import { messageMethods } from './app/methods/message';
|
||
import { searchMethods } from './app/methods/search';
|
||
import { uploadMethods } from './app/methods/upload';
|
||
import { resourceMethods } from './app/methods/resources';
|
||
import { toolingMethods } from './app/methods/tooling';
|
||
import { uiMethods } from './app/methods/ui';
|
||
import { taskPollingMethods } from './app/methods/taskPolling';
|
||
import { monitorMethods } from './app/methods/monitor';
|
||
|
||
// 其他初始化逻辑已迁移到 app/bootstrap.ts
|
||
|
||
const appOptions = {
|
||
data: dataState,
|
||
created,
|
||
mounted,
|
||
beforeUnmount,
|
||
computed,
|
||
watch: watchers,
|
||
|
||
methods: {
|
||
...conversationMethods,
|
||
...historyMethods,
|
||
...searchMethods,
|
||
...messageMethods,
|
||
...uploadMethods,
|
||
...resourceMethods,
|
||
...toolingMethods,
|
||
...uiMethods,
|
||
...monitorMethods,
|
||
...taskPollingMethods,
|
||
...mapActions(useUiStore, {
|
||
uiToggleSidebar: 'toggleSidebar',
|
||
uiSetSidebarCollapsed: 'setSidebarCollapsed',
|
||
uiSetWorkspaceCollapsed: 'setWorkspaceCollapsed',
|
||
uiToggleWorkspaceCollapsed: 'toggleWorkspaceCollapsed',
|
||
uiSetChatDisplayMode: 'setChatDisplayMode',
|
||
uiSetPanelMode: 'setPanelMode',
|
||
uiSetPanelMenuOpen: 'setPanelMenuOpen',
|
||
uiTogglePanelMenu: 'togglePanelMenu',
|
||
uiSetMobileViewport: 'setIsMobileViewport',
|
||
uiSetMobileOverlayMenuOpen: 'setMobileOverlayMenuOpen',
|
||
uiToggleMobileOverlayMenu: 'toggleMobileOverlayMenu',
|
||
uiSetActiveMobileOverlay: 'setActiveMobileOverlay',
|
||
uiCloseMobileOverlay: 'closeMobileOverlay',
|
||
uiPushToast: 'pushToast',
|
||
uiUpdateToast: 'updateToast',
|
||
uiDismissToast: 'dismissToast',
|
||
uiShowQuotaToastMessage: 'showQuotaToastMessage',
|
||
uiDismissQuotaToast: 'dismissQuotaToast',
|
||
uiRequestConfirm: 'requestConfirm',
|
||
uiResolveConfirm: 'resolveConfirm'
|
||
}),
|
||
...mapActions(useModelStore, {
|
||
modelSet: 'setModel'
|
||
}),
|
||
...mapActions(useChatStore, {
|
||
chatExpandBlock: 'expandBlock',
|
||
chatCollapseBlock: 'collapseBlock',
|
||
chatClearExpandedBlocks: 'clearExpandedBlocks',
|
||
chatSetThinkingLock: 'setThinkingLock',
|
||
chatClearThinkingLocks: 'clearThinkingLocks',
|
||
chatSetScrollState: 'setScrollState',
|
||
chatEnableAutoScroll: 'enableAutoScroll',
|
||
chatDisableAutoScroll: 'disableAutoScroll',
|
||
chatToggleScrollLockState: 'toggleScrollLockState',
|
||
chatAddUserMessage: 'addUserMessage',
|
||
chatStartAssistantMessage: 'startAssistantMessage',
|
||
chatStartThinkingAction: 'startThinkingAction',
|
||
chatAppendThinkingChunk: 'appendThinkingChunk',
|
||
chatCompleteThinkingAction: 'completeThinking',
|
||
chatStartTextAction: 'startTextAction',
|
||
chatAppendTextChunk: 'appendTextChunk',
|
||
chatCompleteTextAction: 'completeText',
|
||
chatAddSystemMessage: 'addSystemMessage',
|
||
chatAddAppendPayloadAction: 'addAppendPayloadAction',
|
||
chatAddModifyPayloadAction: 'addModifyPayloadAction',
|
||
chatEnsureAssistantMessage: 'ensureAssistantMessage'
|
||
}),
|
||
...mapActions(useInputStore, {
|
||
inputSetFocused: 'setInputFocused',
|
||
inputToggleQuickMenu: 'toggleQuickMenu',
|
||
inputCloseMenus: 'closeMenus',
|
||
inputOpenQuickMenu: 'openQuickMenu',
|
||
inputSetQuickMenuOpen: 'setQuickMenuOpen',
|
||
inputToggleToolMenu: 'toggleToolMenu',
|
||
inputSetToolMenuOpen: 'setToolMenuOpen',
|
||
inputToggleSettingsMenu: 'toggleSettingsMenu',
|
||
inputSetSettingsOpen: 'setSettingsOpen',
|
||
inputSetMessage: 'setInputMessage',
|
||
inputClearMessage: 'clearInputMessage',
|
||
inputSetLineCount: 'setInputLineCount',
|
||
inputSetMultiline: 'setInputMultiline',
|
||
inputSetImagePickerOpen: 'setImagePickerOpen',
|
||
inputSetSelectedImages: 'setSelectedImages',
|
||
inputAddSelectedImage: 'addSelectedImage',
|
||
inputClearSelectedImages: 'clearSelectedImages',
|
||
inputRemoveSelectedImage: 'removeSelectedImage',
|
||
inputSetVideoPickerOpen: 'setVideoPickerOpen',
|
||
inputSetSelectedVideos: 'setSelectedVideos',
|
||
inputAddSelectedVideo: 'addSelectedVideo',
|
||
inputClearSelectedVideos: 'clearSelectedVideos',
|
||
inputRemoveSelectedVideo: 'removeSelectedVideo'
|
||
}),
|
||
...mapActions(useToolStore, {
|
||
toolRegisterAction: 'registerToolAction',
|
||
toolUnregisterAction: 'unregisterToolAction',
|
||
toolFindAction: 'findToolAction',
|
||
toolTrackAction: 'trackToolAction',
|
||
toolReleaseAction: 'releaseToolAction',
|
||
toolGetLatestAction: 'getLatestActiveToolAction',
|
||
toolResetTracking: 'resetToolTracking',
|
||
toolSetSettings: 'setToolSettings',
|
||
toolSetSettingsLoading: 'setToolSettingsLoading'
|
||
}),
|
||
...mapActions(useResourceStore, {
|
||
resourceUpdateCurrentContextTokens: 'updateCurrentContextTokens',
|
||
resourceFetchConversationTokenStatistics: 'fetchConversationTokenStatistics',
|
||
resourceSetCurrentContextTokens: 'setCurrentContextTokens',
|
||
resourceToggleTokenPanel: 'toggleTokenPanel',
|
||
resourceApplyStatusSnapshot: 'applyStatusSnapshot',
|
||
resourceUpdateContainerStatus: 'updateContainerStatus',
|
||
resourceStartContainerStatsPolling: 'startContainerStatsPolling',
|
||
resourceStopContainerStatsPolling: 'stopContainerStatsPolling',
|
||
resourceStartProjectStoragePolling: 'startProjectStoragePolling',
|
||
resourceStopProjectStoragePolling: 'stopProjectStoragePolling',
|
||
resourceStartUsageQuotaPolling: 'startUsageQuotaPolling',
|
||
resourceStopUsageQuotaPolling: 'stopUsageQuotaPolling',
|
||
resourcePollContainerStats: 'pollContainerStats',
|
||
resourceBindContainerVisibilityWatcher: 'bindContainerVisibilityWatcher',
|
||
resourcePollProjectStorage: 'pollProjectStorage',
|
||
resourceFetchUsageQuota: 'fetchUsageQuota',
|
||
resourceResetTokenStatistics: 'resetTokenStatistics',
|
||
resourceSetUsageQuota: 'setUsageQuota'
|
||
}),
|
||
...mapActions(useUploadStore, {
|
||
uploadHandleSelected: 'handleSelectedFiles',
|
||
uploadBatchFiles: 'uploadFiles'
|
||
}),
|
||
...mapActions(useFileStore, {
|
||
fileFetchTree: 'fetchFileTree',
|
||
fileSetTreeFromResponse: 'setFileTreeFromResponse',
|
||
fileFetchTodoList: 'fetchTodoList',
|
||
fileSetTodoList: 'setTodoList',
|
||
fileHideContextMenu: 'hideContextMenu',
|
||
fileMarkTreeUnavailable: 'markFileTreeUnavailable'
|
||
}),
|
||
...mapActions(useMonitorStore, {
|
||
monitorSyncDesktop: 'syncDesktopFromTree',
|
||
monitorResetVisual: 'resetVisualState',
|
||
monitorResetSpeech: 'resetSpeechBuffer',
|
||
monitorShowSpeech: 'enqueueModelSpeech',
|
||
monitorShowThinking: 'enqueueModelThinking',
|
||
monitorEndModelOutput: 'endModelOutput',
|
||
monitorShowPendingReply: 'showPendingReply',
|
||
monitorPreviewTool: 'previewToolIntent',
|
||
monitorQueueTool: 'enqueueToolEvent',
|
||
monitorResolveTool: 'resolveToolResult'
|
||
}),
|
||
...mapActions(useSubAgentStore, {
|
||
subAgentFetch: 'fetchSubAgents',
|
||
subAgentStartPolling: 'startPolling',
|
||
subAgentStopPolling: 'stopPolling'
|
||
}),
|
||
...mapActions(useFocusStore, {
|
||
focusFetchFiles: 'fetchFocusedFiles',
|
||
focusSetFiles: 'setFocusedFiles'
|
||
}),
|
||
...mapActions(usePersonalizationStore, {
|
||
personalizationOpenDrawer: 'openDrawer'
|
||
})
|
||
}
|
||
};
|
||
|
||
(appOptions as any).components = appComponents;
|
||
|
||
export default appOptions;
|