mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-11 06:05:45 +08:00
### Motivation This PR evolves the harness from a pure execution runtime into an **observable, replayable agent evaluation platform**. The current `harness/graph` checkpoint mechanism is insufficient for true event-sourced introspection—we need append-only event logs capturing every tool call, state transition, memory write, and approval decision, enabling deterministic replay, fork/diff, postmortem analysis, and time-travel debugging. ### Key Design Goals 1. **Event-Sourced Execution Model** Replace coarse checkpoints with granular, append-only event logs. Every operation becomes a durable event: tool invocation, state mutation, memory update, human approval. This unlocks deterministic replay, branching execution histories, and regression datasets derived directly from production failures. 2. **First-Class Replay & Evaluation Loop** Replay is not an afterthought—it is a core primitive. A single live run seeds an offline corpus that supports: repeated playback, model substitution, tool result mocking, and strategy comparison. The harness graduates from "executor" to "continuous evaluation platform" where failed production traces convert directly into offline regression suites. 3. **Operational Observability** Beyond raw traces, expose metrics that prove stability over time: - Tool success / failure rates - Approval latency distributions - Retry frequencies - Checkpoint restore reliability - Memory retrieval quality - Cost per completed task - Fork replay pass rates The underlying thesis: the bottleneck for most agent systems is not execution capability, but the inability to **demonstrate continuous, measurable improvement**. ### Type of change - [x] New Feature (non-breaking change which adds functionality)
33 lines
809 B
Go
33 lines
809 B
Go
package events
|
|
|
|
import (
|
|
"sync/atomic"
|
|
)
|
|
|
|
// LogicalClock is a monotonic logical clock that provides a total order
|
|
// for events within a process. It is safe for concurrent use.
|
|
type LogicalClock struct {
|
|
value atomic.Uint64
|
|
}
|
|
|
|
// NewLogicalClock creates a new LogicalClock starting at 0.
|
|
func NewLogicalClock() *LogicalClock {
|
|
return &LogicalClock{}
|
|
}
|
|
|
|
// Tick atomically increments the clock and returns the new value.
|
|
func (c *LogicalClock) Tick() uint64 {
|
|
return c.value.Add(1)
|
|
}
|
|
|
|
// Now returns the current clock value without incrementing.
|
|
func (c *LogicalClock) Now() uint64 {
|
|
return c.value.Load()
|
|
}
|
|
|
|
// Reset resets the clock to zero. Use with caution — this should only
|
|
// be done when starting a completely independent execution context.
|
|
func (c *LogicalClock) Reset() {
|
|
c.value.Store(0)
|
|
}
|