Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion inc/Abilities/WorkspaceAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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.
*
Expand Down
96 changes: 96 additions & 0 deletions tests/smoke-workspace-cleanup-run-context.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
/**
* Smoke test for workspace cleanup run scheduling context.
*
* php tests/smoke-workspace-cleanup-run-context.php
*
* @package DataMachineCode\Tests
*/

declare( strict_types=1 );

namespace {
if ( ! defined('ABSPATH') ) {
define('ABSPATH', __DIR__);
}

function sanitize_key( $key ): string {
return strtolower(preg_replace('/[^a-z0-9_\-]/', '', (string) $key));
}

class WP_Error {
public function __construct(
private string $code,
private string $message,
private array $data = array()
) {}

public function get_error_code(): string {
return $this->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";
}
Loading