JavaScript Examples¶
JavaScript and TypeScript examples for AG2Trust API integration.
Setup¶
Node.js¶
Browser¶
No additional dependencies needed - use native fetch.
Configuration¶
Basic Usage¶
Send Message to Pool¶
async function sendMessage(content, threadId = null) {
const payload = { content };
if (threadId) {
payload.thread_id = threadId;
}
const response = await fetch(`${BASE_URL}/api/v1/ask/support`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
return response.json();
}
// Usage
const result = await sendMessage('Hello, I need help');
console.log('Response:', result.content);
console.log('Thread ID:', result.thread_id);
Send Message to Specific Agent¶
async function sendToAgent(agentId, message) {
const response = await fetch(
`${BASE_URL}/api/v1/agents/${agentId}/messages`,
{
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
// Extract text content
const text = data.content
.filter(block => block.type === 'text')
.map(block => block.text)
.join('\n');
return { text, metadata: data.metadata };
}
// Usage
const { text, metadata } = await sendToAgent('agent-uuid', 'Hello!');
console.log(text);
console.log(`Tokens used: ${metadata.tokens_used}`);
Conversation Management¶
Multi-Turn Conversation Class¶
class Conversation {
constructor(endpoint = 'support') {
this.endpoint = endpoint;
this.threadId = null;
this.history = [];
}
async send(content) {
const payload = { content };
if (this.threadId) {
payload.thread_id = this.threadId;
}
const response = await fetch(
`${BASE_URL}/api/v1/ask/${this.endpoint}`,
{
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
this.threadId = data.thread_id;
this.history.push({ role: 'user', content });
this.history.push({ role: 'assistant', content: data.content });
return data.content;
}
getHistory() {
return this.history;
}
}
// Usage
const conv = new Conversation('support');
console.log(await conv.send('I have a billing question'));
console.log(await conv.send('Can you show me my recent invoices?'));
console.log(await conv.send('The one from January looks wrong'));
Error Handling¶
Custom Error Classes¶
class AG2TrustError extends Error {
constructor(message, errorCode = null, details = {}) {
super(message);
this.name = 'AG2TrustError';
this.errorCode = errorCode;
this.details = details;
}
}
class RateLimitError extends AG2TrustError {
constructor(retryAfter) {
super('Rate limit exceeded', 'RATE_LIMIT_EXCEEDED');
this.retryAfter = retryAfter;
}
}
class AgentNotAvailableError extends AG2TrustError {
constructor() {
super('No agents available', 'NO_AGENTS_AVAILABLE');
}
}
async function handleResponse(response) {
if (response.ok) {
return response.json();
}
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '5');
throw new RateLimitError(retryAfter);
}
if (response.status === 503) {
throw new AgentNotAvailableError();
}
const error = await response.json();
throw new AG2TrustError(
error.error || 'Unknown error',
error.error_code,
error.details
);
}
Retry Logic¶
async function sendWithRetry(content, maxRetries = 3, threadId = null) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(`${BASE_URL}/api/v1/ask/support`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ content, thread_id: threadId })
});
return await handleResponse(response);
} catch (error) {
if (error instanceof RateLimitError && attempt < maxRetries - 1) {
console.log(`Rate limited, waiting ${error.retryAfter}s...`);
await new Promise(r => setTimeout(r, error.retryAfter * 1000));
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
Using Axios¶
Setup¶
Client with Interceptors¶
import axios from 'axios';
const client = axios.create({
baseURL: BASE_URL,
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
timeout: 65000
});
// Response interceptor for error handling
client.interceptors.response.use(
response => response,
async error => {
const { response, config } = error;
// Handle rate limiting
if (response?.status === 429) {
const retryAfter = parseInt(
response.headers['retry-after'] || '5'
);
if (!config._retry) {
config._retry = true;
await new Promise(r => setTimeout(r, retryAfter * 1000));
return client(config);
}
}
return Promise.reject(error);
}
);
// Usage
async function sendMessage(content, threadId = null) {
const { data } = await client.post('/api/v1/ask/support', {
content,
thread_id: threadId
});
return data;
}
Webhook Handling¶
Express.js Server¶
const express = require('express');
const crypto = require('crypto');
const app = express();
// Use raw body for signature verification
app.use('/webhooks', express.raw({ type: '*/*' }));
function verifySignature(body, signature) {
const expected = crypto
.createHmac('sha256', API_KEY)
.update(body)
.digest('hex');
const provided = signature.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(provided)
);
}
app.post('/webhooks/ag2trust', (req, res) => {
const signature = req.headers['x-webhook-signature'] || '';
if (!verifySignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}
const payload = JSON.parse(req.body);
const { callback_id, status, content } = payload;
if (status === 'completed') {
processResponse(callback_id, content);
} else {
handleFailure(callback_id, payload);
}
res.status(200).send('OK');
});
function processResponse(callbackId, content) {
content.forEach(block => {
if (block.type === 'text') {
console.log(`[${callbackId}] ${block.text}`);
}
});
}
function handleFailure(callbackId, payload) {
console.error(`[${callbackId}] Failed: ${payload.error}`);
}
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});
Send Async Request¶
async function sendAsyncMessage(agentId, message, webhookUrl) {
const response = await fetch(
`${BASE_URL}/api/v1/agents/${agentId}/messages`,
{
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message,
webhook_url: webhookUrl
})
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
// Usage
const result = await sendAsyncMessage(
'agent-uuid',
'Analyze this large dataset...',
'https://your-server.com/webhooks/ag2trust'
);
console.log(`Processing started: ${result.callback_id}`);
TypeScript¶
Type Definitions¶
interface Message {
content: string;
thread_id?: string;
}
interface PoolResponse {
thread_id: string;
agent_id: string;
content: string;
timestamp: string;
}
interface ContentBlock {
type: 'text' | 'error';
text?: string;
error?: string;
}
interface AgentResponse {
message_id: string;
content: ContentBlock[];
metadata: {
tokens_used: number;
model: string;
duration_ms: number;
};
}
interface Agent {
agent_id: string;
name: string;
status: 'running' | 'stopped' | 'error';
capabilities: string[];
}
Typed Client¶
class AG2TrustClient {
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, baseUrl = 'https://agents.ag2trust.com') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async ask(endpoint: string, content: string, threadId?: string): Promise<PoolResponse> {
const payload: Message = { content };
if (threadId) {
payload.thread_id = threadId;
}
const response = await fetch(`${this.baseUrl}/api/v1/ask/${endpoint}`, {
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json() as Promise<PoolResponse>;
}
async sendToAgent(agentId: string, message: string): Promise<AgentResponse> {
const response = await fetch(
`${this.baseUrl}/api/v1/agents/${agentId}/messages`,
{
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json() as Promise<AgentResponse>;
}
async listAgents(): Promise<Agent[]> {
const response = await fetch(`${this.baseUrl}/api/v1/agents`, {
headers: {
'X-API-Key': this.apiKey
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
return data.agents;
}
}
// Usage
const client = new AG2TrustClient(process.env.AG2TRUST_API_KEY!);
const response = await client.ask('support', 'Hello!');
console.log(response.content);
Browser Usage¶
With CORS¶
<!DOCTYPE html>
<html>
<head>
<title>AG2Trust Chat</title>
</head>
<body>
<div id="chat"></div>
<input type="text" id="input" placeholder="Type a message...">
<button onclick="send()">Send</button>
<script>
// NOTE: Never expose API keys in client-side code in production!
// Use a backend proxy instead.
const API_KEY = 'cust_your_api_key'; // Use backend proxy in production
const BASE_URL = 'https://agents.ag2trust.com';
let threadId = null;
async function send() {
const input = document.getElementById('input');
const content = input.value;
input.value = '';
addMessage('You', content);
const payload = { content };
if (threadId) {
payload.thread_id = threadId;
}
const response = await fetch(`${BASE_URL}/api/v1/ask/support`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
const data = await response.json();
threadId = data.thread_id;
addMessage('Agent', data.content);
}
function addMessage(sender, text) {
const chat = document.getElementById('chat');
chat.innerHTML += `<p><strong>${sender}:</strong> ${text}</p>`;
}
</script>
</body>
</html>
API Key Security
Never expose API keys in client-side code for production applications. Use a backend proxy to keep your API key secure.