- Basic Execution
- Status Monitoring
- Complex Data
- Advanced Variables
- Interactive Agent
- Agent Profile Cookies
Execute an agent and wait for the result in the simplest way possible.
Copy
import { client, agentExecutePost, executionGet } from 'asteroid-odyssey';
import type { AgentsExecutionListItem } from 'asteroid-odyssey';
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
async function basicExample() {
// Configure client
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
// Execute agent with variables
const { data, error } = await agentExecutePost({
path: { agentId: 'your-agent-id' },
body: {
inputs: {
DATA: 'First name: John, Last name: Smith',
},
agentProfileId: 'your-agent-profile-id', // Optional
},
});
if (error || !data) {
console.error('Failed to start execution:', error);
return;
}
const executionId = data.executionId;
console.log(`Execution started: ${executionId}`);
// Poll for result
let execution: AgentsExecutionListItem | undefined;
while (true) {
const { data: result } = await executionGet({
path: { executionId },
});
execution = result;
console.log(`Status: ${execution?.status}`);
if (TERMINAL_STATUSES.includes(execution?.status ?? '')) {
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
console.log('Result:', execution);
}
basicExample().catch(console.error);
Monitor an agent’s execution status in real-time while it’s running.
Copy
import { client, agentExecutePost, executionGet } from 'asteroid-odyssey';
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
async function monitorExecution() {
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
const { data } = await agentExecutePost({
path: { agentId: 'your-agent-id' },
body: {
inputs: {
DATA: 'First name: John, Last name: Smith',
},
agentProfileId: 'your-agent-profile-id',
},
});
if (!data) {
console.error('Failed to start execution');
return;
}
const executionId = data.executionId;
console.log('Execution started:', executionId);
// Check status periodically
const checkStatus = async () => {
const { data: execution } = await executionGet({
path: { executionId },
});
console.log(`Status: ${execution?.status}`);
// Continue checking if status is not final
// Possible statuses: 'starting' | 'running' | 'paused' | 'awaiting_confirmation' | 'completed' | 'failed' | 'cancelled' | 'paused_by_agent'
if (!TERMINAL_STATUSES.includes(execution?.status ?? '')) {
setTimeout(checkStatus, 2000); // Check again in 2 seconds
} else {
console.log('Execution finished with final status:', execution?.status);
}
};
checkStatus();
}
monitorExecution().catch(console.error);
Handle complex form data and structured information with your agents.
Copy
import { client, agentExecutePost, executionGet } from 'asteroid-odyssey';
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
async function complexFormExample() {
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
const formData = {
personalInfo: {
firstName: 'John',
lastName: 'Smith',
email: 'john.smith@example.com',
},
preferences: {
newsletter: true,
notifications: false,
},
address: {
street: '123 Main St',
city: 'Anytown',
zipCode: '12345',
},
};
const { data } = await agentExecutePost({
path: { agentId: 'your-agent-id' },
body: {
inputs: {
DATA: JSON.stringify(formData),
},
agentProfileId: 'your-agent-profile-id',
},
});
if (!data) {
console.error('Failed to start execution');
return;
}
// Wait for completion
while (true) {
const { data: execution } = await executionGet({
path: { executionId: data.executionId },
});
if (TERMINAL_STATUSES.includes(execution?.status ?? '')) {
console.log('Form submission result:', execution?.status);
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
complexFormExample().catch(console.error);
Use conditionals, loops, and nested data in your agent prompts for dynamic behavior.
Copy
import { client, agentExecutePost, executionGet } from 'asteroid-odyssey';
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
async function advancedVariablesExample() {
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
// Your agent prompt might look like:
// {{if .is_premium}}
// Navigate to premium dashboard and enable all features
// {{else}}
// Navigate to free dashboard with limited features
// {{end}}
//
// Fill the form with user info:
// Name: {{.user.name}}
// Email: {{.user.email}}
//
// {{range .items}}
// - Add "{{.name}}" ({{.price}}) to cart
// {{end}}
const { data } = await agentExecutePost({
path: { agentId: 'your-agent-id' },
body: {
inputs: {
// Booleans for conditionals
is_premium: true,
// Nested objects
user: {
name: 'Jane Smith',
email: 'jane@example.com',
verified: true,
},
// Arrays for loops
items: [
{ name: 'Product A', price: '$29.99' },
{ name: 'Product B', price: '$49.99' },
{ name: 'Product C', price: '$19.99' },
],
// Numbers and strings
max_quantity: 10,
coupon_code: 'SAVE20',
},
agentProfileId: 'your-agent-profile-id',
},
});
if (!data) {
console.error('Failed to start execution');
return;
}
// Wait for completion
while (true) {
const { data: execution } = await executionGet({
path: { executionId: data.executionId },
});
if (TERMINAL_STATUSES.includes(execution?.status ?? '')) {
console.log('Execution result:', execution?.status);
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
advancedVariablesExample().catch(console.error);
All JSON data types are supported: strings, numbers, booleans, arrays, and objects. See AI Task Node Dynamic Variables for examples.
Build interactive sessions where agents can request human input during execution.For example, create an AI Agent node with this prompt:How to Run:TypeScript:Key Features:
Prerequisites: Your agent must be configured in the Asteroid UI with a prompt that includes the
{{.data}} variable and instructions to request user input when needed.Copy
Your goal is to schedule an appointment. Go to https://asteroid.ai/ and book a demo using these details:
{{.data}}.
If the requested time isn't available, ask the user for help and suggest alternatives. Before submitting, confirm the final selection with the user.
Copy
import {
client,
agentExecutePost,
executionGet,
executionActivitiesGet,
executionUserMessagesAdd,
} from 'asteroid-odyssey';
import readline from 'readline';
// Configuration - Replace with your actual values
const CONFIG = {
agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
inputData: 'Thursday, First name: Ted, Last name: Clubber-Lang, email: ted@clubberlang.com',
pollInterval: 2000, // How often to check for updates (milliseconds)
};
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
let executionId: string | null = null;
// Utility functions
const logHeader = (title: string, char = '═', width = 60) => {
console.log(`\n${title}`);
console.log(char.repeat(width));
};
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
// Execute agent with data
async function startAgentExecution(): Promise<string> {
logHeader('🚀 Starting Agent Execution');
console.log(`🤖 Agent ID: ${CONFIG.agentId}`);
console.log(`📝 Input: ${CONFIG.inputData}`);
console.log('═'.repeat(60));
const { data, error } = await agentExecutePost({
path: { agentId: CONFIG.agentId },
body: {
inputs: { data: CONFIG.inputData },
},
});
if (error || !data) {
console.error('❌ Failed to start agent execution:', error);
process.exit(1);
}
console.log('✅ Agent execution started successfully!');
console.log('📋 Execution ID:', data.executionId);
return data.executionId;
}
// Handle terminal execution states
const handleTerminalStates = (status: string): boolean => {
const states: Record<string, () => void> = {
completed: () => {
console.log('✅ Execution completed successfully!');
process.exit(0);
},
failed: () => {
console.log('❌ Execution failed');
process.exit(1);
},
cancelled: () => {
console.log('🛑 Execution was cancelled');
process.exit(0);
},
};
if (states[status]) {
states[status]();
return true;
}
return false;
};
// Find and display agent's human input request
const findAndDisplayAgentRequest = async (): Promise<boolean> => {
const { data: activities } = await executionActivitiesGet({
path: { executionId: executionId! },
query: { limit: 20, order: 'desc' },
});
if (!activities || activities.length === 0) return false;
// Filter for action_started activities (agent requesting input)
const humanInputRequests = activities.filter(
(activity: any) => activity.payload?.activityType === 'action_started'
);
if (humanInputRequests.length === 0) return false;
const humanInputRequest = humanInputRequests[0];
const timestamp = new Date(humanInputRequest.timestamp).toLocaleString();
logHeader('🤖 Agent Request', '═', 80);
console.log(`📅 ${timestamp}`);
console.log(`💬 Agent is waiting for your response`);
console.log('═'.repeat(80));
return true;
};
async function waitForAgentInput(): Promise<void> {
console.log('🔄 Monitoring execution for agent requests...\n');
while (true) {
const { data: execution } = await executionGet({
path: { executionId: executionId! },
});
const status = execution?.status ?? '';
if (handleTerminalStates(status)) return;
if (status === 'paused_by_agent') {
console.log('⏸️ Agent has paused execution and is requesting input!\n');
if (await findAndDisplayAgentRequest()) return;
} else {
process.stdout.write(
`\r📊 Current Status: ${status.toUpperCase()}${' '.repeat(20)}`
);
}
await sleep(CONFIG.pollInterval);
}
}
// Get user input with readline
const getUserInput = (): Promise<string> =>
new Promise(resolve => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('\n💭 Enter your response: ', answer => {
rl.close();
resolve(answer);
});
});
// Send message to execution
const sendMessage = async (message: string): Promise<void> => {
console.log('\n📤 Sending message...');
await executionUserMessagesAdd({
path: { executionId: executionId! },
body: { message },
});
console.log('✅ Message sent successfully!\n🔄 Waiting for agent to continue...\n');
};
// Main interactive session loop
async function runInteractiveSession(): Promise<void> {
while (true) {
await waitForAgentInput();
const userMessage = await getUserInput();
if (userMessage.trim() === '') {
console.log('⚠️ Empty message, please try again.');
continue;
}
try {
await sendMessage(userMessage);
} catch (error: any) {
console.error('❌ Error sending message:', error.message);
}
}
}
// Main execution flow
async function main(): Promise<void> {
// Configure client
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
logHeader('🚀 Interactive Agent Session');
console.log('💡 Press Ctrl+C to exit\n');
executionId = await startAgentExecution();
await runInteractiveSession();
}
// Graceful exit and error handling
process.on('SIGINT', () => {
console.log('\n\n👋 Goodbye!');
process.exit(0);
});
main().catch(error => {
console.error('❌ Fatal error:', error.message);
process.exit(1);
});
- Save the code above as
interactive-agent.ts - Install the required dependencies:
Copy
npm install asteroid-odyssey typescript tsx - Set your API key and run the TypeScript file:
Copy
export ASTEROID_API_KEY="your-api-key-here" npx tsx interactive-agent.ts
- Save the code above as
interactive-agent.py - Install the required dependencies:
Copy
pip install asteroid-odyssey - Set your API key as an environment variable:
Copy
export ASTEROID_API_KEY="your-api-key-here" - Run the Python script:
Copy
python interactive-agent.py
Copy
🚀 Interactive Agent Session
════════════════════════════════════════════════════════════
💡 Press Ctrl+C to exit
🚀 Starting Agent Execution
════════════════════════════════════════════════════════════
🤖 Agent ID: 216a4c51-217b-401e-ab49-0e87e0e778fd
📝 Input: Thursday, First name: Ted, Last name: Clubber-Lang, email: ted@clubberlang.com
════════════════════════════════════════════════════════════
✅ Agent execution started successfully!
📋 Execution ID: 199b0638-82ea-4976-b996-13f828dbc066
🔄 Monitoring execution for agent requests...
📊 Current Status: STARTING 📊 Current Status: RUNNING ⏸️ Agent has paused execution and is requesting input!
════════════════════════════════════════════════════════════════════════════════
🤖 Agent Request
════════════════════════════════════════════════════════════════════════════════
💬 Agent is waiting for your response
💭 Enter your response: 2:00 PM
📤 Sending message...
✅ Message sent successfully!
🔄 Waiting for agent to continue...
- Real-time status monitoring with visual feedback
- Automatic detection of agent input requests
- Clean command-line interface with emojis and formatting
- Proper error handling and retry logic
- Graceful exit handling
- Set
ASTEROID_API_KEYenvironment variable with your Asteroid API key - Replace
YOUR_AGENT_IDwith the ID of your agent - Replace the
inputDatawith appropriate data for your agent - Adjust
pollIntervalif needed (default: 2 seconds)
Create a profile with cookies and manage them later.
Replace the ID placeholders in the snippet below before running
Copy
import {
client,
agentProfilesCreate,
agentProfileGet,
agentProfileUpdate,
agentExecutePost,
executionGet,
agentProfileDelete,
} from 'asteroid-odyssey';
const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
(async () => {
client.setConfig({
headers: {
'X-Asteroid-Agents-Api-Key': process.env.ASTEROID_API_KEY!,
},
});
// 1) Create an agent profile with cookies
const { data: created } = await agentProfilesCreate({
body: {
name: 'Profile With Cookies',
description: 'Profile preloaded with site cookies',
organizationId: 'YOUR_ORGANIZATION_ID',
proxyCC: 'us',
proxyType: 'residential',
captchaSolverActive: false,
stickyIP: false,
cookies: [
{
name: 'Session Cookie',
key: 'session_id',
value: 'abc123',
domain: 'example.com',
secure: true,
httpOnly: true,
sameSite: 'Lax',
expiry: '2026-01-01T00:00:00Z',
},
],
},
});
console.log('Created Profile ID:', created?.id);
// 2) Fetch the profile to confirm cookies
const { data: profile } = await agentProfileGet({
path: { profileId: created?.id! },
});
console.log('Cookies on profile:', profile?.cookies);
// 3) Update cookies: add one and remove one by ID
const { data: updated } = await agentProfileUpdate({
path: { profileId: created?.id! },
body: {
cookiesToAdd: [
{
name: 'Auth Token',
key: 'auth_token',
value: 'new-token',
domain: 'example.com',
secure: true,
httpOnly: true,
sameSite: 'Strict',
},
],
// Replace with a real cookie id from profile.cookies
cookiesToDelete: profile?.cookies?.length
? [profile.cookies[0].id!]
: [],
},
});
console.log('Updated cookie count:', updated?.cookies.length);
// 4) Execute an agent using the profile with cookies
const { data: execution } = await agentExecutePost({
path: { agentId: 'YOUR_AGENT_ID' },
body: {
agentProfileId: created?.id,
inputs: {
DATA: 'Form input or other structured data',
},
},
});
console.log('Execution started with ID:', execution?.executionId);
// Optionally wait for the result
while (true) {
const { data: result } = await executionGet({
path: { executionId: execution?.executionId! },
});
if (TERMINAL_STATUSES.includes(result?.status ?? '')) {
console.log('Execution result:', result?.status);
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
// 5) Cleanup: delete the agent profile
await agentProfileDelete({
path: { profileId: created?.id! },
});
console.log('Deleted profile:', created?.id);
})().catch(err => {
console.error(err);
process.exit(1);
});

