feat(task): replace built-in task adaptors with a sandboxed JS plugin system (#7076)

This commit is contained in:
Calcium-Ion
2026-08-29 18:51:57 +08:00
committed by GitHub
parent 7037ac15bd
commit eb48396d5f
336 changed files with 52333 additions and 6369 deletions
+22 -9
View File
@@ -850,6 +850,14 @@ func (info *RelayInfo) HasSendResponse() bool {
return info.FirstResponseTime.After(info.StartTime)
}
type OriginTaskRef struct {
TaskID string
UpstreamTaskID string
Action string
Status string
Data []byte
}
type TaskRelayInfo struct {
Action string
OriginTaskID string
@@ -859,6 +867,10 @@ type TaskRelayInfo struct {
ConsumeQuota bool
// OriginTasks are plugin-declared public-task dependencies resolved by the
// host. Driver hooks receive these as ctx.originTasks; presenters do not.
OriginTasks []OriginTaskRef
// LockedChannel holds the full channel object when the request is bound to
// a specific channel (e.g., remix on origin task's channel). Stored as any
// to avoid an import cycle with model; callers type-assert to *model.Channel.
@@ -948,15 +960,16 @@ func (t *TaskSubmitReq) UnmarshalMetadata(v any) error {
}
type TaskInfo struct {
Code int `json:"code"`
TaskID string `json:"task_id"`
Status string `json:"status"`
Reason string `json:"reason,omitempty"`
Url string `json:"url,omitempty"`
RemoteUrl string `json:"remote_url,omitempty"`
Progress string `json:"progress,omitempty"`
CompletionTokens int `json:"completion_tokens,omitempty"` // 用于按倍率计费
TotalTokens int `json:"total_tokens,omitempty"` // 用于按倍率计费
Code int `json:"code"`
TaskID string `json:"task_id"`
Status string `json:"status"`
Reason string `json:"reason,omitempty"`
Url string `json:"url,omitempty"`
RemoteUrl string `json:"remote_url,omitempty"`
Progress string `json:"progress,omitempty"`
CompletionTokens int `json:"completion_tokens,omitempty"` // 用于按倍率计费
TotalTokens int `json:"total_tokens,omitempty"` // 用于按倍率计费
UsageFacts map[string]any `json:"usage_facts,omitempty"`
}
func FailTaskInfo(reason string) *TaskInfo {
+2 -2
View File
@@ -238,9 +238,9 @@ func ValidateMultipartDirect(c *gin.Context, info *RelayInfo) *dto.TaskError {
return taskErr
}
action := constant.TaskActionTextGenerate
action := constant.TaskActionTextToVideo
if hasInputReference {
action = constant.TaskActionGenerate
action = constant.TaskActionImageToVideo
}
if strings.HasPrefix(model, "sora-2") {
+2 -2
View File
@@ -74,7 +74,7 @@ func TestValidateMultipartDirectNormalizesImageField(t *testing.T) {
storedReq, err := GetTaskRequest(context)
require.NoError(t, err)
require.Equal(t, []string{"https://example.com/first.png"}, storedReq.Images)
require.Equal(t, constant.TaskActionGenerate, info.Action)
require.Equal(t, constant.TaskActionImageToVideo, info.Action)
}
// TestTaskDurationBounds guards the billing invariant that user-supplied
@@ -130,7 +130,7 @@ func TestTaskDurationBounds(t *testing.T) {
})
t.Run(tt.name+" (basic task request)", func(t *testing.T) {
context, info := newContext(t, tt.body)
taskErr := ValidateBasicTaskRequest(context, info, constant.TaskActionGenerate)
taskErr := ValidateBasicTaskRequest(context, info, constant.TaskActionImageToVideo)
if tt.wantErr {
require.NotNil(t, taskErr)
require.Equal(t, "invalid_seconds", taskErr.Code)