Skip to main content

JavaScript/TypeScript Integration

Complete JavaScript examples for integrating with Enclava agents.

Create and Chat

class EnclavaAgent {
constructor(apiKey, baseUrl = 'http://localhost/api/v1') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async createAgent(config) {
const response = await fetch(`${this.baseUrl}/agent/configs`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(config)
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to create agent');
}

return await response.json();
}

async chat(agentId, message, conversationId = null) {
const response = await fetch(`${this.baseUrl}/agent/chat`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message,
conversation_id: conversationId
})
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to chat');
}

return await response.json();
}
}

async function main() {
const client = new EnclavaAgent('YOUR_API_KEY');

const agent = await client.createAgent({
name: 'research_agent',
display_name: 'Research Assistant',
description: 'Helps with research tasks using web search',
category: 'research',
system_prompt: 'You are a research assistant. Use web search to find current information.',
model: 'gpt-4',
temperature: 0.3,
builtin_tools: ['web_search'],
tool_choice: 'auto',
max_iterations: 5
});

console.log(`Created agent: ${agent.id}`);

const response = await client.chat(
agent.id,
'What are the latest developments in AI?'
);

console.log(`Response: ${response.response}`);
console.log(`Tools used: ${response.tool_calls?.length || 0}`);
}

main().catch(console.error);

RAG and Web Search Agent

class ResearchAgent {
constructor(apiKey) {
this.apiKey = apiKey;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async createResearchAgent(ragCollection) {
const response = await fetch('http://localhost/api/v1/agent/configs', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
name: 'research_agent',
display_name: 'Research Assistant',
description: 'Combines RAG for internal docs with web search for current info',
category: 'research',
system_prompt: 'You are a research assistant. Use web search for current information and real-time data. Use RAG to search internal documentation. Always cite your sources.',
model: 'gpt-4',
temperature: 0.3,
builtin_tools: ['rag_search', 'web_search'],
tool_choice: 'auto',
max_iterations: 5
})
});

return await response.json();
}

async research(agentId, query) {
const response = await fetch('http://localhost/api/v1/agent/chat', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message: query
})
});

const result = await response.json();

console.log(`\nAnswer: ${result.response}`);

if (result.tool_calls && result.tool_calls.length > 0) {
console.log('\nTools Used:');
result.tool_calls.forEach((tool, i) => {
console.log(`${i + 1}. ${tool.tool_name}`);
if (tool.result) {
const preview = tool.result.substring(0, 100);
console.log(` Preview: ${preview}...`);
}
});
}

return result;
}
}

async function main() {
const client = new ResearchAgent('YOUR_API_KEY');

const agent = await client.createResearchAgent('documentation');

console.log(`Created agent: ${agent.id}`);

await client.research(
agent.id,
'What are the latest AI developments and what do our docs say about them?'
);
}

main().catch(console.error);

Code Execution Agent

class CodeAnalysisAgent {
constructor(apiKey) {
this.apiKey = apiKey;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async createCodeAgent() {
const response = await fetch('http://localhost/api/v1/agent/configs', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
name: 'code_agent',
display_name: 'Code Analysis Assistant',
description: 'Analyzes and executes code in a secure sandbox',
category: 'development',
system_prompt: 'You are a code analysis assistant. Use the code execution tool to run Python code and analyze the results. Always show your work and explain your findings.',
model: 'gpt-4',
temperature: 0.2,
builtin_tools: ['code_execution'],
tool_choice: 'auto',
max_iterations: 5
})
});

return await response.json();
}

async analyzeCode(agentId, codeSnippet, task) {
const prompt = `Here is some code:\n\`\`\`python\n${codeSnippet}\n\`\`\`\n\n${task}`;

const response = await fetch('http://localhost/api/v1/agent/chat', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message: prompt
})
});

const result = await response.json();

console.log(`\nAnalysis: ${result.response}`);

if (result.tool_calls) {
result.tool_calls.forEach(tool => {
if (tool.tool_name === 'code_execution') {
console.log('\nCode Execution Results:');
console.log(tool.result || 'No output');
}
});
}

return result;
}
}

async function main() {
const client = new CodeAnalysisAgent('YOUR_API_KEY');

const agent = await client.createCodeAgent();

console.log(`Created agent: ${agent.id}`);

const code = `
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)

for i in range(10):
print(f"fib({i}) = {fibonacci(i)}")
`;

await client.analyzeCode(
agent.id,
code,
'Analyze this Fibonacci function and identify performance issues.'
);
}

main().catch(console.error);

Direct Tool Calling

class DirectToolCaller {
constructor(apiKey) {
this.apiKey = apiKey;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async callTool(toolName, parameters) {
const response = await fetch('http://localhost/api/v1/agent/tool-calling', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
tool_name: toolName,
parameters
})
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Tool call failed');
}

return await response.json();
}

async searchRAG(query, collection, topK = 5) {
return await this.callTool('rag_search', {
query,
collection,
top_k: topK
});
}

async searchWeb(query, count = 5) {
return await this.callTool('web_search', {
query,
count
});
}

async executeCode(code, language = 'python') {
return await this.callTool('code_execution', {
code,
language
});
}
}

async function main() {
const client = new DirectToolCaller('YOUR_API_KEY');

const ragResults = await client.searchRAG(
'API key configuration',
'documentation',
3
);

console.log('RAG Search Results:');
ragResults.results.forEach((result, i) => {
console.log(`${i + 1}. Document: ${result.document_id}`);
console.log(` Score: ${result.score}`);
console.log(` Content: ${result.content.substring(0, 100)}...\n`);
});

const webResults = await client.searchWeb('latest AI news', 3);

console.log('Web Search Results:');
webResults.results.forEach((result, i) => {
console.log(`${i + 1}. ${result.title}`);
console.log(` URL: ${result.url}`);
console.log(` Snippet: ${result.snippet}\n`);
});

const codeResult = await client.executeCode('print(2 + 2)');

console.log('Code Execution Result:');
console.log(codeResult.output || codeResult);
}

main().catch(console.error);

Multi-Step Workflow Agent

class WorkflowAgent {
constructor(apiKey) {
this.apiKey = apiKey;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async createWorkflowAgent() {
const response = await fetch('http://localhost/api/v1/agent/configs', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
name: 'workflow_agent',
display_name: 'Workflow Assistant',
description: 'Handles complex multi-step tasks',
category: 'automation',
system_prompt: 'You are a workflow assistant. Break down complex tasks into steps. Use available tools to complete each step. Report progress clearly.',
model: 'gpt-4',
temperature: 0.3,
builtin_tools: ['web_search', 'rag_search', 'code_execution'],
tool_choice: 'auto',
max_iterations: 10
})
});

return await response.json();
}

async executeWorkflow(agentId, task, onProgress) {
const response = await fetch('http://localhost/api/v1/agent/chat', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message: task
})
});

const result = await response.json();

if (onProgress && result.tool_calls) {
result.tool_calls.forEach((tool, i) => {
onProgress(`Step ${i + 1}: ${tool.tool_name}`);
});
}

return result;
}
}

async function main() {
const client = new WorkflowAgent('YOUR_API_KEY');

const agent = await client.createWorkflowAgent();

console.log(`Created agent: ${agent.id}`);

const task = 'Research the latest trends in renewable energy, find relevant statistics in our docs, and calculate the percentage growth over the last year.';

await client.executeWorkflow(
agent.id,
task,
(progress) => console.log(progress)
);
}

main().catch(console.error);

React Integration

import React, { useState, useCallback } from 'react';

function AgentInterface() {
const [agentId, setAgentId] = useState('');
const [message, setMessage] = useState('');
const [conversation, setConversation] = useState([]);
const [loading, setLoading] = useState(false);
const [conversationId, setConversationId] = useState(null);
const [toolCalls, setToolCalls] = useState([]);

const sendMessage = useCallback(async () => {
if (!message.trim() || loading) return;

setLoading(true);
try {
const response = await fetch('http://localhost/api/v1/agent/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agent_id: agentId,
message,
conversation_id: conversationId
})
});

const result = await response.json();

setConversation(prev => [...prev, { role: 'user', content: message }]);
setConversation(prev => [...prev, { role: 'assistant', content: result.response }]);
setConversationId(result.conversation_id || conversationId);
setToolCalls(result.tool_calls || []);
setMessage('');
} catch (error) {
console.error('Error:', error);
alert('Failed to send message');
} finally {
setLoading(false);
}
}, [agentId, message, conversationId, loading]);

const createAgent = async () => {
try {
const response = await fetch('http://localhost/api/v1/agent/configs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'my_agent',
display_name: 'My Agent',
description: 'A helpful AI agent',
category: 'general',
system_prompt: 'You are a helpful assistant. Use tools when needed.',
model: 'gpt-4',
builtin_tools: ['web_search', 'rag_search'],
tool_choice: 'auto',
max_iterations: 5
})
});

const agent = await response.json();
setAgentId(agent.id);
console.log('Created agent:', agent.id);
} catch (error) {
console.error('Error:', error);
}
};

return (
<div className="max-w-4xl mx-auto p-6">
{!agentId ? (
<button
onClick={createAgent}
className="px-4 py-2 bg-blue-500 text-white rounded"
>
Create Agent
</button>
) : (
<div className="space-y-4">
<div className="border rounded-lg p-4 h-64 overflow-y-auto">
{conversation.map((msg, i) => (
<div key={i} className={`mb-2 ${msg.role === 'user' ? 'text-right' : 'text-left'}`}>
<span className={`inline-block px-3 py-1 rounded ${
msg.role === 'user' ? 'bg-blue-500 text-white' : 'bg-gray-200'
}`}>
{msg.content}
</span>
</div>
))}
</div>

{toolCalls.length > 0 && (
<div className="border rounded-lg p-4 bg-gray-50">
<h3 className="font-bold mb-2">Tools Used:</h3>
{toolCalls.map((tool, i) => (
<div key={i} className="text-sm">
<span className="font-semibold">{tool.tool_name}</span>
</div>
))}
</div>
)}

<div className="flex space-x-2">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
className="flex-1 px-4 py-2 border rounded"
placeholder="Type your message..."
disabled={loading}
/>
<button
onClick={sendMessage}
disabled={loading}
className="px-6 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
{loading ? 'Sending...' : 'Send'}
</button>
</div>
</div>
)}
</div>
);
}

export default AgentInterface;

Streaming Responses

class StreamingAgent {
constructor(apiKey) {
this.apiKey = apiKey;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}

async chatStream(agentId, message, onChunk, onToolCall) {
const response = await fetch('http://localhost/api/v1/agent/chat', {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message,
stream: true
})
});

if (!response.ok) {
throw new Error('Stream request failed');
}

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
const { done, value } = await reader.read();
if (done) break;

const chunk = decoder.decode(value);
const lines = chunk.split('\n');

for (const line of lines) {
if (line.startsWith('response:')) {
const content = line.slice(9);
onChunk(content);
} else if (line.startsWith('tool_call:')) {
const toolData = JSON.parse(line.slice(11));
if (onToolCall) onToolCall(toolData);
}
}
}
}
}

async function main() {
const client = new StreamingAgent('YOUR_API_KEY');

let fullResponse = '';
let toolsUsed = [];

await client.chatStream(
'your-agent-id',
'Research the latest AI developments',
(chunk) => {
process.stdout.write(chunk);
fullResponse += chunk;
},
(tool) => {
console.log(`\n[Tool Used: ${tool.tool_name}]`);
toolsUsed.push(tool);
}
);

console.log('\n\nFull response:', fullResponse);
console.log('Tools used:', toolsUsed.map(t => t.tool_name));
}

main().catch(console.error);

Error Handling

class RobustAgentClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.base_url = 'http://localhost/api/v1';
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
this.maxRetries = 3;
this.retryDelay = 1000;
}

async chatWithRetry(agentId, message, retries = 0) {
try {
const response = await fetch(`${this.base_url}/agent/chat`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
agent_id: agentId,
message
})
});

if (!response.ok) {
if (retries < this.maxRetries && [429, 500, 502, 503].includes(response.status)) {
console.log(`Attempt ${retries + 1} failed. Retrying...`);
await new Promise(resolve => setTimeout(resolve, this.retryDelay * (retries + 1)));
return this.chatWithRetry(agentId, message, retries + 1);
}
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

return await response.json();
} catch (error) {
console.error('Request failed:', error);
throw error;
}
}
}

async function main() {
const client = new RobustAgentClient('YOUR_API_KEY');

try {
const response = await client.chatWithRetry(
'your-agent-id',
'Hello!'
);
console.log('Response:', response.response);
} catch (error) {
console.error('Failed after retries:', error);
}
}

main().catch(console.error);

Best Practices

  1. Use Conversation IDs - Maintain context across messages
  2. Handle Streaming - Provide better UX for long responses
  3. Error Handling - Implement retry logic for failed requests
  4. Tool Calls Display - Show users which tools are being used
  5. TypeScript - Use TypeScript for better development experience
  6. Progress Feedback - Show progress during multi-step workflows

Next Steps