PropulsionAI
  • Introduction
    • What is PropulsionAI?
    • Key Concepts at a Glance
    • Getting Started
    • Installing the SDK
    • Foundational Models
  • Quick Start
    • Creating Datasets
    • Fine-tuning a Model
    • Deploying Models
    • Generate API Key
    • Using the SDK
    • Function Calling
    • Using Knowledge Base
  • Reference
    • FAQs
    • Understanding Usage Costs
    • Community & Support
    • Our Commitment
Powered by GitBook
On this page
  1. Quick Start

Function Calling

Simple guide to understanding and implementing function calling.

PreviousUsing the SDKNextUsing Knowledge Base

Last updated 9 months ago

Automatic Tool Calling

Here we define the tool function in json

import { RunnableToolFunction } from 'propulsionai/lib/RunnableFunction';

const tools: RunnableToolFunction<any>[] = [
  {
    type: 'function',
    function: {
      name: 'list',
      description: 'list queries books by genre, and returns a list of names of books',
      parameters: {
        type: 'object',
        properties: {
          genre: { type: 'string', enum: ['mystery', 'nonfiction', 'memoir', 'romance', 'historical'] },
        },
      },
      function: list,
      parse: JSON.parse,
    },
  } as RunnableToolFunction<{ genre: string }>,
  {
    type: 'function',
    function: {
      name: 'search',
      description: 'search queries books by their name and returns a list of book names and their ids',
      parameters: {
        type: 'object',
        properties: {
          name: { type: 'string' },
        },
      },
      function: search,
      parse: JSON.parse,
    },
  } as RunnableToolFunction<{ name: string }>,
  {
    type: 'function',
    function: {
      name: 'get',
      description:
        "get returns a book's detailed information based on the id of the book. Note that this does not accept names, and only IDs, which you can get by using search.",
      parameters: {
        type: 'object',
        properties: {
          id: { type: 'string' },
        },
      },
      function: get,
      parse: JSON.parse,
    },
  } as RunnableToolFunction<{ id: string }>,
];

async function list({ genre }: { genre: string }) {
  console.log('calling list: ', genre);
  return db.filter((item) => item.genre === genre).map((item) => ({ name: item.name, id: item.id }));
}

async function search({ name }: { name: string }) {
  console.log('calling search: ', name);
  return db.filter((item) => item.name.includes(name)).map((item) => ({ name: item.name, id: item.id }));
}

async function get({ id }: { id: string }) {
  console.log('calling get: ', id);
  return db.find((item) => item.id === id);
}

Using run_tools for automatic function calling with or without streaming.

async function main() {
  const runner = await client.chat.completions
    .runTools({
      deployment: '<deployment_id>',
      stream: true, // can be false
      tools, // as defined earlier
      messages: [
        {
          role: 'system',
          content:
            'Please use our book database, which you can access using functions to answer the following questions.',
        },
        {
          role: 'user',
          content:
            'I really enjoyed reading Where the Crawdads Sing, could you recommend me a book that is similar and tell me why?',
        },
      ],
    })
    .on('message', (msg) => console.log('msg', msg))
    .on('functionCallResult', (functionCallResult) => console.log('functionCallResult', functionCallResult))
    .on('content', (diff) => process.stdout.write(diff))
    .on('totalUsage', (totalUsage) => console.log('totalUsage', totalUsage))
    .on('task_id', (task_id) => console.log('task_id', task_id));

  const result = await runner.finalChatCompletion();
  console.log();
  console.log('messages');
  console.log(JSON.stringify(runner.messages));

  console.log();
  console.log('final chat completion');
  console.dir(result, { depth: null });
}

main()

Here we define the tool function, its parameters and examples (optional)

def get_current_weather(location: str, format: str) -> str:
    """
    Retrieves the current weather for a specified location.

    This function fetches the current weather data for the given location
    and returns it in the specified format.

    Parameters:
    -----------
    location : str
        The name of the location (city, country, etc.) to get weather for.
    format : str
        The desired output format. Accepted values are 'celsius', 'fahrenheit',
        or 'kelvin' for temperature units.

    Examples:
    ---------
    >>> get_current_weather("New York", "celsius")
    'Current weather in New York: 22°C, Partly Cloudy'

    >>> get_current_weather("London", "fahrenheit")
    'Current weather in London: 59°F, Rainy'
    """
    # print(f"Function Log: Getting weather for {location} in {format} format...")
    return f'{{"temperature": 22, "description": "Partly Cloudy", "location": "{location}", "units": "{format}"}}'

Using run_tools for automatic function calling without streaming.

def sync_main() -> None:
    response = client.chat.completions.run_tools(
        deployment="<deployment_id>",
        messages=[
            {
                "role": "system",
                "content": "You are a helpful assistant.",
            },
            {
                "role": "user",
                "content": "What is the weather in SF and NY?",
            },
        ],
        tools=[get_current_weather],
        stream=False,
        tool_debug=False,
    )
    print(response.to_json())
sync_main()

Using run_tools for automatic function calling while streaming.

def sync_main() -> None:
    response = client.chat.completions.run_tools(
        deployment="<deployment_id>",
        messages=[
            {
                "role": "system",
                "content": "You are a helpful assistant.",
            },
            {
                "role": "user",
                "content": "What is the weather in SF and NY?",
            },
        ],
        tools=[get_current_weather],
        stream=True,
        tool_debug=False,
    )
    for data in response:
      if data:
          chunk = data.to_json()
          chunk_json = json.loads(chunk)
          
          if chunk_json["choices"] and chunk_json["choices"][0]["delta"] is not None:
              delta = chunk_json["choices"][0]["delta"]
              
              # Check if 'content' exists in delta and is not None
              if "content" in delta and delta["content"] is not None:
                  sys.stdout.write(delta["content"])
                  sys.stdout.flush()  # Ensure content is displayed immediately
              
              # Check for tool calls
              # if "tool_calls" in delta:
                  # print("Tool call detected:", delta["tool_calls"])
              
              # Check for finish reason
              # if "finish_reason" in chunk_json["choices"][0] and chunk_json["choices"][0]["finish_reason"] == "stop":
              #     print("\nGeneration complete.")
sync_main()

Manualy manage function calling

// TODO
// TODO
Installing the SDK