> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Async Jobs

> Server-based asynchronous job execution in TypeScript

# Async Jobs (TypeScript)

Server-based job execution with persistence, webhooks, and streaming. Ideal for production deployments.

## Installation

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
npm install praisonai-ts
```

## Basic Usage

### Submitting a Job

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { recipe } from 'praisonai-ts';

// Submit recipe as async job
const job = await recipe.submitJob('my-recipe', {
  input: { query: 'What is AI?' },
  config: { maxTokens: 1000 },
  sessionId: 'session_123',
  timeoutSec: 3600,
  webhookUrl: 'https://example.com/webhook',
  idempotencyKey: 'unique-key-123',
  apiUrl: 'http://127.0.0.1:8005',
});

console.log(`Job ID: ${job.jobId}`);
console.log(`Status: ${job.status}`);
```

### JobHandle Interface

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
interface JobHandle {
  jobId: string;
  recipeName: string;
  status: JobStatus;
  
  getStatus(): Promise<JobStatus>;
  getResult(): Promise<any>;
  cancel(): Promise<boolean>;
  wait(pollInterval?: number, timeout?: number): Promise<any>;
}

type JobStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
```

### Waiting for Completion

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
// Submit and wait
const job = await recipe.submitJob('my-recipe', {
  input: 'test',
  wait: true,
});

// Or wait after submission
const job = await recipe.submitJob('my-recipe', { input: 'test' });
const result = await job.wait(5, 300); // poll every 5s, timeout 300s
console.log(`Result: ${result}`);
```

## Using the Jobs API Client

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { JobsClient, JobSubmitRequest } from 'praisonai-ts';

const client = new JobsClient('http://127.0.0.1:8005');

// Submit job
const request: JobSubmitRequest = {
  prompt: 'Analyze this data',
  recipeName: 'data-analyzer',
  recipeConfig: { format: 'json' },
  timeout: 3600,
  webhookUrl: 'https://example.com/callback',
};

const job = await client.submit(request);
console.log(`Job ID: ${job.jobId}`);

// Get status
const status = await client.getStatus(job.jobId);

// Get result
const result = await client.getResult(job.jobId);

// Stream progress
for await (const event of client.stream(job.jobId)) {
  console.log(`Progress: ${event.progress}%`);
}
```

## Webhooks

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const job = await recipe.submitJob('my-recipe', {
  input: 'test',
  webhookUrl: 'https://example.com/webhook',
});
```

Webhook payload:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "jobId": "run_abc123",
  "status": "succeeded",
  "result": {"output": "..."},
  "completedAt": "2024-01-15T10:30:00Z",
  "durationSeconds": 45.2
}
```

## Idempotency

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
// Same key = same job (no duplicate)
const job1 = await recipe.submitJob('my-recipe', {
  idempotencyKey: 'order-123',
});
const job2 = await recipe.submitJob('my-recipe', {
  idempotencyKey: 'order-123',
});

console.log(job1.jobId === job2.jobId); // true
```

## Configuration

### TEMPLATE.yaml Runtime Block

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
runtime:
  job:
    enabled: true
    timeout_sec: 3600
    webhook_url: "${WEBHOOK_URL}"
    idempotency_scope: "session"
```

## Error Handling

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { recipe, JobError } from 'praisonai-ts';

try {
  const job = await recipe.submitJob('my-recipe', { input: 'test' });
  const result = await job.wait(5, 60);
  
  if (result.status === 'failed') {
    console.error(`Job failed: ${result.error}`);
  }
} catch (error) {
  if (error instanceof JobError) {
    console.error(`Job error: ${error.message}`);
  }
}
```

## See Also

* [Async Jobs CLI](/docs/js/async-jobs-cli) - CLI commands
* [Background Tasks](/docs/js/background-tasks) - In-process execution
* [Scheduler](/docs/js/scheduler) - Periodic scheduling
