Rename CheckpointStatus to AgentStatus
The status values describe the agent state, not the checkpoint data state. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -29,7 +29,7 @@ import (
|
||||
// that may have been active (including handoff targets).
|
||||
func Restore(
|
||||
ctx context.Context,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
registry AgentRegistry,
|
||||
) (*Result, error) {
|
||||
@@ -40,10 +40,6 @@ func Restore(
|
||||
if cp == nil {
|
||||
return nil, fmt.Errorf("cannot restore: no checkpoint for run %s", runID)
|
||||
}
|
||||
if cp.Version != CheckpointVersion {
|
||||
return nil, fmt.Errorf("cannot restore: unsupported checkpoint version %d", cp.Version)
|
||||
}
|
||||
|
||||
agent, err := registry.Agent(cp.AgentName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot resolve agent %q: %w", cp.AgentName, err)
|
||||
@@ -56,17 +52,17 @@ func restoreCheckpoint(
|
||||
ctx context.Context,
|
||||
agent *Agent,
|
||||
cp *Checkpoint,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
registry AgentRegistry,
|
||||
) (*Result, error) {
|
||||
emitHook(agent, func(h RunHooks) { h.OnRunRestore(ctx, agent, cp) })
|
||||
|
||||
switch cp.Status {
|
||||
case CheckpointStatusSuspended:
|
||||
case AgentStatusSuspended:
|
||||
return restoreSuspended(ctx, agent, cp, store, runID, registry)
|
||||
|
||||
case CheckpointStatusAwaitingApproval:
|
||||
case AgentStatusAwaitingApproval:
|
||||
return restoreAwaitingApproval(ctx, agent, cp, store, runID, registry)
|
||||
|
||||
default:
|
||||
@@ -78,7 +74,7 @@ func restoreSuspended(
|
||||
ctx context.Context,
|
||||
agent *Agent,
|
||||
cp *Checkpoint,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
registry AgentRegistry,
|
||||
) (*Result, error) {
|
||||
@@ -94,7 +90,7 @@ func continueFromMessages(
|
||||
agent *Agent,
|
||||
messages []llm.Message,
|
||||
cp *Checkpoint,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
) (*Result, error) {
|
||||
messagesCopy := make([]llm.Message, len(messages))
|
||||
@@ -121,7 +117,7 @@ func continueFromMessages(
|
||||
skipSessionLoad: true,
|
||||
initialUsage: cp.Usage,
|
||||
initialTurns: cp.Turns,
|
||||
checkpointStore: store,
|
||||
checkpointer: store,
|
||||
runID: runID,
|
||||
toolUsedInRun: cp.ToolUsedInRun,
|
||||
},
|
||||
@@ -132,7 +128,7 @@ func restoreNestedSuspended(
|
||||
ctx context.Context,
|
||||
agent *Agent,
|
||||
cp *Checkpoint,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
registry AgentRegistry,
|
||||
) (*Result, error) {
|
||||
@@ -277,7 +273,7 @@ func restoreAwaitingApproval(
|
||||
ctx context.Context,
|
||||
agent *Agent,
|
||||
cp *Checkpoint,
|
||||
store CheckpointStore,
|
||||
store Checkpointer,
|
||||
runID string,
|
||||
registry AgentRegistry,
|
||||
) (*Result, error) {
|
||||
@@ -338,11 +334,11 @@ func restoreAwaitingApproval(
|
||||
ie,
|
||||
ResumeInput{Approvals: cp.ApprovalInput},
|
||||
runOpts{
|
||||
callLLM: blockingCallLLM,
|
||||
onEvent: noopEvent,
|
||||
checkpointStore: store,
|
||||
runID: runID,
|
||||
toolUsedInRun: cp.ToolUsedInRun,
|
||||
callLLM: blockingCallLLM,
|
||||
onEvent: noopEvent,
|
||||
checkpointer: store,
|
||||
runID: runID,
|
||||
toolUsedInRun: cp.ToolUsedInRun,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,18 +26,18 @@ import (
|
||||
"go.probo.inc/probo/pkg/llm"
|
||||
)
|
||||
|
||||
type memoryCheckpointStore struct {
|
||||
type memoryCheckpointer struct {
|
||||
mu sync.Mutex
|
||||
checkpoints map[string]*agent.Checkpoint
|
||||
}
|
||||
|
||||
func newMemoryCheckpointStore() *memoryCheckpointStore {
|
||||
return &memoryCheckpointStore{
|
||||
func newMemoryCheckpointer() *memoryCheckpointer {
|
||||
return &memoryCheckpointer{
|
||||
checkpoints: make(map[string]*agent.Checkpoint),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *memoryCheckpointStore) Save(_ context.Context, runID string, cp *agent.Checkpoint) error {
|
||||
func (s *memoryCheckpointer) Save(_ context.Context, runID string, cp *agent.Checkpoint) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
@@ -46,7 +46,7 @@ func (s *memoryCheckpointStore) Save(_ context.Context, runID string, cp *agent.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *memoryCheckpointStore) Load(_ context.Context, runID string) (*agent.Checkpoint, error) {
|
||||
func (s *memoryCheckpointer) Load(_ context.Context, runID string) (*agent.Checkpoint, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
@@ -59,14 +59,6 @@ func (s *memoryCheckpointStore) Load(_ context.Context, runID string) (*agent.Ch
|
||||
return &clone, nil
|
||||
}
|
||||
|
||||
func (s *memoryCheckpointStore) Delete(_ context.Context, runID string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
delete(s.checkpoints, runID)
|
||||
return nil
|
||||
}
|
||||
|
||||
type simpleRegistry struct {
|
||||
agents map[string]*agent.Agent
|
||||
}
|
||||
@@ -87,7 +79,7 @@ func TestRestore(t *testing.T) {
|
||||
func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
registry := &simpleRegistry{agents: map[string]*agent.Agent{}}
|
||||
|
||||
_, err := agent.Restore(
|
||||
@@ -102,41 +94,6 @@ func TestRestore(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"unsupported checkpoint version returns error",
|
||||
func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
err := store.Save(context.Background(), "run-1", &agent.Checkpoint{
|
||||
Version: 999,
|
||||
Status: agent.CheckpointStatusSuspended,
|
||||
AgentName: "test-agent",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
registry := &simpleRegistry{
|
||||
agents: map[string]*agent.Agent{
|
||||
"test-agent": agent.New(
|
||||
"test-agent",
|
||||
newTestClient(&mockProvider{}),
|
||||
agent.WithModel("test-model"),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
_, err = agent.Restore(
|
||||
context.Background(),
|
||||
store,
|
||||
"run-1",
|
||||
registry,
|
||||
)
|
||||
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "unsupported checkpoint version")
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"suspended checkpoint restores and completes",
|
||||
func(t *testing.T) {
|
||||
@@ -155,10 +112,9 @@ func TestRestore(t *testing.T) {
|
||||
agent.WithModel("test-model"),
|
||||
)
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-suspended", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusSuspended,
|
||||
Status: agent.AgentStatusSuspended,
|
||||
AgentName: "test-agent",
|
||||
Messages: []llm.Message{
|
||||
{
|
||||
@@ -217,10 +173,9 @@ func TestRestore(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-approval", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusAwaitingApproval,
|
||||
Status: agent.AgentStatusAwaitingApproval,
|
||||
AgentName: "test-agent",
|
||||
Messages: []llm.Message{
|
||||
{
|
||||
@@ -303,10 +258,9 @@ func TestRestore(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-approved", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusAwaitingApproval,
|
||||
Status: agent.AgentStatusAwaitingApproval,
|
||||
AgentName: "test-agent",
|
||||
Messages: []llm.Message{
|
||||
{
|
||||
@@ -370,10 +324,9 @@ func TestRestore(t *testing.T) {
|
||||
agent.WithModel("test-model"),
|
||||
)
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-nested", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusAwaitingApproval,
|
||||
Status: agent.AgentStatusAwaitingApproval,
|
||||
AgentName: "test-agent",
|
||||
Messages: []llm.Message{
|
||||
{
|
||||
@@ -401,13 +354,11 @@ func TestRestore(t *testing.T) {
|
||||
},
|
||||
InnerCheckpoints: map[string]*agent.Checkpoint{
|
||||
"tc_inner_1": {
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusAwaitingApproval,
|
||||
Status: agent.AgentStatusAwaitingApproval,
|
||||
AgentName: "inner-agent-1",
|
||||
},
|
||||
"tc_inner_2": {
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusAwaitingApproval,
|
||||
Status: agent.AgentStatusAwaitingApproval,
|
||||
AgentName: "inner-agent-2",
|
||||
},
|
||||
},
|
||||
@@ -452,10 +403,9 @@ func TestRestore(t *testing.T) {
|
||||
func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-unknown", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatusSuspended,
|
||||
Status: agent.AgentStatusSuspended,
|
||||
AgentName: "missing-agent",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -487,10 +437,9 @@ func TestRestore(t *testing.T) {
|
||||
agent.WithModel("test-model"),
|
||||
)
|
||||
|
||||
store := newMemoryCheckpointStore()
|
||||
store := newMemoryCheckpointer()
|
||||
err := store.Save(context.Background(), "run-bad-status", &agent.Checkpoint{
|
||||
Version: 1,
|
||||
Status: agent.CheckpointStatus("bogus"),
|
||||
Status: agent.AgentStatus("bogus"),
|
||||
AgentName: "test-agent",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -49,7 +49,7 @@ type (
|
||||
skipSessionLoad bool
|
||||
initialUsage llm.Usage
|
||||
initialTurns int
|
||||
checkpointStore CheckpointStore
|
||||
checkpointer Checkpointer
|
||||
runID string
|
||||
toolUsedInRun bool
|
||||
}
|
||||
@@ -77,9 +77,9 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func WithCheckpointStore(store CheckpointStore, runID string) RunOption {
|
||||
func WithCheckpointer(cp Checkpointer, runID string) RunOption {
|
||||
return func(o *runOpts) {
|
||||
o.checkpointStore = store
|
||||
o.checkpointer = cp
|
||||
o.runID = runID
|
||||
}
|
||||
}
|
||||
@@ -222,12 +222,11 @@ func (s *loopState) finishRun(ctx context.Context, result *Result, err error) (*
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *loopState) buildCheckpoint(status CheckpointStatus) *Checkpoint {
|
||||
func (s *loopState) buildCheckpoint(status AgentStatus) *Checkpoint {
|
||||
msgsCopy := make([]llm.Message, len(s.messages))
|
||||
copy(msgsCopy, s.messages)
|
||||
|
||||
return &Checkpoint{
|
||||
Version: CheckpointVersion,
|
||||
Status: status,
|
||||
AgentName: s.agent.name,
|
||||
Messages: msgsCopy,
|
||||
@@ -381,11 +380,11 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
if ch := stopSignalFrom(ctx); ch != nil {
|
||||
select {
|
||||
case <-ch:
|
||||
cp := s.buildCheckpoint(CheckpointStatusSuspended)
|
||||
cp := s.buildCheckpoint(AgentStatusSuspended)
|
||||
se := &SuspendedError{RunID: s.opts.runID}
|
||||
|
||||
if s.opts.checkpointStore != nil && s.opts.runID != "" {
|
||||
if saveErr := s.opts.checkpointStore.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
if s.opts.checkpointer != nil && s.opts.runID != "" {
|
||||
if saveErr := s.opts.checkpointer.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
s.logger.ErrorCtx(ctx, "cannot save suspension checkpoint", log.Error(saveErr))
|
||||
se.Checkpoint = cp
|
||||
}
|
||||
@@ -552,14 +551,14 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
|
||||
if err != nil {
|
||||
if se, ok := errors.AsType[*SuspendedError](err); ok {
|
||||
outerCP := s.buildCheckpoint(CheckpointStatusSuspended)
|
||||
outerCP := s.buildCheckpoint(AgentStatusSuspended)
|
||||
if se.Checkpoint != nil {
|
||||
outerCP.AllToolCalls = se.Checkpoint.AllToolCalls
|
||||
outerCP.InnerCheckpoints = se.Checkpoint.InnerCheckpoints
|
||||
outerCP.CompletedCalls = se.Checkpoint.CompletedCalls
|
||||
}
|
||||
if s.opts.checkpointStore != nil && s.opts.runID != "" {
|
||||
if saveErr := s.opts.checkpointStore.Save(ctx, s.opts.runID, outerCP); saveErr != nil {
|
||||
if s.opts.checkpointer != nil && s.opts.runID != "" {
|
||||
if saveErr := s.opts.checkpointer.Save(ctx, s.opts.runID, outerCP); saveErr != nil {
|
||||
s.logger.ErrorCtx(ctx, "cannot save checkpoint", log.Error(saveErr))
|
||||
}
|
||||
}
|
||||
@@ -576,11 +575,11 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
msgsCopy := make([]llm.Message, len(s.messages))
|
||||
copy(msgsCopy, s.messages)
|
||||
|
||||
if s.opts.checkpointStore != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(CheckpointStatusAwaitingApproval)
|
||||
if s.opts.checkpointer != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(AgentStatusAwaitingApproval)
|
||||
cp.PendingToolCalls = nae.allToolCalls
|
||||
cp.PendingApprovals = nae.pendingApprovals
|
||||
if saveErr := s.opts.checkpointStore.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
if saveErr := s.opts.checkpointer.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
s.logger.ErrorCtx(ctx, "cannot save approval checkpoint", log.Error(saveErr))
|
||||
}
|
||||
}
|
||||
@@ -610,16 +609,15 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
msgsCopy := make([]llm.Message, len(s.messages))
|
||||
copy(msgsCopy, s.messages)
|
||||
|
||||
if s.opts.checkpointStore != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(CheckpointStatusAwaitingApproval)
|
||||
if s.opts.checkpointer != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(AgentStatusAwaitingApproval)
|
||||
cp.PendingToolCalls = nie.inner.ToolCalls
|
||||
cp.PendingApprovals = nie.inner.PendingApprovals
|
||||
cp.AllToolCalls = nie.allToolCalls
|
||||
cp.CompletedCalls = nie.completedCalls
|
||||
cp.InnerCheckpoints = map[string]*Checkpoint{
|
||||
nie.toolCallID: {
|
||||
Version: CheckpointVersion,
|
||||
Status: CheckpointStatusAwaitingApproval,
|
||||
Status: AgentStatusAwaitingApproval,
|
||||
AgentName: nie.inner.Agent.name,
|
||||
Messages: nie.inner.Messages,
|
||||
Usage: nie.inner.Usage,
|
||||
@@ -628,7 +626,7 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
PendingApprovals: nie.inner.PendingApprovals,
|
||||
},
|
||||
}
|
||||
if saveErr := s.opts.checkpointStore.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
if saveErr := s.opts.checkpointer.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
s.logger.ErrorCtx(ctx, "cannot save nested approval checkpoint", log.Error(saveErr))
|
||||
}
|
||||
}
|
||||
@@ -694,9 +692,9 @@ func coreLoop(ctx context.Context, startAgent *Agent, inputMessages []llm.Messag
|
||||
}
|
||||
|
||||
// Save incremental checkpoint after completed tool-call turn.
|
||||
if s.opts.checkpointStore != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(CheckpointStatusSuspended)
|
||||
if saveErr := s.opts.checkpointStore.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
if s.opts.checkpointer != nil && s.opts.runID != "" {
|
||||
cp := s.buildCheckpoint(AgentStatusSuspended)
|
||||
if saveErr := s.opts.checkpointer.Save(ctx, s.opts.runID, cp); saveErr != nil {
|
||||
s.logger.ErrorCtx(ctx, "cannot save checkpoint", log.Error(saveErr))
|
||||
}
|
||||
}
|
||||
@@ -1008,8 +1006,7 @@ func executeParallel(
|
||||
|
||||
outerSE := &SuspendedError{
|
||||
Checkpoint: &Checkpoint{
|
||||
Version: CheckpointVersion,
|
||||
Status: CheckpointStatusSuspended,
|
||||
Status: AgentStatusSuspended,
|
||||
AllToolCalls: toolCalls,
|
||||
InnerCheckpoints: innerCheckpoints,
|
||||
CompletedCalls: completed,
|
||||
@@ -1414,7 +1411,7 @@ func resumeWithOpts(ctx context.Context, interrupted *InterruptedError, input Re
|
||||
skipSessionLoad: true,
|
||||
initialUsage: interrupted.Usage,
|
||||
initialTurns: interrupted.Turns,
|
||||
checkpointStore: ro.checkpointStore,
|
||||
checkpointer: ro.checkpointer,
|
||||
runID: ro.runID,
|
||||
toolUsedInRun: ro.toolUsedInRun,
|
||||
},
|
||||
@@ -1497,7 +1494,7 @@ func resumeNested(ctx context.Context, interrupted *InterruptedError, input Resu
|
||||
skipSessionLoad: true,
|
||||
initialUsage: outer.usage,
|
||||
initialTurns: outer.turns,
|
||||
checkpointStore: ro.checkpointStore,
|
||||
checkpointer: ro.checkpointer,
|
||||
runID: ro.runID,
|
||||
toolUsedInRun: ro.toolUsedInRun,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user