refactor: 移除内置USER.md — 仅从工作空间读取,不存在则不注入
This commit is contained in:
+3
-4
@@ -61,8 +61,7 @@ src/
|
|||||||
│ ├── index.html # 入口 HTML(三栏布局 + 全部模态框)
|
│ ├── index.html # 入口 HTML(三栏布局 + 全部模态框)
|
||||||
│ ├── public/
|
│ ├── public/
|
||||||
│ │ ├── AGENT.md # 内置 Agent 行为准则文档
|
│ │ ├── AGENT.md # 内置 Agent 行为准则文档
|
||||||
│ │ ├── SOUL.md # 内置 AI 人格定义
|
│ │ ├── SOUL.md # AI 人格定义(内置 fallback)
|
||||||
│ │ └── USER.md # 内置用户画像模板
|
|
||||||
│ ├── api/
|
│ ├── api/
|
||||||
│ │ └── ollama.ts # Ollama REST API 客户端(流式 + 模型管理)
|
│ │ └── ollama.ts # Ollama REST API 客户端(流式 + 模型管理)
|
||||||
│ ├── components/ # 15 个 UI 组件(原生 DOM)
|
│ ├── components/ # 15 个 UI 组件(原生 DOM)
|
||||||
@@ -195,7 +194,7 @@ INIT → THINKING → PARSING → EXECUTING → OBSERVING → REFLECTING → (CO
|
|||||||
|
|
||||||
| 状态 | 处理器 | 职责 |
|
| 状态 | 处理器 | 职责 |
|
||||||
|------|--------|------|
|
|------|--------|------|
|
||||||
| INIT | `handleInit()` | 构建系统提示词、加载 SOUL/AGENT/USER.md、记忆检索、上下文压缩检测 |
|
| INIT | `handleInit()` | 构建系统提示词、加载 SOUL/AGENT/USER.md(USER.md 仅工作空间)、记忆检索、上下文压缩检测 |
|
||||||
| THINKING | `handleThinking()` | 调用 Ollama 流式 API、工具缓存检查、任务感知注入、Token 预算警告 |
|
| THINKING | `handleThinking()` | 调用 Ollama 流式 API、工具缓存检查、任务感知注入、Token 预算警告 |
|
||||||
| PARSING | `handleParsing()` | 解析模型输出、提取 tool_calls、文本兜底解析 |
|
| PARSING | `handleParsing()` | 解析模型输出、提取 tool_calls、文本兜底解析 |
|
||||||
| EXECUTING | `handleExecuting()` | 按批次并行执行工具、重试(最多 2 次)、去重检测、Hook 触发 |
|
| EXECUTING | `handleExecuting()` | 按批次并行执行工具、重试(最多 2 次)、去重检测、Hook 触发 |
|
||||||
@@ -285,7 +284,7 @@ Hook 异步并行执行,失败不阻塞主流程。可动态注册/移除。
|
|||||||
- **安全豁免**:工作空间目录通过 `addBlocklistExemptions()` 注册,不受路径黑名单限制
|
- **安全豁免**:工作空间目录通过 `addBlocklistExemptions()` 注册,不受路径黑名单限制
|
||||||
- 终端:命令无超时限制,实时流式输出,支持终止
|
- 终端:命令无超时限制,实时流式输出,支持终止
|
||||||
- 文件浏览:限工作空间内,支持上级导航、文件预览
|
- 文件浏览:限工作空间内,支持上级导航、文件预览
|
||||||
- 自定义文件:`SOUL.md`(人格,不可压缩)、`AGENT.md`(行为准则)、`USER.md`(用户画像)
|
- 自定义文件:`SOUL.md`(人格,不可压缩)、`AGENT.md`(行为准则)、`USER.md`(用户画像,仅工作空间)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -446,7 +446,7 @@
|
|||||||
<div class="help-section"><h4>🤖 Agent Loop 增强</h4><ul><li><strong>🎬 视频上传</strong>:支持上传 .mp4/.avi/.mov/.mkv/.webm 等视频(≤10MB),自动 1fps 提取帧序列(带时间戳),多模态模型原生理解视频时序关系</li><li><strong>8 状态机</strong>:INIT→THINKING→PARSING→EXECUTING→OBSERVING→REFLECTING→COMPRESSING→TERMINATED,每个状态独立的中止检查和处理</li><li><strong>智能上下文压缩</strong>:滑动窗口 + LLM结构化JSON摘要,超过50%上下文窗口自动触发</li><li><strong>流式调用超时保护</strong>:可配置超时(默认300s),Ollama 卡死不再永久阻塞</li><li><strong>HTTP/MCP 超时可配</strong>:设置面板可分别调整 HTTP(默认30s)和 MCP(默认60s)超时</li><li><strong>Final Answer 智能检测</strong>:多模式匹配(Final Answer/最终答案/最终回答/总结),避免漏检或误触</li><li><strong>Token 感知迭代预算</strong>:上下文使用率>80%时自动缩减剩余轮次到3轮</li><li><strong>工具缓存 TTL</strong>:搜索5分钟/网页10分钟/文件30分钟,过期自动刷新</li><li><strong>自动子任务拆解</strong>:检测"同时/分别/以及"等并行关键词,自动 spawn 子代理并行处理</li><li><strong>旧工具结果自动截断</strong>:超过10轮的工具结果自动截断到500字符,控制上下文膨胀</li></ul></div>
|
<div class="help-section"><h4>🤖 Agent Loop 增强</h4><ul><li><strong>🎬 视频上传</strong>:支持上传 .mp4/.avi/.mov/.mkv/.webm 等视频(≤10MB),自动 1fps 提取帧序列(带时间戳),多模态模型原生理解视频时序关系</li><li><strong>8 状态机</strong>:INIT→THINKING→PARSING→EXECUTING→OBSERVING→REFLECTING→COMPRESSING→TERMINATED,每个状态独立的中止检查和处理</li><li><strong>智能上下文压缩</strong>:滑动窗口 + LLM结构化JSON摘要,超过50%上下文窗口自动触发</li><li><strong>流式调用超时保护</strong>:可配置超时(默认300s),Ollama 卡死不再永久阻塞</li><li><strong>HTTP/MCP 超时可配</strong>:设置面板可分别调整 HTTP(默认30s)和 MCP(默认60s)超时</li><li><strong>Final Answer 智能检测</strong>:多模式匹配(Final Answer/最终答案/最终回答/总结),避免漏检或误触</li><li><strong>Token 感知迭代预算</strong>:上下文使用率>80%时自动缩减剩余轮次到3轮</li><li><strong>工具缓存 TTL</strong>:搜索5分钟/网页10分钟/文件30分钟,过期自动刷新</li><li><strong>自动子任务拆解</strong>:检测"同时/分别/以及"等并行关键词,自动 spawn 子代理并行处理</li><li><strong>旧工具结果自动截断</strong>:超过10轮的工具结果自动截断到500字符,控制上下文膨胀</li></ul></div>
|
||||||
<div class="help-section"><h4>🔌 MCP(Model Context Protocol)</h4><ul><li>支持连接外部 MCP Server,动态扩展工具能力</li><li>设置面板可添加/启用/禁用/删除 MCP 服务器</li><li>MCP 工具以 <code>mcp_{server}__{tool}</code> 前缀注册,与内置工具统一调度</li><li>启动时自动连接已启用的 MCP 服务器</li></ul></div>
|
<div class="help-section"><h4>🔌 MCP(Model Context Protocol)</h4><ul><li>支持连接外部 MCP Server,动态扩展工具能力</li><li>设置面板可添加/启用/禁用/删除 MCP 服务器</li><li>MCP 工具以 <code>mcp_{server}__{tool}</code> 前缀注册,与内置工具统一调度</li><li>启动时自动连接已启用的 MCP 服务器</li></ul></div>
|
||||||
<div class="help-section"><h4>🔍 SearXNG 元搜索引擎</h4><ul><li>点击顶部 🔍 按钮打开配置面板,可接入自部署的 SearXNG 实例</li><li><strong>JSON 模式</strong>:调用 SearXNG JSON API,聚合 70+ 引擎结果,结构化解析</li><li><strong>HTML 模式</strong>:获取原始搜索结果页面,交由 AI 自行分析提取信息</li><li>支持认证 Key(HTTP Header Authorization),保护私有实例</li><li>启用后替代内置四引擎方案;关闭即回退,无缝切换</li><li>所有参数(引擎、语言、安全搜索、时间范围等)均可独立配置</li></ul></div>
|
<div class="help-section"><h4>🔍 SearXNG 元搜索引擎</h4><ul><li>点击顶部 🔍 按钮打开配置面板,可接入自部署的 SearXNG 实例</li><li><strong>JSON 模式</strong>:调用 SearXNG JSON API,聚合 70+ 引擎结果,结构化解析</li><li><strong>HTML 模式</strong>:获取原始搜索结果页面,交由 AI 自行分析提取信息</li><li>支持认证 Key(HTTP Header Authorization),保护私有实例</li><li>启用后替代内置四引擎方案;关闭即回退,无缝切换</li><li>所有参数(引擎、语言、安全搜索、时间范围等)均可独立配置</li></ul></div>
|
||||||
<div class="help-section"><h4>📋 自定义文件(SOUL.md / AGENT.md / USER.md)</h4><ul><li>在工作空间目录创建以下文件即可自定义 AI 行为,修改后下一轮对话立即生效</li><li><strong>SOUL.md</strong> — AI 身份、性格、行为准则(<strong>永远不可被压缩</strong>,注入为最高优先级系统提示词)</li><li><strong>AGENT.md</strong> — 工具调用规则、链式调用模式、核心约束(内置精简默认版,可通过工作空间覆盖)</li><li><strong>USER.md</strong> — 用户画像:技术栈、偏好、习惯等个人信息,AI 在对话中自动参考</li><li>可在 AI 回复顶部的 📋 系统提示词卡片中查看实际注入的完整上下文</li><li>删除工作空间中的文件即可恢复为内置默认版本</li></ul></div>
|
<div class="help-section"><h4>📋 自定义文件(SOUL.md / AGENT.md / USER.md)</h4><ul><li>在工作空间目录创建以下文件即可自定义 AI 行为,修改后下一轮对话立即生效</li><li><strong>SOUL.md</strong> — AI 身份、性格、行为准则(<strong>永远不可被压缩</strong>,注入为最高优先级系统提示词)</li><li><strong>AGENT.md</strong> — 工具调用规则、链式调用模式、核心约束(内置精简默认版,可通过工作空间覆盖)</li><li><strong>USER.md</strong> — 用户画像:技术栈、偏好、习惯等个人信息,AI 在对话中自动参考(仅工作空间,无内置默认)</li><li>可在 AI 回复顶部的 📋 系统提示词卡片中查看实际注入的完整上下文</li><li>SOUL.md / AGENT.md 删除工作空间中文件可恢复为内置默认版本;USER.md 无内置版,不存在则不注入</li></ul></div>
|
||||||
<div class="help-section"><h4>📊 Token 实时监控</h4><ul><li>点击顶部 📊 按钮打开 Token 监控仪表盘</li><li><strong>全局统计</strong> — 跨会话累计 Token 消耗,柱状图按会话展示趋势</li><li><strong>当前会话</strong> — 实时显示本轮对话的 Token 消耗,按轮次展示明细</li><li>每 2 秒自动刷新数据,支持输入/输出分色显示</li></ul></div>
|
<div class="help-section"><h4>📊 Token 实时监控</h4><ul><li>点击顶部 📊 按钮打开 Token 监控仪表盘</li><li><strong>全局统计</strong> — 跨会话累计 Token 消耗,柱状图按会话展示趋势</li><li><strong>当前会话</strong> — 实时显示本轮对话的 Token 消耗,按轮次展示明细</li><li>每 2 秒自动刷新数据,支持输入/输出分色显示</li></ul></div>
|
||||||
<div class="help-section"><h4>🖥️ 布局说明</h4><ul><li><strong>左侧面板</strong> — 执行日志,实时显示应用运行日志(连接、模型加载、工具调用等)</li><li><strong>中间区域</strong> — 聊天消息,顶部 Header + 模型栏,底部输入框</li><li><strong>右侧面板</strong> — 工作空间(常驻显示),包含 3 个页签:<ul><li><strong>💻 命令行 Tab</strong> — 终端界面,实时流式输出,支持长时间运行(无超时),单一终端进程</li><li><strong>🔧 工具 Tab</strong> — 展示本轮对话的工具调用卡片,含状态统计(总数 ✅ 成功 ❌ 失败),AI 执行命令时自动切到此页签</li><li><strong>📁 文件 Tab</strong> — 浏览工作空间目录,点击文件预览内容(带行号),支持上级目录导航</li></ul></li><li>工作空间目录可在设置中修改</li></ul></div>
|
<div class="help-section"><h4>🖥️ 布局说明</h4><ul><li><strong>左侧面板</strong> — 执行日志,实时显示应用运行日志(连接、模型加载、工具调用等)</li><li><strong>中间区域</strong> — 聊天消息,顶部 Header + 模型栏,底部输入框</li><li><strong>右侧面板</strong> — 工作空间(常驻显示),包含 3 个页签:<ul><li><strong>💻 命令行 Tab</strong> — 终端界面,实时流式输出,支持长时间运行(无超时),单一终端进程</li><li><strong>🔧 工具 Tab</strong> — 展示本轮对话的工具调用卡片,含状态统计(总数 ✅ 成功 ❌ 失败),AI 执行命令时自动切到此页签</li><li><strong>📁 文件 Tab</strong> — 浏览工作空间目录,点击文件预览内容(带行号),支持上级目录导航</li></ul></li><li>工作空间目录可在设置中修改</li></ul></div>
|
||||||
<div class="help-section"><h4>🕐 历史记录</h4><ul><li>所有会话自动保存到本地 SQLite</li><li>点击顶部 🕐 按钮查看、搜索、恢复历史会话</li><li>支持导出 JSON / <code>.metona</code> 加密备份</li></ul></div>
|
<div class="help-section"><h4>🕐 历史记录</h4><ul><li>所有会话自动保存到本地 SQLite</li><li>点击顶部 🕐 按钮查看、搜索、恢复历史会话</li><li>支持导出 JSON / <code>.metona</code> 加密备份</li></ul></div>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# USER.md
|
|
||||||
|
|
||||||
> 💡 在此文件中描述你自己:技术栈、偏好、习惯等。AI 会在对话中自动参考这些信息。
|
|
||||||
@@ -502,28 +502,19 @@ async function handleInit(
|
|||||||
systemPromptParts.push(`[AGENT.md] ${truncated}`);
|
systemPromptParts.push(`[AGENT.md] ${truncated}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 扫描工作空间 USER.md ──
|
// ── 扫描工作空间 USER.md(仅工作空间,无内置 fallback)──
|
||||||
let userMdContent = '';
|
|
||||||
if (workspaceDir) {
|
if (workspaceDir) {
|
||||||
try {
|
try {
|
||||||
const userResult = await window.metonaDesktop?.workspace.readFile(
|
const userResult = await window.metonaDesktop?.workspace.readFile(
|
||||||
workspaceDir.replace(/[\\/]+$/, '') + '/USER.md'
|
workspaceDir.replace(/[\\/]+$/, '') + '/USER.md'
|
||||||
);
|
);
|
||||||
if (userResult?.success && userResult.content) {
|
if (userResult?.success && userResult.content) {
|
||||||
userMdContent = userResult.content;
|
const userMdContent = userResult.content;
|
||||||
|
systemPromptParts.push(`[USER.md] ${userMdContent}`);
|
||||||
logInfo('USER.md 已从工作空间加载', `${userResult.lines || 0} 行`);
|
logInfo('USER.md 已从工作空间加载', `${userResult.lines || 0} 行`);
|
||||||
}
|
}
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
if (!userMdContent) {
|
|
||||||
try {
|
|
||||||
const resp = await fetch('./USER.md');
|
|
||||||
if (resp.ok) { userMdContent = await resp.text(); logInfo('USER.md 已从内置加载', `${userMdContent.length} 字符`); }
|
|
||||||
} catch { /* ignore */ }
|
|
||||||
}
|
|
||||||
if (userMdContent) {
|
|
||||||
systemPromptParts.push(`[USER.md] ${userMdContent}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注入记忆上下文
|
// 注入记忆上下文
|
||||||
if (userContent) {
|
if (userContent) {
|
||||||
|
|||||||
Reference in New Issue
Block a user