Using Tools with OpenAI
// openai-chatbot.js
import readline from "readline";
import OpenAI from "openai";
import { OpenAIAdapter } from "@reacter/openapitools";
// Initialize OpenAI client
const openai = new OpenAI({
apiKey: "your-openai-api-key",
});
// Initialize tools adapter
const toolsAdapter = new OpenAIAdapter(
"your OpenAPI Tools Apikey - https://openapitools.com/dashboard/settings",
{
autoRefreshCount: 50, // Refresh tools after 50 calls
verbose: true,
}
);
// Create readline interface
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// Function to ask a question and get input
function askQuestion(query) {
return new Promise((resolve) => rl.question(query, resolve));
}
async function main() {
console.log("Initializing tools...");
await toolsAdapter.initialize();
// Get tools in OpenAI format
const tools = await toolsAdapter.getOpenAITools();
console.log(`Loaded ${tools.length} tools`);
// Create tool handler
const toolHandler = await toolsAdapter.createOpenAIToolHandler();
// Start conversation
console.log("\n=== AI Assistant with Tools ===");
console.log("Type 'exit' to quit, 'reset' to start a new conversation");
// Store conversation history
const messages = [
{
role: "system",
content: "You are a helpful AI assistant with tool capabilities.",
},
{
role: "assistant",
content:
"Hello! I'm your AI assistant with tool capabilities. How can I help you today?",
},
];
console.log(
"\nAssistant: Hello! I'm your AI assistant with tool capabilities. How can I help you today?"
);
// Chat loop
while (true) {
const userInput = await askQuestion("\nYou: ");
if (userInput.toLowerCase() === "exit") {
console.log("Goodbye!");
rl.close();
break;
}
if (userInput.toLowerCase() === "reset") {
messages.length = 0;
messages.push(
{
role: "system",
content: "You are a helpful AI assistant with tool capabilities.",
},
{
role: "assistant",
content: "Conversation reset. How can I help you?",
}
);
console.log("\nConversation reset.");
console.log("\nAssistant: Conversation reset. How can I help you?");
continue;
}
// Add user message to history
messages.push({
role: "user",
content: userInput,
});
// Show "thinking" indicator
const thinkingInterval = setInterval(() => {
process.stdout.write(".");
}, 500);
try {
// Create API call options
const apiOptions = {
model: "gpt-4o",
temperature: 0.7,
max_tokens: 1024,
messages: messages,
};
// Add tools if available
if (tools && tools.length > 0) {
apiOptions.tools = tools;
}
// Call OpenAI API
const response = await openai.chat.completions.create(apiOptions);
const responseMessage = response.choices[0].message;
// Clear the thinking indicator
clearInterval(thinkingInterval);
process.stdout.write("\n");
// Check if there are tool calls
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
// Add assistant's message with tool calls to history
messages.push({
role: "assistant",
content: responseMessage.content,
tool_calls: responseMessage.tool_calls,
});
console.log(
`\nAssistant: ${
responseMessage.content || "Let me use a tool to help with that."
}`
);
// Process each tool call
for (const toolCall of responseMessage.tool_calls) {
console.log(`\nAssistant is using tool: ${toolCall.function.name}`);
console.log(`Input: ${toolCall.function.arguments}`);
// Execute the tool
try {
const result = await toolHandler(toolCall);
// Format the tool result
const resultContent = result.error
? JSON.stringify({ error: result.error })
: JSON.stringify({ output: result.output });
// Add tool response to messages
messages.push({
role: "tool",
tool_call_id: toolCall.id,
name: toolCall.function.name,
content: resultContent,
});
if (result.error) {
console.log(`\nTool Error: ${result.error}`);
} else {
console.log(`\nTool Result: ${result.output}`);
}
} catch (error) {
console.error(`\nTool execution error: ${error.message}`);
messages.push({
role: "tool",
tool_call_id: toolCall.id,
name: toolCall.function.name,
content: JSON.stringify({
error: `Failed to execute tool: ${error.message}`,
}),
});
}
}
// Get continuation from AI after tool use
const continuation = await openai.chat.completions.create({
model: "gpt-4o",
temperature: 0.7,
max_tokens: 1024,
messages: messages,
tools: tools, // Include tools again for potential future tool calls
});
const continuationMessage = continuation.choices[0].message;
// Check if there are more tool calls in the continuation
if (
continuationMessage.tool_calls &&
continuationMessage.tool_calls.length > 0
) {
// This would require recursive handling, but for simplicity in this example,
// we'll just note that there are more tool calls
console.log(
"\nAssistant wants to use more tools. Simplifying response for this example."
);
messages.push({
role: "assistant",
content:
continuationMessage.content ||
"I'd like to use more tools, but let me summarize what I've found so far.",
});
console.log(
`\nAssistant: ${
continuationMessage.content ||
"Let me summarize what I've found so far."
}`
);
} else {
// Add continuation to history
messages.push({
role: "assistant",
content: continuationMessage.content,
});
console.log(`\nAssistant: ${continuationMessage.content}`);
}
} else {
// Simple text response
console.log(`\nAssistant: ${responseMessage.content}`);
// Add to history
messages.push({
role: "assistant",
content: responseMessage.content,
});
}
} catch (error) {
// Clear the thinking indicator
clearInterval(thinkingInterval);
process.stdout.write("\n");
console.error(`\nError: ${error.message}`);
}
}
}
main().catch((error) => {
console.error("Fatal error:", error);
rl.close();
});
Last updated on