chore: 版本号 0.14.2 → 0.14.3
fix: AI 回复消息卡片重复渲染 — onDone 去掉 updateLastAssistantMessage 避免双重 DOM fix: 用户消息卡片只显示用户文字,代码生成的附件标记不显示 fix: onDone assistantMsg 补充 model 字段
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-v0.14.2-E8734A?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/version-v0.14.3-E8734A?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/electron-33+-47848F?style=flat-square&logo=electron" alt="electron">
|
||||
<img src="https://img.shields.io/badge/typescript-5.7+-3178C6?style=flat-square&logo=typescript" alt="typescript">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license">
|
||||
@@ -253,7 +253,7 @@ npm start
|
||||
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
||||
```
|
||||
|
||||
产出:`release/Metona Ollama Setup v0.14.2.exe`
|
||||
产出:`release/Metona Ollama Setup v0.14.3.exe`
|
||||
|
||||
## 🛠️ 常用命令
|
||||
|
||||
@@ -501,7 +501,7 @@ npm start
|
||||
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
|
||||
```
|
||||
|
||||
Output: `release/Metona Ollama Setup v0.14.2.exe`
|
||||
Output: `release/Metona Ollama Setup v0.14.3.exe`
|
||||
|
||||
## 🛠️ Common Commands
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "metona-ollama-desktop",
|
||||
"version": "0.14.2",
|
||||
"version": "0.14.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "metona-ollama-desktop",
|
||||
"version": "0.14.2",
|
||||
"version": "0.14.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "metona-ollama-desktop",
|
||||
"version": "0.14.2",
|
||||
"version": "0.14.3",
|
||||
"description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端",
|
||||
"main": "dist/main/main.js",
|
||||
"author": "thzxx",
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ export function createMenu(): void {
|
||||
dialog.showMessageBox(mainWindow!, {
|
||||
type: 'info',
|
||||
title: '关于 Metona Ollama',
|
||||
message: 'Metona Ollama Desktop v0.14.2',
|
||||
message: 'Metona Ollama Desktop v0.14.3',
|
||||
detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama',
|
||||
icon: getIconPath()
|
||||
});
|
||||
|
||||
@@ -588,7 +588,7 @@ async function handleRetry(): Promise<void> {
|
||||
if (retryIterations > 0) {
|
||||
if (finalContent) {
|
||||
const lastMsg: ChatMessage = {
|
||||
role: 'assistant', content: finalContent, timestamp: Date.now(),
|
||||
role: 'assistant', content: finalContent, model: getSelectedModel(), timestamp: Date.now(),
|
||||
...(retryThinkContent && { think: retryThinkContent }),
|
||||
...(toolRecords?.length && { toolCalls: toolRecords }),
|
||||
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
|
||||
@@ -599,10 +599,9 @@ async function handleRetry(): Promise<void> {
|
||||
...s, messages: [...s.messages, lastMsg], updatedAt: Date.now()
|
||||
}));
|
||||
}
|
||||
updateLastAssistantMessage(finalContent, retryThinkContent || null, loopStats || null, getSelectedModel(), Date.now(), toolRecords?.length ? toolRecords : undefined);
|
||||
} else {
|
||||
const assistantMsg: ChatMessage = {
|
||||
role: 'assistant', content: finalContent || '', timestamp: Date.now(),
|
||||
role: 'assistant', content: finalContent || '', model: getSelectedModel(), timestamp: Date.now(),
|
||||
...(retryThinkContent && { think: retryThinkContent }),
|
||||
...(toolRecords?.length && { toolCalls: toolRecords }),
|
||||
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
|
||||
@@ -612,8 +611,9 @@ async function handleRetry(): Promise<void> {
|
||||
state.update(KEYS.CURRENT_SESSION, (s: any) => ({
|
||||
...s, messages: [...s.messages, assistantMsg], updatedAt: Date.now()
|
||||
}));
|
||||
updateLastAssistantMessage(finalContent, retryThinkContent || null, loopStats || null, getSelectedModel(), Date.now(), toolRecords?.length ? toolRecords : undefined);
|
||||
}
|
||||
// renderMessages 统一渲染 session 数据,先清掉流式 placeholder 避免 DOM 重复
|
||||
clearMessagesDOM();
|
||||
renderMessages();
|
||||
// ── 保存 Plan Mode 最终进度到会话(供下一轮 Loop 注入)──
|
||||
const lastPlanStatus = state.get<string>('_lastPlanStatus', '');
|
||||
@@ -1135,26 +1135,10 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
|
||||
const hasAttachments = pendingImages.length > 0 || hasVideos || userFiles.length > 0;
|
||||
|
||||
if (hasAttachments) {
|
||||
// 聊天卡片显示用的简短描述
|
||||
const displayParts: string[] = [];
|
||||
if (text) displayParts.push(text);
|
||||
if (pendingVideoMeta && pendingVideoFrames.length > 0) {
|
||||
displayParts.push(`[视频: ${pendingVideoMeta.fileName}, ${pendingVideoFrames.length}帧, 1fps]`);
|
||||
}
|
||||
for (const v of completedVideos) {
|
||||
displayParts.push(`[视频: ${v.fileName}, ${v.frames.length}帧, 1fps]`);
|
||||
}
|
||||
if (pendingImages.length === 1) {
|
||||
displayParts.push(`[图片: ${pendingImages[0].name}]`);
|
||||
} else if (pendingImages.length > 1) {
|
||||
displayParts.push(`[${pendingImages.length} 张图片]`);
|
||||
}
|
||||
for (const f of userFiles) {
|
||||
displayParts.push(`[文件: ${f.name}]`);
|
||||
}
|
||||
const displayContent = displayParts.join('\n');
|
||||
// ── 聊天卡片:只显示用户自己的文字 + 附件视觉预览(缩略图/文件卡片/视频帧),不含代码生成的文本标记 ──
|
||||
const displayContent = text || '';
|
||||
|
||||
// Ollama API 用的完整描述(文字 + 文件 + 视频帧序列 + 图片提示)
|
||||
// ── Ollama API 用:完整描述(文字 + 文件内容 + 视频帧序列 + 图片提示)──
|
||||
const apiParts: string[] = [];
|
||||
if (text) apiParts.push(text);
|
||||
if (userFiles.length > 0) {
|
||||
@@ -1164,9 +1148,9 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
|
||||
logInfo('📄 文件内容已注入', `${fileParts.length} 段, 共 ${fileContents.reduce((s, f) => s + f.content.length, 0)} 字符`);
|
||||
}
|
||||
if (pendingImages.length === 1) {
|
||||
apiParts.push(`[已上传图片: ${pendingImages[0].name} — 此图片已随消息提供,你可以直接分析,无需去磁盘查找]`);
|
||||
apiParts.push(`[已上传图片: ${pendingImages[0].name}]`);
|
||||
} else if (pendingImages.length > 1) {
|
||||
apiParts.push(`[已上传 ${pendingImages.length} 张图片: ${pendingImages.map(img => img.name).join(', ')} — 这些图片已随消息提供,你可以直接分析,无需去磁盘查找]`);
|
||||
apiParts.push(`[已上传 ${pendingImages.length} 张图片: ${pendingImages.map(img => img.name).join(', ')}]`);
|
||||
}
|
||||
let allVids: Array<{ name: string; count: number; dur: number; frames: Array<{ timestampSeconds: number; name: string; base64: string }> }> = [];
|
||||
if (hasVideos) {
|
||||
@@ -1190,6 +1174,7 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
|
||||
role: 'user',
|
||||
content: displayContent,
|
||||
images: [...pendingImages.map(img => img.base64)],
|
||||
_apiContent: apiContentForModel, // 给模型的完整内容,不显示给用户
|
||||
timestamp: now
|
||||
};
|
||||
if (allVids.length > 0) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="header-left">
|
||||
<span class="logo">🦙</span>
|
||||
<span class="app-title">Metona Ollama</span>
|
||||
<span class="app-version">v0.14.2</span>
|
||||
<span class="app-version">v0.14.3</span>
|
||||
<button class="icon-btn help-btn" id="btnHelp" title="使用帮助">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
|
||||
|
||||
Vendored
+2
@@ -122,6 +122,8 @@ export interface ChatMessage {
|
||||
compressed?: boolean;
|
||||
/** 实际发送给模型的完整系统提示词(调试用) */
|
||||
_systemPrompt?: string;
|
||||
/** 实际发送给模型的用户消息内容(含文件/图片/视频帧描述,不显示给用户) */
|
||||
_apiContent?: string;
|
||||
}
|
||||
|
||||
export interface ChatSession {
|
||||
|
||||
Reference in New Issue
Block a user