- AI 应用
- 人工智能
- AI Agent
- 本地部署
- 前端
- 后端
- 工作流自动化
【免费下载链接】ekko-studio
Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.
本篇技术指南聚焦 Hermes Studio(Ekko Studio)为内置 Ekko Agent 新增的独立配置面:它复用了与 Hermes 配置一致的壳层模式(独立路由、专属可折叠/移动端侧边栏、Profile 感知数据与明确的返回路径),首个发布版本覆盖结构化长期记忆(Memory)、Profile 级技能(Skills)与 Profile 级 MCP 服务器配置(MCP)三项能力。读完本文,你将掌握/ekko/*三条路由的前端接线方式、/api/ekko/*全部 HTTP 接口的请求语义与参数约束,以及这些接口如何通过服务层适配ekko-agent包底层的记忆仓库、技能管理器与配置存储。
设计目标:让内置 Agent 拥有自己的配置面
按照 ekko-agent-configuration-pages.md 的规划,Ekko Agent 配置面遵循与 Hermes 配置完全一致的壳层模式:
- 独立路由:不走 Studio 通用侧边栏,也不走 Hermes 配置侧边栏;
- 专属侧边栏:桌面端支持折叠态,移动端支持背板(backdrop)导航与共享的移动端打开事件;
- Profile 感知:每个页面使用共享 API 客户端已挂载的当前 Profile,数据天然按 Profile 隔离;
- 清晰回退路径:侧边栏底部提供返回 Agent Manager 的动作。
配置面承载三个 Ekko 自有的能力域:结构化长期记忆、Profile 本地技能、Profile 本地 MCP 服务器配置。这一设计在客户端代码中有明确落点:App.vue 根据路由元信息ekkoConfig决定挂载EkkoConfigSidebar而非 Studio 侧边栏或 Hermes 配置侧边栏;路由注册见 router/index.ts 中meta: { ekkoConfig: true, requiresSuperAdmin: true }的四条记录(含/ekko/settings)。
导航与壳层:路由、侧边栏与返回路径
路由清单
/ekko/memory -> ekko.memory /ekko/skills -> ekko.skills /ekko/mcp -> ekko.mcp /ekko/settings -> ekko.settings # 额外的设置页,同样使用 ekkoConfig 壳层在 router/index.ts 中,/ekko/memory、/ekko/skills、/ekko/mcp、/ekko/settings均通过() => import('@/views/ekko/...View.vue')懒加载对应视图,并统一标记ekkoConfig: true与requiresSuperAdmin: true,说明整个配置面仅对超级管理员可见。
侧边栏实现
EkkoConfigSidebar.vue 与 Hermes 配置侧边栏共享同一套布局样式表agent-config-sidebar.layout("ekko")(对应 Hermes 侧用"hermes"),因此天然继承:
- 桌面端折叠状态(
collapsed类与appStore.sidebarCollapsed联动); - 移动端背板(
ekko-config-backdrop点击关闭); - 共享的移动端打开事件
hermes:open-page-sidebar; - 自定义背景与桌面拖拽区域。
侧边栏包含 Memory、Skills、MCP(以及 Settings)四个导航项,底部提供返回 Agent Manager(hermes.agentManager)的动作,但没有 Hermes 的 memory/skills/mcp 导航项——从 ekko-config-navigation.test.ts 的断言可以看到,测试明确要求侧边栏包含name: 'hermes.agentManager'且不包含hermes.memory、hermes.skills、hermes.mcp,以证明 Ekko 侧边栏是独立于 Hermes 的。
入口方面,/studio/agents中的 Ekko 卡片点击后router.push({ name: 'ekko.settings' })(或按文档所述打开 Ekko 配置面),进入该壳层。
服务端归属与 API 分层
所有新增 HTTP 操作归属packages/server/src/modules/ekko,统一使用/api/ekko/*前缀。分层遵循“路由薄、控制器校验、服务层适配”的原则:
- 路由层(routes/memory.ts、routes/skills.ts、routes/mcp.ts):只声明 HTTP 方法与路径,并统一挂
requireSuperAdmin鉴权; - 控制器层(controllers/memory.ts、controllers/mcp.ts 等):解析请求体、做入参校验、把 Profile 从
ctx.state.profile取出; - 服务层(services/memory.ts、services/skills.ts、services/mcp.ts):适配
ekko-agent包公开的管理器与配置 API。
Profile 解析统一为String(ctx.state?.profile?.name || 'default').trim() || 'default',未显式指定时回退到default。
Memory:Profile 隔离 + 修订号保护
GET /api/ekko/memory PATCH /api/ekko/memory/:id DELETE /api/ekko/memory/:id列表查询(GET /api/ekko/memory)支持:
| 参数 | 说明 | 约束 |
|---|---|---|
query | 文本搜索 | 透传为memory.list的queryText |
status | 状态过滤 | 必须属于MEMORY_NODE_STATUSES,否则 400 |
limit | 分页大小 | 服务层收敛到[1, 500],默认 100 |
offset | 分页偏移 | 最小 0 |
更新(PATCH /api/ekko/memory/:id):
expectedRevision必须是正整数(Number.isInteger && >= 1),否则 400;- 至少提供
title(string)、content(string)、tags(string 数组)之一; - 服务层先
memory.get(id, { profileId })读当前节点(不存在抛Memory not found.→ 404),再通过memory.update携带expectedRevision创建新的规范修订,写入reason: 'Updated from Ekko memory settings.'、actor: 'studio-user'、explicitUserIntent: true; - 更新失败(
!result.accepted)会抛出result.reason返回 400。
删除(DELETE /api/ekko/memory/:id):默认软删除(mode: 'soft'),同样要求expectedRevision与当前修订匹配。页面从不直接编辑 Ekko 的记忆数据库,全部经由MemoryService的修订保护链路完成。对应的服务层实现见 services/memory.ts,其ListEkkoMemoryInput/UpdateEkkoMemoryInput接口明确标注了这些约束。
Skills:适配 EkkoSkillManager 的发现与写保护
GET /api/ekko/skills GET /api/ekko/skills/:name POST /api/ekko/skills PUT /api/ekko/skills/:name DELETE /api/ekko/skills/:name(当前路由层还包含external-directories、import、files、file、toggle等扩展端点,见 routes/skills.ts,本文聚焦首个发布版本的核心五条。)
服务层围绕EkkoSkillManager适配,完整保留其既有规则:
- 发现(discover):
listEkkoSkills会先调用resolved.directories.profileSkillsDirectory(profile)触发一次显式重扫边界,再skill.discover(query, { profile }),把新发布的 built-in 技能同步进来; - 读后写(read-before-write):更新前先
getEkkoSkill读取详情; - 托管技能保护:built-in 技能不可编辑、不可删除(
Built-in skill cannot be edited/deleted); - 路径包含规则:仅
source === 'local'的技能可编辑/删除,external 技能被拒绝(Only local skills can be edited...)。
create接受{ name, content, category? };setEkkoSkillEnabled通过config.setSkillEnabled(name, enabled, profile)落盘启用状态。页面管理的对象是每个 Profile 的SKILL.md;技能支持文件编辑与导入属于延后工作。这些规则在 services/skills.ts 中逐条可查。
MCP:无 Studio 侧车,直接读写 Ekko 规范配置
GET /api/ekko/mcp/servers POST /api/ekko/mcp/servers PATCH /api/ekko/mcp/servers/:name DELETE /api/ekko/mcp/servers/:name POST /api/ekko/mcp/servers/:name/test存储位置:自定义 stdio 与 Streamable HTTP 服务器定义存放在 Ekko 的规范配置.ekko/config/config.json的mcp.profiles.<profile>.servers模块下,不存在 Studio 自有的 MCP 侧车进程。Ekko 会随其余配置一起校验该模块,并在创建新运行时加载所选 Profile 的服务器列表(resolveEkkoMcpServers在mcp.enabled时把listMcpServers(profile)与运行时传入的provided合并)。
托管注入:Studio 启动时,与 Hermes 相同的四个托管定义会注入到每个 Ekko Profile(services/mcp.ts 中MANAGED_SERVERS):
ekko-studio-api (toolset: api) ekko-studio-browser (toolset: browser) ekko-studio-devices (toolset: devices) ekko-studio-use (toolset: use)注入逻辑要点:
- 由
shouldInjectManagedMcpServers()门控:HERMES_WEB_UI_DISABLE_MCP_AUTOINJECT开启时跳过;AppHome 位于临时目录(tmpdir()//tmp//private/tmp)时默认跳过,除非显式设置HERMES_WEB_UI_ALLOW_TRANSIENT_MCP_AUTOINJECT; - 与 Hermes MCP 页一致,这些注入项可被编辑、删除、启用、禁用;已存在的
enabled: false会在重新注入时保留(if (existing?.enabled === false) desired.enabled = false); - 旧名(
hermes-studio-*、hermes-web-ui-mcp等)的托管条目会被自动迁移/清理(见LEGACY_MANAGED_SERVER_NAMES与LEGACY_MANAGED_COMMANDS); - 若某 Profile 存在同名但非托管的自定义服务器,则跳过该 Profile 的注入(
skipped+ reason)。
校验规则(normalizeEkkoMcpServerConfig):
- 服务器名须匹配
/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/(字母数字开头、含点/下划线/连字符、最长 64 字符); type仅允许stdio或streamable_http(http/streamable-http/streamablehttp会被归一化);不显式声明时,有url无command推断为streamable_http,否则推断为stdio;- stdio 必须提供
command;args必须是字符串数组;env必须是字符串值对象; - streamable_http 必须提供
url且协议只能是http:/https:;headers必须是字符串值对象; enabled必须是布尔值(缺省视为 true)。
测试端点:POST /api/ekko/mcp/servers/:name/test通过createMcpToolProvider()调用listTools({ mcpServers: { [name]: server.config }, timeoutMs: 5_000 })探测工具,禁用中的服务器会被拒绝(Enable the MCP server before testing it.),成功返回{ ok: true, tools: [{ name, description }] }。
API 与页面读写的是同一个配置模块,因此所有变更会直接影响后续运行。
客户端行为:复用 Hermes 组件,仅替换数据回调
每个页面使用共享 API 客户端已附加的活跃 Profile,加载/空/错误/确认/变更等状态均保持在页面局部:
- Memory:可搜索的卡片列表,展示 status/type 元数据,配编辑弹窗;
- Skills:直接复用 Hermes 的
SkillList、SkillDetail组件与共享分栏(split-view)布局,仅数据回调替换为 Ekko API; - MCP:直接复用 Hermes 的
McpServerCard与共享管理器布局(概要卡片、搜索工具栏、响应式服务器网格、工具标签、JSON/YAML 编辑器),Ekko 特有逻辑仅限 API 适配器、transport 感知校验与后台工具探测。
此外,所有新增可见字符串均已同步到各 locale 文件(如 en.ts、zh.ts 等,可在packages/client/src/i18n/locales/下核对)。
验证体系与验收路径
依据 ekko-configuration-services.test.ts,服务层测试覆盖:
- Profile 隔离:不同 Profile 间 memory/skills/MCP 数据互不串扰;
- Memory 修订安全:
expectedRevision校验、更新创建新规范修订、软删除; - 技能管理器适配:discover 重扫、built-in/external 写保护、enable 落盘;
- MCP 持久化与校验:名称正则、stdio/streamable_http 必填项、URL 协议约束、
enabled:false保留与重注入; - 运行时合并:
resolveEkkoMcpServers对配置与运行时注入的合并行为。
客户端测试(ekko-config-navigation.test.ts、ekko-configuration-api.test.ts)覆盖路由、壳层/侧边栏接线、Agent Manager 入口与三个页面的请求流。整体验收路径为:
npm run harness:check npm run build在配置了 Playwright 浏览器时,还会进行浏览器可见的验证。
已延后的工作
首个版本明确将以下能力列入延后清单,作为后续迭代方向:
- Memory 审计历史与硬删除 UI;
- 技能支持文件、归档/导入与外部目录;
- 旧版 HTTP+SSE MCP 传输回退;
- 每工具 include/exclude 控制与长连接遥测。
小结
Ekko Agent 配置面是 Hermes Studio 中“壳层复用 + 数据隔离”的典型实现:前端通过路由元信息切换专属侧边栏并复用 Hermes 的组件库,服务端以/api/ekko/*薄路由 + 控制器校验 + 服务层适配的三层结构,把记忆修订保护、技能写保护与 MCP 配置持久化统一收敛到ekko-agent包的既有管理器中。对开发者而言,理解这组路由、接口与校验规则,即可安全地扩展或集成 Ekko 的内存、技能与 MCP 能力到其他前端面。
- AI 应用
- 人工智能
- AI Agent
- 本地部署
- 前端
- 后端
- 工作流自动化
【免费下载链接】ekko-studio
Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.
相关推荐
Ekko Studio(Hermes Studio)本地优先多 Agent 工作区完全指南:架构、部署与配置
Ekko Studio(Hermes Studio)本地优先多 Agent 工作区完全指南:架构、部署与配置 Ekko Studio 是一个本地优先(local
AI 应用人工智能AI Agent本地部署前端后端工作流自动化Hermes Studio 桌面端 Agent 内置浏览器:基于 Electron WebContentsView 与 CDP 的多 Agent 可操控浏览器架构
Hermes Studio 桌面端 Agent 内置浏览器:基于 Electron WebContentsView 与 CDP 的多 Agent 可操控浏览器架
AI 应用人工智能AI Agent本地部署前端后端工作流自动化Hermes One(hermes-desktop)完全指南:Hermes Agent 的桌面安装、配置与聊天伴侣
Hermes One(hermes desktop)完全指南:Hermes Agent 的桌面安装、配置与聊天伴侣 本文以 README.md https://
AI 应用交互助手桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考