@epoch-agent/core

中文文档
6.2.0发布于 2026/11/13Apache-2.0TypeScriptES Module近 30 天下载 4479

epoch-agent 核心引擎:ReAct 循环、Provider 路由、工具调度、记忆管理

原始使用文档

@epoch-agent/core

Agent 引擎。ReAct 循环、Provider 路由、权限、记忆、技能、Hook、Policy、内容合规、插件、上下文压缩。

  • ✅ 做:领域逻辑
  • ❌ 不做:装配(在 runtime)、命令解析(在 cli)、 渲染(在 tui / web)、任何 UI
  • 依赖:protocol + infra + ai(Vercel AI SDK)+ better-sqlite3 + gpt-tokenizer + js-yaml + zod

嵌入方一般不直接装这个包,装 runtime——它把 core 的十几个服务 装配好了。直接用 core 意味着自己接线。MCP 客户端也不在这里,在 plugin-mcp。

模块

目录职责
agent/ReAct 循环(loop.ts)、工具执行、实时输出泵、prompt 组装、Nudge / Stall 检测、消息编解码、plan 模式状态、运行前 token 估算(run-estimate.ts)、沙箱升权门的措辞层(escalation.ts:判据在 infra 的 sandbox/escalation.ts,入口在 tool-executor.ts 的 resolveEscalation(),2026-10-27 方案 65 §2.1)。⚠️ 附件(图 / @文件 / @: 引用的会话)必须以 parts 一起送出去(2026-11-05 修):只把它们折进 content 那份文本投影的话,模型收到的是一行 [referenced session "…"] 元数据、正文一个字都没有 —— 守着这件事的是 __tests__/session-reference-delivery.test.ts(走真 AgentLoop)
provider/多 provider 路由 + 降级、模型元数据探测、AI SDK 适配、token 估算(tokenizer.ts,全仓唯一口径)
config/10 层配置解析链 + 迁移 + 设置来源分层(sources.ts)+ 「为什么是这个值」(provenance.ts,每个键赢在哪一层)+ 「我现在写、写完谁说了算」(write.ts)+ JSON Schema 导出。schema.ts 是配置形状的唯一真源
session/SQLite 会话持久化 + FTS5 搜索,落盘完整 EpochMessage(工具调用 / artifact 引用)+ 逐轮真实用量(recordUsage)+ 已批准的计划 + 那一次工作区决定(v7 两列,见下)。开给模型那一侧的检索 / 前后文窗口 / 血缘在 query.ts + trace.ts,开给人那一侧的 @: 引用(候选 / 解析 / 当前面)在 reference.ts(子 agent 的会话不在候选里,判据在 DELEGATE_SESSION_SOURCE 上),「哪些会话我能读」两边共用 authorization.ts 那一份,索引体检在 fts-health.ts(epoch doctor 用)
memory/文件 + SQLite 双存储。命中注入模式的条目原文照留、只在渲染给模型时遮罩(索引块 / prefetch / search / read 四条通道回占位符;文件一个字节不动),写前则直接拒 —— 判据在 manager.ts 的 classifyEntry / blockedPlaceholder 上。配额到九成的提醒走 takeNotices() → 那一帧 notice(2026-09-28 之前是 reviewer.ts 的 5 分钟后台审查,结论没人读,已删)
skill/SKILL.md 文件系统 + 自动学习(learner.ts)。读正文有两条路,别混:view() 是模型那条(会 matchCount++,而那个数喂着有效性评分、也就是模型下次看得见哪些技能),body() 是「人点开看一眼」那条(一个字都不动统计)—— 一次浏览不是一次命中,判据写在 SkillSystem.body 上。create() 建的目录名取 frontmatter 的 name(不是参数那个,2026-09-28):索引取的也是它,不对齐的话 learner 那条通知会报一个查不到的名字。写口只有两个导出(previewSkillImport / importSkills,方案 42 §六):从本机目录导入技能,收路径不收字节,staging 那一层刻意不导出 —— 判据在 skill/import.ts 文件头
hook/Hook 匹配与执行、命令执行;sources.ts 定「读哪几份配置」(两级 hooks.json + Claude Code 的三份 settings.json,方案 50),config-loader.ts 只管解析我们自己的格式,claude-settings.ts / claude-matcher.ts 只管翻 Claude Code 的方言
permission/4 级权限(default / acceptEdits / plan / auto;老名字 bypass 是 auto 的别名;出厂默认是 acceptEdits,见 protocol 的 DEFAULT_PERMISSION_LEVEL)+ 审批缓存(approval-cache.ts:记弹窗答案;逐条撤销走 revoke(id) / PermissionManager.revokeApproval(),2026-08-27 补 —— 在那之前一次点错的「拒绝」只在内存里、永不过期,除了重启进程收不回来)+ 无头策略 + 紧凑规则 Tool(content) + 审计流水(audit.ts:权限层每一次裁决的定长流水,getAudit() 取,只在进程内、永不进遥测)
workspace/这次会话的地盘:主根 + --add-dir 的额外根、目录体检、「哪些指令文件没被加载」,外加「已知工作区」最近使用清单(~/.epoch/workspaces.json,本机文件不是服务)。判据本身在 infra 的 isInWorkspace,这里是壳
compliance/内容合规闸门:本地词表 + 正则。缺省只拦用户输入(送进模型之前,命中 block 时请求不发也不计费);模型输出那一侧同一套东西都在(agent/turn.ts 那个唯一出口 + 句子级 holdback),一行配置就能开,但缺省关 —— 它是误伤和流式延迟的大头,判据在 settings.ts。变体归一化(全角 / 零宽 / 分隔符 / leet / 繁简,带 offset 映射因为 mask 要打回原文)、Aho-Corasick 多模式匹配、豁免表(治「台独 命中『平台独立部署』」那一类)、句子级 holdback 的流式 guard。缺省跳过代码(围栏块与行内 code)—— 这是个写代码的 agent,那一格决定这层能不能用。类别 / 动作两个联合住 protocol(它们同时是配置键名、词库文件名、遥测属性值)。内置词表是种子不是生产词库,正式部署挂 ~/.epoch/compliance/<类别>.txt
policy/策略文件加载与校验;sources.ts 定「扫哪几个 policies 目录」
context/上下文压缩(工具结果裁剪是摘要之前的独立一步,头中尾保留,裁完够了就不调模型;2026-08-16 起认 compression.* 两个配置项,见下)、项目发现、指令文件与它的 @import 展开 + 项目外放行闸门、artifact 闸门与清理、图片 token 估算、@ 提及的候选清单与解析(文件和 @: 会话共享同一本 200KB 的账,方案 53)
sandbox/CodeSandbox(code_exec 的执行器)+ 隔离能力的对外说法:describeIsolation() 那句中文、以及「哪些工具走沙箱」两份清单。机制那一半 2026-08-16 搬去了 infra 的 sandbox/(消费者不止 core 一个了,plugin-terminal 够不着 core);既有 import 路径靠再导出保住
delegate/子 agent 任务委托(delegate_task 的后端;background: true 时登记成一格 agent 作业,见 infra/jobs.ts)。⚠️ 2026-10-27 起两件事变了:子任务跑完把整轮按步落进会话库(带 parent_id,source 是 delegate,所以它不出现在「接着哪一段聊」的列表里 —— 判据在 DELEGATE_SESSION_SOURCE 上),以及超时来自 delegate.taskTimeoutSec(缺省 15 分钟,0 = 不限时;在此之前是写死的 5 分钟)
goal/目标(方案 52):一段会话的完成判据 + 那几把尺子。engine / provider / service / store / types / wording 六份;goal 工具与 report_goal 那一路都接在这儿。2026-11-03 补进这张表(上一版漏了)
team/团队通信里住在进程内的那一半:registry.ts(名册 + 共享任务 DAG,写入带 expectedRevision compare-and-set,过期就拒)、inbox.ts(成员收件箱,实现 SteerSource —— 引擎在步骤边界 take(),所以插话当轮生效而不是等下一轮)、board.ts(讨论板:频道 / 线程 / 帖子 / 订阅)。⚠️ 名册和板子的持久性故意不同:名册只在内存(进程退出即散,成员本来就活在进程里),板子挂 sessions.db 的 board namespace(多个 epoch 进程共用同一份库就共享同一块板,2026-10-30 用两个真进程验收过)。别把两者混成一层 —— 判据在这两个文件头。2026-11-02 起主会话在名册里有身份:registerSession 登记每一段活会话(建会话 / 复活 / 每轮 run()),send_message 因此能寻址另一段主会话,成员回给 lead 的消息按 parentSessionId 投回派它出来的那一段 —— 在这之前所有主会话共用一个 lead 收件箱,谁先发请求谁把别人的回话吃掉。⚠️ 2026-11-06 起多了一条「关掉」的路:close(agentId) 连同它派出去的整棵子树一起从名册删干净(codex close_agent 的对应物),subtreeOf(rootSessionId) 让界面按会话取那一棵;名册收工之后照旧留着那一行(markFinished 只翻状态),「不要了」是另一个动作 —— 判据在 TeamRegistry.close 上。⚠️ 2026-11-06 同一轮还补了四处:① 关掉时把没读走的消息报出来(CloseResult.dropped —— 收件箱跟着条目走这件事不变,但「静默地丢话」不行,回执要说得出几条、谁发的);② 讨论板的每个读口都有界(cursor 分页 + 每帖 previewPostText 截断 + readPost 按码点分段),之前 read_thread 一次能把 100 万字符塞进上下文;③ 发帖可以 agentsToNotify(一次性通知,不订阅)和带 requestId(重试幂等,同一个作者 + 同一个 id 回原来那一帖);④ followup_task 多了四道闸 —— 关掉的成员(tombstone)、不在名册上的子会话(isSubagent)、跨目录(crossDirAllowed,跟着权限档走:auto 放行,其余三档对工作区外本来就要问用户,而工具里问不了)、以及归属(ownsMember:只唤得动这段会话自己派出的那棵树,别人的成员知道名字也不动,且这一问排在「它在跑吗」前面 —— 否则会漏出别人的运行状态)。⑤ 归属那道闸当天扩到另外三件:interrupt_agent / close_agent / send_message 也只看同一棵树(判据 TeamRegistry.sameTree / treeRootOf —— 走到根上比;对主会话是「我派的(含再派的)」,对成员是「我这队的兄弟」,兄弟之间必须通)。拒绝时回 7217(打断 / 关掉)/ 7104(发消息),同样排在「碰得动吗」前面;另一段主会话不受它管(那条功能判据在 deliver 上)。判据都在 board.ts / team.ts / send-message.ts 的文件头与 TeamRegistry.close / sameTree 上
agent-role/agent 角色定义、注册与工具作用域收窄(子 agent 和顶层会话两条来路走同一个 roleScopedProvider);createRoleScope 把它包成可变槽 —— 身份行和工具表从同一个变量读,好让「这一条消息换个专家」有地方落。⚠️ 2026-08-18 起这里多了一条写的路(create.ts,全仓第一条建角色的路):它和读口共用同一份 frontmatter schema、同一个解析器,写完先读回来验一遍再落盘。⚠️ 2026-09-16 又多了它的反面(remove.ts,「能加就得能删」):落点靠读口解析出来的 name 找,不是拿名字拼路径 —— frontmatter 的 name 优先于文件名,拼路径要么删不到一份界面上明明列着的身份,要么删掉另一个,而两种错法都不报错;同名两份时一个字节都不删。那道「什么样的客户端才准写」的闸门两条都不在这儿,在 @epoch-agent/server(判据见那两个文件头第三节)
agent-plugin/插件面板那个可变槽(2026-10-20):createPluginScope —— 「这一条消息是点着哪个插件面板发的」,<self> 段从它读。⚠️ 和 agent-role/ 有同一个形状、少两样东西:没有 provider(插件名不换工具表)、没有身份 —— 它只影响 system prompt 里一句话,判据在那份文件头那张对照表上。别照着 createRoleScope 全抄一遍
extensions/项目级扩展:自定义斜杠命令的发现 / 加载 / 插值 / 按轮次收窄工具表;三种扩展物共用的 frontmatter 解析
plugin/插件:清单校验、四种来源的安装、安装记录(带跨进程锁)、市场、加载成「六类扩展物的来源」(PLUGIN_LAYOUT 那七个约定子路径)。见 docs/PLUGINS.md。⚠️ 2026-10-20 起清单里多了 panel 那一格(输入框上方那块面板,url 只收本机回环、判据在 manifest.ts 的 isLoopbackUrl 上):写歪了只有这一格不生效,插件照常装得上 —— 那一条口径逐字同 visibility / appearance
tools/ToolRegistry + builtin/ 下那批内置工具(todo / memory / goal / code_exec / run_code / delegate_task / ask_user_question / skill_view / 技能写入那四个 / tool_search / schedule_draft / plan 模式那两个 / 会话检索那五个)。其中 team / board / 技能写入 / MCP 管理 / 会话检索 / 定时任务 共 29 个默认是 Deferred(靠 tool_search 发现,不占每一轮的上下文)。清单与边界的唯一真源是 docs/TOOLS.md —— 这里不再抄一个会过期的条数(原来写的「13 个」漏了 tool_search)
code-mode/run_code 的 worker 运行时(方案 51):线程入口、宿主 ↔ worker 的工具绑定协议、四道上限、只读闸门、worker 的权限策略(policy.ts)。⚠️ 和 sandbox/ 是两回事,隔离模型正好相反 —— 那一个的边界是 OS 沙箱,这一个的边界是审批 + Node 权限模型(子调用通道本身在 agent/tool-executor.ts)。默认关,tools.mode: both 才注册那个工具
checkpoint/写类工具动手前的文件快照 + 回退(两阶段原子、不覆盖手工改动)。见 docs/CHECKPOINTS.md
tracker/待办追踪的 SQLite 表
schedule/定时任务(方案 45):store / 单实例锁 / 触发器算术 / 保存期校验 / 录像与留存 / 注册器 / doctor,外加 os/ 下的两个 OS 后端(schtasks / launchd)和 draft.ts(对话里那份提案的解析与判定 —— 它自己一个字节都不写,落库是工具那侧调 ScheduleControl.create / update)。不含执行器 —— 跑一次要 buildRuntime(),那在 runtime 的 fireSchedule()。⚠️ store 的读写两侧都过一遍老档位名解析(permissionOfRow):库里可能躺着 bypass 合并之前写进去的 "bypass",而它是另一条路(云同步)从别的进程交过来的,类型在进程边界上什么也不保证
cost/计价表、预算守卫、花费状态。缓存命中单独计价,口径见 pricing.ts 文件头
compat/竞品词汇表。今天只有 claude-tool-names.ts(Claude Code 工具名 ↔ 我们的,双向从同一份数据推出来)—— 放在 hook/ 之外是因为方案 50 §八 点名的第二个消费者(兼容它的权限规则)不住在 hook 里

版本与发布记录

@epoch-agent/core 共发布 57 个版本,首次发布于 2026/08/19;过去 12 个月发布了 57 个版本。

版本发布日期距今
6.2.0latest2026/11/13今天
6.1.02026/11/112 天前
6.0.02026/11/112 天前
5.0.02026/11/103 天前
4.1.12026/11/067 天前
4.1.02026/11/067 天前

关于 @epoch-agent/core 的常见问题

@epoch-agent/core 是什么?

epoch-agent 核心引擎:ReAct 循环、Provider 路由、工具调度、记忆管理

如何安装 @epoch-agent/core?

在项目目录运行 npm install @epoch-agent/core,或使用 pnpm add / yarn add / bun add。

@epoch-agent/core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@epoch-agent/core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@epoch-agent/core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@epoch-agent/core 可以商用吗?

@epoch-agent/core 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@epoch-agent/core 的下载量有多少?

根据 npm 官方下载统计,@epoch-agent/core 在 2026/10/14 – 2026/11/12 这 30 天内被下载 4,479 次,日均约 149 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@epoch-agent/core 还在维护吗?

最新版本 6.2.0 发布于 2026/11/13(今天);至今共发布 57 个版本,其中过去 12 个月发布了 57 个;首次发布于 2026/08/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。