diff --git a/inc/Abilities/WorkspaceAbilities.php b/inc/Abilities/WorkspaceAbilities.php index 8eeadf0..eec378d 100644 --- a/inc/Abilities/WorkspaceAbilities.php +++ b/inc/Abilities/WorkspaceAbilities.php @@ -1464,6 +1464,7 @@ private function registerAbilities(): void { ), 'user_id' => array( 'type' => 'integer' ), 'agent_id' => array( 'type' => 'integer' ), + 'agent_slug' => array( 'type' => 'string' ), ), ), 'output_schema' => array( @@ -2914,6 +2915,14 @@ public static function workspaceCleanupRun( array $input ): array|\WP_Error { if ( isset($input['agent_id']) ) { $context['agent_id'] = (int) $input['agent_id']; } + if ( isset($input['agent_slug']) && '' !== trim( (string) $input['agent_slug']) ) { + $context['agent_slug'] = sanitize_key( (string) $input['agent_slug']); + } elseif ( empty($context['agent_id']) ) { + $agent_slug = self::resolveCleanupAgentSlug( (int) ( $context['user_id'] ?? 0 ) ); + if ( '' !== $agent_slug ) { + $context['agent_slug'] = $agent_slug; + } + } $batch_result = \DataMachine\Engine\Tasks\TaskScheduler::scheduleBatch( $task_type, @@ -2925,7 +2934,10 @@ public static function workspaceCleanupRun( array $input ): array|\WP_Error { } $job_ids = is_array($batch_result['job_ids'] ?? null) ? $batch_result['job_ids'] : array(); - $job_id = (int) ( $job_ids[0] ?? 0 ); + $job_id = (int) ( $job_ids[0] ?? ( $batch_result['batch_job_id'] ?? 0 ) ); + if ( $job_id <= 0 ) { + return new \WP_Error('workspace_cleanup_schedule_empty', 'Workspace cleanup scheduling returned no job id. Check Data Machine logs for the rejected task reason.', array( 'status' => 500 )); + } return array( 'success' => true, @@ -2937,6 +2949,27 @@ public static function workspaceCleanupRun( array $input ): array|\WP_Error { ); } + /** + * Resolve the active Data Machine agent slug for CLI-scheduled cleanup jobs. + * + * @param int $user_id Optional user id from the caller context. + * @return string + */ + private static function resolveCleanupAgentSlug( int $user_id = 0 ): string { + if ( ! class_exists('\\DataMachine\\Core\\FilesRepository\\DirectoryManager') ) { + return ''; + } + + try { + $manager = new \DataMachine\Core\FilesRepository\DirectoryManager(); + $effective_user = $manager->get_effective_user_id($user_id); + $agent_slug = $manager->resolve_agent_slug(array( 'user_id' => $effective_user )); + return '' !== trim( (string) $agent_slug) ? sanitize_key( (string) $agent_slug) : ''; + } catch ( \Throwable $e ) { + return ''; + } + } + /** * Remove a worktree. * diff --git a/tests/smoke-workspace-cleanup-run-context.php b/tests/smoke-workspace-cleanup-run-context.php new file mode 100644 index 0000000..fa61674 --- /dev/null +++ b/tests/smoke-workspace-cleanup-run-context.php @@ -0,0 +1,96 @@ +code; + } + + public function get_error_message(): string { + return $this->message; + } + } +} + +namespace DataMachine\Core\FilesRepository { + class DirectoryManager { + public function get_effective_user_id( int $user_id ): int { + return $user_id > 0 ? $user_id : 1; + } + + public function resolve_agent_slug( array $args ): string { + return 1 === (int) ( $args['user_id'] ?? 0 ) ? 'intelligence-chubes4' : ''; + } + } +} + +namespace DataMachine\Engine\Tasks { + class TaskScheduler { + public static array $last_context = array(); + public static array|false $next_result = array( 'job_ids' => array( 987 ), 'batch_job_id' => 0 ); + + public static function scheduleBatch( string $task_type, array $items, array $context = array() ): array|false { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found + self::$last_context = $context; + return self::$next_result; + } + } +} + +namespace { + include_once dirname(__DIR__) . '/inc/Abilities/WorkspaceAbilities.php'; + + function datamachine_code_cleanup_run_context_assert( bool $condition, string $message ): void { + if ( ! $condition ) { + fwrite(STDERR, "Assertion failed: {$message}\n"); + exit(1); + } + } + + $result = \DataMachineCode\Abilities\WorkspaceAbilities::workspaceCleanupRun( + array( + 'mode' => 'artifacts', + 'source' => 'workspace_cleanup_cli', + ) + ); + + datamachine_code_cleanup_run_context_assert(is_array($result), 'cleanup run returns success array'); + datamachine_code_cleanup_run_context_assert('cleanup-run-987' === ( $result['run_id'] ?? '' ), 'cleanup run uses direct job id'); + datamachine_code_cleanup_run_context_assert('intelligence-chubes4' === ( \DataMachine\Engine\Tasks\TaskScheduler::$last_context['agent_slug'] ?? '' ), 'cleanup run supplies resolved agent slug'); + + \DataMachine\Engine\Tasks\TaskScheduler::$next_result = array( 'job_ids' => array(), 'batch_job_id' => 0 ); + $result = \DataMachineCode\Abilities\WorkspaceAbilities::workspaceCleanupRun( + array( + 'mode' => 'artifacts', + 'agent_slug' => 'explicit-agent', + ) + ); + + datamachine_code_cleanup_run_context_assert($result instanceof \WP_Error, 'cleanup run without scheduled job returns an error'); + datamachine_code_cleanup_run_context_assert('workspace_cleanup_schedule_empty' === $result->get_error_code(), 'cleanup run reports empty schedule explicitly'); + datamachine_code_cleanup_run_context_assert('explicit-agent' === ( \DataMachine\Engine\Tasks\TaskScheduler::$last_context['agent_slug'] ?? '' ), 'explicit agent slug is sanitized and forwarded'); + + echo "Workspace cleanup run context smoke passed.\n"; +}