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 (TypeScript)
Server-based job execution with persistence, webhooks, and streaming. Ideal for production deployments.
Installation
Basic Usage
Submitting a Job
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
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
// 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
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
const job = await recipe.submitJob('my-recipe', {
input: 'test',
webhookUrl: 'https://example.com/webhook',
});
Webhook payload:
{
"jobId": "run_abc123",
"status": "succeeded",
"result": {"output": "..."},
"completedAt": "2024-01-15T10:30:00Z",
"durationSeconds": 45.2
}
Idempotency
// 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
runtime:
job:
enabled: true
timeout_sec: 3600
webhook_url: "${WEBHOOK_URL}"
idempotency_scope: "session"
Error Handling
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