@@ -143,13 +125,12 @@ import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { listen } from '@tauri-apps/api/event'
import { useAiStore } from '../stores/ai'
-import { pendingMaxRounds } from '../composables/ai/useAiEvents'
-import { aiApi } from '../api'
import ConfirmDialog from './ConfirmDialog.vue'
import ConversationSidebar from './ai/ConversationSidebar.vue'
import ChatInput from './ai/ChatInput.vue'
import TopBar from './ai/TopBar.vue'
import MessageList from './ai/MessageList.vue'
+import MaxRoundsCard from './ai/MaxRoundsCard.vue'
import { useConfirm } from '../composables/useConfirm'
import { useProjectStore } from '../stores/project'
import type { AiMessage } from '../api/types'
@@ -522,50 +503,9 @@ async function toggleAlwaysOnTop() {
alwaysOnTop.value = !alwaysOnTop.value
}
-// ── F-260616-03: 达 max_iterations 暂停态操作卡 ──
-// pendingMaxRounds(达 max 事件置)+ 当前视图正在生成(防切走后误显)双重守卫。
-// maxRoundsActing 本地 ref 持按钮 loading:点继续/停止后禁双按钮,等后端事件
-// (continueLoop→新一轮 AiAgentRound;stopLoop→AiCompleted)自然清卡片。
-const maxRoundsActing = ref(false)
-const showMaxRoundsCard = computed(() =>
- pendingMaxRounds.value && isViewingGenerating.value,
-)
-
-/** 点继续:调 ai_continue_loop。后端续 max_iterations 轮(iteration 从 0 重计)。
- * 不主动清 pendingMaxRounds——由后端新一轮事件(AiAgentRound)与最终 AiCompleted/AiError
- * 在 useAiEvents 内清。IPC 失败回滚 acting 让用户可重试。 */
-async function handleContinueLoop(): Promise
{
- const convId = store.state.activeConversationId
- if (!convId) return
- maxRoundsActing.value = true
- try {
- await aiApi.continueLoop(convId)
- } catch (e) {
- maxRoundsActing.value = false
- const msg = e instanceof Error ? e.message : String(e)
- showToast(t('aiChat.continueLoopFailed', { msg }), 'error')
- }
-}
-
-/** 点停止:调 ai_stop_loop。后端复位 generating + emit AiCompleted,useAiEvents 据此
- * 清 pendingMaxRounds。IPC 失败回滚 acting。 */
-async function handleStopLoop(): Promise {
- const convId = store.state.activeConversationId
- if (!convId) return
- maxRoundsActing.value = true
- try {
- await aiApi.stopLoop(convId)
- } catch (e) {
- maxRoundsActing.value = false
- const msg = e instanceof Error ? e.message : String(e)
- showToast(t('aiChat.stopLoopFailed', { msg }), 'error')
- }
-}
-
-/** pendingMaxRounds 离开暂停态(后端事件已清)时复位 acting,允许下次再操作 */
-watch(() => pendingMaxRounds.value, (v) => {
- if (!v) maxRoundsActing.value = false
-})
+// 第五批抽离: F-260616-03 max_iterations 暂停态操作卡(maxRoundsActing/showMaxRoundsCard/
+// handleContinueLoop/handleStopLoop/pendingMaxRounds watch)已迁移至 ai/MaxRoundsCard.vue
+// (零行为变更,store 单例 + pendingMaxRounds 模块级 ref 共享,toast 经 emit 转父)。
// ── F-15 阶段2: 手动上下文管理(清空 / 压缩) ──
// ChatMessage.status 渲染语义(types.ts 未含 status 字段,前端经 cast 读写闭环):
@@ -1169,60 +1109,7 @@ body.ai-sidebar-resizing * {
border-top: 0.5px solid var(--df-border);
background: var(--df-bg);
}
-/* ── F-260616-03: 达 max_iterations 暂停态操作卡(警告色系,复用 ai-queue--timeout 风格) ── */
-.ai-max-rounds {
- display: flex;
- flex-direction: column;
- gap: 3px;
- margin-bottom: 6px;
- padding: 6px 8px;
- background: color-mix(in srgb, var(--df-warning) 10%, transparent);
- border: 0.5px solid color-mix(in srgb, var(--df-warning) 40%, transparent);
- border-radius: var(--df-radius);
-}
-.ai-max-rounds-text {
- font-size: 11.5px;
- font-weight: 600;
- color: var(--df-warning);
-}
-.ai-max-rounds-hint {
- font-size: 10.5px;
- color: var(--df-text-dim);
- opacity: 0.9;
-}
-.ai-max-rounds-actions {
- display: flex;
- align-items: center;
- gap: 6px;
- margin-top: 2px;
-}
-.ai-max-rounds-btn {
- border: none;
- cursor: pointer;
- font-size: 11px;
- font-weight: 600;
- padding: 3px 10px;
- border-radius: calc(var(--df-radius) - 2px);
- transition: filter 0.15s var(--df-ease);
-}
-.ai-max-rounds-btn:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-.ai-max-rounds-btn--continue {
- background: var(--df-warning);
- color: #000;
-}
-.ai-max-rounds-btn--continue:hover:not(:disabled) { filter: brightness(1.1); }
-.ai-max-rounds-btn--stop {
- background: transparent;
- color: var(--df-text-dim);
- border: 0.5px solid var(--df-border);
-}
-.ai-max-rounds-btn--stop:hover:not(:disabled) {
- color: var(--df-text);
- border-color: var(--df-text-dim);
-}
+/* 第五批抽离: F-260616-03 max_iterations 操作卡样式已迁移至 ai/MaxRoundsCard.vue */
/* ── AE-2025-07: Agentic 循环进度条 ── */
.ai-agentic-progress {
diff --git a/src/components/ai/MaxRoundsCard.vue b/src/components/ai/MaxRoundsCard.vue
new file mode 100644
index 0000000..06db5bd
--- /dev/null
+++ b/src/components/ai/MaxRoundsCard.vue
@@ -0,0 +1,144 @@
+
+
+
+
{{ $t('aiChat.maxRoundsReached') }}
+
{{ $t('aiChat.maxRoundsHint') }}
+
+
+
+
+
+
+
+
+
+