Lesson 19: Using the Task API
This lesson introduces the Task API, a specialized interface for structured, non-chat interactions like code generation.
Code: lesson_19_task_api_usage.mjs
This script demonstrates how to get a list of available tasks and then execute a specific task (`code-generate:default`) using both the streaming (`.stream()`) and blocking (`.execute()`) methods.
// lesson_19_task_api_usage.mjs
// Merci SDK Tutorial: Lesson 19 - Using the Task API
// --- IMPORTS ---
import { MerciClient } from '../lib/merci.2.14.0.mjs';
import { token } from '../secret/token.mjs';
// A common task ID. We'll fetch the full list to ensure it's available.
const TASK_ID_TO_TEST = 'code-generate:default';
async function main() {
console.log(`--- Merci SDK Tutorial: Lesson 19 - Using the Task API ---`);
try {
// --- STEP 1: INITIALIZE THE CLIENT ---
console.log('[STEP 1] Initializing MerciClient...');
const client = new MerciClient({ token });
// --- STEP 2: GET THE ROSTER OF AVAILABLE TASKS ---
console.log('
[STEP 2] Fetching the list of available tasks from the roster...');
const roster = await client.tasks.roster();
console.log('Available task IDs:', roster.ids);
if (!roster.ids.includes(TASK_ID_TO_TEST)) {
console.error(`\n[ERROR] The test task "${TASK_ID_TO_TEST}" is not available in the roster. Please choose another one.`);
return;
}
console.log(`[INFO] Will use "${TASK_ID_TO_TEST}" for demonstration.`);
// --- STEP 3: DEFINE TASK PARAMETERS ---
console.log('
[STEP 3] Defining parameters for the code generation task...');
const taskParameters = {
instructions: "Write a simple JavaScript function that returns 'Hello, World!'.",
language: "javascript",
prefix: "",
suffix: ""
};
console.log('Parameters:', JSON.stringify(taskParameters, null, 2));
// --- STEP 4: EXECUTE THE TASK WITH THE STREAMING API ---
console.log(`\n[STEP 4] Executing task "${TASK_ID_TO_TEST}" with .stream()...`);
let streamedResponse = '';
process.stdout.write('🤖 Task Output (Streaming) > ');
const stream = client.tasks.stream(TASK_ID_TO_TEST, taskParameters);
for await (const event of stream) {
if (event.type === 'Content') {
process.stdout.write(event.content);
streamedResponse += event.content;
} else {
// Log other event types for observability
console.log(`\n[STREAM EVENT: ${event.type}]`, event.data);
}
}
process.stdout.write('\n');
console.log('
[INFO] Stream finished.');
// --- STEP 5: EXECUTE THE SAME TASK WITH THE BLOCKING API ---
console.log(`\n[STEP 5] Executing task "${TASK_ID_TO_TEST}" with .execute()...`);
const result = await client.tasks.execute(TASK_ID_TO_TEST, taskParameters);
console.log('[INFO] Execution finished. Received aggregated result object.');
// --- FINAL RESULT ---
console.log('
--- FINAL RESULT ---');
console.log('--- Streaming Response ---');
console.log(streamedResponse);
console.log('
--- Aggregated .execute() Response ---');
console.log('Content:', result.content);
console.log('Finish Metadata:', result.finishMetadata);
console.log('--------------------');
console.log('
Both methods produce the same content, but .stream() provides real-time feedback while .execute() returns a complete object after the task is done.');
} catch (error) {
console.error('
[FATAL ERROR] An error occurred during the operation.');
console.error(' Message:', error.message);
if (error.status) {
console.error(' API Status:', error.status);
}
if (error.details) {
console.error(' Details:', JSON.stringify(error.details, null, 2));
}
if (error.stack) {
console.error(' Stack:', error.stack);
}
console.error('
Possible causes: Invalid token, network issues, or an API service problem.');
process.exit(1); // Exit with a non-zero code to indicate failure.
}
}
main().catch(console.error);
Expected Output
The output shows the list of available tasks, the parameters used for the task, the real-time streaming output, and the final aggregated result from the `.execute()` call, demonstrating both ways to interact with the Task API.
--- Merci SDK Tutorial: Lesson 19 - Using the Task API ---
[STEP 1] Initializing MerciClient...
[STEP 2] Fetching the list of available tasks from the roster...
Available task IDs: ["code-generate:default", ... ]
[INFO] Will use "code-generate:default" for demonstration.
[STEP 3] Defining parameters for the code generation task...
Parameters: {
"instructions": "Write a simple JavaScript function that returns 'Hello, World!'.",
"language": "javascript",
"prefix": "",
"suffix": ""
}
[STEP 4] Executing task "code-generate:default" with .stream()...
🤖 Task Output (Streaming) > function hello() {
return "Hello, World!";
}
[INFO] Stream finished.
[STEP 5] Executing task "code-generate:default" with .execute()...
[INFO] Execution finished. Received aggregated result object.
--- FINAL RESULT ---
--- Streaming Response ---
function hello() {
return "Hello, World!";
}
--- Aggregated .execute() Response ---
Content: function hello() {
return "Hello, World!";
}
Finish Metadata: { reason: "end_turn" }
--------------------
Both methods produce the same content, but .stream() provides real-time feedback while .execute() returns a complete object after the task is done.