feat(volces): 接入任务兼容查询与上游取消

This commit is contained in:
2026-07-22 00:25:22 +08:00
parent ddd68cfebd
commit d7951cfdd2
11 changed files with 885 additions and 55 deletions
+56
View File
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/auth"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/clients"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
"github.com/riverqueue/river/rivertype"
)
@@ -104,6 +105,61 @@ func (s *Service) CancelTask(ctx context.Context, taskID string, user *auth.User
}, nil
}
// CancelVolcesVideoTask extends local queue cancellation with the official
// Volces DELETE call once a video task has a persisted remote task id.
func (s *Service) CancelVolcesVideoTask(ctx context.Context, task store.GatewayTask, user *auth.User) (TaskCancelResult, error) {
local, err := s.CancelTask(ctx, task.ID, user)
if err != nil || local.Cancelled || strings.TrimSpace(task.RemoteTaskID) == "" {
return local, err
}
if taskCancelTerminalStatus(task.Status) {
return local, nil
}
var latest store.TaskAttempt
for _, attempt := range task.Attempts {
if attempt.PlatformModelID != "" && (latest.AttemptNo == 0 || attempt.AttemptNo >= latest.AttemptNo) {
latest = attempt
}
}
candidate, found, err := s.store.GetRuntimeModelCandidateForRemoteTask(ctx, latest.PlatformModelID, latest.PlatformID)
if err != nil {
return TaskCancelResult{}, err
}
if !found || !isVolcesCancellationCandidate(candidate) {
return local, nil
}
httpClient, err := s.httpClientForCandidate(candidate, false)
if err != nil {
return TaskCancelResult{}, err
}
_, _, err = (clients.VolcesClient{HTTPClient: httpClient}).DeleteVideoTask(ctx, clients.Request{
Kind: "videos.generations", Candidate: candidate, HTTPClient: httpClient, RemoteTaskID: task.RemoteTaskID,
})
if err != nil {
return TaskCancelResult{}, err
}
cancelledTask, cancelled, err := s.store.CancelSubmittedTask(ctx, task.ID, task.ExecutionToken, "任务已由火山引擎取消")
if err != nil {
return TaskCancelResult{}, err
}
if !cancelled {
latestTask, latestErr := s.store.GetTask(ctx, task.ID)
if latestErr == nil {
return taskCancelUnavailable(latestTask, "任务状态已变化,未覆盖本地最终状态"), nil
}
return local, nil
}
if err := s.emit(ctx, cancelledTask.ID, "task.cancelled", "cancelled", "cancelled", 1, "任务已由火山引擎取消", map[string]any{"taskId": cancelledTask.ID, "reason": "upstream_cancel"}, cancelledTask.RunMode == "simulation"); err != nil {
return TaskCancelResult{}, err
}
return TaskCancelResult{TaskID: cancelledTask.ID, Cancelled: true, Cancellable: true, Submitted: true, Message: "任务已由火山引擎取消"}, nil
}
func isVolcesCancellationCandidate(candidate store.RuntimeModelCandidate) bool {
provider := strings.ToLower(strings.TrimSpace(candidate.Provider))
return provider == "volces" || provider == "volces-openai"
}
func taskCancelUnavailable(task store.GatewayTask, message string) TaskCancelResult {
return TaskCancelResult{
TaskID: task.ID,