diff --git a/docs/js/typescript.mdx b/docs/js/typescript.mdx
index 5669e2dd7..be92d39c9 100644
--- a/docs/js/typescript.mdx
+++ b/docs/js/typescript.mdx
@@ -264,3 +264,99 @@ agents.start()
```
+
+## Tool Calls Examples
+
+
+
+ Create an agent that can use tools to get information:
+
+```typescript
+import { Agent } from 'praisonai';
+
+/**
+ * Example of a simple agent with tool calling capability
+ *
+ * This example demonstrates how to create a simple agent that can use tools
+ * to get weather information for a location.
+ */
+
+// Define a weather tool
+const getWeather = {
+ type: "function",
+ function: {
+ name: "get_weather",
+ description: "Get current temperature for a given location.",
+ parameters: {
+ type: "object",
+ properties: {
+ location: {
+ type: "string",
+ description: "City and country e.g. Bogotá, Colombia"
+ }
+ },
+ required: ["location"],
+ additionalProperties: false
+ },
+ strict: true
+ }
+};
+
+// Make the function globally available
+// The agent will automatically find and use this function
+(global as any).get_weather = async function(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `20°C`;
+};
+
+// Create an agent with the weather tool
+const agent = new Agent({
+ instructions: `You provide the current weather for requested locations.`,
+ name: "WeatherAgent",
+ tools: [getWeather]
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather in Paris, France?");
+```
+
+
+
+ Create an agent with directly registered function tools:
+
+```typescript
+import { Agent } from 'praisonai';
+
+/**
+ * Example of a simple agent with direct function registration
+ *
+ * This example demonstrates how to create a simple agent that uses directly
+ * registered functions as tools without having to define tool schemas manually
+ * or make functions globally available.
+ */
+
+// Define the functions directly
+async function getWeather(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `${Math.floor(Math.random() * 30)}°C`;
+}
+
+async function getTime(location: string) {
+ console.log(`Getting time for ${location}...`);
+ const now = new Date();
+ return `${now.getHours()}:${now.getMinutes()}`;
+}
+
+// Create an agent with directly registered functions
+const agent = new Agent({
+ instructions: `You provide the current weather and time for requested locations.`,
+ name: "DirectFunctionAgent",
+ // Register functions directly as an array without needing to make them global
+ tools: [getWeather, getTime]
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather and time in Paris, France and Tokyo, Japan?");
+```
+
+
diff --git a/src/praisonai-ts/examples/README-tool-examples.md b/src/praisonai-ts/examples/README-tool-examples.md
new file mode 100644
index 000000000..cc2967b2b
--- /dev/null
+++ b/src/praisonai-ts/examples/README-tool-examples.md
@@ -0,0 +1,193 @@
+# PraisonAI Tool Registration Examples
+
+This document demonstrates the three different ways to register tool functions in PraisonAI.
+
+## Method 1: Using the `tools` array with function objects directly
+
+```typescript
+import { Agent } from 'praisonai';
+
+// Define the functions directly
+async function getWeather(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `${Math.floor(Math.random() * 30)}°C`;
+}
+
+async function getTime(location: string) {
+ console.log(`Getting time for ${location}...`);
+ const now = new Date();
+ return `${now.getHours()}:${now.getMinutes()}`;
+}
+
+// Create an agent with directly registered functions
+const agent = new Agent({
+ instructions: `You provide the current weather and time for requested locations.`,
+ name: "DirectFunctionAgent",
+ // Register functions directly as an array
+ tools: [getWeather, getTime]
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather and time in Paris, France?");
+```
+
+## Method 2: Using the `toolFunctions` object with name-function pairs
+
+```typescript
+import { Agent } from 'praisonai';
+
+// Define the functions directly
+async function getWeather(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `${Math.floor(Math.random() * 30)}°C`;
+}
+
+async function getTime(location: string) {
+ console.log(`Getting time for ${location}...`);
+ const now = new Date();
+ return `${now.getHours()}:${now.getMinutes()}`;
+}
+
+// Create an agent with directly registered functions
+const agent = new Agent({
+ instructions: `You provide the current weather and time for requested locations.`,
+ name: "DirectFunctionAgent",
+ // Register functions with custom names
+ toolFunctions: {
+ get_weather: getWeather,
+ get_time: getTime
+ }
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather and time in Paris, France?");
+```
+
+## Method 3: Using the `tools` array with pre-defined tool definitions
+
+```typescript
+import { Agent } from 'praisonai';
+
+// Define the functions
+async function getWeather(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `${Math.floor(Math.random() * 30)}°C`;
+}
+
+async function getTime(location: string) {
+ console.log(`Getting time for ${location}...`);
+ const now = new Date();
+ return `${now.getHours()}:${now.getMinutes()}`;
+}
+
+// Register functions globally
+import { registerFunction } from 'praisonai';
+registerFunction('get_weather', getWeather);
+registerFunction('get_time', getTime);
+
+// Define tool definitions
+const weatherTool = {
+ type: "function",
+ function: {
+ name: "get_weather",
+ description: "Get the current weather for a location",
+ parameters: {
+ type: "object",
+ properties: {
+ location: {
+ type: "string",
+ description: "The location to get weather for"
+ }
+ },
+ required: ["location"]
+ }
+ }
+};
+
+const timeTool = {
+ type: "function",
+ function: {
+ name: "get_time",
+ description: "Get the current time for a location",
+ parameters: {
+ type: "object",
+ properties: {
+ location: {
+ type: "string",
+ description: "The location to get time for"
+ }
+ },
+ required: ["location"]
+ }
+ }
+};
+
+// Create an agent with pre-defined tool definitions
+const agent = new Agent({
+ instructions: `You provide the current weather and time for requested locations.`,
+ name: "ToolDefinitionAgent",
+ // Register pre-defined tool definitions
+ tools: [weatherTool, timeTool]
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather and time in Paris, France?");
+```
+
+## Combined Approach
+
+You can also combine these approaches as needed:
+
+```typescript
+import { Agent } from 'praisonai';
+
+// Define the functions
+async function getWeather(location: string) {
+ console.log(`Getting weather for ${location}...`);
+ return `${Math.floor(Math.random() * 30)}°C`;
+}
+
+async function getTime(location: string) {
+ console.log(`Getting time for ${location}...`);
+ const now = new Date();
+ return `${now.getHours()}:${now.getMinutes()}`;
+}
+
+// Define a custom tool definition
+const calculatorTool = {
+ type: "function",
+ function: {
+ name: "calculate",
+ description: "Perform a calculation",
+ parameters: {
+ type: "object",
+ properties: {
+ expression: {
+ type: "string",
+ description: "The mathematical expression to calculate"
+ }
+ },
+ required: ["expression"]
+ }
+ }
+};
+
+// Register the calculator function globally
+import { registerFunction } from 'praisonai';
+registerFunction('calculate', async (expression: string) => {
+ console.log(`Calculating ${expression}...`);
+ // Simple eval for demonstration purposes only
+ return eval(expression).toString();
+});
+
+// Create an agent with mixed tool registration approaches
+const agent = new Agent({
+ instructions: `You can provide weather, time, and perform calculations.`,
+ name: "MixedToolAgent",
+ // Register functions directly as an array
+ tools: [getWeather, getTime, calculatorTool]
+});
+
+// Start the agent with a prompt that will trigger tool usage
+agent.start("What's the weather in Paris, the time in Tokyo, and what is 25 * 4?");
+```
diff --git a/src/praisonai-ts/examples/simple/direct-function-tools.ts b/src/praisonai-ts/examples/simple/direct-function-tools.ts
index 5e780c417..a321aab26 100644
--- a/src/praisonai-ts/examples/simple/direct-function-tools.ts
+++ b/src/praisonai-ts/examples/simple/direct-function-tools.ts
@@ -24,11 +24,8 @@ async function getTime(location: string) {
const agent = new Agent({
instructions: `You provide the current weather and time for requested locations.`,
name: "DirectFunctionAgent",
- // Register functions directly without needing to make them global
- toolFunctions: {
- get_weather: getWeather,
- get_time: getTime
- }
+ // Register functions directly as an array without needing to make them global
+ tools: [getWeather, getTime]
});
// Start the agent with a prompt that will trigger tool usage
diff --git a/src/praisonai-ts/package.json b/src/praisonai-ts/package.json
index 4fbe3c220..d5425f856 100644
--- a/src/praisonai-ts/package.json
+++ b/src/praisonai-ts/package.json
@@ -1,6 +1,6 @@
{
"name": "praisonai",
- "version": "1.0.18",
+ "version": "1.0.19",
"description": "PraisonAI TypeScript AI Agents Framework - Node.js, npm, and Javascript AI Agents Framework",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -62,7 +62,7 @@
"fast-xml-parser": "^4.5.1",
"node-fetch": "^2.6.9",
"openai": "^4.81.0",
- "praisonai": "^1.0.17"
+ "praisonai": "^1.0.18"
},
"optionalDependencies": {
"boxen": "^7.1.1",
diff --git a/src/praisonai-ts/src/agent/simple.ts b/src/praisonai-ts/src/agent/simple.ts
index 95705ab5c..6a11fff69 100644
--- a/src/praisonai-ts/src/agent/simple.ts
+++ b/src/praisonai-ts/src/agent/simple.ts
@@ -10,7 +10,7 @@ export interface SimpleAgentConfig {
llm?: string;
markdown?: boolean;
stream?: boolean;
- tools?: any[];
+ tools?: any[] | Function[];
toolFunctions?: Record;
}
@@ -41,6 +41,45 @@ export class Agent {
Logger.setVerbose(this.verbose);
Logger.setPretty(this.pretty);
+ // Process tools array - handle both tool definitions and functions
+ if (config.tools && Array.isArray(config.tools)) {
+ // Convert tools array to proper format if it contains functions
+ const processedTools: any[] = [];
+
+ for (let i = 0; i < config.tools.length; i++) {
+ const tool = config.tools[i];
+
+ if (typeof tool === 'function') {
+ // If it's a function, extract its name and register it
+ const funcName = tool.name || `function_${i}`;
+
+ // Skip functions with empty names
+ if (funcName && funcName.trim() !== '') {
+ this.registerToolFunction(funcName, tool);
+
+ // Auto-generate tool definition
+ this.addAutoGeneratedToolDefinition(funcName, tool);
+ } else {
+ // Generate a random name for functions without names
+ const randomName = `function_${Math.random().toString(36).substring(2, 9)}`;
+ this.registerToolFunction(randomName, tool);
+
+ // Auto-generate tool definition
+ this.addAutoGeneratedToolDefinition(randomName, tool);
+ }
+ } else {
+ // If it's already a tool definition, add it as is
+ processedTools.push(tool);
+ }
+ }
+
+ // Add any pre-defined tool definitions
+ if (processedTools.length > 0) {
+ this.tools = this.tools || [];
+ this.tools.push(...processedTools);
+ }
+ }
+
// Register directly provided tool functions if any
if (config.toolFunctions) {
for (const [name, func] of Object.entries(config.toolFunctions)) {
@@ -98,6 +137,9 @@ export class Agent {
this.tools = [];
}
+ // Ensure we have a valid function name
+ const functionName = name || func.name || `function_${Math.random().toString(36).substring(2, 9)}`;
+
// Extract parameter names from function
const funcStr = func.toString();
const paramMatch = funcStr.match(/\(([^)]*)\)/);
@@ -107,8 +149,8 @@ export class Agent {
const toolDef = {
type: "function",
function: {
- name,
- description: `Auto-generated function for ${name}`,
+ name: functionName,
+ description: `Auto-generated function for ${functionName}`,
parameters: {
type: "object",
properties: {},
@@ -139,7 +181,7 @@ export class Agent {
}
this.tools.push(toolDef);
- Logger.debug(`Auto-generated tool definition for ${name}`);
+ Logger.debug(`Auto-generated tool definition for ${functionName}`);
}
/**
diff --git a/src/praisonai-ts/src/llm/openai.ts b/src/praisonai-ts/src/llm/openai.ts
index 95aee603b..6c2cef98e 100644
--- a/src/praisonai-ts/src/llm/openai.ts
+++ b/src/praisonai-ts/src/llm/openai.ts
@@ -72,15 +72,24 @@ function convertToOpenAIMessage(message: ChatMessage): ChatCompletionMessagePara
function convertToOpenAITool(tool: any): ChatCompletionTool {
// If it's already in the correct format, return it
if (tool.type === 'function' && typeof tool.type === 'string') {
+ // Ensure the function name is valid
+ if (!tool.function?.name || tool.function.name.trim() === '') {
+ tool.function.name = `function_${Math.random().toString(36).substring(2, 9)}`;
+ }
return tool as ChatCompletionTool;
}
+ // Generate a valid function name if none is provided
+ const functionName = tool.function?.name && tool.function.name.trim() !== ''
+ ? tool.function.name
+ : `function_${Math.random().toString(36).substring(2, 9)}`;
+
// Otherwise, try to convert it
return {
type: 'function',
function: {
- name: tool.function?.name || '',
- description: tool.function?.description || '',
+ name: functionName,
+ description: tool.function?.description || `Function ${functionName}`,
parameters: tool.function?.parameters || {}
}
};
diff --git a/src/praisonai-ts/tests/development/simple/direct-function-tools.ts b/src/praisonai-ts/tests/development/simple/direct-function-tools.ts
index 2665c9085..0785b41ab 100644
--- a/src/praisonai-ts/tests/development/simple/direct-function-tools.ts
+++ b/src/praisonai-ts/tests/development/simple/direct-function-tools.ts
@@ -24,11 +24,8 @@ async function getTime(location: string) {
const agent = new Agent({
instructions: `You provide the current weather and time for requested locations.`,
name: "DirectFunctionAgent",
- // Register functions directly without needing to make them global
- toolFunctions: {
- get_weather: getWeather,
- get_time: getTime
- }
+ // Register functions directly as an array without needing to make them global
+ tools: [getWeather, getTime]
});
// Start the agent with a prompt that will trigger tool usage