feat(loop): agent loop(8 轮 + checkpoint + 流式 + 记忆注入/提取 + trace + 工具超时回喂)
This commit is contained in:
1 parent
01a4e29f84
commit
71697ca4f8
12 files changed
+1292
No files matched your search
@@ -0,0 +1,46 @@
|
||||
package loop
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/persist"
|
||||
)
|
||||
|
||||
// checkpointState is the durable snapshot persisted at every step. Carrying the
|
||||
// message window and the step index lets a long-running task be resumed from the
|
||||
// latest checkpoint without losing context (design §1 durable execution).
|
||||
type checkpointState struct {
|
||||
Step int `json:"step"`
|
||||
Messages []model.Message `json:"messages"`
|
||||
StopReason string `json:"stop_reason,omitempty"`
|
||||
}
|
||||
|
||||
// saveCheckpoint persists a snapshot at step. It never fails the run: a nil store
|
||||
// is a no-op and a marshal/save error is logged.
|
||||
func (l *Loop) saveCheckpoint(ctx context.Context, sessionID string, step int, messages []model.Message, stopReason string) {
|
||||
if l.checkpoint == nil {
|
||||
return
|
||||
}
|
||||
state := checkpointState{
|
||||
Step: step,
|
||||
Messages: messages,
|
||||
StopReason: stopReason,
|
||||
}
|
||||
buf, err := json.Marshal(state)
|
||||
if err != nil {
|
||||
l.log.Warn("checkpoint marshal", "step", step, "error", err)
|
||||
return
|
||||
}
|
||||
cp := &persist.Checkpoint{
|
||||
ID: fmt.Sprintf("%s:%d", sessionID, step),
|
||||
AgentID: sessionID,
|
||||
Step: step,
|
||||
State: buf,
|
||||
}
|
||||
if err := l.checkpoint.Save(ctx, cp); err != nil {
|
||||
l.log.Warn("checkpoint save", "step", step, "error", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user