博客

把 eva-core 设计成 Eva-CLI 的基础契约层

为什么 eva-core 应该作为第一个实现模块:先稳定 Topic、ID、Event、调用契约和结构化错误,再让运行时行为扩散到其他 crate。

发布: 分类: 运行时

eva-core 适合作为第一个实现模块,因为它定义的是所有其他 crate 都会依赖的基础契约。在 Eva-CLI 继续实现 EventBus 投递、Scheduler 路由、Lua Agent 执行、Adapter transport、记忆、硬件和 runtime generation 切换之前,项目需要一套不执行副作用的共享语言。

它的价值不是“功能强”,而是稳定、克制、不容易被误用:Topic 在路由前就能校验,ID 不会被当作普通字符串混用,Event 带有链路追踪字段,invoke request 形态可预测,错误也用结构化字段表达,而不是只传一段字符串。

eva-core 基础契约边界图,展示 eva-core 在 config、EventBus、Scheduler、Agent、Adapter、Runtime 和 CLI 之间提供 Event、Topic、ID、Capability、Invoke 与结构化错误契约。
eva-core 应停留在契约边界:所有模块共享它,但它不拥有任何运行时副作用。

第一个模块应该减少后续返工

先做 transport 或 Agent runtime 看起来更直观,但这些模块很快就会需要共同类型。如果每个 crate 都自己定义 Topic 字符串、request id、payload 包装和错误分类,第二轮实现就会变成删除重复契约。

eva-core 的作用就是先固定最底层的数据形态。它不应该决定 policy,不应该执行 Lua,不应该调用 provider,不应该读取配置文件,也不应该发布事件。它只负责让这些模块之间传递的数据显式、可校验、可测试。

契约 为什么属于 eva-core 最先使用者
Topic 路由、订阅、emit topic 和 policy 校验都需要同一套规则。 eva-schedulereva-policyeva-config
ID newtype Agent、Adapter、Capability、Event 和 Request 标识不应只是可混用的字符串。 全部 runtime crate
Event EventBus、Scheduler、AgentRuntime、audit 和 recovery 都需要同一个事件信封。 eva-eventbuseva-schedulereva-agent
Invoke Agent 与 capability 调用需要先有稳定 request/response 边界,再实现具体 transport。 eva-agenteva-capabilityeva-adapter
Error 跨 crate 失败需要 kind、message、retryable、provider code 和链路字段。 所有 crate 边界

刻意保持边界狭窄

好的 eva-core 设计不仅取决于它负责什么,也取决于它拒绝什么。它不应该加载 YAML,不应该合并权限,不应该持久化事件,不应该运行 Lua,不应该拥有 Adapter manifest,不应该实现 MCP,也不应该管理 lifecycle generation。这些都是运行时职责。如果把它们塞进 eva-core,基础层会变重,并最终形成依赖环。

eva-core
  -> Topic, TopicPattern
  -> AgentId, AdapterId, CapabilityName, RequestId, EventId
  -> Event, EventTarget, trace linkage fields
  -> AgentInvokeRequest, CapabilityInvokeRequest, InvokeResponse
  -> EvaError, ErrorKind, retryable, provider_code

可落地的第一阶段

第一阶段要足够小,能快速完成;也要足够严格,能解锁后续模块。Topic 解析和 pattern 校验应该先做,因为配置、路由、权限和 Agent emit 都依赖它。ID newtype 紧随其后,用来防止后续 API 接受任意字符串。然后再实现 Event 和 invoke 契约,为 EventBus、Scheduler、AgentRuntime 和 AdapterRouter 提供共享表面。

优先级 交付物 验收检查
1 TopicTopicPattern 接受 /input/user,拒绝空段,并限制 ** 只能出现在最后一段。
2 ID newtype Agent ID、Adapter ID 和 Request ID 不能被误传给错误 API。
3 Event 包含 event_idtopic、payload、可选 target 和链路字段。
4 Invoke request/response 在实现具体 transport 前,Agent 与 capability 调用先拥有统一形态。
5 结构化错误 每个跨模块错误都包含分类、消息、可重试性和可选 provider 上下文。

它会解锁什么

一旦 eva-core 稳定,eva-config 就可以把 YAML 解析成强类型引用,eva-eventbus 可以发布真正的 Eventeva-scheduler 可以不靠临时字符串逻辑匹配 Topic,eva-agent 也能收到清晰的事件信封。这是让后续 Eva-CLI 实现从“推测”变成“增量落地”的最小基础。

详细模块文档见 eva-core 模块设计