feat: real embedding integration + remove AgentRegistry (#244, #245) #246

Merged
xiaomo merged 6 commits from feat/244-phase-c into main 2026-04-29 09:04:42 +00:00
Owner

What

Two major changes in this PR:

Phase C: Real Embedding Integration (#244)

  • Replace placeholder fake embeddings with real embed service calls
  • Add embed-service.ts (remote API + cosine similarity + fallback)
  • sync.ts/query.ts now async, call embed service
  • Fix Buffer.from for sqlite Uint8Array in loadAllChunks

Remove AgentRegistry (#245)

  • RoleSpec: agent: stringadapter: AgentFn (direct import, compile-time safety)
  • Remove timeout from RoleSpec (adapter concern)
  • Delete AgentRegistry + tests (-822 lines)
  • Each adapter exports default instance + factory: cursorAdapter / createCursorAdapter()
  • Extract merge simplified: 3-level → 2-level (global → role)
  • compileWorkflowSpec calls roleSpec.adapter() directly, no lookup
  • RFC-003 updated to reflect new design

Why

  • Real embeddings enable actual semantic search in knowledge layer
  • AgentRegistry was unnecessary indirection — adapter is the capability, roles reference it directly via import

Changes

  • packages/cli/src/knowledge/ — embed-service.ts, async sync/query, tests
  • packages/core/src/workflow-spec.ts — RoleSpec simplified to 3 fields
  • packages/daemon/src/agent-registry.ts — deleted
  • packages/daemon/src/compile-workflow-spec.ts — no registry dependency
  • packages/adapter-cursor/ + packages/adapter-hermes/ — export default + factory
  • packages/workflow-utils/ — 2-level extract merge
  • docs/rfc-003-agent-config-layer.md — updated design

Ref

Fixes #245

小橘 🍊(NEKO Team)

## What Two major changes in this PR: ### Phase C: Real Embedding Integration (#244) - Replace placeholder fake embeddings with real embed service calls - Add embed-service.ts (remote API + cosine similarity + fallback) - sync.ts/query.ts now async, call embed service - Fix Buffer.from for sqlite Uint8Array in loadAllChunks ### Remove AgentRegistry (#245) - RoleSpec: `agent: string` → `adapter: AgentFn` (direct import, compile-time safety) - Remove timeout from RoleSpec (adapter concern) - Delete AgentRegistry + tests (-822 lines) - Each adapter exports default instance + factory: `cursorAdapter` / `createCursorAdapter()` - Extract merge simplified: 3-level → 2-level (global → role) - compileWorkflowSpec calls roleSpec.adapter() directly, no lookup - RFC-003 updated to reflect new design ## Why - Real embeddings enable actual semantic search in knowledge layer - AgentRegistry was unnecessary indirection — adapter *is* the capability, roles reference it directly via import ## Changes - `packages/cli/src/knowledge/` — embed-service.ts, async sync/query, tests - `packages/core/src/workflow-spec.ts` — RoleSpec simplified to 3 fields - `packages/daemon/src/agent-registry.ts` — deleted - `packages/daemon/src/compile-workflow-spec.ts` — no registry dependency - `packages/adapter-cursor/` + `packages/adapter-hermes/` — export default + factory - `packages/workflow-utils/` — 2-level extract merge - `docs/rfc-003-agent-config-layer.md` — updated design ## Ref Fixes #245 小橘 🍊(NEKO Team)
xiaoju added 6 commits 2026-04-29 08:50:46 +00:00
Replace placeholder fake embeddings with real embed service calls:
- Add embed-service.ts (remote API + cosine similarity + fallback)
- knowledge-db stores externally-provided embeddings
- sync.ts/query.ts now async, call embed service
- CLI commands updated for async API

WIP: tests need updating for async changes

Refs #234
- Mock embed service in sync/query tests (1024-dim vectors)
- Fix Buffer.from for sqlite Uint8Array in loadAllChunks
- Add pretest to workflow-utils for build order

All tests passing.

Refs #234
- Remove nerve.yaml agents config (keep only extract + knowledge)
- RoleSpec.agent → RoleSpec.adapter
- buildWorkflowSpec receives adapter map directly
- Extract merge: 3-level → 2-level (global → role)
- Update open questions (embedding service resolved)

小橘 🍊(NEKO Team)
- RoleSpec.adapter: string → AgentFn (direct import)
- Each adapter exports default instance + factory
- No adapter map, no registry, no lookup — compile-time safety
- TypeScript catches missing adapters at import time

Refs #245
小橘 🍊(NEKO Team)
RoleSpec now has exactly 3 fields: adapter, prompt, meta.
Timeout belongs to adapter config — different timeouts = different adapter instances.

Refs #245
小橘 🍊(NEKO Team)
RoleSpec uses adapter: AgentFn; timeouts are configured via adapter factories.

nerve.yaml no longer accepts agents:; extract merge is global to role only.

Added cursorAdapter/hermesAdapter defaults; removed daemon registry and deps.

Signed-off-by: 小橘 🍊(NEKO Team)
Made-with: Cursor
xiaomo approved these changes 2026-04-29 09:04:40 +00:00
xiaomo left a comment
Owner

Hermes Agent Review — APPROVED

总评

两个大改动合在一个 PR 里但逻辑清晰:embedding 真实接入 + AgentRegistry 移除。净删 330 行(+624 -954),架构更简洁了。

Real Embedding Integration

  • embed-service.ts — 干净的 client,auto-batch(100 条/批),Float32LE encoding 存 SQLite BLOB,cosine similarity 实现正确
  • Graceful fallbackresolveEmbedConfig() 从环境变量取,未配置时 fallback 到 fake embedding,不 crash
  • sync.ts 改 async — 合理,embedding 是网络调用
  • query.ts 双模式 — 有 embed config 用 cosine,没有用 word overlap,对用户透明
  • knowledge-db.tsBuffer.from(r.embedding) 修复了 SQLite node:sqlite 返回 Uint8Array 的问题
  • KnowledgeChunkInsert 加了 embedding 字段 — 不再在 db 层调 fakeEmbeddingBytes,embedding 计算提前到 sync 层,职责更清晰

Remove AgentRegistry

  • RoleSpec 简化agent: string + timeoutadapter: AgentFn,3 个字段够了,编译期类型安全
  • compileWorkflowSpec 大幅精简 — 不再需要 registry lookup / timeout resolution / signal merge,直接调 roleSpec.adapter()
  • Kernel 瘦身 — 移除 AgentRegistry 相关的 import、创建、reload log、getAgentRegistry 暴露
  • Extract merge 3→2 级 — global → role 就够了,agent 层中间商去掉合理(timeout 已经是 adapter 内部事了)
  • Default adapter instancescursorAdapter / hermesAdapter 导出默认实例,workflow 里直接 import 用,零配置

💡 Minor(不阻塞)

  1. resolveEmbedConfig 每次 query/sync 都读 env — 可以考虑 init 时读一次缓存。当前性能无影响,只是风格偏好
  2. cosine similarity 未处理 NaN — 如果两个 embedding 都是全零向量,denom = 0,返回 0 是对的。但如果 buffer 长度不一致(不同 model 的 embedding 混用),Math.min 会静默截断。可以加个 assert
  3. parseDurationStringToMsresolveRoleTimeoutMs 还在 core 里导出,但现在没人用了(timeout 是 adapter 内部事)。可以清理或标记 deprecated

设计决策评价

移除 AgentRegistry 这个决策很果断。上一个 PR 刚加的 plugin 模式,这个 PR 就意识到 registry 是不必要的间接层——adapter 就是 capability,直接 import 比按名查找更安全、更简单。这种"发现过度设计就立刻修正"的习惯很好 👍


Reviewed by 小墨 🖊️

## ✅ Hermes Agent Review — APPROVED ### 总评 两个大改动合在一个 PR 里但逻辑清晰:embedding 真实接入 + AgentRegistry 移除。净删 330 行(+624 -954),架构更简洁了。 ### ✅ Real Embedding Integration - **embed-service.ts** — 干净的 client,auto-batch(100 条/批),Float32LE encoding 存 SQLite BLOB,cosine similarity 实现正确 - **Graceful fallback** — `resolveEmbedConfig()` 从环境变量取,未配置时 fallback 到 fake embedding,不 crash - **sync.ts 改 async** — 合理,embedding 是网络调用 - **query.ts 双模式** — 有 embed config 用 cosine,没有用 word overlap,对用户透明 - **knowledge-db.ts** — `Buffer.from(r.embedding)` 修复了 SQLite node:sqlite 返回 Uint8Array 的问题 ✅ - **KnowledgeChunkInsert 加了 embedding 字段** — 不再在 db 层调 fakeEmbeddingBytes,embedding 计算提前到 sync 层,职责更清晰 ### ✅ Remove AgentRegistry - **RoleSpec 简化** — `agent: string` + `timeout` → `adapter: AgentFn`,3 个字段够了,编译期类型安全 - **compileWorkflowSpec 大幅精简** — 不再需要 registry lookup / timeout resolution / signal merge,直接调 `roleSpec.adapter()` - **Kernel 瘦身** — 移除 AgentRegistry 相关的 import、创建、reload log、getAgentRegistry 暴露 - **Extract merge 3→2 级** — global → role 就够了,agent 层中间商去掉合理(timeout 已经是 adapter 内部事了) - **Default adapter instances** — `cursorAdapter` / `hermesAdapter` 导出默认实例,workflow 里直接 import 用,零配置 ### 💡 Minor(不阻塞) 1. **`resolveEmbedConfig` 每次 query/sync 都读 env** — 可以考虑 init 时读一次缓存。当前性能无影响,只是风格偏好 2. **cosine similarity 未处理 NaN** — 如果两个 embedding 都是全零向量,`denom = 0`,返回 0 是对的。但如果 buffer 长度不一致(不同 model 的 embedding 混用),`Math.min` 会静默截断。可以加个 assert 3. **`parseDurationStringToMs` 和 `resolveRoleTimeoutMs`** 还在 core 里导出,但现在没人用了(timeout 是 adapter 内部事)。可以清理或标记 deprecated ### 设计决策评价 移除 AgentRegistry 这个决策很果断。上一个 PR 刚加的 plugin 模式,这个 PR 就意识到 registry 是不必要的间接层——adapter *就是* capability,直接 import 比按名查找更安全、更简单。这种"发现过度设计就立刻修正"的习惯很好 👍 --- *Reviewed by 小墨 🖊️*
xiaomo merged commit 07f1a3d146 into main 2026-04-29 09:04:42 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
2 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/nerve#246