Skip to content

Commit 94f2d25

Browse files
committed
fix: lint issues, add GetAgent to Runtime, wire verifyRestoredState in example
- Fix 32 errcheck/ineffassign/SA1012/unused lint issues across 7 test files - Add GetAgent(agentID) method to runtime.Manager for agent lookup - Wire verifyRestoredState() call in runtime_resurrection example - Remove ineffectual assignment in pg_store_test.go - Add nolint directive for intentional nil context test
1 parent 6c30743 commit 94f2d25

13 files changed

Lines changed: 650 additions & 44 deletions

File tree

docs/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
Welcome to the GoAgent framework documentation center.
44

5-
## Documentation Languages
5+
## Release Notes / 发布说明
6+
7+
| Version | 中文 | English |
8+
|---------|------|---------|
9+
| v0.2.0 | [发布说明](./zh/releases/v0.2.0.md) | [Release Notes](./en/releases/v0.2.0.md) |
10+
11+
## Documentation Languages / 文档语言
612

713
- **[中文文档](./zh/)** — Chinese documentation
814
- **[English Docs](./en/)** — English documentation

docs/en/releases/v0.2.0.md

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# GoAgent v0.2.0 Release Notes
2+
3+
**Release Date:** 2026-06-12
4+
**Branch:** improve
5+
**Commits:** 119 files changed, 22,634 insertions, 1,302 deletions
6+
7+
---
8+
9+
## Overview
10+
11+
v0.2.0 introduces a Runtime layer for agent lifecycle management, event sourcing for operational recovery, a dynamic workflow engine with human-in-the-loop support, and a pluggable vector store interface. The focus shifts from "agents manage themselves" to "Runtime manages agents" — agents become disposable executors.
12+
13+
---
14+
15+
## Architecture Changes
16+
17+
### Before (v0.1.x)
18+
19+
```
20+
Leader Agent
21+
├── manages sub-agents
22+
├── manages own lifecycle
23+
├── manages own memory
24+
└── single point of failure
25+
```
26+
27+
### After (v0.2.0)
28+
29+
```
30+
Runtime Layer
31+
├── manages ALL agent lifecycles
32+
├── resurrects failed agents
33+
├── replays events for state recovery
34+
35+
├── EventStore (operational recovery)
36+
│ └── "What step was I on?"
37+
38+
├── MemoryStore (cognitive recovery)
39+
│ └── "Who am I? Why did I do this?"
40+
41+
└── Agents (disposable executors)
42+
├── Leader Agent
43+
├── Sub Agents
44+
└── Custom Agents
45+
```
46+
47+
Key principle: **Agents are disposable executors. Real state lives in EventStore and MemoryStore.**
48+
49+
---
50+
51+
## New Features
52+
53+
### 1. Runtime Layer (`internal/runtime/`)
54+
55+
Agent lifecycle management with automatic resurrection.
56+
57+
```go
58+
type Runtime interface {
59+
StartAgent(ctx, agent) error
60+
StopAgent(ctx, agentID) error
61+
RestartAgent(ctx, agentID) error
62+
RestoreAgent(ctx, agentID, factory) error
63+
NotifyAgentDead(agentID, reason)
64+
RegisterAgent(agent, factory)
65+
Start(ctx) error
66+
Stop() error
67+
Stats() RuntimeStats
68+
}
69+
```
70+
71+
- `NotifyAgentDead` — non-blocking, triggers async resurrection
72+
- `RestoreAgent` — factory → replayEvents → RestoreState → Start
73+
- Concurrent shutdown with configurable timeout
74+
- Panic recovery in all agent goroutines
75+
76+
### 2. Event Sourcing (`internal/events/`)
77+
78+
EventStore interface with two implementations.
79+
80+
```go
81+
type EventStore interface {
82+
Append(ctx, streamID, events, expectedVersion) error
83+
Read(ctx, streamID, opts) ([]*Event, error)
84+
ReadAll(ctx, opts) ([]*Event, error)
85+
Subscribe(ctx, filter) (<-chan *Event, error)
86+
StreamVersion(ctx, streamID) (int64, error)
87+
}
88+
```
89+
90+
- **MemoryEventStore** — in-memory, for dev/test
91+
- **PostgresEventStore** — PostgreSQL with optimistic concurrency
92+
- 17 event types covering agent lifecycle, tasks, memory, workflow
93+
- DLQ auto-retry with MaxRetries
94+
95+
### 3. Dynamic Workflow Engine (`internal/workflow/engine/`)
96+
97+
Runtime-mutable DAG with HITL support.
98+
99+
- **MutableDAG** — AddNode/RemoveNode/AddEdge/RemoveEdge with incremental BFS cycle detection
100+
- **DynamicExecutor** — ApplyAtCheckpoint / ApplyImmediate modes
101+
- **GraphEventHub** — pub/sub for mutation notifications
102+
- **HITL** — InterruptConfig on steps, InterruptHandler, InterruptStore
103+
104+
### 4. Pluggable Vector Store (`internal/storage/`)
105+
106+
```go
107+
type VectorStore interface {
108+
Search(ctx, table, embedding, limit) ([]*SearchResult, error)
109+
AddEmbedding(ctx, table, id, embedding, metadata) error
110+
CreateCollection(ctx, name, dimension) error
111+
}
112+
```
113+
114+
- **PostgreSQL + pgvector** — production implementation
115+
- **In-memory** — dev/test implementation
116+
- Users can plug in Qdrant, Milvus, SQLite, Elasticsearch, or custom backends
117+
118+
### 5. StatefulAgent Interface (`internal/agents/base/`)
119+
120+
```go
121+
type StatefulAgent interface {
122+
RestoreState(state map[string]any) error
123+
ReplayEvents(events []*Event) error
124+
Snapshot() (map[string]any, error)
125+
}
126+
```
127+
128+
Both leader and sub agents implement this interface with compile-time checks.
129+
130+
### 6. Resurrection Plugin (`internal/plugins/resurrection/`)
131+
132+
Pluggable agent resurrection via HealthChecker interface.
133+
134+
- `HeartbeatAdapter` bridges AHP heartbeat to HealthChecker
135+
- `Supervisor` with concurrent resurrection deduplication
136+
- Factory-based recovery — each agent type provides its own factory
137+
138+
### 7. WorkflowService API (`api/core/workflow.go`, `api/service/workflow/`)
139+
140+
High-level workflow orchestration abstraction.
141+
142+
```go
143+
type WorkflowService interface {
144+
Execute(ctx, req) (*WorkflowResponse, error)
145+
ExecuteStream(ctx, req) (<-chan WorkflowEvent, error)
146+
ListWorkflows(ctx) ([]*WorkflowSummary, error)
147+
GetWorkflow(ctx, id) (*WorkflowDefinition, error)
148+
}
149+
```
150+
151+
---
152+
153+
## Bug Fixes (50 total)
154+
155+
### Storage (12)
156+
- Embedding queue dedup key mismatch (SHA256 vs MD5)
157+
- Write buffer data loss on Stop()
158+
- Transactional EnqueueTx for atomic writes
159+
- FOR UPDATE SKIP LOCKED without transaction
160+
- Reconcile threshold time arithmetic (Go duration vs PG interval)
161+
- ManagedRow connection leak (missing finalizer)
162+
- Missing migration tables (4 tables)
163+
- Circuit breaker halfOpen cleanup
164+
- safeFormatTable returning empty string
165+
- Immediate retry on flush failure
166+
- VectorSearcher dimension validation
167+
- Enqueue silent on duplicate (now returns ErrDuplicateTask)
168+
169+
### Workflow (8)
170+
- Panic recovery ordering (wg.Done after recover)
171+
- Graph executor in-degree tracking
172+
- Deadlock false positive (stepDone channel)
173+
- DynamicExecutor hang on node removal (synthetic skipped result)
174+
- stepEg.Wait() concurrent with Go()
175+
- Duplicate step ID detection
176+
- MaxAttempts=0 clamp
177+
- recomputeOrder version-check race
178+
179+
### AHP Protocol (7)
180+
- Send on closed channel (recover guard)
181+
- HeartbeatSender Start/Stop race
182+
- getRandomSuffix nil dereference
183+
- SendMessage error preservation
184+
- Protocol.Close() method
185+
- Peek() atomicity
186+
- DLQ.Remove trailing pointer
187+
188+
### Agent System (8)
189+
- WaitGroup panic in finalizeMemory
190+
- Start/Stop TOCTOU race
191+
- Process mutual exclusion
192+
- Start partial validation cleanup
193+
- subAgent ProcessStream goroutine leak
194+
- doFailover cancelled context
195+
- Dispatcher partial results
196+
- streamEg tied to stopCh
197+
198+
### Runtime (5)
199+
- Nil errgroup panic before Start()
200+
- Stop() data race on ma.stopped
201+
- Unbounded event replay (MaxReplayEvents=10000)
202+
- buildCognitiveState DB call timeout
203+
- Stop() using cancelled context
204+
205+
### Event Sourcing (5)
206+
- FromVersion inclusive/exclusive semantics
207+
- Since filter inclusive semantics
208+
- ReadAll ignoring FromVersion
209+
- PostgreSQL unique violation → ErrVersionConflict
210+
- ConcurrentAppend test verification
211+
212+
### Other (5)
213+
- SA5011 nil-pointer in 17 test files
214+
- SA1012 nil context in test
215+
- errcheck in integration tests
216+
- Mermaid diagram errors in README
217+
- safeFormatTable return value
218+
219+
---
220+
221+
## Infrastructure
222+
223+
- **CI/CD**: GitHub Actions pipeline (lint, test, integration, benchmark)
224+
- **Integration Tests**: 60+ tests across 12 test files
225+
- **Benchmarks**: 36 benchmarks with count=3, updated report
226+
- **Documentation**: Bilingual (en/zh), 12 new docs
227+
- **Examples**: 6 runnable examples in `examples/advanced/`
228+
229+
---
230+
231+
## Breaking Changes
232+
233+
| Change | Before | After |
234+
|--------|--------|-------|
235+
| `NewLeaderSupervisor` signature | 4 params | 5 params (added `eventStore`) |
236+
| `NewColdRestartStrategy` signature | 2 params | 3 params (added `checkpoint`) |
237+
| `MemoryManager` interface | 11 methods | 12 methods (added `GetLatestSessionForLeader`) |
238+
| `Repository.Vector` field | `*VectorSearcher` | `storage.VectorStore` |
239+
| `StatefulAgent` interface | `RestoreState` only | + `ReplayEvents`, `Snapshot` |
240+
241+
---
242+
243+
## Benchmark Results
244+
245+
Platform: Apple M3 Max, Go 1.26.4, darwin/arm64
246+
247+
| Category | Benchmarks | Hot (< 1μs) | Normal (1-100μs) | Cold (> 100μs) |
248+
|----------|-----------|-------------|-------------------|-----------------|
249+
| Eval | 5 | 2 | 2 | 1 |
250+
| Handler | 3 | 1 | 2 | 0 |
251+
| Tools/Core | 9 | 6 | 3 | 0 |
252+
| Distillation | 9 | 4 | 4 | 1 |
253+
| Errors | 4 | 4 | 0 | 0 |
254+
| Event Sourcing | 6 | 4 | 1 | 1 |
255+
| **Total** | **36** | **21** | **12** | **3** |
256+
257+
Selected hot-path results:
258+
259+
| Operation | ns/op | allocs/op |
260+
|-----------|-------|-----------|
261+
| ResultCreation | 0.27 | 0 |
262+
| Wrap | 0.28 | 0 |
263+
| ExactMatchEvaluator | 3.11 | 0 |
264+
| ToolExecution | 14.66 | 0 |
265+
| ParameterValidation | 7.26 | 0 |
266+
| ConflictDetection | 1,067 | 0 |
267+
| MemoryStore_Append | 563 | 7 |
268+
| MemoryStore_ConcurrentAppend | 707 | 6 |
269+
270+
---
271+
272+
## Migration Guide
273+
274+
### From v0.1.x to v0.2.0
275+
276+
1. **Runtime is optional.** Existing code using `LeaderSupervisor` continues to work. Migrate to `Runtime` when ready.
277+
278+
2. **EventStore is optional.** Existing checkpoint-based recovery continues to work. Add EventStore for richer recovery.
279+
280+
3. **VectorStore is a drop-in replacement.** `Repository.Vector` is now an interface. Existing `*VectorSearcher` satisfies it automatically.
281+
282+
4. **StatefulAgent is opt-in.** Only implement if you want your agents to support resurrection via event replay.
283+
284+
---
285+
286+
## What's Next (v0.3.0)
287+
288+
- SQLite + sqlite-vec compatibility (VectorStore interface ready)
289+
- Distributed Runtime (multi-node agent management)
290+
- Enhanced HITL (approval workflows, multi-step review)
291+
- Performance optimization (TopNFilter regression investigation)

0 commit comments

Comments
 (0)