diff --git a/internal/acp/gateway_runtime_test.go b/internal/acp/gateway_runtime_test.go index dc0d8d8..f025616 100644 --- a/internal/acp/gateway_runtime_test.go +++ b/internal/acp/gateway_runtime_test.go @@ -93,17 +93,18 @@ func TestReassociateOpenClawTaskDerivesRuntimeBudgetWithoutExplicitBudget(t *tes sess := server.reassociateOpenClawTask(tc.params) if sess == nil { t.Fatal("expected reassociated session") - } - sess.mu.Lock() - gotTaskBudget := sess.task.RuntimeBudgetMinutes - gotRecordBudget := sess.openClaw.RuntimeBudgetMinutes - sess.mu.Unlock() + } else { + sess.mu.Lock() + gotTaskBudget := sess.task.RuntimeBudgetMinutes + gotRecordBudget := sess.openClaw.RuntimeBudgetMinutes + sess.mu.Unlock() - if gotTaskBudget != tc.want { - t.Fatalf("task RuntimeBudgetMinutes = %d, want %d", gotTaskBudget, tc.want) - } - if gotRecordBudget != tc.want { - t.Fatalf("record RuntimeBudgetMinutes = %d, want %d", gotRecordBudget, tc.want) + if gotTaskBudget != tc.want { + t.Fatalf("task RuntimeBudgetMinutes = %d, want %d", gotTaskBudget, tc.want) + } + if gotRecordBudget != tc.want { + t.Fatalf("record RuntimeBudgetMinutes = %d, want %d", gotRecordBudget, tc.want) + } } }) } diff --git a/internal/acp/openclaw_async_tasks.go b/internal/acp/openclaw_async_tasks.go index 073bb82..d535109 100644 --- a/internal/acp/openclaw_async_tasks.go +++ b/internal/acp/openclaw_async_tasks.go @@ -445,6 +445,9 @@ func (o *SessionOrchestrator) completeOpenClawTask( } if output == "" { output = firstNonEmptyString(waitPayload, "output", "message", "summary", "assistantText", "text") + if output == "" { + output = firstNonEmptyString(shared.AsMap(waitPayload["result"]), "output", "message", "summary", "assistantText", "text") + } } noDisplayableOutput := strings.TrimSpace(output) == "" if output == "" { @@ -471,6 +474,9 @@ func (o *SessionOrchestrator) completeOpenClawTask( "runtimeBudgetMinutes": record.RuntimeBudgetMinutes, } mergeOpenClawArtifactPayload(result, waitPayload) + if nestedResult := shared.AsMap(waitPayload["result"]); len(nestedResult) > 0 { + mergeOpenClawArtifactPayload(result, nestedResult) + } if collector != nil { mergeOpenClawArtifactPayload(result, collector.artifactPayload()) } diff --git a/internal/acp/orchestrator.go b/internal/acp/orchestrator.go index ec2f738..5ad4797 100644 --- a/internal/acp/orchestrator.go +++ b/internal/acp/orchestrator.go @@ -1336,18 +1336,6 @@ func applyOpenClawArtifactContractResult(result map[string]any, contract openCla } } -func openClawArtifactExtension(artifact map[string]any) string { - for _, key := range []string{"relativePath", "path", "label", "name"} { - value := strings.TrimSpace(shared.StringArg(artifact, key, "")) - if value == "" { - continue - } - if extension := strings.TrimPrefix(strings.ToLower(filepath.Ext(value)), "."); extension != "" { - return extension - } - } - return "" -} func mergeOpenClawArtifactPayload(result map[string]any, source map[string]any) { if result == nil || len(source) == 0 { diff --git a/internal/acp/routing_test.go b/internal/acp/routing_test.go index de44cee..ae9bafa 100644 --- a/internal/acp/routing_test.go +++ b/internal/acp/routing_test.go @@ -471,8 +471,7 @@ func TestExecuteSessionTaskExplicitGatewayUsesResolvedGatewayProvider(t *testing }) if rpcErr == nil { t.Fatalf("expected gateway connectivity rpc error, got response: %v", response) - } - if rpcErr.Message == "GATEWAY_PROVIDER_REQUIRED" { + } else if rpcErr.Message == "GATEWAY_PROVIDER_REQUIRED" { t.Fatalf("expected resolved gateway provider to be reused, got %q", rpcErr.Message) } } @@ -1213,8 +1212,7 @@ func TestExecuteSessionTaskGatewaySurfacesOpenClawChatSendError(t *testing.T) { }) if rpcErr == nil { t.Fatalf("expected OpenClaw chat.send error, got response: %#v", response) - } - if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "openclaw chat failed") { + } else if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "openclaw chat failed") { t.Fatalf("expected surfaced chat.send failure, got %#v", rpcErr) } if got := gateway.Methods(); !sameMethods(got, []string{"connect", "xworkmate.artifacts.prepare", "chat.send"}) { @@ -1288,8 +1286,7 @@ func TestExecuteSessionTaskGatewayReturnsStructuredOpenClawSocketCloseAfterRetry }) if rpcErr == nil { t.Fatalf("expected OpenClaw socket close error, got response: %#v", response) - } - if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "OPENCLAW_GATEWAY_SOCKET_CLOSED") { + } else if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "OPENCLAW_GATEWAY_SOCKET_CLOSED") { t.Fatalf("expected structured socket close failure, got %#v", rpcErr) } data := shared.AsMap(rpcErr.Data) @@ -2369,8 +2366,7 @@ func TestExecuteSessionTaskGatewayRejectsOversizedInlineAttachmentBeforeChatSend }) if rpcErr == nil { t.Fatalf("expected oversized attachment rpc error, got response: %#v", response) - } - if !strings.Contains(rpcErr.Message, "OPENCLAW_ATTACHMENT_FILE_TOO_LARGE") { + } else if !strings.Contains(rpcErr.Message, "OPENCLAW_ATTACHMENT_FILE_TOO_LARGE") { t.Fatalf("expected attachment size error, got %#v", rpcErr) } if gateway.ChatSendCount() != 0 { @@ -2500,8 +2496,7 @@ func TestExecuteSessionTaskDefaultsExplicitGatewayToOpenClaw(t *testing.T) { }) if rpcErr == nil { t.Fatal("expected gateway connectivity error") - } - if rpcErr.Message == "GATEWAY_PROVIDER_REQUIRED" { + } else if rpcErr.Message == "GATEWAY_PROVIDER_REQUIRED" { t.Fatalf("expected openclaw default from routing result, got %#v", rpcErr) } } @@ -3317,38 +3312,6 @@ func sameMethods(got []string, want []string) bool { return true } -func responseArtifactMaps(t *testing.T, response map[string]any) []map[string]any { - t.Helper() - if artifacts, ok := response["artifacts"].([]map[string]any); ok { - return artifacts - } - raw, ok := response["artifacts"].([]any) - if !ok { - t.Fatalf("expected artifacts payload, got %#v", response["artifacts"]) - } - artifacts := make([]map[string]any, 0, len(raw)) - for _, item := range raw { - artifacts = append(artifacts, shared.AsMap(item)) - } - return artifacts -} - -func mustStepMaps(t *testing.T, value any) []map[string]any { - t.Helper() - switch typed := value.(type) { - case []map[string]any: - return typed - case []any: - steps := make([]map[string]any, 0, len(typed)) - for _, item := range typed { - steps = append(steps, shared.AsMap(item)) - } - return steps - default: - t.Fatalf("expected step map list, got %#v", value) - return nil - } -} func waitForCondition(t *testing.T, condition func() bool) { t.Helper() @@ -3500,8 +3463,7 @@ func TestExecuteSessionTaskKeepsRemoteWorkspaceHintOutOfLocalCWD(t *testing.T) { sess := server.sessions["session-remote-hint"] if sess == nil { t.Fatal("expected session state to be retained") - } - if sess.control.RequestedWorkingDir != workspaceDir { + } else if sess.control.RequestedWorkingDir != workspaceDir { t.Fatalf("expected local requested cwd %q, got %q", workspaceDir, sess.control.RequestedWorkingDir) } if sess.control.RemoteWorkingDirHint != "/owners/local/user/demo/threads/main" { @@ -3530,8 +3492,7 @@ func TestExecuteSessionTaskRequiresRouting(t *testing.T) { }) if rpcErr == nil { t.Fatalf("expected routing-required error") - } - if rpcErr.Message != "ROUTING_REQUIRED" { + } else if rpcErr.Message != "ROUTING_REQUIRED" { t.Fatalf("expected ROUTING_REQUIRED, got %#v", rpcErr) } } @@ -3566,8 +3527,7 @@ func TestExecuteSessionMessageMissingProviderStateReturnsContinuationUnavailable }) if rpcErr == nil { t.Fatalf("expected continuation unavailable error, got response %#v", response) - } - if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "SESSION_CONTINUATION_UNAVAILABLE") { + } else if rpcErr.Code != -32002 || !strings.Contains(rpcErr.Message, "SESSION_CONTINUATION_UNAVAILABLE") { t.Fatalf("expected structured continuation error, got %#v", rpcErr) } data := shared.AsMap(rpcErr.Data) @@ -3607,8 +3567,7 @@ func TestExecuteSessionTaskComplexRequestNoLongerPromotesToMultiAgent(t *testing }) if rpcErr == nil { t.Fatalf("expected gateway-not-connected error, got response %#v", response) - } - if strings.Contains(rpcErr.Message, "multi-agent") { + } else if strings.Contains(rpcErr.Message, "multi-agent") { t.Fatalf("expected no multi-agent path, got rpc error: %v", rpcErr) } } diff --git a/internal/desktop/input.go b/internal/desktop/input.go index 14e3dd0..c2b016d 100644 --- a/internal/desktop/input.go +++ b/internal/desktop/input.go @@ -78,7 +78,7 @@ func (xi *XdotoolInjector) Start() error { } if err := cmd.Start(); err != nil { - stdin.Close() + _ = stdin.Close() return fmt.Errorf("failed to start xdotool process: %w", err) } @@ -144,7 +144,7 @@ func (xi *XdotoolInjector) Inject(event InputEvent) error { // Try to restart if pipe is broken log.Printf("xdotool write error: %v. Attempting to restart injector.", err) xi.isStarted = false - xi.stdin.Close() + _ = xi.stdin.Close() if restartErr := xi.Start(); restartErr == nil { _, _ = xi.stdin.Write([]byte(cmdStr)) } diff --git a/internal/desktop/service.go b/internal/desktop/service.go index 8890011..52042ca 100644 --- a/internal/desktop/service.go +++ b/internal/desktop/service.go @@ -56,19 +56,19 @@ func (s *Service) StartSession(sessionID string, cfg PipelineConfig, iceServers // 2. Initialize WebRTC server webrtcSrv, err := NewWebRTCServer(injector) if err != nil { - injector.Close() + _ = injector.Close() return nil, fmt.Errorf("failed to create WebRTC server: %w", err) } if err := webrtcSrv.InitPeerConnection(iceServers); err != nil { - injector.Close() + _ = injector.Close() return nil, fmt.Errorf("failed to init peer connection: %w", err) } // Start local UDP listener for GStreamer RTP packets if err := webrtcSrv.StartRTPReceiver(cfg.Port); err != nil { webrtcSrv.Close() - injector.Close() + _ = injector.Close() return nil, fmt.Errorf("failed to start RTP receiver: %w", err) } @@ -76,7 +76,7 @@ func (s *Service) StartSession(sessionID string, cfg PipelineConfig, iceServers pipeline := NewPipelineManager() if err := pipeline.Start(cfg); err != nil { webrtcSrv.Close() - injector.Close() + _ = injector.Close() return nil, fmt.Errorf("failed to start capture pipeline: %w", err) } diff --git a/internal/desktop/webrtc.go b/internal/desktop/webrtc.go index ae8ae95..d3b3ac3 100644 --- a/internal/desktop/webrtc.go +++ b/internal/desktop/webrtc.go @@ -59,13 +59,13 @@ func (w *WebRTCServer) InitPeerConnection(iceServers []string) error { "xworkmate-desktop", ) if err != nil { - pc.Close() + _ = pc.Close() return fmt.Errorf("failed to create video track: %w", err) } _, err = pc.AddTrack(videoTrack) if err != nil { - pc.Close() + _ = pc.Close() return fmt.Errorf("failed to add video track: %w", err) }