fix(agent): 修复流式推理与工具参数重试
This commit is contained in:
66
backend/internal/app/cloud_agent_stream.go
Normal file
66
backend/internal/app/cloud_agent_stream.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unicode/utf8"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"infinite-canvas/backend/internal/model"
|
||||
"infinite-canvas/backend/internal/repository"
|
||||
)
|
||||
|
||||
// Publish upstream deltas to the same durable, revisioned transcript used by
|
||||
// Agent SSE/replay. Each flush re-reads state; never overwrite a scheduler's
|
||||
// checkpoint with the snapshot from when the model request started.
|
||||
func newCloudAgentStreamPublisher(s *Service, userID, taskID, kind string) *taskTextStreamPublisher {
|
||||
p := newTaskTextStreamPublisher(s, userID, taskID)
|
||||
written := 0
|
||||
p.sink = func(delta string) error {
|
||||
remaining := 32000 - written
|
||||
if remaining <= 0 {
|
||||
return nil
|
||||
}
|
||||
if len(delta) > remaining {
|
||||
delta = delta[:remaining]
|
||||
for !utf8.ValidString(delta) {
|
||||
delta = delta[:len(delta)-1]
|
||||
}
|
||||
}
|
||||
if delta == "" {
|
||||
return nil
|
||||
}
|
||||
for attempt := 0; attempt < 3; attempt++ {
|
||||
run, err := s.repo.CloudAgentForActiveTask(userID, taskID)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = s.repo.MutateCloudAgent(userID, run.ID, run.Revision, func(current *model.CloudAgentExecution, _ *repository.Repository) error {
|
||||
state, err := cloudAgentDecode(current)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if state.ActiveTaskID != taskID || (current.Status != "running" && current.Status != "queued") {
|
||||
return nil
|
||||
}
|
||||
messageID := taskID
|
||||
if kind == "reasoning_delta" {
|
||||
messageID += ":reasoning"
|
||||
}
|
||||
state.event(run.ID, kind, map[string]any{"messageId": messageID, "text": delta})
|
||||
return cloudAgentSave(current, &state)
|
||||
})
|
||||
if errors.Is(err, repository.ErrCreationConflict) {
|
||||
continue
|
||||
}
|
||||
if err == nil {
|
||||
written += len(delta)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return repository.ErrCreationConflict
|
||||
}
|
||||
return p
|
||||
}
|
||||
Reference in New Issue
Block a user