132 lines
4.6 KiB
Go
132 lines
4.6 KiB
Go
package acp
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"xworkmate-bridge/internal/router"
|
|
"xworkmate-bridge/internal/shared"
|
|
)
|
|
|
|
const (
|
|
openClawShortTaskMinutes = 10
|
|
openClawLongTaskMinutes = 30
|
|
openClawComplexTaskMinutes = 60
|
|
)
|
|
|
|
type OpenClawTaskRecord struct {
|
|
SessionID string
|
|
ThreadID string
|
|
TurnID string
|
|
RunID string
|
|
SessionKey string
|
|
GatewayProviderID string
|
|
TaskLoadClass string
|
|
RuntimeBudgetMinutes int
|
|
StartedAt time.Time
|
|
DeadlineAt time.Time
|
|
ProgressStage string
|
|
ProgressMessage string
|
|
PreparedArtifact *openClawPreparedArtifactScope
|
|
RequiresArtifactExport bool
|
|
ExpectedArtifactDirs []string
|
|
RequiredArtifactExts []string
|
|
ResolvedModel string
|
|
ResolvedSkills []string
|
|
}
|
|
|
|
func openClawTaskRuntimePolicy(params map[string]any, chatParams map[string]any, contract openClawArtifactContract) (string, int) {
|
|
message := strings.TrimSpace(shared.StringArg(chatParams, "message", ""))
|
|
if message == "" {
|
|
message = openClawCurrentTurnMessage(params)
|
|
}
|
|
lower := strings.ToLower(message)
|
|
taskLoadClass := strings.TrimSpace(contract.TaskLoadClass)
|
|
if taskLoadClass == "" {
|
|
taskLoadClass = strings.TrimSpace(shared.StringArg(params, "taskLoadClass", ""))
|
|
}
|
|
metadataClass := strings.TrimSpace(shared.StringArg(shared.AsMap(params["metadata"]), "taskLoadClass", ""))
|
|
if taskLoadClass == "" {
|
|
taskLoadClass = metadataClass
|
|
}
|
|
switch taskLoadClass {
|
|
case "short_task":
|
|
return "short_task", openClawShortTaskMinutes
|
|
case "long_task":
|
|
return "long_task", openClawLongTaskMinutes
|
|
case "complex_chain_task", "complex_long_chain_task":
|
|
return "complex_chain_task", openClawComplexTaskMinutes
|
|
}
|
|
if metadataClass == "complex_long_chain_task" || contract.ComplexLongChain || openClawMessageContainsAny(lower, []string{
|
|
"复杂链路", "多章节", "每章", "拆章节", "汇总排版", "gpt images", "images2", "image generation", "视频", "渲染", "hyperframes", "remotion", "ffmpeg",
|
|
}) {
|
|
return "complex_chain_task", openClawComplexTaskMinutes
|
|
}
|
|
if openClawMessageContainsAny(lower, []string{
|
|
"生成文件", "同步生成文件", "产物", "附件", "pdf", "docx", "ppt", "pptx", "markdown", ".md", "png", "jpg", "jpeg", "mp4",
|
|
}) || len(shared.ListArg(params, "attachments"))+len(shared.ListArg(params, "inlineAttachments")) >= 2 {
|
|
return "long_task", openClawLongTaskMinutes
|
|
}
|
|
return "short_task", openClawShortTaskMinutes
|
|
}
|
|
|
|
func openClawRunningTaskResult(record *OpenClawTaskRecord) map[string]any {
|
|
if record == nil {
|
|
return map[string]any{"success": true, "status": "running", "mode": router.ExecutionTargetGatewayChat}
|
|
}
|
|
result := map[string]any{
|
|
"success": true,
|
|
"status": string(TaskStateRunning),
|
|
"turnId": record.TurnID,
|
|
"runId": record.RunID,
|
|
"sessionId": record.SessionID,
|
|
"threadId": record.ThreadID,
|
|
"appThreadKey": record.ThreadID,
|
|
"openclawSessionKey": record.SessionKey,
|
|
"mode": router.ExecutionTargetGatewayChat,
|
|
"resolvedGatewayProviderId": record.GatewayProviderID,
|
|
"taskLoadClass": record.TaskLoadClass,
|
|
"runtimeBudgetMinutes": record.RuntimeBudgetMinutes,
|
|
"requiresArtifactExport": record.RequiresArtifactExport,
|
|
"startedAt": record.StartedAt.UTC().Format(time.RFC3339Nano),
|
|
"deadlineAt": record.DeadlineAt.UTC().Format(time.RFC3339Nano),
|
|
"progress": openClawTaskProgress(record),
|
|
}
|
|
if record.PreparedArtifact != nil {
|
|
applyOpenClawPreparedArtifactToResult(result, record.PreparedArtifact)
|
|
}
|
|
if len(record.ExpectedArtifactDirs) > 0 {
|
|
result["expectedArtifactDirs"] = append([]string(nil), record.ExpectedArtifactDirs...)
|
|
}
|
|
if len(record.RequiredArtifactExts) > 0 {
|
|
result["requiredArtifactExtensions"] = append([]string(nil), record.RequiredArtifactExts...)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func openClawTaskProgress(record *OpenClawTaskRecord) map[string]any {
|
|
now := time.Now()
|
|
stage := strings.TrimSpace(record.ProgressStage)
|
|
if stage == "" {
|
|
stage = "running"
|
|
}
|
|
message := strings.TrimSpace(record.ProgressMessage)
|
|
if message == "" {
|
|
message = "OpenClaw task is running"
|
|
}
|
|
return map[string]any{
|
|
"stage": stage,
|
|
"message": message,
|
|
"elapsedMs": maxInt64(0, now.Sub(record.StartedAt).Milliseconds()),
|
|
"budgetMs": (time.Duration(record.RuntimeBudgetMinutes) * time.Minute).Milliseconds(),
|
|
"terminal": false,
|
|
}
|
|
}
|
|
|
|
func maxInt64(a int64, b int64) int64 {
|
|
if a > b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|