10a601c28b
Reflect recent changes across all docs: - README: add executor loop (fire-and-forget), task events lifecycle, pending-tasks projection, update architecture diagram, add pulse-hermes package, add RFC #58 reference - CONTRIBUTING: add task-events.ts, defs.ts, projection-engine.ts, pending-tasks-projection.ts to code structure, update architecture diagram to three-layer decoupled model, add design principles 6-7, add ui/ directory, add migrate.ts, add RFC #58 reference - DESIGN: update packages table with all current packages
213 lines
8.7 KiB
Markdown
213 lines
8.7 KiB
Markdown
# Pulse
|
|
|
|
Agent 的自主神经系统。
|
|
|
|
```
|
|
Rule = (prev, curr, inner) => Promise<[Effect[], tickMs]>
|
|
```
|
|
|
|
有状态响应式循环:**Percept → Understand → Execute**。确定性任务自己做,不确定才上报 Agent。
|
|
|
|
## 三原语
|
|
|
|
| 层 | 英文 | 组件 | 输出 | 佛教映射 |
|
|
|---|---|---|---|---|
|
|
| **感知** | Percept | Watchers(六处) | Events(六入,按 sense 分类) | 六处触尘 |
|
|
| **认知** | Understand | Rules | Effects(序列化的行动参数) | 受想行 |
|
|
| **行动** | Execute | Executors | Events(执行结果) | 身口意业 |
|
|
|
|
**一切皆业**:Percept / Tick / Execute 都写 events。Events 是不可变的业的记录。
|
|
|
|
> Effects 不是行动本身,是行动的描述——序列化的参数,由 Executor 解释执行。
|
|
|
|
## 架构
|
|
|
|
```
|
|
Percept 层(vitals.db) Understand 层(events.db) Execute 层
|
|
Watchers → 写 vitals → 唤醒判定 rebuildSnapshot → Rule Chain executorLoop
|
|
└── wakeTick() ──────────────→ 提前唤醒 → write effect events ───→ scan & execute
|
|
→ effect-acked/failed
|
|
```
|
|
|
|
**三层解耦**:Watchers 每 5s 感知写 vitals,关键事件提前唤醒 tick。Tick 层重建 snapshot,Rules 认知产生 effects 写入 events.db。独立的 executorLoop 后台扫描 effect events 并异步执行(fire-and-forget)。
|
|
|
|
**洋葱 Rule 模型**:每个 Rule 接收 `inner`(剩余 rule chain),可以放行、bypass(跳过内层)、修饰结果、变换 snapshot。保命 rules 硬编码在最外层,agent 的业务 rules 在内层。
|
|
|
|
## 三层不可变性
|
|
|
|
| 层级 | 比喻 | 谁能改 |
|
|
|---|---|---|
|
|
| **植物神经** — watchers、保命 rules、executors | 心跳、痛觉 | 只能 npm 升级 |
|
|
| **浅层自主神经** — 业务 rules | 呼吸节奏 | Agent staging → promote |
|
|
| **意识层** — OC Agent session | 思考、决策 | kill/restart 不影响 Pulse |
|
|
|
|
人不能通过大脑控制让心脏停跳。Agent 不能修改自己的保命逻辑。
|
|
|
|
## 包结构
|
|
|
|
| 包 | 说明 | npm |
|
|
|---|---|---|
|
|
| `@uncaged/pulse` | 核心引擎 + 保命层 + watchers + task projections + executor loop | [](https://www.npmjs.com/package/@uncaged/pulse) |
|
|
| `@uncaged/pulse-openclaw` | OpenClaw 适配器(Gateway/LLM watchers + rules + executors) | [](https://www.npmjs.com/package/@uncaged/pulse-openclaw) |
|
|
| `@uncaged/pulse-cursor` | Cursor Agent CLI executor 适配器 | [](https://www.npmjs.com/package/@uncaged/pulse-cursor) |
|
|
| `@uncaged/pulse-hermes` | Hermes Agent 适配器 | [](https://www.npmjs.com/package/@uncaged/pulse-hermes) |
|
|
| `@uncaged/upulse` | CLI:daemon 管理、staging/promote/rollback、WebUI | [](https://www.npmjs.com/package/@uncaged/upulse) |
|
|
|
|
## 快速开始
|
|
|
|
```bash
|
|
# 安装
|
|
bun add @uncaged/pulse
|
|
bun add -g @uncaged/upulse
|
|
|
|
# 初始化 engine 目录
|
|
upulse init
|
|
|
|
# 开发模式(热重载)
|
|
upulse dev
|
|
|
|
# 部署到生产
|
|
upulse deploy
|
|
|
|
# 启动 daemon
|
|
upulse daemon start
|
|
```
|
|
|
|
## 核心概念
|
|
|
|
### 三原语:Percept → Understand → Execute
|
|
|
|
| 层 | 英文 | 组件 | 输出 | 佛教映射 |
|
|
|---|---|---|---|---|
|
|
| **感知** | Percept | Watchers(六处) | Events(六入,按 sense 分类) | 六处触尘 |
|
|
| **认知** | Understand | Rules | Effects(序列化的行动参数) | 受想行 |
|
|
| **行动** | Execute | Executors | Events(执行结果) | 身口意业 |
|
|
|
|
**一切皆业**:Percept / Tick / Execute 都写 events。Events 是不可变的业的记录。
|
|
|
|
> Effects 不是行动本身,是行动的描述——序列化的参数,由 Executor 解释执行。
|
|
|
|
### Rule(洋葱中间件)
|
|
|
|
```typescript
|
|
type Rule<S, E> = (
|
|
prev: S, // 上一次 snapshot
|
|
curr: S, // 当前 snapshot
|
|
inner: (prev: S, curr: S) => Promise<[E[], number]> // 内层 rule chain
|
|
) => Promise<[E[], number]> // [effects, tickMs]
|
|
```
|
|
|
|
Rule 可以:
|
|
- **放行**:`return inner(prev, curr)`
|
|
- **Bypass**:`return [myEffects, 5000]`(不调 inner,跳过内层)
|
|
- **修饰**:先 `await inner(prev, curr)` 再追加/过滤 effects
|
|
- **变换 snapshot**:`return inner(prev, modifiedCurr)`
|
|
|
|
### Watcher(Percept 层)
|
|
|
|
```typescript
|
|
interface WatcherDef {
|
|
name: string
|
|
key: string // vitals 表的 key
|
|
collect: () => Promise<unknown> | unknown // 采集数据
|
|
shouldWake: (window: VitalWithData[]) => boolean // 唤醒判定
|
|
intervalMs?: number // 采集间隔,默认 5000
|
|
}
|
|
```
|
|
|
|
Watcher 持续采集写 vitals,唤醒判定看最近 1 分钟窗口(~12 条),关键事件 `wakeTick()` 提前唤醒 tick。
|
|
|
|
### 异步 Executor Loop
|
|
|
|
tick 循环与 effect 执行彻底解耦。tick 产生 effects 写入 events.db,独立的 `executorLoop` 后台扫描 pending effect events 并异步执行:
|
|
|
|
```
|
|
Tick Loop (sense·think) Executor Loop (act)
|
|
rebuildSnapshot → Rules scan effect events
|
|
→ write effect events ─────→ → effect-executing
|
|
→ sleep(tickMs) → execute(effect)
|
|
→ effect-acked / effect-failed
|
|
```
|
|
|
|
- **Fire-and-forget**:tick 不等待 effect 执行完成
|
|
- **去重**:inflight set + effect-acked/effect-failed 事件防止重复执行
|
|
- **可配置**:`executorScanIntervalMs`(默认 1000ms)
|
|
|
|
### Task Events & Projections
|
|
|
|
Pulse 内置任务生命周期管理。任务通过事件驱动状态机流转:
|
|
|
|
```
|
|
task-created → task-assigned → task-executing → task-acked → task-closed
|
|
→ task-given-up
|
|
```
|
|
|
|
| 类型 | 说明 |
|
|
|---|---|
|
|
| `TaskState` | 任务完整状态(id、project、title、prompt、priority、status、agent、result) |
|
|
| `PendingTasksData` | 待处理任务汇总(pendingCount、tasks、byProject) |
|
|
| `AgentCapabilityStats` | 每个 agent 的能力统计(assigned/closed/givenUp/consecutiveFailures/avgDurationMs) |
|
|
|
|
`rebuildSnapshot` 自动注入:当 `senseKeys` 包含 `'pending-tasks'` 时,snapshot 中自动包含 `pending-tasks` 和 `agent-capability-stats` 两个 projection,供 Rules 做任务分配决策。
|
|
|
|
### 存储
|
|
|
|
| 库 | 内容 | 策略 |
|
|
|---|---|---|
|
|
| `events.db` | promote/rollback/effect/effect-acked/effect-failed/error/collect/task-* | 永不压缩 |
|
|
| `vitals.db` | 系统资源/进程/网络/LLM 健康 | 可 gc |
|
|
| `objects/` | CAS(内容寻址,不可变) | 自动去重 |
|
|
|
|
### 保命层(P0 Survival)
|
|
|
|
4 个内置 Watcher + 7 个保命 Rule,零 LLM 零网络依赖:
|
|
|
|
**Watchers:**
|
|
- `system-resource` — CPU/内存/磁盘/swap
|
|
- `process-alive` — 关键进程存活
|
|
- `network` — DNS + HTTP 出站
|
|
- `error-log` — 日志关键词匹配
|
|
|
|
**Rules(洋葱顺序,最外层先执行):**
|
|
1. `panicRollback` — 保命动作连续失败 → 紧急回滚
|
|
2. `autoRollback` — promote 后大量 error → 自动回滚
|
|
3. `processWatchdog` — 进程挂了 → restart
|
|
4. `resourceGuard` — 内存/磁盘超限 → archive sessions + 清理
|
|
5. `llmWatchdog` — LLM 不通 → restart LiteLLM
|
|
6. `networkWatchdog` — 网络断了 → 通知
|
|
7. `errorEscalate` — 错误日志 → 通知 + 加速巡检
|
|
|
|
## Engine 目录
|
|
|
|
每个 Agent 维护自己的 Rule repo:
|
|
|
|
```
|
|
~/.upulse/
|
|
config.json
|
|
pulse.db / vitals.db / objects/
|
|
engine/ ← main branch(生产)
|
|
types.ts
|
|
rules/
|
|
watchers/
|
|
executors/
|
|
staging/ ← git worktree(安全实验)
|
|
```
|
|
|
|
`upulse promote` = git merge + tsc 守门 + daemon reload
|
|
`upulse rollback` = git revert + 自动恢复
|
|
|
|
## 设计文档
|
|
|
|
- [RFC #1: Pulse — Agent 的自主神经系统](https://github.com/oc-xiaoju/pulse/issues/1)
|
|
- [RFC #2: upulse CLI](https://github.com/oc-xiaoju/pulse/issues/2)
|
|
- [RFC #4: 核心洞察 — 感知·认知·行动](https://github.com/oc-xiaoju/pulse/issues/4)
|
|
- [RFC #5: 一切皆事件 — 存储模型](https://github.com/oc-xiaoju/pulse/issues/5)
|
|
- [RFC #22: 多实例管理](https://github.com/oc-xiaoju/pulse/issues/22)
|
|
- [RFC #23: Autonomic Layer + Rule Middleware Refactor](https://github.com/oc-xiaoju/pulse/issues/23)
|
|
- [Design #27: P0 保命层完整设计](https://github.com/oc-xiaoju/pulse/issues/27)
|
|
- [RFC #58: Definition Layer + Projection Engine + Rule Projections](https://github.com/oc-xiaoju/pulse/issues/58)
|
|
|
|
## License
|
|
|
|
MIT
|