新增: 待发箱抽屉与对话体验前端批

- 待发箱抽屉: ChatInput ⏰ 入口 + OutboxDrawer + useAiOutbox IPC 封装
- U2 进度语义三层: 内容层(最近动作) + 静默三档降速脉冲, 永不自动判死
- 流式心跳自愈: 竞态窗口旧任务迟到完成事件误收敛的自愈判定(949 前端兜底)
- 953 截断提示: 末条气泡渲染截断标记 + 继续输出按钮, 事件契约透传
This commit is contained in:
lxy
2026-10-11 07:38:00 +08:00
parent 31510d3555
commit 3818a63522
22 changed files with 1151 additions and 19 deletions
+48
View File
@@ -815,6 +815,23 @@ async function onInstallObscura(): Promise<void> {
}
}
/**
* 看板 953:截断气泡「继续输出」按钮。回复被 provider max_tokens 上限腰斩时,注入续写指令
* 走既有发送通道(复用 store.sendMessage,对齐 onInstallObscura 模式),模型从上条回复的
* 中断处衔接输出,不再整段重发。streaming 中按钮 disabled(模板绑定);失败 toast 对齐
* handleRetry 错误处理模式。
*/
async function onContinueAfterTruncation(): Promise<void> {
try {
await store.sendMessage(t('ai.continueOutputPrompt'))
await nextTick()
scrollToBottom()
} catch (e) {
const msg = e instanceof Error ? e.message : String(e)
emit('toast', { msg: t('aiChat.sendFailed', { msg }), type: 'error' })
}
}
// ── F-15 阶段2: 消息分段(归档段折叠) ──
// ChatMessage.status 渲染语义(types.ts AiMessage.status 字面量联合定义):
// null | undefined | 'active' → 正常消息(现状)
@@ -1835,6 +1852,20 @@ defineExpose({
<span class="ai-cursor"></span>
</div>
<!-- 看板 953:max_tokens 截断提示条(仅末条 assistant 带标记时,气泡尾部弱提示)。
点击继续输出=注入续写指令复用 sendMessage,衔接勿重复;streaming 中禁用防叠发。 -->
<div v-if="isLastAi(item.msg) && item.msg.truncatedByMaxTokens" class="ai-msg-truncated">
<span class="ai-msg-truncated-text">{{ $t('ai.truncatedByMaxTokens') }}</span>
<button
class="ai-msg-act"
:disabled="store.state.streaming"
@click.stop="onContinueAfterTruncation"
>
<svg aria-hidden="true" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 11-2.12-9.36L23 10"/></svg>
<span>{{ $t('ai.continueOutput') }}</span>
</button>
</div>
<!-- UX-03 / 错误气泡操作入口(重试 / 去设置) -->
<div v-if="item.msg.isError" class="ai-msg-actions ai-msg-actions--error">
<span v-if="!canRetry(item.msg)" class="ai-msg-not-retryable">{{ $t('ai.notRetryable') }}</span>
@@ -2458,6 +2489,23 @@ defineExpose({
color: var(--df-accent);
}
/* 看板 953:max_tokens 截断弱提示条(末条 assistant 气泡尾部,warning 弱化不着色抢焦) */
.ai-msg-truncated {
display: flex;
align-items: center;
gap: 6px;
margin-top: 4px;
padding: 3px 8px;
border-radius: var(--df-radius-sm);
background: color-mix(in srgb, var(--df-warning, #ffc107) 10%, transparent);
width: fit-content;
}
.ai-msg-truncated-text {
font-size: 10.5px;
line-height: 1.4;
color: var(--df-text-dim);
}
/* -- Streaming Cursor -- */
.ai-cursor {
display: inline-block;