diff --git a/docs/02-dynamic-routes.ipynb b/docs/02-dynamic-routes.ipynb
index 665508ea0d5e0d1cf43b85ed5934be029728b10f..e1ab77164ec67cc5d56084d6b0b9ee8eeb706689 100644
--- a/docs/02-dynamic-routes.ipynb
+++ b/docs/02-dynamic-routes.ipynb
@@ -79,7 +79,7 @@
           "name": "stdout",
           "output_type": "stream",
           "text": [
-            "Requirement already satisfied: tzdata in c:\\users\\siraj\\documents\\personal\\work\\aurelio\\virtual environments\\semantic_router_2\\lib\\site-packages (2024.1)\n"
+            "Requirement already satisfied: tzdata in c:\\users\\siraj\\documents\\personal\\work\\aurelio\\virtual environments\\semantic_router_3\\lib\\site-packages (2024.1)\n"
           ]
         },
         {
@@ -129,7 +129,7 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "c:\\Users\\Siraj\\Documents\\Personal\\Work\\Aurelio\\Virtual Environments\\semantic_router_2\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
+            "c:\\Users\\Siraj\\Documents\\Personal\\Work\\Aurelio\\Virtual Environments\\semantic_router_3\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
             "  from .autonotebook import tqdm as notebook_tqdm\n"
           ]
         }
@@ -185,27 +185,27 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger local\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 2 length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 2 trunc length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 3 length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 3 trunc length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 4 length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 4 trunc length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 5 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 5 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 6 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 6 trunc length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 7 length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 7 trunc length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 8 length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 8 trunc length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 9 length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 9 trunc length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 10 length: 22\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:32 INFO semantic_router.utils.logger Document 10 trunc length: 22\u001b[0m\n"
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger local\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 2 length: 51\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 2 trunc length: 51\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 3 length: 66\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 3 trunc length: 66\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 4 length: 38\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 4 trunc length: 38\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 5 length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 5 trunc length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 6 length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 6 trunc length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 7 length: 21\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 7 trunc length: 21\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 8 length: 20\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 8 trunc length: 20\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 9 length: 25\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 9 trunc length: 25\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 10 length: 22\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:28 INFO semantic_router.utils.logger Document 10 trunc length: 22\u001b[0m\n"
           ]
         }
       ],
@@ -254,8 +254,8 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
           ]
         },
         {
@@ -332,7 +332,7 @@
         {
           "data": {
             "text/plain": [
-              "'06:42'"
+              "'17:50'"
             ]
           },
           "execution_count": 6,
@@ -367,10 +367,13 @@
         {
           "data": {
             "text/plain": [
-              "{'name': 'get_time',\n",
-              " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n",
-              " 'signature': '(timezone: str) -> str',\n",
-              " 'output': \"<class 'str'>\"}"
+              "{'type': 'function',\n",
+              " 'function': {'name': 'get_time',\n",
+              "  'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n",
+              "  'parameters': {'type': 'object',\n",
+              "   'properties': {'timezone': {'type': 'string',\n",
+              "     'description': 'The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.'}},\n",
+              "   'required': ['timezone']}}}"
             ]
           },
           "execution_count": 7,
@@ -379,9 +382,9 @@
         }
       ],
       "source": [
-        "from semantic_router.utils.function_call import get_schema\n",
+        "from semantic_router.utils.function_call import get_schema_openai\n",
         "\n",
-        "schema = get_schema(get_time)\n",
+        "schema = get_schema_openai(get_time)\n",
         "schema"
       ]
     },
@@ -446,13 +449,13 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 2 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 2 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 3 length: 32\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:33 INFO semantic_router.utils.logger Document 3 trunc length: 32\u001b[0m\n"
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 2 length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 2 trunc length: 27\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 3 length: 32\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:29 INFO semantic_router.utils.logger Document 3 trunc length: 32\u001b[0m\n"
           ]
         }
       ],
@@ -494,14 +497,9 @@
           "name": "stderr",
           "output_type": "stream",
           "text": [
-            "\u001b[32m2024-04-29 14:42:34 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:34 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[33m2024-04-29 14:42:34 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:34 INFO semantic_router.utils.logger Extracting function input...\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:35 INFO semantic_router.utils.logger LLM output: {\n",
-            "\t\"timezone\": \"America/New_York\"\n",
-            "}\u001b[0m\n",
-            "\u001b[32m2024-04-29 14:42:35 INFO semantic_router.utils.logger Function inputs: {'timezone': 'America/New_York'}\u001b[0m\n"
+            "\u001b[32m2024-04-30 01:50:30 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
+            "\u001b[32m2024-04-30 01:50:30 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
+            "\u001b[33m2024-04-30 01:50:30 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n"
           ]
         },
         {
@@ -528,7 +526,7 @@
         {
           "data": {
             "text/plain": [
-              "'06:42'"
+              "'17:50'"
             ]
           },
           "execution_count": 13,
diff --git a/docs/10-dynamic-routes-via-openai-function-calling.ipynb b/docs/10-dynamic-routes-via-openai-function-calling.ipynb
deleted file mode 100644
index 3db3b3feb61833b37ab7a305d074521e3f1658ec..0000000000000000000000000000000000000000
--- a/docs/10-dynamic-routes-via-openai-function-calling.ipynb
+++ /dev/null
@@ -1,632 +0,0 @@
-{
-  "cells": [
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "UxqB7_Ieur0s"
-      },
-      "source": [
-        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb)"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "EduhQaNAur0u"
-      },
-      "source": [
-        "# Dynamic Routes via OpenAI Function Calling"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "_4JgNeX4ur0v"
-      },
-      "source": [
-        "In this Notebook we showcase an alternative to dynamic routes where an `openai_function_schema` is specified or the Route, and in doing so, OpenAIs \"Function Calling\" API is utilized. \n",
-        "\n",
-        "The usual Semantic Router procedure is used to determine which Route is most appropriate for the input utterance. Then, rather than using a regular LLM call with careful prompt engineering to allow the LLM to extract function arguments from the input, OpenAIs Function Calling is leveraged to try and obtain function arguments more reliably. \n"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "bbmw8CO4ur0v"
-      },
-      "source": [
-        "## Installing the Library"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 1,
-      "metadata": {
-        "id": "dLElfRhgur0v"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "Requirement already satisfied: tzdata in c:\\users\\siraj\\documents\\personal\\work\\aurelio\\virtual environments\\semantic_router_3\\lib\\site-packages (2024.1)\n"
-          ]
-        },
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\n",
-            "[notice] A new release of pip is available: 23.1.2 -> 24.0\n",
-            "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
-          ]
-        }
-      ],
-      "source": [
-        "# !pip install -qU semantic-router==0.0.37\n",
-        "!pip install tzdata"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "BixZd6Eour0w"
-      },
-      "source": [
-        "## Initializing Routes and RouteLayer"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "PxnW9qBvur0x"
-      },
-      "source": [
-        "Dynamic routes are treated in the same way as static routes, let's begin by initializing a `RouteLayer` consisting of static routes."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 2,
-      "metadata": {
-        "id": "kc9Ty6Lgur0x"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "c:\\Users\\Siraj\\Documents\\Personal\\Work\\Aurelio\\Virtual Environments\\semantic_router_3\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
-            "  from .autonotebook import tqdm as notebook_tqdm\n"
-          ]
-        }
-      ],
-      "source": [
-        "from semantic_router import Route\n",
-        "\n",
-        "politics = Route(\n",
-        "    name=\"politics\",\n",
-        "    utterances=[\n",
-        "        \"isn't politics the best thing ever\",\n",
-        "        \"why don't you tell me about your political opinions\",\n",
-        "        \"don't you just love the president\" \"don't you just hate the president\",\n",
-        "        \"they're going to destroy this country!\",\n",
-        "        \"they will save the country!\",\n",
-        "    ],\n",
-        ")\n",
-        "chitchat = Route(\n",
-        "    name=\"chitchat\",\n",
-        "    utterances=[\n",
-        "        \"how's the weather today?\",\n",
-        "        \"how are things going?\",\n",
-        "        \"lovely weather today\",\n",
-        "        \"the weather is horrendous\",\n",
-        "        \"let's go to the chippy\",\n",
-        "    ],\n",
-        ")\n",
-        "\n",
-        "routes = [politics, chitchat]"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "voWyqmffur0x"
-      },
-      "source": [
-        "We initialize our `RouteLayer` with our `encoder` and `routes`. We can use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`, or local alternatives like `FastEmbedEncoder`."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 3,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "BI9AiDspur0y",
-        "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger local\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 2 length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 2 trunc length: 51\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 3 length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 3 trunc length: 66\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 4 length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 4 trunc length: 38\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 5 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 5 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 6 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 6 trunc length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 7 length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 7 trunc length: 21\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 8 length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 8 trunc length: 20\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 9 length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 9 trunc length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 10 length: 22\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:45 INFO semantic_router.utils.logger Document 10 trunc length: 22\u001b[0m\n"
-          ]
-        }
-      ],
-      "source": [
-        "import os\n",
-        "from getpass import getpass\n",
-        "from semantic_router import RouteLayer\n",
-        "from semantic_router.encoders import CohereEncoder, OpenAIEncoder\n",
-        "\n",
-        "# dashboard.cohere.ai\n",
-        "# os.environ[\"COHERE_API_KEY\"] = os.getenv(\"COHERE_API_KEY\") or getpass(\n",
-        "#     \"Enter Cohere API Key: \"\n",
-        "# )\n",
-        "# platform.openai.com\n",
-        "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n",
-        "    \"Enter OpenAI API Key: \"\n",
-        ")\n",
-        "\n",
-        "# encoder = CohereEncoder()\n",
-        "encoder = OpenAIEncoder()\n",
-        "\n",
-        "rl = RouteLayer(encoder=encoder, routes=routes)"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "GuLCeIS5ur0y"
-      },
-      "source": [
-        "We run the solely static routes layer:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 4,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "_rNREh7gur0y",
-        "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='chitchat', function_call=None, similarity_score=None)"
-            ]
-          },
-          "execution_count": 4,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "rl(\"how's the weather today?\")"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "McbLKO26ur0y"
-      },
-      "source": [
-        "## Creating a Dynamic Route"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "ANAoEjxYur0y"
-      },
-      "source": [
-        "As with static routes, we must create a dynamic route before adding it to our route layer. To make a route dynamic, we need to provide a `function_schema`. The function schema provides instructions on what a function is, so that an LLM can decide how to use it correctly."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 5,
-      "metadata": {
-        "id": "5jaF1Xa5ur0y"
-      },
-      "outputs": [],
-      "source": [
-        "from datetime import datetime\n",
-        "from zoneinfo import ZoneInfo\n",
-        "\n",
-        "\n",
-        "def get_time(timezone: str) -> str:\n",
-        "    \"\"\"Finds the current time in a specific timezone.\n",
-        "\n",
-        "    :param timezone: The timezone to find the current time in, should\n",
-        "        be a valid timezone from the IANA Time Zone Database like\n",
-        "        \"America/New_York\" or \"Europe/London\". Do NOT put the place\n",
-        "        name itself like \"rome\", or \"new york\", you must provide\n",
-        "        the IANA format.\n",
-        "    :type timezone: str\n",
-        "    :return: The current time in the specified timezone.\"\"\"\n",
-        "    now = datetime.now(ZoneInfo(timezone))\n",
-        "    return now.strftime(\"%H:%M\")"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 6,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/",
-          "height": 35
-        },
-        "id": "YyFKV8jMur0z",
-        "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "'08:25'"
-            ]
-          },
-          "execution_count": 6,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "get_time(\"America/New_York\")"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "4qyaRuNXur0z"
-      },
-      "source": [
-        "To get the function schema we can use the `get_schema` function from the `function_call` module."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 7,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "tOjuhp5Xur0z",
-        "outputId": "ca88a3ea-d70a-4950-be9a-63fab699de3b"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "{'name': 'get_time',\n",
-              " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n",
-              " 'signature': '(timezone: str) -> str',\n",
-              " 'output': \"<class 'str'>\"}"
-            ]
-          },
-          "execution_count": 7,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "from semantic_router.utils.function_call import get_schema\n",
-        "\n",
-        "schema = get_schema(get_time)\n",
-        "schema"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 8,
-      "metadata": {},
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "{'type': 'function',\n",
-              " 'function': {'name': 'get_time',\n",
-              "  'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n",
-              "  'parameters': {'type': 'object',\n",
-              "   'properties': {'timezone': {'type': 'string',\n",
-              "     'description': 'The timezone to find the current time in, should\\n    be a valid timezone from the IANA Time Zone Database like\\n    \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n    name itself like \"rome\", or \"new york\", you must provide\\n    the IANA format.'}},\n",
-              "   'required': ['timezone']}}}"
-            ]
-          },
-          "execution_count": 8,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "from semantic_router.utils.function_call import get_schema_openai_func_calling\n",
-        "\n",
-        "openai_function_schema = get_schema_openai_func_calling(get_time)\n",
-        "openai_function_schema"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "HcF7jGjAur0z"
-      },
-      "source": [
-        "We use this to define our dynamic route:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 9,
-      "metadata": {
-        "id": "iesBG9P3ur0z"
-      },
-      "outputs": [],
-      "source": [
-        "time_route = Route(\n",
-        "    name=\"get_time\",\n",
-        "    utterances=[\n",
-        "        \"what is the time in new york city?\",\n",
-        "        \"what is the time in london?\",\n",
-        "        \"I live in Rome, what time is it?\",\n",
-        "    ],\n",
-        "    # function_schema=schema,\n",
-        "    openai_function_schema=openai_function_schema,\n",
-        ")"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "ZiUs3ovpur0z"
-      },
-      "source": [
-        "Add the new route to our `layer`:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 10,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "-0vY8PRXur0z",
-        "outputId": "db01e14c-eab3-4f93-f4c2-e30f508c8b5d"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 2 length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 2 trunc length: 27\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 3 length: 32\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:46 INFO semantic_router.utils.logger Document 3 trunc length: 32\u001b[0m\n"
-          ]
-        }
-      ],
-      "source": [
-        "rl.add(time_route)"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "7yoE0IrNur0z"
-      },
-      "source": [
-        "Now we can ask our layer a time related question to trigger our new dynamic route."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 11,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/",
-          "height": 53
-        },
-        "id": "Wfb68M0-ur0z",
-        "outputId": "79923883-2a4d-4744-f8ce-e818cb5f14c3"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:47 INFO semantic_router.utils.logger Document 1 length: 34\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:47 INFO semantic_router.utils.logger Document 1 trunc length: 34\u001b[0m\n",
-            "\u001b[33m2024-04-29 16:25:47 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='get_time', function_call={'timezone': 'America/New_York'}, similarity_score=None)"
-            ]
-          },
-          "execution_count": 11,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "out = rl(\"what is the time in new york city?\")\n",
-        "out"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 12,
-      "metadata": {},
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "'08:25'"
-            ]
-          },
-          "execution_count": 12,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "get_time(**out.function_call)"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "Qt0vkq2Xur00"
-      },
-      "source": [
-        "Our dynamic route provides both the route itself _and_ the input parameters required to use the route."
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {},
-      "source": [
-        "Now let's just verify that the other route selection still work correctly, starting with chitchat."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 13,
-      "metadata": {},
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:48 INFO semantic_router.utils.logger Document 1 length: 24\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:48 INFO semantic_router.utils.logger Document 1 trunc length: 24\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='chitchat', function_call=None, similarity_score=None)"
-            ]
-          },
-          "execution_count": 13,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "out = rl(\"What's the weather like?\")\n",
-        "out"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {},
-      "source": [
-        "Now, an utterance that shouldn't fall into any of the routes defined above."
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 14,
-      "metadata": {},
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-04-29 16:25:48 INFO semantic_router.utils.logger Document 1 length: 25\u001b[0m\n",
-            "\u001b[32m2024-04-29 16:25:48 INFO semantic_router.utils.logger Document 1 trunc length: 25\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name=None, function_call=None, similarity_score=None)"
-            ]
-          },
-          "execution_count": 14,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "out = rl(\"Tell me how to bake cake?\")\n",
-        "out"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "J0oD1dxIur00"
-      },
-      "source": [
-        "---"
-      ]
-    }
-  ],
-  "metadata": {
-    "colab": {
-      "provenance": []
-    },
-    "kernelspec": {
-      "display_name": "decision-layer",
-      "language": "python",
-      "name": "python3"
-    },
-    "language_info": {
-      "codemirror_mode": {
-        "name": "ipython",
-        "version": 3
-      },
-      "file_extension": ".py",
-      "mimetype": "text/x-python",
-      "name": "python",
-      "nbconvert_exporter": "python",
-      "pygments_lexer": "ipython3",
-      "version": "3.11.4"
-    }
-  },
-  "nbformat": 4,
-  "nbformat_minor": 0
-}
diff --git a/semantic_router/llms/openai.py b/semantic_router/llms/openai.py
index 2b41f17a06b3bbe15ba8a3343792e36ff545852e..ee621bc888c9876fcac36717e019c72d1978734b 100644
--- a/semantic_router/llms/openai.py
+++ b/semantic_router/llms/openai.py
@@ -40,13 +40,13 @@ class OpenAILLM(BaseLLM):
     def __call__(
         self,
         messages: List[Message],
-        openai_function_schema: Optional[dict[str, Any]] = None,
+        function_schema: Optional[dict[str, Any]] = None,
     ) -> str:
         if self.client is None:
             raise ValueError("OpenAI client is not initialized.")
         try:
-            if openai_function_schema:
-                tools = [openai_function_schema]
+            if function_schema:
+                tools = [function_schema]
             else:
                 tools = None
 
@@ -58,39 +58,34 @@ class OpenAILLM(BaseLLM):
                 tools=tools,  # type: ignore # MyPy expecting Iterable[ChatCompletionToolParam] | NotGiven, but dict is accepted by OpenAI.
             )
 
-            if openai_function_schema:
-                tool_calls = completion.choices[0].message.tool_calls
-                if tool_calls is None:
-                    raise ValueError("Invalid output, expected a tool call.")
-                if len(tool_calls) != 1:
-                    raise ValueError(
-                        "Invalid output, expected a single tool to be specified."
-                    )
-                arguments = tool_calls[0].function.arguments
-                if arguments is None:
-                    raise ValueError(
-                        "Invalid output, expected arguments to be specified."
-                    )
-                output = str(arguments)  # str to keep MyPy happy.
-            else:
-                content = completion.choices[0].message.content
-                if content is None:
-                    raise ValueError("Invalid output, expected content.")
-                output = str(content)  # str to keep MyPy happy.
+            tool_calls = completion.choices[0].message.tool_calls
+            if tool_calls is None:
+                raise ValueError("Invalid output, expected a tool call.")
+            if len(tool_calls) != 1:
+                raise ValueError(
+                    "Invalid output, expected a single tool to be specified."
+                )
+            arguments = tool_calls[0].function.arguments
+            if arguments is None:
+                raise ValueError(
+                    "Invalid output, expected arguments to be specified."
+                )
+            output = str(arguments)  # str to keep MyPy happy.
             return output
+        
         except Exception as e:
             logger.error(f"LLM error: {e}")
             raise Exception(f"LLM error: {e}") from e
 
-    def extract_function_inputs_openai(
-        self, query: str, openai_function_schema: dict[str, Any]
+    def extract_function_inputs(
+        self, query: str, function_schema: dict[str, Any]
     ) -> dict:
         messages = []
         system_prompt = "You are an intelligent AI. Given a command or request from the user, call the function to complete the request."
         messages.append(Message(role="system", content=system_prompt))
         messages.append(Message(role="user", content=query))
         function_inputs_str = self(
-            messages=messages, openai_function_schema=openai_function_schema
+            messages=messages, function_schema=function_schema
         )
         function_inputs = json.loads(function_inputs_str)
         return function_inputs
diff --git a/semantic_router/utils/function_call.py b/semantic_router/utils/function_call.py
index cddbff3b2f4be7970b3094e3feec56a05b8ad8cf..416191bfaf7cc1f7919cd92b042a60b8806be74e 100644
--- a/semantic_router/utils/function_call.py
+++ b/semantic_router/utils/function_call.py
@@ -58,7 +58,7 @@ def convert_param_type_to_json_type(param_type: str) -> str:
         return "object"
 
 
-def get_schema_openai_func_calling(item: Callable) -> Dict[str, Any]:
+def get_schema_openai(item: Callable) -> Dict[str, Any]:
     if not callable(item):
         raise ValueError("Provided item must be a callable function.")