Azad Client Documentation¶
Overview¶
The Azad Client is a high-level TypeScript client that facilitates communication between your application and an AI assistant through WebSocket connections. It manages task execution, tool calling, message streaming, and provides a structured interface for handling various AI events.
Architecture¶
The Azad Client architecture consists of several key components:
- WebSocketClient: Low-level client that handles the WebSocket connection and message passing
- AzadClient: High-level client that orchestrates task execution and event handling
- LocalEnvironment: Manages tool registration, execution, and provides a bridge between tools and the client
- Tools: Individual capabilities that can be registered with the environment and called by the AI assistant
┌─────────────┐ ┌────────────────┐ ┌───────────────┐
│ AzadClient │◄────►│ WebSocketClient│◄────►│ Remote Server │
└──────┬──────┘ └────────────────┘ └───────────────┘
│
▼
┌──────────────┐ ┌───────────┐
│ Environment │◄───►│ Tools │
└──────────────┘ └───────────┘
Key Interfaces¶
AzadClient¶
The AzadClient class is the main entry point for working with the Azad system.
class AzadClient {
constructor(workingDirectory: string);
// Connection management
async connect(): Promise<void>;
async disconnect(): Promise<void>;
// Task execution
async executeTask(options: ExecuteTaskOptions): Promise<void>;
// Task management
public loadTask(task: Task): void;
public answerToolCall(toolCallId: string, result: ApprovalResponse): void;
}
ExecuteTaskOptions¶
Options for executing a task through the Azad Client:
interface ExecuteTaskOptions {
// Model configuration
model: {
id: string;
apiKey: string;
};
// Tool and task options
tools: AnyToolSchema[];
toolDialect?: 'xml' | 'json' | 'native';
thinkingBudgetTokens?: number;
maxSteps?: number;
system?: string;
maxRetry?: number;
task?: (ImagePart | TextPart)[];
initialTask?: (ImagePart | TextPart)[];
// Event callbacks
onText?: TextStreamCallback;
onReasoning?: ReasoningStreamCallback;
onStepStart?: StepStartCallback;
onStepEnd?: StepEndCallback;
onToolExecutionStart?: ToolExecutionStartCallback;
onToolCallParamsUpdate?: ToolCallParamsUpdateCallback;
onToolExecutionEnd?: ToolExecutionEndCallback;
onToolApproval?: ToolApprovalCallback;
onNetworkError?: (error: Error) => void;
}
WebSocketClient¶
The WebSocketClient handles low-level WebSocket communication:
class WebSocketClient {
constructor(url: string, environment: Environment);
// Connection management
async connect(): Promise<void>;
async disconnect(): Promise<void>;
// API methods
async abortStep(
args: Omit<AbortStepMessage['data'], 'operation'>
): Promise<any>;
async getLoadedTask(
args: Omit<GetLoadedTaskMessage['data'], 'operation'>
): Promise<DataResponse<Task | null>>;
async loadTask(
args: Omit<LoadTaskMessage['data'], 'operation'>
): Promise<MessageResponse | ErrorResponse>;
// Streaming API methods
async *runServerTool(
args: Omit<RunServerToolMessage['data'], 'operation'>
): AsyncGenerator<AINetworkEvent, void>;
async *stepTask(
args: Omit<StepTaskMessage['data'], 'operation'>
): AsyncGenerator<AINetworkEvent, void>;
}
Usage Examples¶
Basic Task Execution¶
import { AzadClient } from './server/azad-client';
import { executeCommandTool } from './environment/tools/definitions/execute-command';
// Initialize the client with the current working directory
const client = new AzadClient(process.cwd());
// Execute a task
await client.executeTask({
model: {
id: 'gpt-4',
apiKey: 'your-api-key',
},
tools: [executeCommandTool],
toolDialect: 'xml',
task: 'List all the files in the current directory and create a summary of their contents.',
// Text streaming callback
onText: (chunk, accumulated) => {
console.log('New text:', chunk);
},
// Tool approval callback
onToolApproval: async (toolName, toolCallId, args) => {
console.log(`Tool approval requested: ${toolName}`);
console.log('Arguments:', args);
// Automatically approve all tools
return { approved: true, images: [], feedback: null };
},
});
// Disconnect when done
await client.disconnect();
Advanced Task Execution with Callbacks¶
const client = new AzadClient(process.cwd());
await client.executeTask({
model: {
id: 'gpt-4',
apiKey: 'your-api-key',
},
tools: [executeCommandTool, readFileTool, writeFileTool],
toolDialect: 'xml',
maxSteps: 10,
system: 'You are a helpful coding assistant.',
task: 'Analyze the package.json file and upgrade all dependencies to their latest versions.',
// Full event callbacks
onText: (chunk, accumulated) => {
process.stdout.write(chunk);
},
onReasoning: (chunk, accumulated) => {
process.stderr.write(chalk.gray(chunk));
},
onStepStart: (assistantMessage) => {
console.log('\n--- Step started ---');
},
onStepEnd: (task, newMessages) => {
console.log('\n--- Step completed ---');
},
onToolExecutionStart: (toolCall) => {
console.log(`\n[Tool] Executing: ${toolCall.tool_name}`);
},
onToolCallParamsUpdate: (toolCall) => {
console.log(`[Tool] Params updated for: ${toolCall.tool_name}`);
},
onToolExecutionEnd: (toolCall, result) => {
console.log(`[Tool] Execution completed: ${toolCall.tool_name}`);
console.log(`[Tool] Success: ${result.success}`);
},
onToolApproval: async (toolName, toolCallId, args) => {
// Prompt the user for approval
const answer = await promptUser(`Approve tool ${toolName}? (y/n)`);
return {
approved: answer.toLowerCase() === 'y',
images: [],
feedback: answer.toLowerCase() !== 'y' ? 'Tool rejected by user' : null,
};
},
onNetworkError: (error) => {
console.error(`Error: `, error);
},
});
Task and Message Structure¶
Tasks in the Azad system have a specific structure:
interface Task {
id: string;
content: Array<TaskContent>;
state: 'running' | 'completed' | 'failed';
messages: Array<Message>;
}
interface Message {
role: 'user' | 'assistant' | 'system' | 'taskconfig';
id: string;
task_id: string;
started_ts: number;
content: Array<MessageContent>;
// Additional properties depending on the role
}
Event Types¶
The Azad Client processes various event types during task execution:
- Connection Events:
network_attempt_connection,ai_first_token,network_connection_established, etc. - Text Events:
text_start,text_chunk,text_end - Reasoning Events:
reasoning_start,reasoning_chunk,reasoning_end - Tool Events:
tool_name,parameter_start,parameter_chunk,parameter_end,parameters_complete,tool_ready - Task Events:
task_message,step_end
Error Handling¶
The Azad Client includes built-in error handling with retry capabilities:
// Configure retry behavior
await client.executeTask({
// Other options...
maxRetry: 3, // Retry up to 3 times on failure
});
Implementation Details¶
Connection Management¶
The WebSocketClient handles the low-level WebSocket connection:
- Connection: Establishes a WebSocket connection to the specified URL
- Message Queuing: Queues messages when not connected and sends them when the connection is established
- Reconnection: Handles reconnection with retry logic
- Event Handling: Processes incoming messages and routes them to the appropriate handlers
Task Execution Flow¶
- Task Creation: A task is created with the provided options
- Tool Registration: Tools are registered with the LocalEnvironment
- Task Configuration: The task is configured with model settings, tool metadata, etc.
- Execution: The task is executed by sending a stepTask request to the server
- Event Processing: Events are processed as they arrive and routed to the appropriate callbacks
- Task Completion: The task is marked as completed when the execution is finished
Tool Approval and Execution¶
- Tool Call: The AI assistant generates a tool call
- Parameter Collection: Parameters are collected and accumulated
- Tool Approval: The tool call is sent for approval via the onToolApproval callback
- Tool Execution: If approved, the tool is executed by the LocalEnvironment
- Result Processing: The tool result is processed and sent back to the assistant
Advanced Topics¶
Custom Tools¶
Custom tools can be registered with the Azad Client by creating a ToolSchema and passing it to the executeTask method. See the Tool Creation Guide for details.
Multi-step Tasks¶
Complex tasks may require multiple steps to complete. The Azad Client tracks the task state and messages across steps, allowing for continuous interaction.
Parallel Tool Execution¶
The Azad system supports parallel tool execution, allowing multiple tools to be executed simultaneously in one assistant response for improved performance.
- Note execution is sequental and awaited (Tool > Tool Result, ...)
Best Practices¶
- Resource Management: Always disconnect the client when done to free up resources
- Error Handling: Use the maxRetry option to handle transient errors
- Tool Approval: Implement proper tool approval to ensure security
- Environment Details: Provide accurate working directory information for proper tool execution
- Callback Management: Keep callback functions lightweight to avoid blocking the event processing loop