docs: rewrite README — philosophy, three-layer model, Agent-in-the-Loop
小橘 🍊(NEKO Team)
This commit is contained in:
parent
98bee0aedd
commit
cedd46a18d
62
README.md
62
README.md
@ -1,37 +1,72 @@
|
|||||||
# OGraph
|
# OGraph
|
||||||
|
|
||||||
**Event Sourcing + Projection + Reaction engine on Cloudflare Workers.**
|
**Event Sourcing + Projection + Reaction engine for Agent ecosystems.**
|
||||||
|
|
||||||
Part of the [Uncaged](https://github.com/oc-xiaoju/uncaged) ecosystem.
|
Part of the [Uncaged](https://github.com/oc-xiaoju/uncaged) ecosystem.
|
||||||
|
|
||||||
|
## Philosophy
|
||||||
|
|
||||||
|
1. **Event is fact** — immutable, append-only, no logic
|
||||||
|
2. **Projection is cache** — lazy, closed-world, on-demand computation
|
||||||
|
3. **Intelligence lives in the Agent, not the Engine** — Agent-in-the-Loop
|
||||||
|
|
||||||
|
### Why not Kafka?
|
||||||
|
|
||||||
|
| | Kafka | OGraph |
|
||||||
|
|---|---|---|
|
||||||
|
| Metaphor | Ballistic missile (design, fire) | Guided missile (adjust in flight) |
|
||||||
|
| Pipeline | Pre-defined by humans | Agent defines/adjusts at runtime |
|
||||||
|
| Computation | Eager (continuous update) | **Lazy** (on-demand) |
|
||||||
|
| JOIN | ✅ KTable synchronized | ❌ Projections are independently lazy |
|
||||||
|
| Aggregation | Pre-set materialized views | Actor (Agent) assembles in real-time |
|
||||||
|
| Core assumption | Humans design everything upfront | **Agent-in-the-Loop: runtime decisions** |
|
||||||
|
|
||||||
|
Traditional Event Sourcing (Kafka, EventStoreDB) assumes pipelines are designed, deployed, and maintained by human developers. OGraph assumes an Agent with decision-making capability dynamically defines Projections, adjusts Watch lists, and assembles aggregations at runtime.
|
||||||
|
|
||||||
|
This is not a feature trade-off. It's a paradigm difference.
|
||||||
|
|
||||||
|
### Lazy Update — a logical necessity
|
||||||
|
|
||||||
|
1. Agent can define new Projections at any time → can't assume all Projections are deployed
|
||||||
|
2. → Must be Lazy (compute on demand)
|
||||||
|
3. → No consistent cross-Projection snapshot → abandon JOIN
|
||||||
|
|
||||||
|
Each step is logically inevitable. From a single assumption — "Agent defines Projections at runtime" — the entire computation model follows.
|
||||||
|
|
||||||
|
## Three-Layer Modeling
|
||||||
|
|
||||||
|
### Layer 1: Event — Facts
|
||||||
|
Immutable records of what happened. No judgment, no derived logic.
|
||||||
|
|
||||||
|
### Layer 2: Projection — Cache
|
||||||
|
Deterministic computation over event streams. Core constraint: **computational closure** — expression inputs are only `$state`, `$event`, `$params`. Cannot query other Projections or make external calls.
|
||||||
|
|
||||||
|
### Layer 3: Actor — Behavior
|
||||||
|
Observes multiple Projections, executes complex logic and side effects. Watch lists are **dynamic** — derived from data, not hardcoded.
|
||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
|
|
||||||
| Package | Description | npm |
|
| Package | Description | npm |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| [`@uncaged/ograph`](packages/engine/) | CF Worker engine — events, projections, reactions | [](https://www.npmjs.com/package/@uncaged/ograph) |
|
| [`@uncaged/ograph`](packages/engine/) | CF Worker engine — events, projections, reactions | [](https://www.npmjs.com/package/@uncaged/ograph) |
|
||||||
| [`@uncaged/ograph-cli`](packages/cli/) | CLI for managing OGraph instances | [](https://www.npmjs.com/package/@uncaged/ograph-cli) |
|
| [`@uncaged/ograph-cli`](packages/cli/) | CLI for managing OGraph instances | [](https://www.npmjs.com/package/@uncaged/ograph-cli) |
|
||||||
|
| [`@uncaged/ograph-dispatcher`](packages/dispatcher/) | Local daemon — polls projections, notifies Agent when idle | |
|
||||||
## Core Concepts
|
|
||||||
|
|
||||||
- **Event** — Immutable facts with typed properties and object references
|
|
||||||
- **Projection** — Derived state computed incrementally from events via reducers
|
|
||||||
- **Reaction** — Side effects triggered by projection state changes (webhooks, event emission, handlers)
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -g @uncaged/ograph-cli
|
npm install -g @uncaged/ograph-cli
|
||||||
ograph deploy # Deploy to Cloudflare Workers
|
ograph deploy # Deploy to Cloudflare Workers
|
||||||
ograph event-def add # Define event types
|
ograph event-defs list # List event types
|
||||||
ograph event add # Emit events
|
ograph events emit # Emit events
|
||||||
ograph projection list # Query projections
|
ograph schema # View all definitions
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
npm test # Run all tests
|
npm test # Run all tests (163+)
|
||||||
cd packages/engine && npm run dev # Local dev server
|
cd packages/engine && npm run dev # Local dev server
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -39,8 +74,11 @@ cd packages/engine && npm run dev # Local dev server
|
|||||||
|
|
||||||
- **D1** for storage (events, projections, reactions)
|
- **D1** for storage (events, projections, reactions)
|
||||||
- **Hono** for API routing
|
- **Hono** for API routing
|
||||||
- **Incremental reduce** — projections track `last_event_id` for O(delta) updates
|
- **Lazy incremental reduce** — projections track `last_event_id` for O(delta) updates
|
||||||
|
- **Projection health** — errored projections stop updating, auto-recover when fixed
|
||||||
- **Dynamic handlers** — `new Function()` sandboxed execution with emit/log/kv API injection
|
- **Dynamic handlers** — `new Function()` sandboxed execution with emit/log/kv API injection
|
||||||
|
- **API Key** — `ogk_` prefix, SHA-256 hash, event type whitelist
|
||||||
|
- **Structured errors** — `{ error: { code, message } }`
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user