# Task API

The Task API provides asynchronous task execution with real-time progress monitoring, completion tracking, and event handling. Perfect for delegating work to agents or team members, managing long-running operations, and orchestrating multi-step workflows.

## Quick Start

```typescript
import { definePlugin } from '@majkapp/plugin-kit';

const plugin = definePlugin('task-example', 'Task Example', '1.0.0')
  .pluginRoot(__dirname)

  .function('analyzeCode', {
    description: 'Start code analysis task and monitor progress',
    input: { type: 'object', properties: {}, additionalProperties: false },
    output: { type: 'object', properties: { taskId: { type: 'string' }, result: { type: 'string' } } },
    handler: async (_, ctx) => {
      // Start a new task
      const task = await ctx.majk.tasks.start({
        title: 'Code Analysis',
        message: 'Analyze the codebase for security issues and performance problems',
        agentId: 'security-analyzer',
        workingDirectory: './src',
        taskType: 'analysis',
        context: {
          scope: 'security,performance',
          depth: 'thorough'
        }
      });

      // Monitor progress with event handlers
      await task.onProgress(progress => {
        console.log(`Progress: ${progress.stage} - ${progress.message}`);
        if (progress.percentage) {
          console.log(`${progress.percentage}% complete`);
        }
      });

      // Wait for completion with timeout
      const result = await task.waitForCompletion(300000); // 5 minutes

      return {
        taskId: task.id,
        result: result.success ? 'Analysis completed successfully' : 'Analysis failed'
      };
    }
  })

  .build();
```

## Core Concepts

### Task Lifecycle

Tasks progress through these states:
- **pending**: Task created but not yet started
- **running**: Task is actively being executed
- **completed**: Task finished successfully
- **failed**: Task encountered an error and stopped

### Task Types

The API supports different task categories:
- `code-project`: Development and coding tasks
- `automation`: Automated workflows and scripts
- `analysis`: Data analysis and research tasks
- `chat`: Conversational interactions
- `research`: Information gathering and investigation

### Working with Task Handles

Task handles provide a rich interface for monitoring and controlling task execution:

```typescript
// Get task status without blocking
const status = await task.getStatus();
console.log('Current status:', status);

// Check if task is complete
const isComplete = await task.isComplete();

// Send additional instructions
await task.send('Please also check for SQL injection vulnerabilities');

// Send follow-up messages
await task.sendFollowup('Focus on the authentication module');

// Stop a running task
await task.stop();
```

## API Reference

### TaskAPI Interface

```typescript
interface TaskAPI {
  start(request: StartTaskRequest): Promise<TaskHandle>;
  get(taskId: string): Promise<TaskHandle | null>;
  list(filter?: TaskFilter): Promise<TaskHandle[]>;
  onTaskStarted(handler: TaskEventHandler): Promise<Unsubscribe>;
  onTaskCompleted(handler: TaskEventHandler): Promise<Unsubscribe>;
  onTaskFailed(handler: TaskEventHandler): Promise<Unsubscribe>;
}
```

### Starting Tasks

```typescript
interface StartTaskRequest {
  title: string;                    // Human-readable task title
  message: string;                  // Initial instruction/prompt
  agentId?: string;                 // Specific agent to use
  teamMemberId?: string;            // Team member to assign to
  workingDirectory?: string;        // Directory context
  context?: Record<string, any>;    // Additional context data
  triggerImmediately?: boolean;     // Start immediately (default: true)
  taskType?: 'code-project' | 'automation' | 'analysis' | 'chat' | 'research';
}
```

### Task Handle Interface

```typescript
interface TaskHandle {
  readonly id: string;
  readonly conversationId: string;
  readonly title: string;
  readonly status: 'pending' | 'running' | 'completed' | 'failed'; // Deprecated - use getStatus()
  readonly agentId: string;
  readonly teamMemberId?: string;
  readonly startedAt: Date;
  readonly completedAt?: Date;

  // Communication
  send(message: string): Promise<void>;
  sendFollowup(message: string): Promise<void>;

  // Status and Control
  getStatus(): Promise<'pending' | 'running' | 'completed' | 'failed'>;
  isComplete(): Promise<boolean>;
  waitForCompletion(timeout?: number): Promise<TaskResult>;
  stop(): Promise<void>;

  // Event Handling
  onMessage(handler: (message: TaskMessage) => void): Promise<Unsubscribe>;
  onProgress(handler: (progress: TaskProgress) => void): Promise<Unsubscribe>;
  onComplete(handler: (result: TaskResult) => void): Promise<Unsubscribe>;
  onError(handler: (error: TaskError) => void): Promise<Unsubscribe>;

  // Data Access
  getMessages(): Promise<TaskMessage[]>;
  getConversation(): Promise<Conversation>;
}
```

## Common Patterns

### Fire and Forget

Start a task and let it run without waiting:

```typescript
async function startBackgroundAnalysis() {
  const task = await ctx.majk.tasks.start({
    title: 'Background Security Scan',
    message: 'Scan the entire codebase for security vulnerabilities',
    taskType: 'analysis',
    triggerImmediately: true
  });

  console.log(`Started task ${task.id}, running in background`);
  return task.id;
}
```

### Progress Monitoring

Track task progress with detailed feedback:

```typescript
async function monitoredTask() {
  const task = await ctx.majk.tasks.start({
    title: 'Code Refactoring',
    message: 'Refactor the user authentication module',
    taskType: 'code-project'
  });

  // Set up progress monitoring
  await task.onProgress(progress => {
    console.log(`Stage: ${progress.stage}`);
    console.log(`Message: ${progress.message}`);

    if (progress.percentage) {
      console.log(`Progress: ${progress.percentage}%`);
    }

    if (progress.toolCall) {
      console.log(`Tool: ${progress.toolCall.name} (${progress.toolCall.status})`);
    }
  });

  // Set up message monitoring
  await task.onMessage(message => {
    console.log(`[${message.role}]: ${message.content}`);
  });

  const result = await task.waitForCompletion();
  return result;
}
```

### Error Handling

Handle task failures gracefully:

```typescript
async function robustTaskExecution() {
  const task = await ctx.majk.tasks.start({
    title: 'Data Processing',
    message: 'Process the uploaded data files',
    taskType: 'automation'
  });

  // Set up error handling
  await task.onError(error => {
    console.error(`Task failed: ${error.message}`);
    console.error(`Error code: ${error.code}`);
    if (error.details) {
      console.error('Details:', error.details);
    }
  });

  try {
    const result = await task.waitForCompletion(600000); // 10 minutes

    if (result.success) {
      console.log('Task completed successfully');
      return result.output;
    } else {
      console.error('Task failed:', result.error);
      throw new Error(result.error);
    }
  } catch (error) {
    console.error('Task timeout or error:', error.message);
    await task.stop(); // Clean shutdown
    throw error;
  }
}
```

### Batch Task Management

Manage multiple tasks concurrently:

```typescript
async function processBatchTasks() {
  const files = ['file1.js', 'file2.js', 'file3.js'];
  const tasks = [];

  // Start multiple tasks
  for (const file of files) {
    const task = await ctx.majk.tasks.start({
      title: `Process ${file}`,
      message: `Analyze and optimize ${file}`,
      taskType: 'code-project',
      context: { filename: file }
    });
    tasks.push(task);
  }

  // Wait for all tasks to complete
  const results = await Promise.all(
    tasks.map(task => task.waitForCompletion())
  );

  // Process results
  const successful = results.filter(r => r.success).length;
  const failed = results.filter(r => !r.success).length;

  console.log(`Completed: ${successful}, Failed: ${failed}`);
  return results;
}
```

### Interactive Task Communication

Send additional instructions during task execution:

```typescript
async function interactiveTask() {
  const task = await ctx.majk.tasks.start({
    title: 'Code Review',
    message: 'Review the authentication module',
    taskType: 'code-project'
  });

  // Wait a bit then send additional instructions
  setTimeout(async () => {
    await task.send('Please pay special attention to SQL injection vulnerabilities');
  }, 5000);

  // Send follow-up after more time
  setTimeout(async () => {
    await task.sendFollowup('Also check for proper error handling');
  }, 10000);

  return await task.waitForCompletion();
}
```

### Task Discovery and Management

List and manage existing tasks:

```typescript
async function manageActiveTasks() {
  // List all running tasks
  const runningTasks = await ctx.majk.tasks.list({
    status: 'running'
  });

  console.log(`Found ${runningTasks.length} running tasks`);

  // List tasks by agent
  const agentTasks = await ctx.majk.tasks.list({
    agentId: 'code-analyzer'
  });

  // List recent tasks
  const recentTasks = await ctx.majk.tasks.list({
    startedAfter: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours
  });

  // Get specific task
  const task = await ctx.majk.tasks.get('task-id-123');
  if (task) {
    const status = await task.getStatus();
    console.log(`Task ${task.id} status: ${status}`);
  }
}
```

### Global Task Event Monitoring

Listen for task lifecycle events across the system:

```typescript
async function setupGlobalTaskMonitoring() {
  // Monitor task starts
  await ctx.majk.tasks.onTaskStarted(event => {
    console.log(`Task started: ${event.taskId} by ${event.agentId}`);
  });

  // Monitor task completions
  await ctx.majk.tasks.onTaskCompleted(event => {
    console.log(`Task completed: ${event.taskId}`);
  });

  // Monitor task failures
  await ctx.majk.tasks.onTaskFailed(event => {
    console.log(`Task failed: ${event.taskId}`);
  });
}
```

## Best Practices

### Resource Management

Always clean up event handlers and stop tasks when appropriate:

```typescript
async function properResourceManagement() {
  const task = await ctx.majk.tasks.start({
    title: 'Long Running Task',
    message: 'This might take a while',
    taskType: 'analysis'
  });

  // Set up handlers
  const unsubscribeProgress = await task.onProgress(progress => {
    console.log('Progress:', progress.message);
  });

  const unsubscribeError = await task.onError(error => {
    console.error('Error:', error.message);
  });

  try {
    const result = await task.waitForCompletion();
    return result;
  } finally {
    // Clean up subscriptions
    unsubscribeProgress();
    unsubscribeError();
  }
}
```

### Timeout Handling

Use appropriate timeouts for different task types:

```typescript
function getTimeoutForTaskType(taskType: string): number {
  switch (taskType) {
    case 'chat':
      return 30000;    // 30 seconds
    case 'analysis':
      return 300000;   // 5 minutes
    case 'code-project':
      return 600000;   // 10 minutes
    case 'research':
      return 900000;   // 15 minutes
    default:
      return 120000;   // 2 minutes
  }
}

async function taskWithAppropriateTimeout() {
  const taskType = 'analysis';
  const task = await ctx.majk.tasks.start({
    title: 'Security Analysis',
    message: 'Analyze for security issues',
    taskType
  });

  const timeout = getTimeoutForTaskType(taskType);
  return await task.waitForCompletion(timeout);
}
```

### Context Enrichment

Provide rich context for better task execution:

```typescript
async function taskWithRichContext() {
  const task = await ctx.majk.tasks.start({
    title: 'Code Optimization',
    message: 'Optimize the payment processing module',
    taskType: 'code-project',
    workingDirectory: './src/payments',
    context: {
      priority: 'high',
      deadline: '2024-01-15',
      constraints: {
        maintainCompatibility: true,
        maxPerformanceImpact: '5%'
      },
      relatedFiles: [
        'payment-processor.js',
        'transaction-validator.js',
        'payment-gateway.js'
      ],
      requirements: [
        'Reduce memory usage',
        'Improve error handling',
        'Add comprehensive logging'
      ]
    }
  });

  return await task.waitForCompletion();
}
```

## Type Definitions

### TaskMessage

```typescript
interface TaskMessage {
  role: 'user' | 'assistant' | 'tool' | 'system';
  content: string;
  timestamp: Date;
  seq: number;
}
```

### TaskProgress

```typescript
interface TaskProgress {
  stage?: string;           // Current processing stage
  message?: string;         // Progress description
  percentage?: number;      // Completion percentage (0-100)
  messageCount?: number;    // Number of messages exchanged
  toolCall?: {             // Currently executing tool
    name: string;
    status: string;
  };
}
```

### TaskResult

```typescript
interface TaskResult {
  success: boolean;         // Whether task completed successfully
  output?: any;            // Task output data
  error?: string;          // Error message if failed
  conversationId?: string; // Associated conversation ID
  duration?: number;       // Execution time in milliseconds
}
```

### TaskError

```typescript
interface TaskError {
  code: string;            // Error code for categorization
  message: string;         // Human-readable error message
  details?: any;           // Additional error context
}
```

### TaskFilter

```typescript
interface TaskFilter {
  status?: 'pending' | 'running' | 'completed' | 'failed';
  agentId?: string;
  teamMemberId?: string;
  startedAfter?: Date;
  startedBefore?: Date;
}
```

## Error Handling

The Task API can throw various errors during operation:

```typescript
async function handleTaskErrors() {
  try {
    const task = await ctx.majk.tasks.start({
      title: 'Test Task',
      message: 'Test message'
    });

    await task.waitForCompletion();
  } catch (error) {
    if (error.code === 'TASK_TIMEOUT') {
      console.error('Task timed out');
    } else if (error.code === 'AGENT_UNAVAILABLE') {
      console.error('Requested agent is not available');
    } else if (error.code === 'INVALID_CONTEXT') {
      console.error('Task context is invalid');
    } else {
      console.error('Unknown error:', error.message);
    }
  }
}
```

## Integration Examples

### With Batch Processing

Combine task management with batch operations:

```typescript
async function batchTaskProcessing() {
  const files = await getFilesToProcess();
  const batchSize = 5;
  const activeTasks = new Set();

  for (let i = 0; i < files.length; i += batchSize) {
    const batch = files.slice(i, i + batchSize);

    for (const file of batch) {
      const task = await ctx.majk.tasks.start({
        title: `Process ${file}`,
        message: `Analyze and process ${file}`,
        taskType: 'code-project'
      });

      activeTasks.add(task);

      // Remove completed tasks
      task.onComplete(() => {
        activeTasks.delete(task);
      });
    }

    // Wait for current batch to complete before starting next
    await Promise.all([...activeTasks].map(task => task.waitForCompletion()));
  }
}
```

### With Event Bus Integration

Integrate task events with the broader event system:

```typescript
async function integrateWithEventBus() {
  // Listen to task events and forward to event bus
  await ctx.majk.tasks.onTaskCompleted(async (event) => {
    // Emit custom event
    await ctx.majk.eventBus.emit('custom:task:completed', {
      taskId: event.taskId,
      agentId: event.agentId,
      completedAt: event.timestamp
    });
  });

  // Start task and let it be monitored by event system
  const task = await ctx.majk.tasks.start({
    title: 'Monitored Task',
    message: 'This task will emit events',
    taskType: 'automation'
  });

  return task;
}
```

The Task API provides a powerful foundation for managing asynchronous work across your MAJK plugin ecosystem. Use it to orchestrate complex workflows, delegate work to specialized agents, and build responsive applications that can handle long-running operations gracefully.