mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 09:17:31 +00:00
docs: 把「业务语义归插件、联动走事件总线」补进 OVERVIEW 与 PLUGIN_DEV
上一提交只在 ARCHITECTURE 里记了终端归属。本次把这条**通用原则**补到另外两份
文档,避免只读 OVERVIEW / 插件开发指南的人仍旧按旧直觉写代码。
## OVERVIEW(中英)
设计要点新增一条「业务语义留在插件层」:内核不定义业务对象(终端、命令历史、
设备状态、媒体库都是插件域)。以终端为例说明:PTY/生命周期/输出缓冲归
agentcli,WebUI/CLI 订阅总线自攒视图,内核只提供事件总线与注册面 —— 新增一类
能力不需要改内核,也不会在核心里堆出第二套业务真相。
## PLUGIN_DEV(中英)
PluginSDK 章节新增「与其它插件联动 — 走事件总线,不要依赖内核内部组件」:
- 代码示例:订阅 terminal_output + tool_call 自己攒视图
- 两条稳定事件表(谁发布、用途)
- ★ 外部插件只能订阅、不能发布(Publish 属 withheld 能力),所以「能力所有者
需要广播状态」的插件必须内置(agentcli 即此例)
- 指向 internal/pluginview 作为参考实现,并写明「视图不是权威、晚启动会缺早期
事件」
一个准确性修正:公开 SDK **没有** EventTerminalOutput 常量(属内核内部事件
类型),所以示例里外部插件用 sdk.EventType("terminal_output") 字符串订阅,
并注明内置插件可用 internal sdk 常量 —— 避免文档给出编不过的示例。
验证:四份文档代码围栏配对(74/74、0/0);仅文档改动,无代码影响。
This commit is contained in:
@ -18,6 +18,15 @@ Core architecture: a long-running kernel process (`homed`) that connects to vari
|
||||
|
||||
The significance lies in clear responsibility boundaries: the kernel focuses on orchestration and memory management, while plugins handle IO implementation — the two are not coupled.
|
||||
|
||||
**Business semantics stay in plugins** — the kernel does not define business
|
||||
objects: terminals, command history, device state and media libraries all belong to
|
||||
the plugin domain. Take terminals: the PTY, session lifecycle and output buffering
|
||||
all live in `agentcli`; when WebUI or CLI needs a terminal panel it **subscribes to
|
||||
the event bus** (`EventTerminalOutput` + `EventToolCall`) and builds its own view
|
||||
instead of reading a state component inside the kernel. The kernel offers only the
|
||||
event bus and the plugin registration surface — adding a new capability does not
|
||||
require touching the kernel, and no second version of business truth accumulates there.
|
||||
|
||||
**Three-Layer Memory Architecture** — Manages information retention across long agent runtimes through a tiered storage strategy:
|
||||
- **Context Layer**: In-memory pretrained word embedding scored event window (StaticEmbedder word vectors → CosineSimilarity, TF-IDF fallback), maintains recent context in real-time, low-relevance events automatically sink to the next layer
|
||||
- **Document Layer**: JSON files + TF-IDF vector-indexed temporary memory, supports explicit submission and implicit archival, cold data distills to Graph
|
||||
|
||||
@ -460,6 +460,45 @@ unsub := s.Events().Subscribe(sdk.EventToolCall, func(evt *sdk.Event) {
|
||||
defer unsub()
|
||||
```
|
||||
|
||||
#### Inter-plugin Integration — Use the Event Bus, Not Kernel Components
|
||||
|
||||
The kernel carries no business-domain semantics (terminals, device state, media
|
||||
libraries all belong to plugins). Plugins that need to coordinate should therefore
|
||||
**subscribe to the event bus**, not read some state component inside the kernel —
|
||||
the latter creates a second copy of the truth and pushes business logic back into
|
||||
the kernel.
|
||||
|
||||
```go
|
||||
// Panel-style plugins (WebUI/CLI): subscribe to terminal events, build a view
|
||||
// Note: terminal_output has no public constant yet (it is a kernel-internal event
|
||||
// type), so external plugins subscribe by string; built-in plugins can use the
|
||||
// internal SDK's EventTerminalOutput constant.
|
||||
unsubTerm := s.Events().Subscribe(sdk.EventType("terminal_output"), func(evt *sdk.Event) {
|
||||
// evt.Payload: terminal_id / command / output / running
|
||||
})
|
||||
unsubTool := s.Events().Subscribe(sdk.EventToolCall, func(evt *sdk.Event) {
|
||||
// evt.Payload: tool / args / status (cmd_run, terminal_create/close, ...)
|
||||
})
|
||||
defer unsubTerm()
|
||||
defer unsubTool()
|
||||
```
|
||||
|
||||
The two stable events:
|
||||
|
||||
| Event | Publisher | Purpose |
|
||||
|---|---|---|
|
||||
| `EventTerminalOutput` | agentcli | terminal output and lifecycle (create/close/timeout) |
|
||||
| `EventToolCall` | kernel | tool invocations (incl. `cmd_run`, `terminal_create/close`) |
|
||||
|
||||
★ **External plugins can subscribe but cannot publish**: `Publish` is a withheld
|
||||
capability (`withheldCapabilities`), so a plugin that *owns* a capability and must
|
||||
broadcast its state (like agentcli publishing terminal events) has to be built-in.
|
||||
If your plugin is only a consumer, subscribing is enough.
|
||||
|
||||
Reference implementation: `internal/pluginview` (the terminal view shared by WebUI
|
||||
and CLI). It shows how a view is assembled from events, and the boundary that the
|
||||
view is not authoritative — a late starter misses early events.
|
||||
|
||||
#### Capability Access
|
||||
|
||||
```go
|
||||
|
||||
Reference in New Issue
Block a user