# Function Calling

{% tabs %}
{% tab title="NodeJS (TS)" %}

```typescript
import PropulsionAI from 'propulsionai';
import {
  ModelChatResponse,
  ModelChatParams
} from 'propulsionai/resources/models';

// Initialize PropulsionAI with bearer token from environment variables
const p8n = new PropulsionAI({
  bearerToken: process.env['PROPULSIONAI_BEARER_TOKEN'] as string,
});

// Example dummy function hardcoded to return the same weather
// In production, this could be your backend API or an external API
interface WeatherParameters {
  location: string;
  unit?: string;
}
function getCurrentWeather(parameters: WeatherParameters): string {
  let { location } = parameters;

  if (location.toLowerCase().includes("tokyo")) {
    return JSON.stringify({ location: "Tokyo", temperature: "10", unit: "celsius" });
  } else if (location.toLowerCase().includes("san francisco")) {
    return JSON.stringify({ location: "San Francisco", temperature: "72", unit: "fahrenheit" });
  } else if (location.toLowerCase().includes("paris")) {
    return JSON.stringify({ location: "Paris", temperature: "22", unit: "fahrenheit" });
  } else {
    return JSON.stringify({ location, temperature: "unknown" });
  }
}

async function main() {
  const tools: Array<ModelChatParams.Tool> = [
    {
      type: "function",
      function: {
        name: "get_current_weather",
        description: "Get the current weather in a given location",
        function: getCurrentWeather, // Optional: Link your actual function
        parameters: {
          type: "object",
          properties: {
            location: {
              type: "string",
              description: "The city and state, e.g., San Francisco, CA",
            },
            unit: {
              type: "string",
              enum: ["celsius", "fahrenheit"]
            },
          },
          required: ["location"],
          example: `get_current_weather("Tokyo", "celsius")`
        },
      },
    },
  ];
  let deployment_tag: string = '<deployment_tag>';
  let params: ModelChatParams = {
    tools: tools,
    messages: [
      {
        role: 'system',
        content: "You are a weatherman.",
      },
      {
        role: 'user',
        content: "What is the weather of Tokyo?",
      },
    ],
    model: 'auto',
    stream: false,
    wait: true,
  };

  let response: ModelChatResponse;
  try {
    response = await p8n.models.epAuto(deployment_tag, params);
  } catch (e) {
    console.log('Error:', e);
    return;
  }
  console.log("Task ID:", response.task_id);
  if (response.choices) {
    response.choices.forEach((choice) => {
      console.log(`${choice.message?.role}: ${choice.message?.content}`);
    });
  }
  if (response.toolCalls) {
    response.toolCalls.forEach((toolCall) => {
      console.log(`${toolCall.function?.name}: ${JSON.stringify(toolCall.function?.parameters)}`);
    });
  }
}

main();
```

{% endtab %}

{% tab title="NodeJS (JS)" %}

```javascript
import PropulsionAI from 'propulsionai';
// Initialize PropulsionAI with bearer token from environment variables
const p8n = new PropulsionAI({
  bearerToken: process.env['PROPULSIONAI_BEARER_TOKEN'],
});

// Example dummy function hardcoded to return the same weather
// In production, this could be your backend API or an external API
function getCurrentWeather(parameters) {
  let { location } = parameters;

  if (location.toLowerCase().includes("tokyo")) {
    return JSON.stringify({ location: "Tokyo", temperature: "10", unit: "celsius" });
  } else if (location.toLowerCase().includes("san francisco")) {
    return JSON.stringify({ location: "San Francisco", temperature: "72", unit: "fahrenheit" });
  } else if (location.toLowerCase().includes("paris")) {
    return JSON.stringify({ location: "Paris", temperature: "22", unit: "fahrenheit" });
  } else {
    return JSON.stringify({ location, temperature: "unknown" });
  }
}

async function main() {
  const tools = [
    {
      type: "function",
      function: {
        name: "get_current_weather",
        description: "Get the current weather in a given location",
        function: getCurrentWeather, // Optional: Link your actual function
        parameters: {
          type: "object",
          properties: {
            location: {
              type: "string",
              description: "The city and state, e.g., San Francisco, CA",
            },
            unit: {
              type: "string",
              enum: ["celsius", "fahrenheit"]
            },
          },
          required: ["location"],
          example: `get_current_weather("Tokyo", "celsius")` // Optional: Provide an example
        },
      },
    },
  ];
  let deployment_tag = '<deployment_tag>';
  let params = {
    tools: tools,
    messages: [
      {
        role: 'system',
        content: "You are a weatherman.",
      },
      {
        role: 'user',
        content: "What is the weather of Tokyo in F?",
      },
    ],
    model: 'auto',
    stream: false,
    wait: true,
  };

  let response;
  try {
    response = await p8n.models.epAuto(deployment_tag, params);
  } catch (e) {
    console.log('Error:', e);
    return;
  }
  console.log("Task ID:", response.task_id);
  if (response.choices) {
    response.choices.forEach((choice) => {
      console.log(`${choice.message?.role}: ${choice.message?.content}`);
    });
  }
  if (response.toolCalls) {
    response.toolCalls.forEach((toolCall) => {
      console.log(`${toolCall.function?.name}: ${JSON.stringify(toolCall.function?.parameters)}`);
    });
  }
}

main();
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from typing import Any, Dict, Callable, Coroutine
from propulsionai import AsyncPropulsionAI
from propulsionai.models import ModelChatResponse

# Initialize AsyncPropulsionAI with bearer token from environment variables
p8n = AsyncPropulsionAI(
    bearer_token=os.environ.get("PROPULSIONAI_BEARER_TOKEN"),
)

# Example dummy function hard coded to return the same weather
# In production, this could be your backend API or an external API
async def get_current_weather(location: str, unit: str = "fahrenheit") -> str:
    if "tokyo" in location.lower():
        return '{"location": "Tokyo", "temperature": "10", "unit": "celsius"}'
    elif "san francisco" in location.lower():
        return '{"location": "San Francisco", "temperature": "72", "unit": "fahrenheit"}'
    elif "paris" in location.lower():
        return '{"location": "Paris", "temperature": "22", "unit": "fahrenheit"}'
    else:
        return f'{{"location": "{location}", "temperature": "unknown"}}'

# Function map to map the function name to the actual function
available_function_map: Dict[str, Callable[..., Coroutine[Any, Any, str]]] = {
    "get_current_weather": get_current_weather,
}

async def main() -> None:
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get the current weather in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g., San Francisco, CA",
                        },
                        "unit": { 
                            "type": "string", 
                            "enum": ["celsius", "fahrenheit"] 
                        },
                    },
                    "required": ["location"],
                },
            },
        },
    ]
    
    try:
        response: ModelChatResponse = await p8n.models.ep_auto(
            '<deployment_tag>',
            available_function_map=available_function_map,
            tools=tools,
            messages=[
                {
                    "role": "system",
                    "content": "You are a weatherman.",
                },
                {
                    "role": 'user',
                    "content": "What is the weather of Tokyo?",
                },
            ],
            model="auto",
            stream=False,
            wait=True,
        )
        print(response.id)
        print(response.content)
    except Exception as e:
        print(f"Error during model call: {e}")

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())


```

{% endtab %}

{% tab title="cURL" %}

```bash
# Inference Call
curl -X "POST" "https://api.propulsionhq.com/api/v1/chat/<deployment_tag>?wait=true" \
     -H 'Authorization: Bearer <PROPULSIONAI_BEARER_TOKEN>' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d '{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_current_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g., San Francisco, CA"
            },
            "unit": { 
              "type": "string", 
              "enum": ["celsius", "fahrenheit"] 
            }
          },
          "required": ["location"]
        }
      }
    }
  ],
  "tool_choice": "auto",
  "messages": [
    {
      "role": "system",
      "content": "You are a weatherman."
    },
    {
      "role": "user",
      "content": "What is the weather of Tokyo"
    }
  ],
  "model": "auto"
}'

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.propulsionhq.com/developer-guide/function-calling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
