diff --git a/README.md b/README.md
index dc84d25..0991fce 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
-
+
@@ -34,7 +34,7 @@
| | 功能 | 说明 |
|:---:|:---|:---|
-| 🤖 | **ReAct Agent Loop** | Thought → Action → Observation → Reflection 完整循环,最大 85 轮(可配置),自动重试 2 次,工具去重,并行/链式执行 |
+| 🤖 | **ReAct Agent Loop** | 始终开启的唯一对话模式。Thought → Action → Observation → Reflection 完整循环,最大 85 轮(可配置),自动重试 2 次,工具去重,并行/链式执行 |
| 🔧 | **38 个内置工具** | 文件系统 · 命令执行 · 联网搜索 · 浏览器控制 · Git · 记忆 · 技能 · 会话 · 子代理 |
| 🧠 | **智能记忆系统** | 三类记忆(fact / preference / rule),FTS5 全文搜索 + 向量语义搜索,写入前安全扫描,容量 500 条,90 天衰减 |
| 📋 | **自定义文件** | SOUL.md(人格,不可压缩)+ AGENT.md(行为准则)+ USER.md(用户画像),工作空间优先,内置默认 fallback |
@@ -231,7 +231,7 @@ npm start
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
```
-产出:`release/Metona Ollama Setup v0.10.0.exe`
+产出:`release/Metona Ollama Setup v0.10.1.exe`
## 🛠️ 常用命令
@@ -261,7 +261,7 @@ npm run dist # 构建 Windows 安装包
| | Feature | Description |
|:---:|:---|:---|
-| 🤖 | **ReAct Agent Loop** | Full Thought → Action → Observation → Reflection cycle, up to 85 iterations (configurable), auto-retry 2 times, tool dedup, parallel/chain execution |
+| 🤖 | **ReAct Agent Loop** | Always-on, only chat mode. Full Thought → Action → Observation → Reflection cycle, up to 85 iterations (configurable), auto-retry 2 times, tool dedup, parallel/chain execution |
| 🔧 | **38 Built-in Tools** | File system · Command · Web search · Browser · Git · Memory · Skills · Sessions · Sub-agent |
| 🧠 | **Smart Memory System** | Three types (fact / preference / rule), FTS5 + vector semantic search, pre-write security scan, 500 capacity, 90-day decay |
| 📋 | **Custom Files** | SOUL.md (persona, never compressed) + AGENT.md (behavior rules) + USER.md (user profile), workspace-first with built-in defaults |
@@ -454,7 +454,7 @@ npm start
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
```
-Output: `release/Metona Ollama Setup v0.10.0.exe`
+Output: `release/Metona Ollama Setup v0.10.1.exe`
## 🛠️ Common Commands
diff --git a/docs/BUILD.md b/docs/BUILD.md
index a2b7a4b..c938fed 100644
--- a/docs/BUILD.md
+++ b/docs/BUILD.md
@@ -91,7 +91,7 @@ npm run dist # NSIS 安装包
| 文件 | 说明 |
|------|------|
-| `release/Metona Ollama Setup v0.10.0.exe` | NSIS 安装包(可选目录、创建快捷方式) |
+| `release/Metona Ollama Setup v0.10.1.exe` | NSIS 安装包(可选目录、创建快捷方式) |
> 仅提供 NSIS 安装包。
@@ -103,7 +103,7 @@ npm run dist # NSIS 安装包
TOKEN="your_access_token"
curl -X POST "https://gitee.com/api/v5/repos/thzxx/metona-ollama-desktop/releases?access_token=$TOKEN" \
-H "Content-Type: application/json" \
- -d '{"tag_name":"v0.10.0","name":"v0.10.0","body":"Release notes","target_commitish":"master"}'
+ -d '{"tag_name":"v0.10.1","name":"v0.10.1","body":"Release notes","target_commitish":"master"}'
```
### 上传附件
@@ -112,7 +112,7 @@ curl -X POST "https://gitee.com/api/v5/repos/thzxx/metona-ollama-desktop/release
TOKEN="your_access_token"
RELEASE_ID=""
curl -X POST "https://gitee.com/api/v5/repos/thzxx/metona-ollama-desktop/releases/$RELEASE_ID/attach_files?access_token=$TOKEN" \
- -H "Content-Type: multipart/form-data" -F "file=@release/Metona Ollama Setup v0.10.0.exe"
+ -H "Content-Type: multipart/form-data" -F "file=@release/Metona Ollama Setup v0.10.1.exe"
```
## 故障排查
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
index 8ca45fc..1e12e78 100644
--- a/docs/DEVELOPMENT.md
+++ b/docs/DEVELOPMENT.md
@@ -1,6 +1,6 @@
# Metona Ollama Desktop — 开发规范
-> 版本: v0.10.0 | 更新: 2026-06-05 | 维护: 项目团队
+> 版本: v0.10.1 | 更新: 2026-06-05 | 维护: 项目团队
---
diff --git a/package-lock.json b/package-lock.json
index bee77d5..dd5edbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "metona-ollama-desktop",
- "version": "0.10.0",
+ "version": "0.10.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "metona-ollama-desktop",
- "version": "0.10.0",
+ "version": "0.10.1",
"license": "MIT",
"dependencies": {
"sql.js": "^1.11.0"
diff --git a/package.json b/package.json
index 08fb95a..2dd85b5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "metona-ollama-desktop",
- "version": "0.10.0",
+ "version": "0.10.1",
"description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端",
"main": "dist/main/main.js",
"author": "thzxx",
@@ -48,7 +48,7 @@
"requestedExecutionLevel": "asInvoker"
},
"nsis": {
- "artifactName": "Metona Ollama Setup v0.10.0.${ext}",
+ "artifactName": "Metona Ollama Setup v0.10.1.${ext}",
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
diff --git a/src/main/menu.ts b/src/main/menu.ts
index 9760ad0..aa9b795 100644
--- a/src/main/menu.ts
+++ b/src/main/menu.ts
@@ -101,7 +101,7 @@ export function createMenu(): void {
dialog.showMessageBox(mainWindow!, {
type: 'info',
title: '关于 Metona Ollama',
- message: 'Metona Ollama Desktop v0.10.0',
+ message: 'Metona Ollama Desktop v0.10.1',
detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama',
icon: getIconPath()
});
diff --git a/src/renderer/api/ollama.ts b/src/renderer/api/ollama.ts
index d0e45d7..d01762a 100644
--- a/src/renderer/api/ollama.ts
+++ b/src/renderer/api/ollama.ts
@@ -56,6 +56,7 @@ export class OllamaAPI {
model: params.model,
messages: params.messages,
stream: false,
+ keep_alive: '1h',
};
if (params.think !== undefined) body.think = params.think;
if (params.system) body.system = params.system;
@@ -117,7 +118,7 @@ export class OllamaAPI {
const chunk: OllamaStreamChunk = JSON.parse(line);
if (onChunk) onChunk(chunk);
if (chunk.done) {
- reader.cancel();
+ // 不调用 reader.cancel() — TCP RST 可能导致 Ollama 不执行 keep_alive
return;
}
} catch {
diff --git a/src/renderer/components/input-area.ts b/src/renderer/components/input-area.ts
index e062ad9..76c13d4 100644
--- a/src/renderer/components/input-area.ts
+++ b/src/renderer/components/input-area.ts
@@ -327,22 +327,19 @@ async function handleRetry(): Promise {
clearMessagesDOM();
renderMessages();
- // 重新触发 Agent Loop / 普通聊天
- const toolCallingEnabled = state.get('toolCallingEnabled', false);
+ // 重新触发 Agent Loop
const model = getSelectedModel() || currentSession.model;
// 新一轮开始:清理上一轮的工作空间状态
- if (toolCallingEnabled) {
- clearToolCardsExternal();
- clearTerminalExternal();
- }
+ clearToolCardsExternal();
+ clearTerminalExternal();
appendAssistantPlaceholder();
state.set(KEYS.IS_STREAMING, true);
updateSendButton(true);
- if (toolCallingEnabled) {
- const historyMessages = currentSession.messages
+ // 始终走 Agent Loop
+ const historyMessages = currentSession.messages
.filter(m => m.role === 'user' || m.role === 'assistant')
.slice(0, -1) // 不包含刚保留的最后一条 user 消息
.slice(-20)
@@ -441,16 +438,8 @@ async function handleRetry(): Promise {
}
});
} catch (err) {
- logError('重试失败', (err as Error).message);
- appendSystemMessage(`❌ 重试失败: ${(err as Error).message}`);
- }
- } else {
- // 普通聊天模式重试 - 直接调用 sendMessage
- chatInputEl.value = userMsg.content || '';
- state.set(KEYS.IS_STREAMING, false);
- updateSendButton(false);
- await sendMessage();
- return;
+ logError('重试失败', (err as Error).message);
+ appendSystemMessage(`❌ 重试失败: ${(err as Error).message}`);
}
state.set(KEYS.IS_STREAMING, false);
@@ -770,320 +759,9 @@ export async function sendMessage(): Promise {
const currentSession = state.get(KEYS.CURRENT_SESSION);
if (!currentSession) return;
- // ── Tool Calling Agent Loop 分支 ──
- const toolCallingEnabled = state.get('toolCallingEnabled', false);
- if (toolCallingEnabled) {
- // 检查模型是否支持 Tool Calling
- if (!isToolCallingSupported()) {
- appendSystemMessage('⚠️ 当前模型未声明支持 Tool Calling,Agent Loop 可能不稳定。建议使用 Qwen3、Llama 3.1+ 或 Mistral 等支持工具调用的模型。');
- }
- await sendMessageWithAgentLoop(text, currentSession, model);
- return;
- }
-
- // ── 原有普通聊天流程 ──
-
- const now = Date.now();
- const msgsToAdd: ChatMessage[] = [];
-
- const userFiles: ChatFile[] = pendingFiles.map(f => ({ name: f.name, language: f.language, size: f.size }));
-
- if (pendingImages.length > 0) {
- msgsToAdd.push({
- role: 'user',
- content: pendingImages.length === 1 ? `[上传了图片: ${pendingImages[0].name}]` : `[上传了 ${pendingImages.length} 张图片]`,
- images: pendingImages.map(img => img.base64),
- timestamp: now
- });
- }
-
- if (text || pendingFiles.length > 0) {
- const msg: ChatMessage = {
- role: 'user',
- content: text || '',
- timestamp: now
- };
- if (userFiles.length > 0) {
- msg.files = userFiles;
- msg._fileContents = pendingFiles.map(f => ({ language: f.language, content: f.content }));
- }
- msgsToAdd.push(msg);
- }
-
- const isFirstMsg = currentSession.messages.length === 0;
- state.update(KEYS.CURRENT_SESSION, (session: any) => ({
- ...session,
- ...(isFirstMsg && {
- title: truncate(text || (pendingFiles.length > 0 ? `[文件: ${pendingFiles.map(f => f.name).join(', ')}]` : '[图片消息]'), 30),
- model
- }),
- messages: [...session.messages, ...msgsToAdd],
- updatedAt: Date.now()
- }));
-
- const freshSession = state.get(KEYS.CURRENT_SESSION);
-
- enableAutoScroll();
- renderMessages();
- await saveCurrentSession();
-
- chatInputEl.value = '';
- pendingImages = [];
- pendingFiles = [];
- imagePreviewEl.style.display = 'none';
- imagePreviewEl.innerHTML = '';
- filePreviewEl.style.display = 'none';
- filePreviewEl.innerHTML = '';
- autoResizeTextarea();
-
- appendAssistantPlaceholder();
-
- state.set(KEYS.IS_STREAMING, true);
- updateSendButton(true);
-
- const api = state.get(KEYS.API)!;
- const abortController = new AbortController();
- state.set(KEYS.ABORT_CONTROLLER, abortController);
- const thinkMode = isThinkEnabled();
- const numCtx = state.get(KEYS.NUM_CTX, 24576);
-
- let assistantContent = '';
- let thinkContent = '';
- let finalStats: any = null;
- let modelName = '';
-
- try {
- const apiMessages = buildApiMessages(freshSession.messages);
- const temperature = state.get('temperature', 0.7);
-
- const chatParams: Record = {
- model,
- messages: apiMessages,
- stream: true,
- think: thinkMode,
- };
- if (numCtx) chatParams.options = { num_ctx: numCtx, temperature };
-
- // ── 扫描工作空间 SOUL.md ──
- let soulContent = '';
- let soulMdContent = '';
- const workspaceDir = getWorkspaceDirPath();
- if (workspaceDir) {
- try {
- const soulResult = await window.metonaDesktop?.workspace.readFile(
- workspaceDir.replace(/\/+$/, '') + '/SOUL.md'
- );
- if (soulResult?.success && soulResult.content) {
- soulMdContent = soulResult.content;
- }
- } catch { /* 工作空间 SOUL.md 不存在 */ }
- }
-
- // fallback:读取内置 SOUL.md
- if (!soulMdContent) {
- try {
- const resp = await fetch('./SOUL.md');
- if (resp.ok) {
- soulMdContent = await resp.text();
- }
- } catch { /* 内置 SOUL.md 也不可用 */ }
- }
-
- if (soulMdContent) {
- soulContent = `[SOUL.md] ${soulMdContent}`;
- }
-
- // ── 扫描工作空间 USER.md ──
- let userMdContent = '';
- if (workspaceDir) {
- try {
- const userResult = await window.metonaDesktop?.workspace.readFile(
- workspaceDir.replace(/\/+$/, '') + '/USER.md'
- );
- if (userResult?.success && userResult.content) {
- userMdContent = userResult.content;
- }
- } catch { /* 工作空间 USER.md 不存在 */ }
- }
- if (!userMdContent) {
- try {
- const resp = await fetch('./USER.md');
- if (resp.ok) {
- userMdContent = await resp.text();
- }
- } catch { /* 内置 USER.md 也不可用 */ }
- }
-
- // ── Agent 记忆注入 ──
- if (isMemoryEnabled()) {
- const userMessage = text || (msgsToAdd.find(m => m.role === 'user')?.content || '');
- if (userMessage) {
- const relevantMemories = searchMemories(userMessage, 6);
- if (relevantMemories.length > 0) {
- const memoryContext = buildMemoryContext(relevantMemories);
- const parts = [soulContent, userMdContent ? `[USER.md] ${userMdContent}` : '', memoryContext].filter(Boolean);
- chatParams.system = parts.join('\n\n');
- for (const m of relevantMemories) {
- await markMemoryUsed(m.id);
- }
- appendSystemMessage(`🧠 已注入 ${relevantMemories.length} 条相关记忆`, 'memory-status');
- }
- }
- }
- if (soulContent && !chatParams.system) {
- const parts = [soulContent, userMdContent ? `[USER.md] ${userMdContent}` : ''].filter(Boolean);
- chatParams.system = parts.join('\n\n');
- }
-
- // 存入 state 供 chat-area 渲染系统提示词卡片
- state.set('_lastSystemPrompt', chatParams.system || '');
-
- await api.chatStream(chatParams as any, (chunk: OllamaStreamChunk) => {
- if (chunk.message) {
- if (chunk.message.content) assistantContent += chunk.message.content;
- const think = chunk.message.thinking || chunk.message.reasoning_content;
- if (think && typeof think === 'string') thinkContent += think;
- }
- if (chunk.model) modelName = chunk.model;
- // 捕获任何包含统计的 chunk(不限于 done)
- if (chunk.eval_count || chunk.prompt_eval_count || chunk.total_duration) {
- finalStats = {
- eval_count: chunk.eval_count ?? finalStats?.eval_count,
- prompt_eval_count: chunk.prompt_eval_count ?? finalStats?.prompt_eval_count,
- total_duration: chunk.total_duration ?? finalStats?.total_duration,
- };
- }
- updateLastAssistantMessage(assistantContent, thinkContent || null, null, modelName || undefined);
- if (chunk.done) {
- // done chunk 优先使用其统计,保留之前的兜底
- finalStats = {
- eval_count: chunk.eval_count ?? finalStats?.eval_count,
- prompt_eval_count: chunk.prompt_eval_count ?? finalStats?.prompt_eval_count,
- total_duration: chunk.total_duration ?? finalStats?.total_duration,
- };
- }
- }, abortController);
-
- if (!assistantContent && !thinkContent) {
- appendSystemMessage('⚠️ 模型未返回任何内容,可能是上下文过长或模型不支持当前请求');
- logWarn('模型未返回任何内容');
- }
-
- logStream(`流式完成: ${assistantContent.length} 字符${finalStats?.eval_count ? `, ${finalStats.eval_count} tokens` : ''}`);
-
- const assistantMsg: ChatMessage = {
- role: 'assistant',
- content: assistantContent || '',
- timestamp: Date.now(),
- ...(modelName && { model: modelName }),
- ...(thinkContent && { think: thinkContent }),
- ...((finalStats || {}) as any)
- };
- state.update(KEYS.CURRENT_SESSION, (session: any) => ({
- ...session,
- messages: [...session.messages, assistantMsg],
- updatedAt: Date.now()
- }));
-
- if (finalStats) {
- updateLastAssistantMessage(assistantContent, thinkContent || null, finalStats, modelName || undefined, Date.now());
- } else {
- updateLastAssistantMessage(assistantContent, thinkContent || null, null, modelName || undefined, Date.now());
- }
-
- await saveCurrentSession();
-
- // ── 自动提取记忆(非阻塞)──
- if (isMemoryEnabled() && freshSession.messages.length >= 10) {
- const currentSession2 = state.get(KEYS.CURRENT_SESSION);
- if (currentSession2) {
- extractMemoriesFromConversation(
- currentSession2.messages.map(m => ({ role: m.role, content: m.content })),
- currentSession2.title
- ).then(count => {
- if (count > 0) {
- logInfo(`自动提取了 ${count} 条记忆`);
- }
- }).catch(err => logError('记忆提取失败', (err as Error).message));
- }
- }
- } catch (err) {
- if ((err as Error).name === 'AbortError') {
- const placeholder = document.querySelector('#messagesContainer .message.assistant.loading') as HTMLElement;
- const loadingDots = placeholder?.querySelector('.loading-dots');
- const loadingText = placeholder?.querySelector('.loading-text');
- if (loadingDots) loadingDots.remove();
- if (loadingText) loadingText.remove();
- placeholder?.classList.remove('loading');
-
- const contentDiv = placeholder?.querySelector('.msg-content');
- const partialMsg: ChatMessage = {
- role: 'assistant',
- content: assistantContent,
- timestamp: Date.now(),
- ...(modelName && { model: modelName }),
- ...(thinkContent && { think: thinkContent }),
- stopped: true
- };
- state.update(KEYS.CURRENT_SESSION, (session: any) => ({
- ...session,
- messages: [...session.messages, partialMsg],
- updatedAt: Date.now()
- }));
-
- if (contentDiv) {
- let html = assistantContent ? safeMarkdown(assistantContent) : '';
- html += '[已停止]
';
- contentDiv.innerHTML = html;
- }
- appendSystemMessage('⏹ 已停止生成');
- await saveCurrentSession();
- state.set(KEYS.IS_STREAMING, false);
- updateSendButton(false);
- state.set(KEYS.ABORT_CONTROLLER, null);
- return;
- }
-
- const placeholder = document.querySelector('#messagesContainer .message.assistant.loading') as HTMLElement;
- const loadingDots = placeholder?.querySelector('.loading-dots');
- const loadingText = placeholder?.querySelector('.loading-text');
- if (loadingDots) loadingDots.remove();
- if (loadingText) loadingText.remove();
- placeholder?.classList.remove('loading');
-
- const contentDiv = placeholder?.querySelector('.msg-content');
-
- if (assistantContent && contentDiv) {
- state.update(KEYS.CURRENT_SESSION, (session: any) => ({
- ...session,
- messages: [...session.messages, { role: 'assistant', content: assistantContent + '\n\n`[已中断]`', timestamp: Date.now() } as ChatMessage],
- updatedAt: Date.now()
- }));
- contentDiv.innerHTML = safeMarkdown(assistantContent) + '[已中断]
';
- await saveCurrentSession();
- } else {
- if (placeholder) placeholder.remove();
- }
-
- let errMsg = `❌ 错误: ${(err as Error).message}`;
- if ((err as Error).message.includes('Failed to fetch') || (err as Error).message.includes('NetworkError')) {
- errMsg = '❌ 连接失败。请检查:\n1. Ollama 是否正在运行\n2. 地址是否正确\n3. 是否设置了 OLLAMA_ORIGINS="*"';
- logError('连接失败', 'Ollama 服务不可达');
- } else if ((err as Error).message.includes('400')) {
- errMsg = '❌ 请求参数错误,可能是上下文过长';
- logError('请求参数错误 (400)', (err as Error).message);
- } else if ((err as Error).message.includes('500')) {
- errMsg = '❌ Ollama 服务器错误,请检查 Ollama 日志';
- logError('Ollama 服务器错误 (500)', (err as Error).message);
- } else {
- logError('对话错误', (err as Error).message);
- }
- appendSystemMessage(errMsg);
- } finally {
- state.set(KEYS.IS_STREAMING, false);
- updateSendButton(false);
- state.set(KEYS.ABORT_CONTROLLER, null);
- }
+ // 所有消息统一走 Agent Loop
+ await sendMessageWithAgentLoop(text, currentSession, model);
+ return;
}
/** 更新当前会话消息中最近一个 'running' 状态的同名工具记录 */
diff --git a/src/renderer/components/tools-modal.ts b/src/renderer/components/tools-modal.ts
index a5979c6..7e4045a 100644
--- a/src/renderer/components/tools-modal.ts
+++ b/src/renderer/components/tools-modal.ts
@@ -1,6 +1,6 @@
/**
* ToolsModal - 工具面板模态框
- * 展示所有可用工具的详细信息,管理 Tool Calling 开关
+ * 展示所有可用工具的详细信息。Tool Calling 始终开启,不可关闭。
*/
import { state, KEYS } from '../state/state.js';
@@ -21,27 +21,14 @@ export function initToolsModal(): void {
if (e.target === modalEl) closeToolsModal();
});
- // Tool Calling 主开关
+ // Tool Calling 始终开启,不可关闭
const toggleToolCalling = modalEl.querySelector('#toggleToolCalling') as HTMLInputElement;
if (toggleToolCalling) {
- toggleToolCalling.addEventListener('change', async () => {
- const db = state.get(KEYS.DB);
- state.set('toolCallingEnabled', toggleToolCalling.checked);
- if (db) await db.saveSetting('toolCallingEnabled', toggleToolCalling.checked);
- if (toggleToolCalling.checked) {
- const modelSupportsTools = state.get('modelSupportsTools', false);
- if (!modelSupportsTools) {
- showToast('⚠️ 当前模型可能不支持 Tool Calling,建议使用 Qwen3、Llama 3.1+ 等模型', 'warning', 5000);
- logWarn('Tool Calling 已开启(模型不支持)');
- } else {
- showToast('工具调用已开启', 'info');
- logInfo('Tool Calling 已开启');
- }
- } else {
- showToast('工具调用已关闭', 'info');
- logInfo('Tool Calling 已关闭');
- }
- });
+ toggleToolCalling.checked = true;
+ toggleToolCalling.disabled = true;
+ state.set('toolCallingEnabled', true);
+ const db = state.get(KEYS.DB);
+ if (db) db.saveSetting('toolCallingEnabled', true);
}
// run_command 模式下拉框
@@ -76,10 +63,12 @@ function updateRunCommandBadge(mode: string): void {
}
export function openToolsModal(): void {
- // 同步开关状态
- const toolCallingEnabled = state.get('toolCallingEnabled', false);
+ // 同步开关状态 — 始终开启
const toggleTC = modalEl.querySelector('#toggleToolCalling') as HTMLInputElement;
- if (toggleTC) toggleTC.checked = toolCallingEnabled;
+ if (toggleTC) {
+ toggleTC.checked = true;
+ toggleTC.disabled = true;
+ }
const runCommandMode = state.get('runCommandMode', 'confirm');
const selectMode = modalEl.querySelector('#selectRunCommandMode') as HTMLSelectElement;
diff --git a/src/renderer/index.html b/src/renderer/index.html
index 2a9acc6..2049f90 100644
--- a/src/renderer/index.html
+++ b/src/renderer/index.html
@@ -28,7 +28,7 @@