diff --git a/docs/02-dynamic-routes.ipynb b/docs/02-dynamic-routes.ipynb
index 6353e71a3a3a261887790dc28cc1f5ca874d61fe..01525299984e5a1ed846d907c702b0a72d8fa3ed 100644
--- a/docs/02-dynamic-routes.ipynb
+++ b/docs/02-dynamic-routes.ipynb
@@ -1,1178 +1,1177 @@
 {
-  "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"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "_4JgNeX4ur0v"
-      },
-      "source": [
-        "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n",
-        "\n",
-        "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route does the same thing, but it also extracts key information from the input utterance to be used in a function associated with that route.\n",
-        "\n",
-        "For example we could provide a dynamic route with associated utterances:\n",
-        "\n",
-        "```\n",
-        "\"what is x to the power of y?\"\n",
-        "\"what is 9 to the power of 4?\"\n",
-        "\"calculate the result of base x and exponent y\"\n",
-        "\"calculate the result of base 10 and exponent 3\"\n",
-        "\"return x to the power of y\"\n",
-        "```\n",
-        "\n",
-        "and we could also provide the route with a schema outlining key features of the function:\n",
-        "\n",
-        "```\n",
-        "def power(base: float, exponent: float) -> float:\n",
-        "    \"\"\"Raise base to the power of exponent.\n",
-        "\n",
-        "    Args:\n",
-        "        base (float): The base number.\n",
-        "        exponent (float): The exponent to which the base is raised.\n",
-        "\n",
-        "    Returns:\n",
-        "        float: The result of base raised to the power of exponent.\n",
-        "    \"\"\"\n",
-        "    return base ** exponent\n",
-        "```\n",
-        "\n",
-        "Then, if the users input utterance is \"What is 2 to the power of 3?\", the route will be triggered, as the input utterance is semantically similar to the route utterances. Furthermore, the route utilizes an LLM to identify that `base=2` and `expoenent=3`. These values are returned in such a way that they can be used in the above `power` function. That is, the dynamic router automates the process of calling relevant functions from natural language inputs.\n",
-        "\n",
-        "***⚠️ Note: We have a fully local version of dynamic routes available at [docs/05-local-execution.ipynb](https://github.com/aurelio-labs/semantic-router/blob/main/docs/05-local-execution.ipynb). The local 05 version tends to outperform the OpenAI version we demo in this notebook, so we'd recommend trying [05](https://github.com/aurelio-labs/semantic-router/blob/main/docs/05-local-execution.ipynb)!***"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "bbmw8CO4ur0v"
-      },
-      "source": [
-        "## Installing the Library"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "dLElfRhgur0v",
-        "outputId": "da0e506e-24cf-43da-9243-894a7c4955db"
-      },
-      "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 tzdata\n",
-        "!pip install -qU semantic-router"
-      ]
-    },
-    {
-      "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": null,
-      "metadata": {
-        "id": "kc9Ty6Lgur0x",
-        "outputId": "f32e3a25-c073-4802-ced3-d7a5663670c1"
-      },
-      "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": null,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "BI9AiDspur0y",
-        "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:57:55 INFO semantic_router.utils.logger local\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": null,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "_rNREh7gur0y",
-        "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7"
-      },
-      "outputs": [
-        {
-          "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 the `function_schemas` as a list. Each 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": null,
-      "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": null,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/",
-          "height": 35
-        },
-        "id": "YyFKV8jMur0z",
-        "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "'17:57'"
-            ]
-          },
-          "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": null,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "tOjuhp5Xur0z",
-        "outputId": "ca88a3ea-d70a-4950-be9a-63fab699de3b"
-      },
-      "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": 7,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "from semantic_router.llms.openai import get_schemas_openai\n",
-        "\n",
-        "schemas = get_schemas_openai([get_time])\n",
-        "schemas"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "HcF7jGjAur0z"
-      },
-      "source": [
-        "We use this to define our dynamic route:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "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_schemas=schemas,\n",
-        ")"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "jmVwEWEIg9hq"
-      },
-      "outputs": [],
-      "source": [
-        "time_route.llm"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "ZiUs3ovpur0z"
-      },
-      "source": [
-        "Add the new route to our `layer`:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "colab": {
-          "base_uri": "https://localhost:8080/"
-        },
-        "id": "-0vY8PRXur0z",
-        "outputId": "db01e14c-eab3-4f93-f4c2-e30f508c8b5d"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:57:56 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n"
-          ]
-        }
-      ],
-      "source": [
-        "rl.add(time_route)"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "mbccVdy5g9hr"
-      },
-      "outputs": [],
-      "source": [
-        "time_route.llm"
-      ]
-    },
-    {
-      "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": null,
-      "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[33m2024-05-08 01:57:57 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-05-08 01:57:58 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='get_time', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}], similarity_score=None)"
-            ]
-          },
-          "execution_count": 12,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl(\"what is the time in new york city?\")\n",
-        "response"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "92x96x1Og9hr",
-        "outputId": "c1e46a81-b681-4a10-fff6-71e03342a88e"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\n"
-          ]
-        }
-      ],
-      "source": [
-        "print(response.function_call)"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "xvdyUPKqg9hr",
-        "outputId": "4161e7e0-ab6d-4e76-f068-2d66728305ff"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "17:57\n"
-          ]
-        }
-      ],
-      "source": [
-        "import json\n",
-        "\n",
-        "for call in response.function_call:\n",
-        "    if call[\"function_name\"] == \"get_time\":\n",
-        "        args = call[\"arguments\"]\n",
-        "        result = get_time(**args)\n",
-        "print(result)"
-      ]
-    },
-    {
-      "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": {
-        "id": "jToYBo8Ug9hr"
-      },
-      "source": [
-        "## Dynamic Routes with Multiple Functions"
-      ]
-    },
-    {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "J0oD1dxIur00"
-      },
-      "source": [
-        "---"
-      ]
-    },
+ "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"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "_4JgNeX4ur0v"
+   },
+   "source": [
+    "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n",
+    "\n",
+    "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route does the same thing, but it also extracts key information from the input utterance to be used in a function associated with that route.\n",
+    "\n",
+    "For example we could provide a dynamic route with associated utterances:\n",
+    "\n",
+    "```\n",
+    "\"what is x to the power of y?\"\n",
+    "\"what is 9 to the power of 4?\"\n",
+    "\"calculate the result of base x and exponent y\"\n",
+    "\"calculate the result of base 10 and exponent 3\"\n",
+    "\"return x to the power of y\"\n",
+    "```\n",
+    "\n",
+    "and we could also provide the route with a schema outlining key features of the function:\n",
+    "\n",
+    "```\n",
+    "def power(base: float, exponent: float) -> float:\n",
+    "    \"\"\"Raise base to the power of exponent.\n",
+    "\n",
+    "    Args:\n",
+    "        base (float): The base number.\n",
+    "        exponent (float): The exponent to which the base is raised.\n",
+    "\n",
+    "    Returns:\n",
+    "        float: The result of base raised to the power of exponent.\n",
+    "    \"\"\"\n",
+    "    return base ** exponent\n",
+    "```\n",
+    "\n",
+    "Then, if the users input utterance is \"What is 2 to the power of 3?\", the route will be triggered, as the input utterance is semantically similar to the route utterances. Furthermore, the route utilizes an LLM to identify that `base=2` and `expoenent=3`. These values are returned in such a way that they can be used in the above `power` function. That is, the dynamic router automates the process of calling relevant functions from natural language inputs.\n",
+    "\n",
+    "***⚠️ Note: We have a fully local version of dynamic routes available at [docs/05-local-execution.ipynb](https://github.com/aurelio-labs/semantic-router/blob/main/docs/05-local-execution.ipynb). The local 05 version tends to outperform the OpenAI version we demo in this notebook, so we'd recommend trying [05](https://github.com/aurelio-labs/semantic-router/blob/main/docs/05-local-execution.ipynb)!***"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "bbmw8CO4ur0v"
+   },
+   "source": [
+    "## Installing the Library"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "dLElfRhgur0v",
+    "outputId": "da0e506e-24cf-43da-9243-894a7c4955db"
+   },
+   "outputs": [
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "vEkTpoVAg9hr"
-      },
-      "source": [
-        "Routes can be assigned multiple functions. Then, when that particular Route is selected by the Route Layer, a number of those functions might be invoked due to the users utterance containing relevant information that fits their arguments."
-      ]
+     "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"
+     ]
     },
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "BHUlB3org9hs"
-      },
-      "source": [
-        "Let's define a Route that has multiple functions."
-      ]
-    },
+     "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 tzdata\n",
+    "!pip install -qU semantic-router"
+   ]
+  },
+  {
+   "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": null,
+   "metadata": {
+    "id": "kc9Ty6Lgur0x",
+    "outputId": "f32e3a25-c073-4802-ced3-d7a5663670c1"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "dtrksov0g9hs"
-      },
-      "outputs": [],
-      "source": [
-        "from datetime import datetime, timedelta\n",
-        "from zoneinfo import ZoneInfo\n",
-        "\n",
-        "\n",
-        "# Function with one argument\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\")\n",
-        "\n",
-        "\n",
-        "def get_time_difference(timezone1: str, timezone2: str) -> str:\n",
-        "    \"\"\"Calculates the time difference between two timezones.\n",
-        "    :param timezone1: The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\n",
-        "    :param timezone2: The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\n",
-        "    :type timezone1: str\n",
-        "    :type timezone2: str\n",
-        "    :return: The time difference in hours between the two timezones.\"\"\"\n",
-        "    # Get the current time in UTC\n",
-        "    now_utc = datetime.utcnow().replace(tzinfo=ZoneInfo(\"UTC\"))\n",
-        "\n",
-        "    # Convert the UTC time to the specified timezones\n",
-        "    tz1_time = now_utc.astimezone(ZoneInfo(timezone1))\n",
-        "    tz2_time = now_utc.astimezone(ZoneInfo(timezone2))\n",
-        "\n",
-        "    # Calculate the difference in offsets from UTC\n",
-        "    tz1_offset = tz1_time.utcoffset().total_seconds()\n",
-        "    tz2_offset = tz2_time.utcoffset().total_seconds()\n",
-        "\n",
-        "    # Calculate the difference in hours\n",
-        "    hours_difference = (tz2_offset - tz1_offset) / 3600\n",
-        "\n",
-        "    return f\"The time difference between {timezone1} and {timezone2} is {hours_difference} hours.\"\n",
-        "\n",
-        "\n",
-        "# Function with three arguments\n",
-        "def convert_time(time: str, from_timezone: str, to_timezone: str) -> str:\n",
-        "    \"\"\"Converts a specific time from one timezone to another.\n",
-        "    :param time: The time to convert in HH:MM format.\n",
-        "    :param from_timezone: The original timezone of the time, should be a valid IANA timezone.\n",
-        "    :param to_timezone: The target timezone for the time, should be a valid IANA timezone.\n",
-        "    :type time: str\n",
-        "    :type from_timezone: str\n",
-        "    :type to_timezone: str\n",
-        "    :return: The converted time in the target timezone.\n",
-        "    :raises ValueError: If the time format or timezone strings are invalid.\n",
-        "\n",
-        "    Example:\n",
-        "        convert_time(\"12:30\", \"America/New_York\", \"Asia/Tokyo\") -> \"03:30\"\n",
-        "    \"\"\"\n",
-        "    try:\n",
-        "        # Use today's date to avoid historical timezone issues\n",
-        "        today = datetime.now().date()\n",
-        "        datetime_string = f\"{today} {time}\"\n",
-        "        time_obj = datetime.strptime(datetime_string, \"%Y-%m-%d %H:%M\").replace(\n",
-        "            tzinfo=ZoneInfo(from_timezone)\n",
-        "        )\n",
-        "\n",
-        "        converted_time = time_obj.astimezone(ZoneInfo(to_timezone))\n",
-        "\n",
-        "        formatted_time = converted_time.strftime(\"%H:%M\")\n",
-        "        return formatted_time\n",
-        "    except Exception as e:\n",
-        "        raise ValueError(f\"Error converting time: {e}\")"
-      ]
+     "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": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/"
     },
+    "id": "BI9AiDspur0y",
+    "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "AjoYy7mFg9hs"
-      },
-      "outputs": [],
-      "source": [
-        "functions = [get_time, get_time_difference, convert_time]"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:57:55 INFO semantic_router.utils.logger local\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": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/"
     },
+    "id": "_rNREh7gur0y",
+    "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "DoOkXV2Tg9hs",
-        "outputId": "f1e0fe08-b6ed-4f50-d845-5c54832ca677"
-      },
-      "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']}}},\n",
-              " {'type': 'function',\n",
-              "  'function': {'name': 'get_time_difference',\n",
-              "   'description': 'Calculates the time difference between two timezones.\\n:param timezone1: The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\\n:param timezone2: The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\\n:type timezone1: str\\n:type timezone2: str\\n:return: The time difference in hours between the two timezones.',\n",
-              "   'parameters': {'type': 'object',\n",
-              "    'properties': {'timezone1': {'type': 'string',\n",
-              "      'description': 'The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".'},\n",
-              "     'timezone2': {'type': 'string',\n",
-              "      'description': 'The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".'}},\n",
-              "    'required': ['timezone1', 'timezone2']}}},\n",
-              " {'type': 'function',\n",
-              "  'function': {'name': 'convert_time',\n",
-              "   'description': 'Converts a specific time from one timezone to another.\\n:param time: The time to convert in HH:MM format.\\n:param from_timezone: The original timezone of the time, should be a valid IANA timezone.\\n:param to_timezone: The target timezone for the time, should be a valid IANA timezone.\\n:type time: str\\n:type from_timezone: str\\n:type to_timezone: str\\n:return: The converted time in the target timezone.\\n:raises ValueError: If the time format or timezone strings are invalid.\\n\\nExample:\\n    convert_time(\"12:30\", \"America/New_York\", \"Asia/Tokyo\") -> \"03:30\"',\n",
-              "   'parameters': {'type': 'object',\n",
-              "    'properties': {'time': {'type': 'string',\n",
-              "      'description': 'The time to convert in HH:MM format.'},\n",
-              "     'from_timezone': {'type': 'string',\n",
-              "      'description': 'The original timezone of the time, should be a valid IANA timezone.'},\n",
-              "     'to_timezone': {'type': 'string',\n",
-              "      'description': 'The target timezone for the time, should be a valid IANA timezone.'}},\n",
-              "    'required': ['time', 'from_timezone', 'to_timezone']}}}]"
-            ]
-          },
-          "execution_count": 17,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "# Generate schemas for all functions\n",
-        "from semantic_router.llms.openai import get_schemas_openai\n",
-        "\n",
-        "schemas = get_schemas_openai(functions)\n",
-        "schemas"
+     "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 the `function_schemas` as a list. Each 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": null,
+   "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": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/",
+     "height": 35
     },
+    "id": "YyFKV8jMur0z",
+    "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "YBRHxhnkg9hs"
-      },
-      "outputs": [],
-      "source": [
-        "# Define the dynamic route with multiple functions\n",
-        "multi_function_route = Route(\n",
-        "    name=\"timezone_management\",\n",
-        "    utterances=[\n",
-        "        # Utterances for get_time function\n",
-        "        \"what is the time in New York?\",\n",
-        "        \"current time in Berlin?\",\n",
-        "        \"tell me the time in Moscow right now\",\n",
-        "        \"can you show me the current time in Tokyo?\",\n",
-        "        \"please provide the current time in London\",\n",
-        "        # Utterances for get_time_difference function\n",
-        "        \"how many hours ahead is Tokyo from London?\",\n",
-        "        \"time difference between Sydney and Cairo\",\n",
-        "        \"what's the time gap between Los Angeles and New York?\",\n",
-        "        \"how much time difference is there between Paris and Sydney?\",\n",
-        "        \"calculate the time difference between Dubai and Toronto\",\n",
-        "        # Utterances for convert_time function\n",
-        "        \"convert 15:00 from New York time to Berlin time\",\n",
-        "        \"change 09:00 from Paris time to Moscow time\",\n",
-        "        \"adjust 20:00 from Rome time to London time\",\n",
-        "        \"convert 12:00 from Madrid time to Chicago time\",\n",
-        "        \"change 18:00 from Beijing time to Los Angeles time\"\n",
-        "        # All three functions\n",
-        "        \"What is the time in Seattle? What is the time difference between Mumbai and Tokyo? What is 5:53 Toronto time in Sydney time?\",\n",
-        "    ],\n",
-        "    function_schemas=schemas,\n",
-        ")"
+     "data": {
+      "text/plain": [
+       "'17:57'"
       ]
+     },
+     "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": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/"
     },
+    "id": "tOjuhp5Xur0z",
+    "outputId": "ca88a3ea-d70a-4950-be9a-63fab699de3b"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "yEbQadQbg9ht"
-      },
-      "outputs": [],
-      "source": [
-        "routes = [politics, chitchat, multi_function_route]"
+     "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": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from semantic_router.llms.openai import get_schemas_openai\n",
+    "\n",
+    "schemas = get_schemas_openai([get_time])\n",
+    "schemas"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "HcF7jGjAur0z"
+   },
+   "source": [
+    "We use this to define our dynamic route:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "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_schemas=schemas,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "jmVwEWEIg9hq"
+   },
+   "outputs": [],
+   "source": [
+    "time_route.llm"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "ZiUs3ovpur0z"
+   },
+   "source": [
+    "Add the new route to our `layer`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/"
     },
+    "id": "-0vY8PRXur0z",
+    "outputId": "db01e14c-eab3-4f93-f4c2-e30f508c8b5d"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "C0aYIXaog9ht",
-        "outputId": "74114a86-4a6f-49c5-8e2e-600f577d63f5"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:57:58 INFO semantic_router.utils.logger local\u001b[0m\n"
-          ]
-        }
-      ],
-      "source": [
-        "rl2 = RouteLayer(encoder=encoder, routes=routes)"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:57:56 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "rl.add(time_route)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "mbccVdy5g9hr"
+   },
+   "outputs": [],
+   "source": [
+    "time_route.llm"
+   ]
+  },
+  {
+   "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": null,
+   "metadata": {
+    "colab": {
+     "base_uri": "https://localhost:8080/",
+     "height": 53
     },
+    "id": "Wfb68M0-ur0z",
+    "outputId": "79923883-2a4d-4744-f8ce-e818cb5f14c3"
+   },
+   "outputs": [
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "cG98YLZ5g9ht"
-      },
-      "source": [
-        "### Function to Parse Route Layer Responses"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[33m2024-05-08 01:57:57 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-05-08 01:57:58 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\u001b[0m\n"
+     ]
     },
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "PJR97klVg9ht"
-      },
-      "outputs": [],
-      "source": [
-        "def parse_response(response: str):\n",
-        "\n",
-        "    for call in response.function_call:\n",
-        "        args = call[\"arguments\"]\n",
-        "        if call[\"function_name\"] == \"get_time\":\n",
-        "            result = get_time(**args)\n",
-        "            print(result)\n",
-        "        if call[\"function_name\"] == \"get_time_difference\":\n",
-        "            result = get_time_difference(**args)\n",
-        "            print(result)\n",
-        "        if call[\"function_name\"] == \"convert_time\":\n",
-        "            result = convert_time(**args)\n",
-        "            print(result)"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='get_time', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}], similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl(\"what is the time in new york city?\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "92x96x1Og9hr",
+    "outputId": "c1e46a81-b681-4a10-fff6-71e03342a88e"
+   },
+   "outputs": [
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "OUbPbxZKg9ht"
-      },
-      "source": [
-        "### Checking that Politics Non-Dynamic Route Still Works"
-      ]
-    },
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(response.function_call)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "xvdyUPKqg9hr",
+    "outputId": "4161e7e0-ab6d-4e76-f068-2d66728305ff"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "D2kXFv9Xg9ht",
-        "outputId": "569cf17f-2091-4aea-9cba-11bb0af2ebd4"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='politics', function_call=None, similarity_score=None)"
-            ]
-          },
-          "execution_count": 22,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl2(\"What is your political leaning?\")\n",
-        "response"
-      ]
-    },
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "17:57\n"
+     ]
+    }
+   ],
+   "source": [
+    "import json\n",
+    "\n",
+    "for call in response.function_call:\n",
+    "    if call[\"function_name\"] == \"get_time\":\n",
+    "        args = call[\"arguments\"]\n",
+    "        result = get_time(**args)\n",
+    "print(result)"
+   ]
+  },
+  {
+   "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": {
+    "id": "jToYBo8Ug9hr"
+   },
+   "source": [
+    "## Dynamic Routes with Multiple Functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "J0oD1dxIur00"
+   },
+   "source": [
+    "---"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "vEkTpoVAg9hr"
+   },
+   "source": [
+    "Routes can be assigned multiple functions. Then, when that particular Route is selected by the Route Layer, a number of those functions might be invoked due to the users utterance containing relevant information that fits their arguments."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "BHUlB3org9hs"
+   },
+   "source": [
+    "Let's define a Route that has multiple functions."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "dtrksov0g9hs"
+   },
+   "outputs": [],
+   "source": [
+    "from datetime import datetime, timedelta\n",
+    "from zoneinfo import ZoneInfo\n",
+    "\n",
+    "\n",
+    "# Function with one argument\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\")\n",
+    "\n",
+    "\n",
+    "def get_time_difference(timezone1: str, timezone2: str) -> str:\n",
+    "    \"\"\"Calculates the time difference between two timezones.\n",
+    "    :param timezone1: The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\n",
+    "    :param timezone2: The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\n",
+    "    :type timezone1: str\n",
+    "    :type timezone2: str\n",
+    "    :return: The time difference in hours between the two timezones.\"\"\"\n",
+    "    # Get the current time in UTC\n",
+    "    now_utc = datetime.utcnow().replace(tzinfo=ZoneInfo(\"UTC\"))\n",
+    "\n",
+    "    # Convert the UTC time to the specified timezones\n",
+    "    tz1_time = now_utc.astimezone(ZoneInfo(timezone1))\n",
+    "    tz2_time = now_utc.astimezone(ZoneInfo(timezone2))\n",
+    "\n",
+    "    # Calculate the difference in offsets from UTC\n",
+    "    tz1_offset = tz1_time.utcoffset().total_seconds()\n",
+    "    tz2_offset = tz2_time.utcoffset().total_seconds()\n",
+    "\n",
+    "    # Calculate the difference in hours\n",
+    "    hours_difference = (tz2_offset - tz1_offset) / 3600\n",
+    "\n",
+    "    return f\"The time difference between {timezone1} and {timezone2} is {hours_difference} hours.\"\n",
+    "\n",
+    "\n",
+    "# Function with three arguments\n",
+    "def convert_time(time: str, from_timezone: str, to_timezone: str) -> str:\n",
+    "    \"\"\"Converts a specific time from one timezone to another.\n",
+    "    :param time: The time to convert in HH:MM format.\n",
+    "    :param from_timezone: The original timezone of the time, should be a valid IANA timezone.\n",
+    "    :param to_timezone: The target timezone for the time, should be a valid IANA timezone.\n",
+    "    :type time: str\n",
+    "    :type from_timezone: str\n",
+    "    :type to_timezone: str\n",
+    "    :return: The converted time in the target timezone.\n",
+    "    :raises ValueError: If the time format or timezone strings are invalid.\n",
+    "\n",
+    "    Example:\n",
+    "        convert_time(\"12:30\", \"America/New_York\", \"Asia/Tokyo\") -> \"03:30\"\n",
+    "    \"\"\"\n",
+    "    try:\n",
+    "        # Use today's date to avoid historical timezone issues\n",
+    "        today = datetime.now().date()\n",
+    "        datetime_string = f\"{today} {time}\"\n",
+    "        time_obj = datetime.strptime(datetime_string, \"%Y-%m-%d %H:%M\").replace(\n",
+    "            tzinfo=ZoneInfo(from_timezone)\n",
+    "        )\n",
+    "\n",
+    "        converted_time = time_obj.astimezone(ZoneInfo(to_timezone))\n",
+    "\n",
+    "        formatted_time = converted_time.strftime(\"%H:%M\")\n",
+    "        return formatted_time\n",
+    "    except Exception as e:\n",
+    "        raise ValueError(f\"Error converting time: {e}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "AjoYy7mFg9hs"
+   },
+   "outputs": [],
+   "source": [
+    "functions = [get_time, get_time_difference, convert_time]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "DoOkXV2Tg9hs",
+    "outputId": "f1e0fe08-b6ed-4f50-d845-5c54832ca677"
+   },
+   "outputs": [
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "ZHgw8QoWg9ht"
-      },
-      "source": [
-        "### Checking that Chitchat Non-Dynamic Route Still Works"
+     "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']}}},\n",
+       " {'type': 'function',\n",
+       "  'function': {'name': 'get_time_difference',\n",
+       "   'description': 'Calculates the time difference between two timezones.\\n:param timezone1: The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\\n:param timezone2: The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".\\n:type timezone1: str\\n:type timezone2: str\\n:return: The time difference in hours between the two timezones.',\n",
+       "   'parameters': {'type': 'object',\n",
+       "    'properties': {'timezone1': {'type': 'string',\n",
+       "      'description': 'The first timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".'},\n",
+       "     'timezone2': {'type': 'string',\n",
+       "      'description': 'The second timezone, should be a valid timezone from the IANA Time Zone Database like \"America/New_York\" or \"Europe/London\".'}},\n",
+       "    'required': ['timezone1', 'timezone2']}}},\n",
+       " {'type': 'function',\n",
+       "  'function': {'name': 'convert_time',\n",
+       "   'description': 'Converts a specific time from one timezone to another.\\n:param time: The time to convert in HH:MM format.\\n:param from_timezone: The original timezone of the time, should be a valid IANA timezone.\\n:param to_timezone: The target timezone for the time, should be a valid IANA timezone.\\n:type time: str\\n:type from_timezone: str\\n:type to_timezone: str\\n:return: The converted time in the target timezone.\\n:raises ValueError: If the time format or timezone strings are invalid.\\n\\nExample:\\n    convert_time(\"12:30\", \"America/New_York\", \"Asia/Tokyo\") -> \"03:30\"',\n",
+       "   'parameters': {'type': 'object',\n",
+       "    'properties': {'time': {'type': 'string',\n",
+       "      'description': 'The time to convert in HH:MM format.'},\n",
+       "     'from_timezone': {'type': 'string',\n",
+       "      'description': 'The original timezone of the time, should be a valid IANA timezone.'},\n",
+       "     'to_timezone': {'type': 'string',\n",
+       "      'description': 'The target timezone for the time, should be a valid IANA timezone.'}},\n",
+       "    'required': ['time', 'from_timezone', 'to_timezone']}}}]"
       ]
-    },
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Generate schemas for all functions\n",
+    "from semantic_router.llms.openai import get_schemas_openai\n",
+    "\n",
+    "schemas = get_schemas_openai(functions)\n",
+    "schemas"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "YBRHxhnkg9hs"
+   },
+   "outputs": [],
+   "source": [
+    "# Define the dynamic route with multiple functions\n",
+    "multi_function_route = Route(\n",
+    "    name=\"timezone_management\",\n",
+    "    utterances=[\n",
+    "        # Utterances for get_time function\n",
+    "        \"what is the time in New York?\",\n",
+    "        \"current time in Berlin?\",\n",
+    "        \"tell me the time in Moscow right now\",\n",
+    "        \"can you show me the current time in Tokyo?\",\n",
+    "        \"please provide the current time in London\",\n",
+    "        # Utterances for get_time_difference function\n",
+    "        \"how many hours ahead is Tokyo from London?\",\n",
+    "        \"time difference between Sydney and Cairo\",\n",
+    "        \"what's the time gap between Los Angeles and New York?\",\n",
+    "        \"how much time difference is there between Paris and Sydney?\",\n",
+    "        \"calculate the time difference between Dubai and Toronto\",\n",
+    "        # Utterances for convert_time function\n",
+    "        \"convert 15:00 from New York time to Berlin time\",\n",
+    "        \"change 09:00 from Paris time to Moscow time\",\n",
+    "        \"adjust 20:00 from Rome time to London time\",\n",
+    "        \"convert 12:00 from Madrid time to Chicago time\",\n",
+    "        \"change 18:00 from Beijing time to Los Angeles time\"\n",
+    "        # All three functions\n",
+    "        \"What is the time in Seattle? What is the time difference between Mumbai and Tokyo? What is 5:53 Toronto time in Sydney time?\",\n",
+    "    ],\n",
+    "    function_schemas=schemas,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "yEbQadQbg9ht"
+   },
+   "outputs": [],
+   "source": [
+    "routes = [politics, chitchat, multi_function_route]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "C0aYIXaog9ht",
+    "outputId": "74114a86-4a6f-49c5-8e2e-600f577d63f5"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "YsI5O_bHg9ht",
-        "outputId": "a6e3814b-97e0-4406-ec9a-17b1c7103e40"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='chitchat', function_call=None, similarity_score=None)"
-            ]
-          },
-          "execution_count": 23,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl2(\"Hello bot, how are you today?\")\n",
-        "response"
-      ]
-    },
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:57:58 INFO semantic_router.utils.logger local\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "rl2 = RouteLayer(encoder=encoder, routes=routes)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "cG98YLZ5g9ht"
+   },
+   "source": [
+    "### Function to Parse Route Layer Responses"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "PJR97klVg9ht"
+   },
+   "outputs": [],
+   "source": [
+    "def parse_response(response: str):\n",
+    "    for call in response.function_call:\n",
+    "        args = call[\"arguments\"]\n",
+    "        if call[\"function_name\"] == \"get_time\":\n",
+    "            result = get_time(**args)\n",
+    "            print(result)\n",
+    "        if call[\"function_name\"] == \"get_time_difference\":\n",
+    "            result = get_time_difference(**args)\n",
+    "            print(result)\n",
+    "        if call[\"function_name\"] == \"convert_time\":\n",
+    "            result = convert_time(**args)\n",
+    "            print(result)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "OUbPbxZKg9ht"
+   },
+   "source": [
+    "### Checking that Politics Non-Dynamic Route Still Works"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "D2kXFv9Xg9ht",
+    "outputId": "569cf17f-2091-4aea-9cba-11bb0af2ebd4"
+   },
+   "outputs": [
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "uZDiY787g9hu"
-      },
-      "source": [
-        "### Testing the `multi_function_route` - The `get_time` Function"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='politics', function_call=None, similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl2(\"What is your political leaning?\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "ZHgw8QoWg9ht"
+   },
+   "source": [
+    "### Checking that Chitchat Non-Dynamic Route Still Works"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "YsI5O_bHg9ht",
+    "outputId": "a6e3814b-97e0-4406-ec9a-17b1c7103e40"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "BdOfLx-wg9hu",
-        "outputId": "ef55a34c-7c34-4acc-918d-a173fac95171"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[33m2024-05-08 01:58:00 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-05-08 01:58:01 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}], similarity_score=None)"
-            ]
-          },
-          "execution_count": 24,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl2(\"what is the time in New York?\")\n",
-        "response"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='chitchat', function_call=None, similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl2(\"Hello bot, how are you today?\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "uZDiY787g9hu"
+   },
+   "source": [
+    "### Testing the `multi_function_route` - The `get_time` Function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "BdOfLx-wg9hu",
+    "outputId": "ef55a34c-7c34-4acc-918d-a173fac95171"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "QrpF_JcHg9hu",
-        "outputId": "242d645f-43c3-4e9f-9a46-d3aa3105f02a"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "17:58\n"
-          ]
-        }
-      ],
-      "source": [
-        "parse_response(response)"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[33m2024-05-08 01:58:00 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-05-08 01:58:01 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}]\u001b[0m\n"
+     ]
     },
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "wcjQ4Dbpg9hu"
-      },
-      "source": [
-        "### Testing the `multi_function_route` - The `get_time_difference` Function"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'America/New_York'}}], similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl2(\"what is the time in New York?\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "QrpF_JcHg9hu",
+    "outputId": "242d645f-43c3-4e9f-9a46-d3aa3105f02a"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "W85287lAg9hu",
-        "outputId": "4f247f13-046b-4a5c-f119-de17df29131f"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:58:02 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time_difference', 'arguments': {'timezone1': 'America/Los_Angeles', 'timezone2': 'Europe/Istanbul'}}]\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time_difference', 'arguments': {'timezone1': 'America/Los_Angeles', 'timezone2': 'Europe/Istanbul'}}], similarity_score=None)"
-            ]
-          },
-          "execution_count": 26,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl2(\"What is the time difference between Los Angeles and Istanbul?\")\n",
-        "response"
-      ]
-    },
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "17:58\n"
+     ]
+    }
+   ],
+   "source": [
+    "parse_response(response)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "wcjQ4Dbpg9hu"
+   },
+   "source": [
+    "### Testing the `multi_function_route` - The `get_time_difference` Function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "W85287lAg9hu",
+    "outputId": "4f247f13-046b-4a5c-f119-de17df29131f"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "2jxAIi6rg9hv",
-        "outputId": "8abff974-602f-4c0d-8d21-3a275b0eee62"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "The time difference between America/Los_Angeles and Europe/Istanbul is 10.0 hours.\n"
-          ]
-        }
-      ],
-      "source": [
-        "parse_response(response)"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:58:02 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time_difference', 'arguments': {'timezone1': 'America/Los_Angeles', 'timezone2': 'Europe/Istanbul'}}]\u001b[0m\n"
+     ]
     },
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "14qz-ApLg9hv"
-      },
-      "source": [
-        "### Testing the `multi_function_route` - The `convert_time` Function"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time_difference', 'arguments': {'timezone1': 'America/Los_Angeles', 'timezone2': 'Europe/Istanbul'}}], similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl2(\"What is the time difference between Los Angeles and Istanbul?\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "2jxAIi6rg9hv",
+    "outputId": "8abff974-602f-4c0d-8d21-3a275b0eee62"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "PzM1HH7Rg9hv",
-        "outputId": "e123c86f-9754-453a-d895-bfcce26110d4"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:58:04 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'convert_time', 'arguments': {'time': '23:02', 'from_timezone': 'Asia/Dubai', 'to_timezone': 'Asia/Tokyo'}}]\u001b[0m\n"
-          ]
-        },
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='timezone_management', function_call=[{'function_name': 'convert_time', 'arguments': {'time': '23:02', 'from_timezone': 'Asia/Dubai', 'to_timezone': 'Asia/Tokyo'}}], similarity_score=None)"
-            ]
-          },
-          "execution_count": 28,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response = rl2(\"What is 23:02 Dubai time in Tokyo time? Please and thank you.\")\n",
-        "response"
-      ]
-    },
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The time difference between America/Los_Angeles and Europe/Istanbul is 10.0 hours.\n"
+     ]
+    }
+   ],
+   "source": [
+    "parse_response(response)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "14qz-ApLg9hv"
+   },
+   "source": [
+    "### Testing the `multi_function_route` - The `convert_time` Function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "PzM1HH7Rg9hv",
+    "outputId": "e123c86f-9754-453a-d895-bfcce26110d4"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "QFKZ757Pg9hv",
-        "outputId": "af5c1328-f6dd-4dc7-c104-e920198885fc"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "04:02\n"
-          ]
-        }
-      ],
-      "source": [
-        "parse_response(response)"
-      ]
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:58:04 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'convert_time', 'arguments': {'time': '23:02', 'from_timezone': 'Asia/Dubai', 'to_timezone': 'Asia/Tokyo'}}]\u001b[0m\n"
+     ]
     },
     {
-      "cell_type": "markdown",
-      "metadata": {
-        "id": "TSRfC6JJg9hv"
-      },
-      "source": [
-        "### The Cool Bit - Testing `multi_function_route` - Multiple Functions at Once"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='timezone_management', function_call=[{'function_name': 'convert_time', 'arguments': {'time': '23:02', 'from_timezone': 'Asia/Dubai', 'to_timezone': 'Asia/Tokyo'}}], similarity_score=None)"
       ]
-    },
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response = rl2(\"What is 23:02 Dubai time in Tokyo time? Please and thank you.\")\n",
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "QFKZ757Pg9hv",
+    "outputId": "af5c1328-f6dd-4dc7-c104-e920198885fc"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "Vnj6A3AVg9hv",
-        "outputId": "c8a61c3f-a504-430b-82fb-c211c0523dcb"
-      },
-      "outputs": [
-        {
-          "name": "stderr",
-          "output_type": "stream",
-          "text": [
-            "\u001b[32m2024-05-08 01:58:07 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'Europe/Prague'}}, {'function_name': 'get_time_difference', 'arguments': {'timezone1': 'Europe/Berlin', 'timezone2': 'Asia/Shanghai'}}, {'function_name': 'convert_time', 'arguments': {'time': '05:53', 'from_timezone': 'Europe/Lisbon', 'to_timezone': 'Asia/Bangkok'}}]\u001b[0m\n"
-          ]
-        }
-      ],
-      "source": [
-        "response = rl2(\n",
-        "    \"\"\"\n",
-        "    What is the time in Prague?\n",
-        "    What is the time difference between Frankfurt and Beijing?\n",
-        "    What is 5:53 Lisbon time in Bangkok time?\n",
-        "\"\"\"\n",
-        ")"
-      ]
-    },
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "04:02\n"
+     ]
+    }
+   ],
+   "source": [
+    "parse_response(response)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "id": "TSRfC6JJg9hv"
+   },
+   "source": [
+    "### The Cool Bit - Testing `multi_function_route` - Multiple Functions at Once"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "Vnj6A3AVg9hv",
+    "outputId": "c8a61c3f-a504-430b-82fb-c211c0523dcb"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "L9jq_Yoag9hv",
-        "outputId": "50fae028-4af4-46f5-f6e9-4262b8874caa"
-      },
-      "outputs": [
-        {
-          "data": {
-            "text/plain": [
-              "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'Europe/Prague'}}, {'function_name': 'get_time_difference', 'arguments': {'timezone1': 'Europe/Berlin', 'timezone2': 'Asia/Shanghai'}}, {'function_name': 'convert_time', 'arguments': {'time': '05:53', 'from_timezone': 'Europe/Lisbon', 'to_timezone': 'Asia/Bangkok'}}], similarity_score=None)"
-            ]
-          },
-          "execution_count": 31,
-          "metadata": {},
-          "output_type": "execute_result"
-        }
-      ],
-      "source": [
-        "response"
-      ]
-    },
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[32m2024-05-08 01:58:07 INFO semantic_router.utils.logger Function inputs: [{'function_name': 'get_time', 'arguments': {'timezone': 'Europe/Prague'}}, {'function_name': 'get_time_difference', 'arguments': {'timezone1': 'Europe/Berlin', 'timezone2': 'Asia/Shanghai'}}, {'function_name': 'convert_time', 'arguments': {'time': '05:53', 'from_timezone': 'Europe/Lisbon', 'to_timezone': 'Asia/Bangkok'}}]\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = rl2(\n",
+    "    \"\"\"\n",
+    "    What is the time in Prague?\n",
+    "    What is the time difference between Frankfurt and Beijing?\n",
+    "    What is 5:53 Lisbon time in Bangkok time?\n",
+    "\"\"\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "L9jq_Yoag9hv",
+    "outputId": "50fae028-4af4-46f5-f6e9-4262b8874caa"
+   },
+   "outputs": [
     {
-      "cell_type": "code",
-      "execution_count": null,
-      "metadata": {
-        "id": "Hw3raSVBg9hv",
-        "outputId": "d30b9cba-979d-4bdf-86e0-37c550c4187d"
-      },
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "23:58\n",
-            "The time difference between Europe/Berlin and Asia/Shanghai is 6.0 hours.\n",
-            "11:53\n"
-          ]
-        }
-      ],
-      "source": [
-        "parse_response(response)"
+     "data": {
+      "text/plain": [
+       "RouteChoice(name='timezone_management', function_call=[{'function_name': 'get_time', 'arguments': {'timezone': 'Europe/Prague'}}, {'function_name': 'get_time_difference', 'arguments': {'timezone1': 'Europe/Berlin', 'timezone2': 'Asia/Shanghai'}}, {'function_name': 'convert_time', 'arguments': {'time': '05:53', 'from_timezone': 'Europe/Lisbon', 'to_timezone': 'Asia/Bangkok'}}], similarity_score=None)"
       ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
     }
-  ],
-  "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"
+   ],
+   "source": [
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "id": "Hw3raSVBg9hv",
+    "outputId": "d30b9cba-979d-4bdf-86e0-37c550c4187d"
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "23:58\n",
+      "The time difference between Europe/Berlin and Asia/Shanghai is 6.0 hours.\n",
+      "11:53\n"
+     ]
     }
+   ],
+   "source": [
+    "parse_response(response)"
+   ]
+  }
+ ],
+ "metadata": {
+  "colab": {
+   "provenance": []
+  },
+  "kernelspec": {
+   "display_name": "decision-layer",
+   "language": "python",
+   "name": "python3"
   },
-  "nbformat": 4,
-  "nbformat_minor": 0
+  "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
 }
\ No newline at end of file
diff --git a/docs/08-async-dynamic-routes.ipynb b/docs/08-async-dynamic-routes.ipynb
index 0cfb4e0a3baee9772b1b80565c4c73c0967fe98b..ab83a765e12686ae091257dc4a887f4ea8cc78ad 100644
--- a/docs/08-async-dynamic-routes.ipynb
+++ b/docs/08-async-dynamic-routes.ipynb
@@ -707,7 +707,6 @@
    "outputs": [],
    "source": [
     "def parse_response(response: str):\n",
-    "\n",
     "    for call in response.function_call:\n",
     "        args = call[\"arguments\"]\n",
     "        if call[\"function_name\"] == \"get_time\":\n",
diff --git a/docs/source/_autosummary/semantic_router.encoders.AutoEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.AutoEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..74cf9bec1cf79be0b2c517940e47899cfab58a6e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.AutoEncoder.rst
@@ -0,0 +1,33 @@
+semantic\_router.encoders.AutoEncoder
+=====================================
+
+.. currentmodule:: semantic_router.encoders
+
+.. autoclass:: AutoEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~AutoEncoder.__init__
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~AutoEncoder.type
+      ~AutoEncoder.name
+      ~AutoEncoder.model
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.base.BaseEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.base.BaseEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2eab803d61f0366df287f1ffb7f71cccb51cd6c8
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.base.BaseEncoder.rst
@@ -0,0 +1,47 @@
+semantic\_router.encoders.base.BaseEncoder
+==========================================
+
+.. currentmodule:: semantic_router.encoders.base
+
+.. autoclass:: BaseEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BaseEncoder.__init__
+      ~BaseEncoder.acall
+      ~BaseEncoder.construct
+      ~BaseEncoder.copy
+      ~BaseEncoder.dict
+      ~BaseEncoder.from_orm
+      ~BaseEncoder.json
+      ~BaseEncoder.parse_file
+      ~BaseEncoder.parse_obj
+      ~BaseEncoder.parse_raw
+      ~BaseEncoder.schema
+      ~BaseEncoder.schema_json
+      ~BaseEncoder.set_score_threshold
+      ~BaseEncoder.update_forward_refs
+      ~BaseEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BaseEncoder.name
+      ~BaseEncoder.score_threshold
+      ~BaseEncoder.type
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.base.rst b/docs/source/_autosummary/semantic_router.encoders.base.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8becbcadb3feb9bf5bde93900ee3ffa420aa8ce6
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.base.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.base
+==============================
+
+.. automodule:: semantic_router.encoders.base
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BaseEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.bedrock.BedrockEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.bedrock.BedrockEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cc8f7e33b62ebccf8067bc050921e7db2cc7ed3e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.bedrock.BedrockEncoder.rst
@@ -0,0 +1,55 @@
+semantic\_router.encoders.bedrock.BedrockEncoder
+================================================
+
+.. currentmodule:: semantic_router.encoders.bedrock
+
+.. autoclass:: BedrockEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BedrockEncoder.__init__
+      ~BedrockEncoder.acall
+      ~BedrockEncoder.chunk_strings
+      ~BedrockEncoder.construct
+      ~BedrockEncoder.copy
+      ~BedrockEncoder.dict
+      ~BedrockEncoder.from_orm
+      ~BedrockEncoder.get_env_variable
+      ~BedrockEncoder.json
+      ~BedrockEncoder.parse_file
+      ~BedrockEncoder.parse_obj
+      ~BedrockEncoder.parse_raw
+      ~BedrockEncoder.schema
+      ~BedrockEncoder.schema_json
+      ~BedrockEncoder.set_score_threshold
+      ~BedrockEncoder.update_forward_refs
+      ~BedrockEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BedrockEncoder.client
+      ~BedrockEncoder.type
+      ~BedrockEncoder.input_type
+      ~BedrockEncoder.name
+      ~BedrockEncoder.access_key_id
+      ~BedrockEncoder.secret_access_key
+      ~BedrockEncoder.session_token
+      ~BedrockEncoder.region
+      ~BedrockEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.bedrock.rst b/docs/source/_autosummary/semantic_router.encoders.bedrock.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e86fa15f256a0704b0cb724baf0eb3abdcf219a7
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.bedrock.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.bedrock
+=================================
+
+.. automodule:: semantic_router.encoders.bedrock
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BedrockEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.bm25.BM25Encoder.rst b/docs/source/_autosummary/semantic_router.encoders.bm25.BM25Encoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2eea51494ffc24fc23b865e5465f7bcf53fdef98
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.bm25.BM25Encoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.bm25.BM25Encoder
+==========================================
+
+.. currentmodule:: semantic_router.encoders.bm25
+
+.. autoclass:: BM25Encoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BM25Encoder.__init__
+      ~BM25Encoder.acall
+      ~BM25Encoder.construct
+      ~BM25Encoder.copy
+      ~BM25Encoder.dict
+      ~BM25Encoder.fit
+      ~BM25Encoder.from_orm
+      ~BM25Encoder.json
+      ~BM25Encoder.parse_file
+      ~BM25Encoder.parse_obj
+      ~BM25Encoder.parse_raw
+      ~BM25Encoder.schema
+      ~BM25Encoder.schema_json
+      ~BM25Encoder.set_score_threshold
+      ~BM25Encoder.update_forward_refs
+      ~BM25Encoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BM25Encoder.model
+      ~BM25Encoder.idx_mapping
+      ~BM25Encoder.type
+      ~BM25Encoder.name
+      ~BM25Encoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.bm25.rst b/docs/source/_autosummary/semantic_router.encoders.bm25.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a69b892f70e539ba1c983e229322e08dd524416e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.bm25.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.bm25
+==============================
+
+.. automodule:: semantic_router.encoders.bm25
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BM25Encoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.clip.CLIPEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.clip.CLIPEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..59df55cafa262656f9031b2593a9a2b20825b2c8
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.clip.CLIPEncoder.rst
@@ -0,0 +1,51 @@
+semantic\_router.encoders.clip.CLIPEncoder
+==========================================
+
+.. currentmodule:: semantic_router.encoders.clip
+
+.. autoclass:: CLIPEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~CLIPEncoder.__init__
+      ~CLIPEncoder.acall
+      ~CLIPEncoder.construct
+      ~CLIPEncoder.copy
+      ~CLIPEncoder.dict
+      ~CLIPEncoder.from_orm
+      ~CLIPEncoder.json
+      ~CLIPEncoder.parse_file
+      ~CLIPEncoder.parse_obj
+      ~CLIPEncoder.parse_raw
+      ~CLIPEncoder.schema
+      ~CLIPEncoder.schema_json
+      ~CLIPEncoder.set_score_threshold
+      ~CLIPEncoder.update_forward_refs
+      ~CLIPEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~CLIPEncoder.name
+      ~CLIPEncoder.type
+      ~CLIPEncoder.score_threshold
+      ~CLIPEncoder.tokenizer_kwargs
+      ~CLIPEncoder.processor_kwargs
+      ~CLIPEncoder.model_kwargs
+      ~CLIPEncoder.device
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.clip.rst b/docs/source/_autosummary/semantic_router.encoders.clip.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2d97c1c69584bb3c5e451b05f9f3c85afc0a9bc3
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.clip.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.clip
+==============================
+
+.. automodule:: semantic_router.encoders.clip
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      CLIPEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.cohere.CohereEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.cohere.CohereEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b37412df066278c5f535763d33e9ab6edbda0831
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.cohere.CohereEncoder.rst
@@ -0,0 +1,49 @@
+semantic\_router.encoders.cohere.CohereEncoder
+==============================================
+
+.. currentmodule:: semantic_router.encoders.cohere
+
+.. autoclass:: CohereEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~CohereEncoder.__init__
+      ~CohereEncoder.acall
+      ~CohereEncoder.construct
+      ~CohereEncoder.copy
+      ~CohereEncoder.dict
+      ~CohereEncoder.from_orm
+      ~CohereEncoder.json
+      ~CohereEncoder.parse_file
+      ~CohereEncoder.parse_obj
+      ~CohereEncoder.parse_raw
+      ~CohereEncoder.schema
+      ~CohereEncoder.schema_json
+      ~CohereEncoder.set_score_threshold
+      ~CohereEncoder.update_forward_refs
+      ~CohereEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~CohereEncoder.client
+      ~CohereEncoder.type
+      ~CohereEncoder.input_type
+      ~CohereEncoder.name
+      ~CohereEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.cohere.rst b/docs/source/_autosummary/semantic_router.encoders.cohere.rst
new file mode 100644
index 0000000000000000000000000000000000000000..193f6903aad6761fe943222ca998d8614f3ddc1d
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.cohere.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.cohere
+================================
+
+.. automodule:: semantic_router.encoders.cohere
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      CohereEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.fastembed.FastEmbedEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.fastembed.FastEmbedEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bee72bcf46c5b0dfc7bae8b609ad330f432dff5b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.fastembed.FastEmbedEncoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.fastembed.FastEmbedEncoder
+====================================================
+
+.. currentmodule:: semantic_router.encoders.fastembed
+
+.. autoclass:: FastEmbedEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~FastEmbedEncoder.__init__
+      ~FastEmbedEncoder.acall
+      ~FastEmbedEncoder.construct
+      ~FastEmbedEncoder.copy
+      ~FastEmbedEncoder.dict
+      ~FastEmbedEncoder.from_orm
+      ~FastEmbedEncoder.json
+      ~FastEmbedEncoder.parse_file
+      ~FastEmbedEncoder.parse_obj
+      ~FastEmbedEncoder.parse_raw
+      ~FastEmbedEncoder.schema
+      ~FastEmbedEncoder.schema_json
+      ~FastEmbedEncoder.set_score_threshold
+      ~FastEmbedEncoder.update_forward_refs
+      ~FastEmbedEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~FastEmbedEncoder.type
+      ~FastEmbedEncoder.name
+      ~FastEmbedEncoder.max_length
+      ~FastEmbedEncoder.cache_dir
+      ~FastEmbedEncoder.threads
+      ~FastEmbedEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.fastembed.rst b/docs/source/_autosummary/semantic_router.encoders.fastembed.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c0e6a2a22aa0af8ebf327ec69302bf5e154476d2
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.fastembed.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.fastembed
+===================================
+
+.. automodule:: semantic_router.encoders.fastembed
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      FastEmbedEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.google.GoogleEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.google.GoogleEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..81b4787397bdf9eb8db1a9a0da3475a3589e9f2a
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.google.GoogleEncoder.rst
@@ -0,0 +1,48 @@
+semantic\_router.encoders.google.GoogleEncoder
+==============================================
+
+.. currentmodule:: semantic_router.encoders.google
+
+.. autoclass:: GoogleEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~GoogleEncoder.__init__
+      ~GoogleEncoder.acall
+      ~GoogleEncoder.construct
+      ~GoogleEncoder.copy
+      ~GoogleEncoder.dict
+      ~GoogleEncoder.from_orm
+      ~GoogleEncoder.json
+      ~GoogleEncoder.parse_file
+      ~GoogleEncoder.parse_obj
+      ~GoogleEncoder.parse_raw
+      ~GoogleEncoder.schema
+      ~GoogleEncoder.schema_json
+      ~GoogleEncoder.set_score_threshold
+      ~GoogleEncoder.update_forward_refs
+      ~GoogleEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~GoogleEncoder.client
+      ~GoogleEncoder.type
+      ~GoogleEncoder.name
+      ~GoogleEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.google.rst b/docs/source/_autosummary/semantic_router.encoders.google.rst
new file mode 100644
index 0000000000000000000000000000000000000000..40235d251c55a7d4b4f624eb70a7838791399c76
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.google.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.google
+================================
+
+.. automodule:: semantic_router.encoders.google
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      GoogleEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.huggingface.HFEndpointEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.huggingface.HFEndpointEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fcef2410b7ffdc7b744fa214108af665f57a8311
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.huggingface.HFEndpointEncoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.huggingface.HFEndpointEncoder
+=======================================================
+
+.. currentmodule:: semantic_router.encoders.huggingface
+
+.. autoclass:: HFEndpointEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~HFEndpointEncoder.__init__
+      ~HFEndpointEncoder.acall
+      ~HFEndpointEncoder.construct
+      ~HFEndpointEncoder.copy
+      ~HFEndpointEncoder.dict
+      ~HFEndpointEncoder.from_orm
+      ~HFEndpointEncoder.json
+      ~HFEndpointEncoder.parse_file
+      ~HFEndpointEncoder.parse_obj
+      ~HFEndpointEncoder.parse_raw
+      ~HFEndpointEncoder.query
+      ~HFEndpointEncoder.schema
+      ~HFEndpointEncoder.schema_json
+      ~HFEndpointEncoder.set_score_threshold
+      ~HFEndpointEncoder.update_forward_refs
+      ~HFEndpointEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~HFEndpointEncoder.name
+      ~HFEndpointEncoder.huggingface_url
+      ~HFEndpointEncoder.huggingface_api_key
+      ~HFEndpointEncoder.score_threshold
+      ~HFEndpointEncoder.type
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.huggingface.HuggingFaceEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.huggingface.HuggingFaceEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e78399abeea9cdfb89376eba41f7b0ca506fe89f
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.huggingface.HuggingFaceEncoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.huggingface.HuggingFaceEncoder
+========================================================
+
+.. currentmodule:: semantic_router.encoders.huggingface
+
+.. autoclass:: HuggingFaceEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~HuggingFaceEncoder.__init__
+      ~HuggingFaceEncoder.acall
+      ~HuggingFaceEncoder.construct
+      ~HuggingFaceEncoder.copy
+      ~HuggingFaceEncoder.dict
+      ~HuggingFaceEncoder.from_orm
+      ~HuggingFaceEncoder.json
+      ~HuggingFaceEncoder.parse_file
+      ~HuggingFaceEncoder.parse_obj
+      ~HuggingFaceEncoder.parse_raw
+      ~HuggingFaceEncoder.schema
+      ~HuggingFaceEncoder.schema_json
+      ~HuggingFaceEncoder.set_score_threshold
+      ~HuggingFaceEncoder.update_forward_refs
+      ~HuggingFaceEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~HuggingFaceEncoder.name
+      ~HuggingFaceEncoder.type
+      ~HuggingFaceEncoder.score_threshold
+      ~HuggingFaceEncoder.tokenizer_kwargs
+      ~HuggingFaceEncoder.model_kwargs
+      ~HuggingFaceEncoder.device
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.huggingface.rst b/docs/source/_autosummary/semantic_router.encoders.huggingface.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6f72719f50732de25cf832f70c194004de81b10b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.huggingface.rst
@@ -0,0 +1,32 @@
+semantic\_router.encoders.huggingface
+=====================================
+
+.. automodule:: semantic_router.encoders.huggingface
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      HFEndpointEncoder
+      HuggingFaceEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.mistral.MistralEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.mistral.MistralEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e5e8e30a13aa5e97888eaa9fc0fd2ba4286bac5c
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.mistral.MistralEncoder.rst
@@ -0,0 +1,47 @@
+semantic\_router.encoders.mistral.MistralEncoder
+================================================
+
+.. currentmodule:: semantic_router.encoders.mistral
+
+.. autoclass:: MistralEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~MistralEncoder.__init__
+      ~MistralEncoder.acall
+      ~MistralEncoder.construct
+      ~MistralEncoder.copy
+      ~MistralEncoder.dict
+      ~MistralEncoder.from_orm
+      ~MistralEncoder.json
+      ~MistralEncoder.parse_file
+      ~MistralEncoder.parse_obj
+      ~MistralEncoder.parse_raw
+      ~MistralEncoder.schema
+      ~MistralEncoder.schema_json
+      ~MistralEncoder.set_score_threshold
+      ~MistralEncoder.update_forward_refs
+      ~MistralEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~MistralEncoder.type
+      ~MistralEncoder.name
+      ~MistralEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.mistral.rst b/docs/source/_autosummary/semantic_router.encoders.mistral.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ddd9f8fac0841095f5764ae92b590416e58112ce
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.mistral.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.mistral
+=================================
+
+.. automodule:: semantic_router.encoders.mistral
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      MistralEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.openai.OpenAIEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.openai.OpenAIEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3a388a84223c1f3eb160e97f6350838a7bf7c4ee
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.openai.OpenAIEncoder.rst
@@ -0,0 +1,51 @@
+semantic\_router.encoders.openai.OpenAIEncoder
+==============================================
+
+.. currentmodule:: semantic_router.encoders.openai
+
+.. autoclass:: OpenAIEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~OpenAIEncoder.__init__
+      ~OpenAIEncoder.acall
+      ~OpenAIEncoder.construct
+      ~OpenAIEncoder.copy
+      ~OpenAIEncoder.dict
+      ~OpenAIEncoder.from_orm
+      ~OpenAIEncoder.json
+      ~OpenAIEncoder.parse_file
+      ~OpenAIEncoder.parse_obj
+      ~OpenAIEncoder.parse_raw
+      ~OpenAIEncoder.schema
+      ~OpenAIEncoder.schema_json
+      ~OpenAIEncoder.set_score_threshold
+      ~OpenAIEncoder.update_forward_refs
+      ~OpenAIEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~OpenAIEncoder.client
+      ~OpenAIEncoder.async_client
+      ~OpenAIEncoder.dimensions
+      ~OpenAIEncoder.token_limit
+      ~OpenAIEncoder.type
+      ~OpenAIEncoder.name
+      ~OpenAIEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.openai.rst b/docs/source/_autosummary/semantic_router.encoders.openai.rst
new file mode 100644
index 0000000000000000000000000000000000000000..41bced5b7258de767511ccc76ede76e5cc8c6b11
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.openai.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.openai
+================================
+
+.. automodule:: semantic_router.encoders.openai
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      OpenAIEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.rst b/docs/source/_autosummary/semantic_router.encoders.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1f615b3def14c8c59cc4bb1fe9616f0df73c380e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.rst
@@ -0,0 +1,52 @@
+semantic\_router.encoders
+=========================
+
+.. automodule:: semantic_router.encoders
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      AutoEncoder
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.encoders.base
+   semantic_router.encoders.bedrock
+   semantic_router.encoders.bm25
+   semantic_router.encoders.clip
+   semantic_router.encoders.cohere
+   semantic_router.encoders.fastembed
+   semantic_router.encoders.google
+   semantic_router.encoders.huggingface
+   semantic_router.encoders.mistral
+   semantic_router.encoders.openai
+   semantic_router.encoders.tfidf
+   semantic_router.encoders.vit
+   semantic_router.encoders.zure
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.tfidf.TfidfEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.tfidf.TfidfEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2bed919c89a8049140e71e57e7492a7a0a5ab247
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.tfidf.TfidfEncoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.tfidf.TfidfEncoder
+============================================
+
+.. currentmodule:: semantic_router.encoders.tfidf
+
+.. autoclass:: TfidfEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~TfidfEncoder.__init__
+      ~TfidfEncoder.acall
+      ~TfidfEncoder.construct
+      ~TfidfEncoder.copy
+      ~TfidfEncoder.dict
+      ~TfidfEncoder.fit
+      ~TfidfEncoder.from_orm
+      ~TfidfEncoder.json
+      ~TfidfEncoder.parse_file
+      ~TfidfEncoder.parse_obj
+      ~TfidfEncoder.parse_raw
+      ~TfidfEncoder.schema
+      ~TfidfEncoder.schema_json
+      ~TfidfEncoder.set_score_threshold
+      ~TfidfEncoder.update_forward_refs
+      ~TfidfEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~TfidfEncoder.idf
+      ~TfidfEncoder.word_index
+      ~TfidfEncoder.name
+      ~TfidfEncoder.score_threshold
+      ~TfidfEncoder.type
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.tfidf.rst b/docs/source/_autosummary/semantic_router.encoders.tfidf.rst
new file mode 100644
index 0000000000000000000000000000000000000000..499c6060254ef702845dde63ab25c23d550ba31e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.tfidf.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.tfidf
+===============================
+
+.. automodule:: semantic_router.encoders.tfidf
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      TfidfEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.vit.VitEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.vit.VitEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3fe1db29a2ac5b008176f085ec149ecc5e296d72
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.vit.VitEncoder.rst
@@ -0,0 +1,50 @@
+semantic\_router.encoders.vit.VitEncoder
+========================================
+
+.. currentmodule:: semantic_router.encoders.vit
+
+.. autoclass:: VitEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~VitEncoder.__init__
+      ~VitEncoder.acall
+      ~VitEncoder.construct
+      ~VitEncoder.copy
+      ~VitEncoder.dict
+      ~VitEncoder.from_orm
+      ~VitEncoder.json
+      ~VitEncoder.parse_file
+      ~VitEncoder.parse_obj
+      ~VitEncoder.parse_raw
+      ~VitEncoder.schema
+      ~VitEncoder.schema_json
+      ~VitEncoder.set_score_threshold
+      ~VitEncoder.update_forward_refs
+      ~VitEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~VitEncoder.name
+      ~VitEncoder.type
+      ~VitEncoder.score_threshold
+      ~VitEncoder.processor_kwargs
+      ~VitEncoder.model_kwargs
+      ~VitEncoder.device
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.vit.rst b/docs/source/_autosummary/semantic_router.encoders.vit.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1fbe48326a4752aeca53039f7f7ff6d30961844c
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.vit.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.vit
+=============================
+
+.. automodule:: semantic_router.encoders.vit
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      VitEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.encoders.zure.AzureOpenAIEncoder.rst b/docs/source/_autosummary/semantic_router.encoders.zure.AzureOpenAIEncoder.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d19d59367096caf03286f6f19dad99a63bc66e68
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.zure.AzureOpenAIEncoder.rst
@@ -0,0 +1,55 @@
+semantic\_router.encoders.zure.AzureOpenAIEncoder
+=================================================
+
+.. currentmodule:: semantic_router.encoders.zure
+
+.. autoclass:: AzureOpenAIEncoder
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~AzureOpenAIEncoder.__init__
+      ~AzureOpenAIEncoder.acall
+      ~AzureOpenAIEncoder.construct
+      ~AzureOpenAIEncoder.copy
+      ~AzureOpenAIEncoder.dict
+      ~AzureOpenAIEncoder.from_orm
+      ~AzureOpenAIEncoder.json
+      ~AzureOpenAIEncoder.parse_file
+      ~AzureOpenAIEncoder.parse_obj
+      ~AzureOpenAIEncoder.parse_raw
+      ~AzureOpenAIEncoder.schema
+      ~AzureOpenAIEncoder.schema_json
+      ~AzureOpenAIEncoder.set_score_threshold
+      ~AzureOpenAIEncoder.update_forward_refs
+      ~AzureOpenAIEncoder.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~AzureOpenAIEncoder.client
+      ~AzureOpenAIEncoder.async_client
+      ~AzureOpenAIEncoder.dimensions
+      ~AzureOpenAIEncoder.type
+      ~AzureOpenAIEncoder.api_key
+      ~AzureOpenAIEncoder.deployment_name
+      ~AzureOpenAIEncoder.azure_endpoint
+      ~AzureOpenAIEncoder.api_version
+      ~AzureOpenAIEncoder.model
+      ~AzureOpenAIEncoder.name
+      ~AzureOpenAIEncoder.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.encoders.zure.rst b/docs/source/_autosummary/semantic_router.encoders.zure.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f9c11641086a238305095f96e71d276b010cc184
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.encoders.zure.rst
@@ -0,0 +1,31 @@
+semantic\_router.encoders.zure
+==============================
+
+.. automodule:: semantic_router.encoders.zure
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      AzureOpenAIEncoder
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.hybrid_layer.HybridRouteLayer.rst b/docs/source/_autosummary/semantic_router.hybrid_layer.HybridRouteLayer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f29381efd18a5d02f29d0430de3a4ec2cd19a86b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.hybrid_layer.HybridRouteLayer.rst
@@ -0,0 +1,37 @@
+semantic\_router.hybrid\_layer.HybridRouteLayer
+===============================================
+
+.. currentmodule:: semantic_router.hybrid_layer
+
+.. autoclass:: HybridRouteLayer
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~HybridRouteLayer.__init__
+      ~HybridRouteLayer.add
+      ~HybridRouteLayer.update_dense_embeddings_index
+      ~HybridRouteLayer.update_sparse_embeddings_index
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~HybridRouteLayer.categories
+      ~HybridRouteLayer.index
+      ~HybridRouteLayer.sparse_index
+      ~HybridRouteLayer.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.hybrid_layer.rst b/docs/source/_autosummary/semantic_router.hybrid_layer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d8744ff6ed7d39edc600318c051d6b287b17e43a
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.hybrid_layer.rst
@@ -0,0 +1,31 @@
+semantic\_router.hybrid\_layer
+==============================
+
+.. automodule:: semantic_router.hybrid_layer
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      HybridRouteLayer
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.index.base.BaseIndex.rst b/docs/source/_autosummary/semantic_router.index.base.BaseIndex.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b0b423ea9a63d7cd4ae43fa3d8ade3a4df408ea4
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.base.BaseIndex.rst
@@ -0,0 +1,55 @@
+semantic\_router.index.base.BaseIndex
+=====================================
+
+.. currentmodule:: semantic_router.index.base
+
+.. autoclass:: BaseIndex
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BaseIndex.__init__
+      ~BaseIndex.add
+      ~BaseIndex.aquery
+      ~BaseIndex.construct
+      ~BaseIndex.copy
+      ~BaseIndex.delete
+      ~BaseIndex.delete_index
+      ~BaseIndex.describe
+      ~BaseIndex.dict
+      ~BaseIndex.from_orm
+      ~BaseIndex.json
+      ~BaseIndex.parse_file
+      ~BaseIndex.parse_obj
+      ~BaseIndex.parse_raw
+      ~BaseIndex.query
+      ~BaseIndex.schema
+      ~BaseIndex.schema_json
+      ~BaseIndex.update_forward_refs
+      ~BaseIndex.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BaseIndex.index
+      ~BaseIndex.routes
+      ~BaseIndex.utterances
+      ~BaseIndex.dimensions
+      ~BaseIndex.type
+      ~BaseIndex.init_async_index
+      ~BaseIndex.sync
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.base.rst b/docs/source/_autosummary/semantic_router.index.base.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cb6f0ef3ea28309a3026fba81237087ad1eec6f9
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.base.rst
@@ -0,0 +1,31 @@
+semantic\_router.index.base
+===========================
+
+.. automodule:: semantic_router.index.base
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BaseIndex
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.index.local.LocalIndex.rst b/docs/source/_autosummary/semantic_router.index.local.LocalIndex.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c6d000266e1abde873a2b087ef2110a73fc52417
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.local.LocalIndex.rst
@@ -0,0 +1,56 @@
+semantic\_router.index.local.LocalIndex
+=======================================
+
+.. currentmodule:: semantic_router.index.local
+
+.. autoclass:: LocalIndex
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~LocalIndex.__init__
+      ~LocalIndex.add
+      ~LocalIndex.aquery
+      ~LocalIndex.construct
+      ~LocalIndex.copy
+      ~LocalIndex.delete
+      ~LocalIndex.delete_index
+      ~LocalIndex.describe
+      ~LocalIndex.dict
+      ~LocalIndex.from_orm
+      ~LocalIndex.get_routes
+      ~LocalIndex.json
+      ~LocalIndex.parse_file
+      ~LocalIndex.parse_obj
+      ~LocalIndex.parse_raw
+      ~LocalIndex.query
+      ~LocalIndex.schema
+      ~LocalIndex.schema_json
+      ~LocalIndex.update_forward_refs
+      ~LocalIndex.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~LocalIndex.index
+      ~LocalIndex.routes
+      ~LocalIndex.utterances
+      ~LocalIndex.dimensions
+      ~LocalIndex.type
+      ~LocalIndex.init_async_index
+      ~LocalIndex.sync
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.local.rst b/docs/source/_autosummary/semantic_router.index.local.rst
new file mode 100644
index 0000000000000000000000000000000000000000..06a5adcdd872c2c3bbc8c34e1bd8db87246a29c0
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.local.rst
@@ -0,0 +1,31 @@
+semantic\_router.index.local
+============================
+
+.. automodule:: semantic_router.index.local
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      LocalIndex
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.index.pinecone.PineconeIndex.rst b/docs/source/_autosummary/semantic_router.index.pinecone.PineconeIndex.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6e8007381de79f78f29d0d988eb420e708e2fd1f
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.pinecone.PineconeIndex.rst
@@ -0,0 +1,69 @@
+semantic\_router.index.pinecone.PineconeIndex
+=============================================
+
+.. currentmodule:: semantic_router.index.pinecone
+
+.. autoclass:: PineconeIndex
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~PineconeIndex.__init__
+      ~PineconeIndex.add
+      ~PineconeIndex.aquery
+      ~PineconeIndex.construct
+      ~PineconeIndex.copy
+      ~PineconeIndex.delete
+      ~PineconeIndex.delete_all
+      ~PineconeIndex.delete_index
+      ~PineconeIndex.describe
+      ~PineconeIndex.dict
+      ~PineconeIndex.from_orm
+      ~PineconeIndex.get_routes
+      ~PineconeIndex.json
+      ~PineconeIndex.parse_file
+      ~PineconeIndex.parse_obj
+      ~PineconeIndex.parse_raw
+      ~PineconeIndex.query
+      ~PineconeIndex.schema
+      ~PineconeIndex.schema_json
+      ~PineconeIndex.update_forward_refs
+      ~PineconeIndex.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~PineconeIndex.index_prefix
+      ~PineconeIndex.api_key
+      ~PineconeIndex.index_name
+      ~PineconeIndex.dimensions
+      ~PineconeIndex.metric
+      ~PineconeIndex.cloud
+      ~PineconeIndex.region
+      ~PineconeIndex.host
+      ~PineconeIndex.client
+      ~PineconeIndex.async_client
+      ~PineconeIndex.index
+      ~PineconeIndex.ServerlessSpec
+      ~PineconeIndex.namespace
+      ~PineconeIndex.base_url
+      ~PineconeIndex.routes
+      ~PineconeIndex.utterances
+      ~PineconeIndex.type
+      ~PineconeIndex.init_async_index
+      ~PineconeIndex.sync
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.pinecone.PineconeRecord.rst b/docs/source/_autosummary/semantic_router.index.pinecone.PineconeRecord.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cc88ffe4fa6c5f609d0303d7f071cc59a1a6b27d
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.pinecone.PineconeRecord.rst
@@ -0,0 +1,47 @@
+semantic\_router.index.pinecone.PineconeRecord
+==============================================
+
+.. currentmodule:: semantic_router.index.pinecone
+
+.. autoclass:: PineconeRecord
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~PineconeRecord.__init__
+      ~PineconeRecord.construct
+      ~PineconeRecord.copy
+      ~PineconeRecord.dict
+      ~PineconeRecord.from_orm
+      ~PineconeRecord.json
+      ~PineconeRecord.parse_file
+      ~PineconeRecord.parse_obj
+      ~PineconeRecord.parse_raw
+      ~PineconeRecord.schema
+      ~PineconeRecord.schema_json
+      ~PineconeRecord.to_dict
+      ~PineconeRecord.update_forward_refs
+      ~PineconeRecord.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~PineconeRecord.id
+      ~PineconeRecord.values
+      ~PineconeRecord.route
+      ~PineconeRecord.utterance
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.pinecone.clean_route_name.rst b/docs/source/_autosummary/semantic_router.index.pinecone.clean_route_name.rst
new file mode 100644
index 0000000000000000000000000000000000000000..58f5914be1a61fb6bb5b9af7d2700b25c969957e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.pinecone.clean_route_name.rst
@@ -0,0 +1,6 @@
+semantic\_router.index.pinecone.clean\_route\_name
+==================================================
+
+.. currentmodule:: semantic_router.index.pinecone
+
+.. autofunction:: clean_route_name
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.pinecone.rst b/docs/source/_autosummary/semantic_router.index.pinecone.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9e3c28e0a8db98c4e583b791d97149555e610948
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.pinecone.rst
@@ -0,0 +1,39 @@
+semantic\_router.index.pinecone
+===============================
+
+.. automodule:: semantic_router.index.pinecone
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      clean_route_name
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      PineconeIndex
+      PineconeRecord
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.index.qdrant.QdrantIndex.rst b/docs/source/_autosummary/semantic_router.index.qdrant.QdrantIndex.rst
new file mode 100644
index 0000000000000000000000000000000000000000..87379adec92bfd0f1de31ede10d29a19587ec2de
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.qdrant.QdrantIndex.rst
@@ -0,0 +1,74 @@
+semantic\_router.index.qdrant.QdrantIndex
+=========================================
+
+.. currentmodule:: semantic_router.index.qdrant
+
+.. autoclass:: QdrantIndex
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~QdrantIndex.__init__
+      ~QdrantIndex.add
+      ~QdrantIndex.aquery
+      ~QdrantIndex.construct
+      ~QdrantIndex.convert_metric
+      ~QdrantIndex.copy
+      ~QdrantIndex.delete
+      ~QdrantIndex.delete_index
+      ~QdrantIndex.describe
+      ~QdrantIndex.dict
+      ~QdrantIndex.from_orm
+      ~QdrantIndex.get_routes
+      ~QdrantIndex.json
+      ~QdrantIndex.parse_file
+      ~QdrantIndex.parse_obj
+      ~QdrantIndex.parse_raw
+      ~QdrantIndex.query
+      ~QdrantIndex.schema
+      ~QdrantIndex.schema_json
+      ~QdrantIndex.update_forward_refs
+      ~QdrantIndex.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~QdrantIndex.index_name
+      ~QdrantIndex.location
+      ~QdrantIndex.url
+      ~QdrantIndex.port
+      ~QdrantIndex.grpc_port
+      ~QdrantIndex.prefer_grpc
+      ~QdrantIndex.https
+      ~QdrantIndex.api_key
+      ~QdrantIndex.prefix
+      ~QdrantIndex.timeout
+      ~QdrantIndex.host
+      ~QdrantIndex.path
+      ~QdrantIndex.grpc_options
+      ~QdrantIndex.dimensions
+      ~QdrantIndex.metric
+      ~QdrantIndex.config
+      ~QdrantIndex.client
+      ~QdrantIndex.aclient
+      ~QdrantIndex.index
+      ~QdrantIndex.routes
+      ~QdrantIndex.utterances
+      ~QdrantIndex.type
+      ~QdrantIndex.init_async_index
+      ~QdrantIndex.sync
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.index.qdrant.rst b/docs/source/_autosummary/semantic_router.index.qdrant.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2c835215d6716c2add00042a66e0113cfbe8208b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.qdrant.rst
@@ -0,0 +1,31 @@
+semantic\_router.index.qdrant
+=============================
+
+.. automodule:: semantic_router.index.qdrant
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      QdrantIndex
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.index.rst b/docs/source/_autosummary/semantic_router.index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7925fbddb0823d31c46ada9c5ea0693d74a99865
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.index.rst
@@ -0,0 +1,35 @@
+semantic\_router.index
+======================
+
+.. automodule:: semantic_router.index
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.index.base
+   semantic_router.index.local
+   semantic_router.index.pinecone
+   semantic_router.index.qdrant
+
diff --git a/docs/source/_autosummary/semantic_router.layer.LayerConfig.rst b/docs/source/_autosummary/semantic_router.layer.LayerConfig.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e477eea55c497a9524b6536b7ec0c2c007c44656
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.layer.LayerConfig.rst
@@ -0,0 +1,37 @@
+semantic\_router.layer.LayerConfig
+==================================
+
+.. currentmodule:: semantic_router.layer
+
+.. autoclass:: LayerConfig
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~LayerConfig.__init__
+      ~LayerConfig.add
+      ~LayerConfig.from_file
+      ~LayerConfig.get
+      ~LayerConfig.remove
+      ~LayerConfig.to_dict
+      ~LayerConfig.to_file
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~LayerConfig.routes
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.layer.RouteLayer.rst b/docs/source/_autosummary/semantic_router.layer.RouteLayer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..11c02875d54fc76d12b90caa914dd52cbb948522
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.layer.RouteLayer.rst
@@ -0,0 +1,52 @@
+semantic\_router.layer.RouteLayer
+=================================
+
+.. currentmodule:: semantic_router.layer
+
+.. autoclass:: RouteLayer
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~RouteLayer.__init__
+      ~RouteLayer.acall
+      ~RouteLayer.add
+      ~RouteLayer.async_group_scores_by_class
+      ~RouteLayer.check_for_matching_routes
+      ~RouteLayer.delete
+      ~RouteLayer.evaluate
+      ~RouteLayer.fit
+      ~RouteLayer.from_config
+      ~RouteLayer.from_json
+      ~RouteLayer.from_yaml
+      ~RouteLayer.get
+      ~RouteLayer.get_thresholds
+      ~RouteLayer.group_scores_by_class
+      ~RouteLayer.list_route_names
+      ~RouteLayer.retrieve_multiple_routes
+      ~RouteLayer.to_config
+      ~RouteLayer.to_json
+      ~RouteLayer.to_yaml
+      ~RouteLayer.update
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~RouteLayer.score_threshold
+      ~RouteLayer.encoder
+      ~RouteLayer.index
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.layer.is_valid.rst b/docs/source/_autosummary/semantic_router.layer.is_valid.rst
new file mode 100644
index 0000000000000000000000000000000000000000..30de0588e4f0b1bf0223f94d14bec5d89b39d741
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.layer.is_valid.rst
@@ -0,0 +1,6 @@
+semantic\_router.layer.is\_valid
+================================
+
+.. currentmodule:: semantic_router.layer
+
+.. autofunction:: is_valid
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.layer.rst b/docs/source/_autosummary/semantic_router.layer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fbcbc3e993e1b75df1b6a6e4c6c6903400f11d49
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.layer.rst
@@ -0,0 +1,40 @@
+semantic\_router.layer
+======================
+
+.. automodule:: semantic_router.layer
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      is_valid
+      threshold_random_search
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      LayerConfig
+      RouteLayer
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.layer.threshold_random_search.rst b/docs/source/_autosummary/semantic_router.layer.threshold_random_search.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1d278cf1a0f5742af9f41c03e2998a0c3d1afdb0
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.layer.threshold_random_search.rst
@@ -0,0 +1,6 @@
+semantic\_router.layer.threshold\_random\_search
+================================================
+
+.. currentmodule:: semantic_router.layer
+
+.. autofunction:: threshold_random_search
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.linear.rst b/docs/source/_autosummary/semantic_router.linear.rst
new file mode 100644
index 0000000000000000000000000000000000000000..af4deb515b9b7bf36cdb6a3ecbe0dd4cb19ee0aa
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.linear.rst
@@ -0,0 +1,31 @@
+semantic\_router.linear
+=======================
+
+.. automodule:: semantic_router.linear
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      similarity_matrix
+      top_scores
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.linear.similarity_matrix.rst b/docs/source/_autosummary/semantic_router.linear.similarity_matrix.rst
new file mode 100644
index 0000000000000000000000000000000000000000..09d3a6271cc1bc44fb3bf77d379551adff629fdd
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.linear.similarity_matrix.rst
@@ -0,0 +1,6 @@
+semantic\_router.linear.similarity\_matrix
+==========================================
+
+.. currentmodule:: semantic_router.linear
+
+.. autofunction:: similarity_matrix
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.linear.top_scores.rst b/docs/source/_autosummary/semantic_router.linear.top_scores.rst
new file mode 100644
index 0000000000000000000000000000000000000000..10dce95858383c7fb91ab84f58220074e0ddc0ca
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.linear.top_scores.rst
@@ -0,0 +1,6 @@
+semantic\_router.linear.top\_scores
+===================================
+
+.. currentmodule:: semantic_router.linear
+
+.. autofunction:: top_scores
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.base.BaseLLM.rst b/docs/source/_autosummary/semantic_router.llms.base.BaseLLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b53d0116de11956360c60414f73a809a9209e76b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.base.BaseLLM.rst
@@ -0,0 +1,44 @@
+semantic\_router.llms.base.BaseLLM
+==================================
+
+.. currentmodule:: semantic_router.llms.base
+
+.. autoclass:: BaseLLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BaseLLM.__init__
+      ~BaseLLM.construct
+      ~BaseLLM.copy
+      ~BaseLLM.dict
+      ~BaseLLM.extract_function_inputs
+      ~BaseLLM.from_orm
+      ~BaseLLM.json
+      ~BaseLLM.parse_file
+      ~BaseLLM.parse_obj
+      ~BaseLLM.parse_raw
+      ~BaseLLM.schema
+      ~BaseLLM.schema_json
+      ~BaseLLM.update_forward_refs
+      ~BaseLLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BaseLLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.base.rst b/docs/source/_autosummary/semantic_router.llms.base.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5d1a967c94092a5885f43c8890b6080fce154adc
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.base.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.base
+==========================
+
+.. automodule:: semantic_router.llms.base
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BaseLLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.cohere.CohereLLM.rst b/docs/source/_autosummary/semantic_router.llms.cohere.CohereLLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a7422525a56dfa979432950548c52c7adda04789
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.cohere.CohereLLM.rst
@@ -0,0 +1,45 @@
+semantic\_router.llms.cohere.CohereLLM
+======================================
+
+.. currentmodule:: semantic_router.llms.cohere
+
+.. autoclass:: CohereLLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~CohereLLM.__init__
+      ~CohereLLM.construct
+      ~CohereLLM.copy
+      ~CohereLLM.dict
+      ~CohereLLM.extract_function_inputs
+      ~CohereLLM.from_orm
+      ~CohereLLM.json
+      ~CohereLLM.parse_file
+      ~CohereLLM.parse_obj
+      ~CohereLLM.parse_raw
+      ~CohereLLM.schema
+      ~CohereLLM.schema_json
+      ~CohereLLM.update_forward_refs
+      ~CohereLLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~CohereLLM.client
+      ~CohereLLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.cohere.rst b/docs/source/_autosummary/semantic_router.llms.cohere.rst
new file mode 100644
index 0000000000000000000000000000000000000000..81a473f13284709d8b74fc00aa804ce7c619a853
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.cohere.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.cohere
+============================
+
+.. automodule:: semantic_router.llms.cohere
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      CohereLLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.llamacpp.LlamaCppLLM.rst b/docs/source/_autosummary/semantic_router.llms.llamacpp.LlamaCppLLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..055a6536e0cf27fc8e26fd142d36d39c7713c2ec
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.llamacpp.LlamaCppLLM.rst
@@ -0,0 +1,48 @@
+semantic\_router.llms.llamacpp.LlamaCppLLM
+==========================================
+
+.. currentmodule:: semantic_router.llms.llamacpp
+
+.. autoclass:: LlamaCppLLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~LlamaCppLLM.__init__
+      ~LlamaCppLLM.construct
+      ~LlamaCppLLM.copy
+      ~LlamaCppLLM.dict
+      ~LlamaCppLLM.extract_function_inputs
+      ~LlamaCppLLM.from_orm
+      ~LlamaCppLLM.json
+      ~LlamaCppLLM.parse_file
+      ~LlamaCppLLM.parse_obj
+      ~LlamaCppLLM.parse_raw
+      ~LlamaCppLLM.schema
+      ~LlamaCppLLM.schema_json
+      ~LlamaCppLLM.update_forward_refs
+      ~LlamaCppLLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~LlamaCppLLM.llm
+      ~LlamaCppLLM.temperature
+      ~LlamaCppLLM.max_tokens
+      ~LlamaCppLLM.grammar
+      ~LlamaCppLLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.llamacpp.rst b/docs/source/_autosummary/semantic_router.llms.llamacpp.rst
new file mode 100644
index 0000000000000000000000000000000000000000..43a9e460a9ae97324b02af352dae32a178fc351c
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.llamacpp.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.llamacpp
+==============================
+
+.. automodule:: semantic_router.llms.llamacpp
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      LlamaCppLLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.mistral.MistralAILLM.rst b/docs/source/_autosummary/semantic_router.llms.mistral.MistralAILLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a865730b2514064eb53624e2321a39741413031b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.mistral.MistralAILLM.rst
@@ -0,0 +1,46 @@
+semantic\_router.llms.mistral.MistralAILLM
+==========================================
+
+.. currentmodule:: semantic_router.llms.mistral
+
+.. autoclass:: MistralAILLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~MistralAILLM.__init__
+      ~MistralAILLM.construct
+      ~MistralAILLM.copy
+      ~MistralAILLM.dict
+      ~MistralAILLM.extract_function_inputs
+      ~MistralAILLM.from_orm
+      ~MistralAILLM.json
+      ~MistralAILLM.parse_file
+      ~MistralAILLM.parse_obj
+      ~MistralAILLM.parse_raw
+      ~MistralAILLM.schema
+      ~MistralAILLM.schema_json
+      ~MistralAILLM.update_forward_refs
+      ~MistralAILLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~MistralAILLM.temperature
+      ~MistralAILLM.max_tokens
+      ~MistralAILLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.mistral.rst b/docs/source/_autosummary/semantic_router.llms.mistral.rst
new file mode 100644
index 0000000000000000000000000000000000000000..35ecf37a586e5e57036491a047c442348dc57ee1
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.mistral.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.mistral
+=============================
+
+.. automodule:: semantic_router.llms.mistral
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      MistralAILLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.ollama.OllamaLLM.rst b/docs/source/_autosummary/semantic_router.llms.ollama.OllamaLLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0538d2e7fbf6df5dd2f73cdfe5f154c3a2689f15
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.ollama.OllamaLLM.rst
@@ -0,0 +1,48 @@
+semantic\_router.llms.ollama.OllamaLLM
+======================================
+
+.. currentmodule:: semantic_router.llms.ollama
+
+.. autoclass:: OllamaLLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~OllamaLLM.__init__
+      ~OllamaLLM.construct
+      ~OllamaLLM.copy
+      ~OllamaLLM.dict
+      ~OllamaLLM.extract_function_inputs
+      ~OllamaLLM.from_orm
+      ~OllamaLLM.json
+      ~OllamaLLM.parse_file
+      ~OllamaLLM.parse_obj
+      ~OllamaLLM.parse_raw
+      ~OllamaLLM.schema
+      ~OllamaLLM.schema_json
+      ~OllamaLLM.update_forward_refs
+      ~OllamaLLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~OllamaLLM.temperature
+      ~OllamaLLM.llm_name
+      ~OllamaLLM.max_tokens
+      ~OllamaLLM.stream
+      ~OllamaLLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.ollama.rst b/docs/source/_autosummary/semantic_router.llms.ollama.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d6bf8a76355e54392788bb62908a605820669640
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.ollama.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.ollama
+============================
+
+.. automodule:: semantic_router.llms.ollama
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      OllamaLLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.openai.OpenAILLM.rst b/docs/source/_autosummary/semantic_router.llms.openai.OpenAILLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c203c2b256fe4ea3dfc6c7025bda484cafe2657a
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.openai.OpenAILLM.rst
@@ -0,0 +1,51 @@
+semantic\_router.llms.openai.OpenAILLM
+======================================
+
+.. currentmodule:: semantic_router.llms.openai
+
+.. autoclass:: OpenAILLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~OpenAILLM.__init__
+      ~OpenAILLM.acall
+      ~OpenAILLM.async_extract_function_inputs
+      ~OpenAILLM.async_extract_tool_calls_info
+      ~OpenAILLM.construct
+      ~OpenAILLM.copy
+      ~OpenAILLM.dict
+      ~OpenAILLM.extract_function_inputs
+      ~OpenAILLM.from_orm
+      ~OpenAILLM.json
+      ~OpenAILLM.parse_file
+      ~OpenAILLM.parse_obj
+      ~OpenAILLM.parse_raw
+      ~OpenAILLM.schema
+      ~OpenAILLM.schema_json
+      ~OpenAILLM.update_forward_refs
+      ~OpenAILLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~OpenAILLM.client
+      ~OpenAILLM.async_client
+      ~OpenAILLM.temperature
+      ~OpenAILLM.max_tokens
+      ~OpenAILLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.openai.get_schemas_openai.rst b/docs/source/_autosummary/semantic_router.llms.openai.get_schemas_openai.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f466acf00c54101cafccc505838fc49934200161
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.openai.get_schemas_openai.rst
@@ -0,0 +1,6 @@
+semantic\_router.llms.openai.get\_schemas\_openai
+=================================================
+
+.. currentmodule:: semantic_router.llms.openai
+
+.. autofunction:: get_schemas_openai
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.openai.rst b/docs/source/_autosummary/semantic_router.llms.openai.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9fbf813e5d404be90e19e3aee8eeeaece7fad44b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.openai.rst
@@ -0,0 +1,38 @@
+semantic\_router.llms.openai
+============================
+
+.. automodule:: semantic_router.llms.openai
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      get_schemas_openai
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      OpenAILLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.openrouter.OpenRouterLLM.rst b/docs/source/_autosummary/semantic_router.llms.openrouter.OpenRouterLLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..710603949c6bc801036ce97c65d8cbede9762b8d
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.openrouter.OpenRouterLLM.rst
@@ -0,0 +1,48 @@
+semantic\_router.llms.openrouter.OpenRouterLLM
+==============================================
+
+.. currentmodule:: semantic_router.llms.openrouter
+
+.. autoclass:: OpenRouterLLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~OpenRouterLLM.__init__
+      ~OpenRouterLLM.construct
+      ~OpenRouterLLM.copy
+      ~OpenRouterLLM.dict
+      ~OpenRouterLLM.extract_function_inputs
+      ~OpenRouterLLM.from_orm
+      ~OpenRouterLLM.json
+      ~OpenRouterLLM.parse_file
+      ~OpenRouterLLM.parse_obj
+      ~OpenRouterLLM.parse_raw
+      ~OpenRouterLLM.schema
+      ~OpenRouterLLM.schema_json
+      ~OpenRouterLLM.update_forward_refs
+      ~OpenRouterLLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~OpenRouterLLM.client
+      ~OpenRouterLLM.base_url
+      ~OpenRouterLLM.temperature
+      ~OpenRouterLLM.max_tokens
+      ~OpenRouterLLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.openrouter.rst b/docs/source/_autosummary/semantic_router.llms.openrouter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bfe09e351878821d555260eb4caea055ad9fdf3b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.openrouter.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.openrouter
+================================
+
+.. automodule:: semantic_router.llms.openrouter
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      OpenRouterLLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.llms.rst b/docs/source/_autosummary/semantic_router.llms.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fb84e4168c2c187596f7a55ece694f616355254c
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.rst
@@ -0,0 +1,39 @@
+semantic\_router.llms
+=====================
+
+.. automodule:: semantic_router.llms
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.llms.base
+   semantic_router.llms.cohere
+   semantic_router.llms.llamacpp
+   semantic_router.llms.mistral
+   semantic_router.llms.ollama
+   semantic_router.llms.openai
+   semantic_router.llms.openrouter
+   semantic_router.llms.zure
+
diff --git a/docs/source/_autosummary/semantic_router.llms.zure.AzureOpenAILLM.rst b/docs/source/_autosummary/semantic_router.llms.zure.AzureOpenAILLM.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c94ac8e02b26ec5a4a125521948ecae9cae38d80
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.zure.AzureOpenAILLM.rst
@@ -0,0 +1,47 @@
+semantic\_router.llms.zure.AzureOpenAILLM
+=========================================
+
+.. currentmodule:: semantic_router.llms.zure
+
+.. autoclass:: AzureOpenAILLM
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~AzureOpenAILLM.__init__
+      ~AzureOpenAILLM.construct
+      ~AzureOpenAILLM.copy
+      ~AzureOpenAILLM.dict
+      ~AzureOpenAILLM.extract_function_inputs
+      ~AzureOpenAILLM.from_orm
+      ~AzureOpenAILLM.json
+      ~AzureOpenAILLM.parse_file
+      ~AzureOpenAILLM.parse_obj
+      ~AzureOpenAILLM.parse_raw
+      ~AzureOpenAILLM.schema
+      ~AzureOpenAILLM.schema_json
+      ~AzureOpenAILLM.update_forward_refs
+      ~AzureOpenAILLM.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~AzureOpenAILLM.client
+      ~AzureOpenAILLM.temperature
+      ~AzureOpenAILLM.max_tokens
+      ~AzureOpenAILLM.name
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.llms.zure.rst b/docs/source/_autosummary/semantic_router.llms.zure.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6690bcc5449b7a33cfa18c0f0e802d254550e0ec
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.llms.zure.rst
@@ -0,0 +1,31 @@
+semantic\_router.llms.zure
+==========================
+
+.. automodule:: semantic_router.llms.zure
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      AzureOpenAILLM
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.route.Route.rst b/docs/source/_autosummary/semantic_router.route.Route.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4a5f3449ca40420afcf22017fca88e39e4a21a9e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.route.Route.rst
@@ -0,0 +1,52 @@
+semantic\_router.route.Route
+============================
+
+.. currentmodule:: semantic_router.route
+
+.. autoclass:: Route
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~Route.__init__
+      ~Route.acall
+      ~Route.construct
+      ~Route.copy
+      ~Route.dict
+      ~Route.from_dict
+      ~Route.from_dynamic_route
+      ~Route.from_orm
+      ~Route.json
+      ~Route.parse_file
+      ~Route.parse_obj
+      ~Route.parse_raw
+      ~Route.schema
+      ~Route.schema_json
+      ~Route.to_dict
+      ~Route.update_forward_refs
+      ~Route.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~Route.name
+      ~Route.utterances
+      ~Route.description
+      ~Route.function_schemas
+      ~Route.llm
+      ~Route.score_threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.route.is_valid.rst b/docs/source/_autosummary/semantic_router.route.is_valid.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0e278ef2b3da70f249da6822fc43f8c08a71b2de
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.route.is_valid.rst
@@ -0,0 +1,6 @@
+semantic\_router.route.is\_valid
+================================
+
+.. currentmodule:: semantic_router.route
+
+.. autofunction:: is_valid
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.route.rst b/docs/source/_autosummary/semantic_router.route.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ea559a1e882a40d81aeab3b178310e7827cf2634
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.route.rst
@@ -0,0 +1,38 @@
+semantic\_router.route
+======================
+
+.. automodule:: semantic_router.route
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      is_valid
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      Route
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.rst b/docs/source/_autosummary/semantic_router.rst
new file mode 100644
index 0000000000000000000000000000000000000000..87e3eb9915f63bc528700ddfeb1e2a1501cb8d37
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.rst
@@ -0,0 +1,42 @@
+semantic\_router
+================
+
+.. automodule:: semantic_router
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.encoders
+   semantic_router.hybrid_layer
+   semantic_router.index
+   semantic_router.layer
+   semantic_router.linear
+   semantic_router.llms
+   semantic_router.route
+   semantic_router.schema
+   semantic_router.splitters
+   semantic_router.text
+   semantic_router.utils
+
diff --git a/docs/source/_autosummary/semantic_router.schema.DocumentSplit.rst b/docs/source/_autosummary/semantic_router.schema.DocumentSplit.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f2e556fa2a34d0a30ec6fc15453acf5df8b859f1
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.DocumentSplit.rst
@@ -0,0 +1,48 @@
+semantic\_router.schema.DocumentSplit
+=====================================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: DocumentSplit
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~DocumentSplit.__init__
+      ~DocumentSplit.construct
+      ~DocumentSplit.copy
+      ~DocumentSplit.dict
+      ~DocumentSplit.from_orm
+      ~DocumentSplit.json
+      ~DocumentSplit.parse_file
+      ~DocumentSplit.parse_obj
+      ~DocumentSplit.parse_raw
+      ~DocumentSplit.schema
+      ~DocumentSplit.schema_json
+      ~DocumentSplit.update_forward_refs
+      ~DocumentSplit.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~DocumentSplit.content
+      ~DocumentSplit.docs
+      ~DocumentSplit.is_triggered
+      ~DocumentSplit.triggered_score
+      ~DocumentSplit.token_count
+      ~DocumentSplit.metadata
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.EncoderInfo.rst b/docs/source/_autosummary/semantic_router.schema.EncoderInfo.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bff52290b38107b396b18aac9109933ccb30fb85
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.EncoderInfo.rst
@@ -0,0 +1,45 @@
+semantic\_router.schema.EncoderInfo
+===================================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: EncoderInfo
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~EncoderInfo.__init__
+      ~EncoderInfo.construct
+      ~EncoderInfo.copy
+      ~EncoderInfo.dict
+      ~EncoderInfo.from_orm
+      ~EncoderInfo.json
+      ~EncoderInfo.parse_file
+      ~EncoderInfo.parse_obj
+      ~EncoderInfo.parse_raw
+      ~EncoderInfo.schema
+      ~EncoderInfo.schema_json
+      ~EncoderInfo.update_forward_refs
+      ~EncoderInfo.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~EncoderInfo.name
+      ~EncoderInfo.token_limit
+      ~EncoderInfo.threshold
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.EncoderType.rst b/docs/source/_autosummary/semantic_router.schema.EncoderType.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3f69d02673ec1348d00d276647a2275ab492bb67
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.EncoderType.rst
@@ -0,0 +1,36 @@
+semantic\_router.schema.EncoderType
+===================================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: EncoderType
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~EncoderType.AZURE
+      ~EncoderType.COHERE
+      ~EncoderType.OPENAI
+      ~EncoderType.BM25
+      ~EncoderType.TFIDF
+      ~EncoderType.FASTEMBED
+      ~EncoderType.HUGGINGFACE
+      ~EncoderType.MISTRAL
+      ~EncoderType.VIT
+      ~EncoderType.CLIP
+      ~EncoderType.GOOGLE
+      ~EncoderType.BEDROCK
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.Message.rst b/docs/source/_autosummary/semantic_router.schema.Message.rst
new file mode 100644
index 0000000000000000000000000000000000000000..184c7e85bc83eae5a7c53eb739cc576a6325fe9f
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.Message.rst
@@ -0,0 +1,48 @@
+semantic\_router.schema.Message
+===============================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: Message
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~Message.__init__
+      ~Message.construct
+      ~Message.copy
+      ~Message.dict
+      ~Message.from_orm
+      ~Message.json
+      ~Message.parse_file
+      ~Message.parse_obj
+      ~Message.parse_raw
+      ~Message.schema
+      ~Message.schema_json
+      ~Message.to_cohere
+      ~Message.to_llamacpp
+      ~Message.to_mistral
+      ~Message.to_openai
+      ~Message.update_forward_refs
+      ~Message.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~Message.role
+      ~Message.content
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.Metric.rst b/docs/source/_autosummary/semantic_router.schema.Metric.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d7904b2b4cb40eb8ea95b0fb5203e99bf3c8810b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.Metric.rst
@@ -0,0 +1,28 @@
+semantic\_router.schema.Metric
+==============================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: Metric
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~Metric.COSINE
+      ~Metric.DOTPRODUCT
+      ~Metric.EUCLIDEAN
+      ~Metric.MANHATTAN
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.RouteChoice.rst b/docs/source/_autosummary/semantic_router.schema.RouteChoice.rst
new file mode 100644
index 0000000000000000000000000000000000000000..79c627d2277b85560b10485aa0c91b3f4576995f
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.RouteChoice.rst
@@ -0,0 +1,45 @@
+semantic\_router.schema.RouteChoice
+===================================
+
+.. currentmodule:: semantic_router.schema
+
+.. autoclass:: RouteChoice
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~RouteChoice.__init__
+      ~RouteChoice.construct
+      ~RouteChoice.copy
+      ~RouteChoice.dict
+      ~RouteChoice.from_orm
+      ~RouteChoice.json
+      ~RouteChoice.parse_file
+      ~RouteChoice.parse_obj
+      ~RouteChoice.parse_raw
+      ~RouteChoice.schema
+      ~RouteChoice.schema_json
+      ~RouteChoice.update_forward_refs
+      ~RouteChoice.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~RouteChoice.name
+      ~RouteChoice.function_call
+      ~RouteChoice.similarity_score
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.schema.rst b/docs/source/_autosummary/semantic_router.schema.rst
new file mode 100644
index 0000000000000000000000000000000000000000..71cc22ed959ce2766ded49f247932dcdd6c10903
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.schema.rst
@@ -0,0 +1,36 @@
+semantic\_router.schema
+=======================
+
+.. automodule:: semantic_router.schema
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      DocumentSplit
+      EncoderInfo
+      EncoderType
+      Message
+      Metric
+      RouteChoice
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.base.BaseSplitter.rst b/docs/source/_autosummary/semantic_router.splitters.base.BaseSplitter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4e8f3f11b2097e494d28233f37bc5092b08557fc
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.base.BaseSplitter.rst
@@ -0,0 +1,45 @@
+semantic\_router.splitters.base.BaseSplitter
+============================================
+
+.. currentmodule:: semantic_router.splitters.base
+
+.. autoclass:: BaseSplitter
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~BaseSplitter.__init__
+      ~BaseSplitter.construct
+      ~BaseSplitter.copy
+      ~BaseSplitter.dict
+      ~BaseSplitter.from_orm
+      ~BaseSplitter.json
+      ~BaseSplitter.parse_file
+      ~BaseSplitter.parse_obj
+      ~BaseSplitter.parse_raw
+      ~BaseSplitter.print
+      ~BaseSplitter.schema
+      ~BaseSplitter.schema_json
+      ~BaseSplitter.update_forward_refs
+      ~BaseSplitter.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~BaseSplitter.name
+      ~BaseSplitter.encoder
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.base.rst b/docs/source/_autosummary/semantic_router.splitters.base.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9bf5ab3901b04d6a143fdc478a18a6ab314e6f63
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.base.rst
@@ -0,0 +1,31 @@
+semantic\_router.splitters.base
+===============================
+
+.. automodule:: semantic_router.splitters.base
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      BaseSplitter
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.ConsecutiveSimSplitter.rst b/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.ConsecutiveSimSplitter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5a4649517ee1dd520c80865a2119826467358af9
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.ConsecutiveSimSplitter.rst
@@ -0,0 +1,45 @@
+semantic\_router.splitters.consecutive\_sim.ConsecutiveSimSplitter
+==================================================================
+
+.. currentmodule:: semantic_router.splitters.consecutive_sim
+
+.. autoclass:: ConsecutiveSimSplitter
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~ConsecutiveSimSplitter.__init__
+      ~ConsecutiveSimSplitter.construct
+      ~ConsecutiveSimSplitter.copy
+      ~ConsecutiveSimSplitter.dict
+      ~ConsecutiveSimSplitter.from_orm
+      ~ConsecutiveSimSplitter.json
+      ~ConsecutiveSimSplitter.parse_file
+      ~ConsecutiveSimSplitter.parse_obj
+      ~ConsecutiveSimSplitter.parse_raw
+      ~ConsecutiveSimSplitter.print
+      ~ConsecutiveSimSplitter.schema
+      ~ConsecutiveSimSplitter.schema_json
+      ~ConsecutiveSimSplitter.update_forward_refs
+      ~ConsecutiveSimSplitter.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~ConsecutiveSimSplitter.name
+      ~ConsecutiveSimSplitter.encoder
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.rst b/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.rst
new file mode 100644
index 0000000000000000000000000000000000000000..aa42f3c8e6ad194151abc40c6bc59619bc359671
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.consecutive_sim.rst
@@ -0,0 +1,31 @@
+semantic\_router.splitters.consecutive\_sim
+===========================================
+
+.. automodule:: semantic_router.splitters.consecutive_sim
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      ConsecutiveSimSplitter
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.CumulativeSimSplitter.rst b/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.CumulativeSimSplitter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7b99020983d5460531d045d724d32ce1dcbe1aec
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.CumulativeSimSplitter.rst
@@ -0,0 +1,45 @@
+semantic\_router.splitters.cumulative\_sim.CumulativeSimSplitter
+================================================================
+
+.. currentmodule:: semantic_router.splitters.cumulative_sim
+
+.. autoclass:: CumulativeSimSplitter
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~CumulativeSimSplitter.__init__
+      ~CumulativeSimSplitter.construct
+      ~CumulativeSimSplitter.copy
+      ~CumulativeSimSplitter.dict
+      ~CumulativeSimSplitter.from_orm
+      ~CumulativeSimSplitter.json
+      ~CumulativeSimSplitter.parse_file
+      ~CumulativeSimSplitter.parse_obj
+      ~CumulativeSimSplitter.parse_raw
+      ~CumulativeSimSplitter.print
+      ~CumulativeSimSplitter.schema
+      ~CumulativeSimSplitter.schema_json
+      ~CumulativeSimSplitter.update_forward_refs
+      ~CumulativeSimSplitter.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~CumulativeSimSplitter.name
+      ~CumulativeSimSplitter.encoder
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.rst b/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b08e04bf1d33d33235f78ff3814e3b64a6cb7af5
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.cumulative_sim.rst
@@ -0,0 +1,31 @@
+semantic\_router.splitters.cumulative\_sim
+==========================================
+
+.. automodule:: semantic_router.splitters.cumulative_sim
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      CumulativeSimSplitter
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.rolling_window.RollingWindowSplitter.rst b/docs/source/_autosummary/semantic_router.splitters.rolling_window.RollingWindowSplitter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..48e6d57f65c2b52b047777cf1e68be254daca788
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.rolling_window.RollingWindowSplitter.rst
@@ -0,0 +1,47 @@
+semantic\_router.splitters.rolling\_window.RollingWindowSplitter
+================================================================
+
+.. currentmodule:: semantic_router.splitters.rolling_window
+
+.. autoclass:: RollingWindowSplitter
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~RollingWindowSplitter.__init__
+      ~RollingWindowSplitter.construct
+      ~RollingWindowSplitter.copy
+      ~RollingWindowSplitter.dict
+      ~RollingWindowSplitter.from_orm
+      ~RollingWindowSplitter.json
+      ~RollingWindowSplitter.parse_file
+      ~RollingWindowSplitter.parse_obj
+      ~RollingWindowSplitter.parse_raw
+      ~RollingWindowSplitter.plot_sentence_similarity_scores
+      ~RollingWindowSplitter.plot_similarity_scores
+      ~RollingWindowSplitter.print
+      ~RollingWindowSplitter.schema
+      ~RollingWindowSplitter.schema_json
+      ~RollingWindowSplitter.update_forward_refs
+      ~RollingWindowSplitter.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~RollingWindowSplitter.name
+      ~RollingWindowSplitter.encoder
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.rolling_window.SplitStatistics.rst b/docs/source/_autosummary/semantic_router.splitters.rolling_window.SplitStatistics.rst
new file mode 100644
index 0000000000000000000000000000000000000000..be102ef7a848dc621b2ff26c281aca904c7ae406
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.rolling_window.SplitStatistics.rst
@@ -0,0 +1,38 @@
+semantic\_router.splitters.rolling\_window.SplitStatistics
+==========================================================
+
+.. currentmodule:: semantic_router.splitters.rolling_window
+
+.. autoclass:: SplitStatistics
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~SplitStatistics.__init__
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~SplitStatistics.total_documents
+      ~SplitStatistics.total_splits
+      ~SplitStatistics.splits_by_threshold
+      ~SplitStatistics.splits_by_max_chunk_size
+      ~SplitStatistics.splits_by_last_split
+      ~SplitStatistics.min_token_size
+      ~SplitStatistics.max_token_size
+      ~SplitStatistics.splits_by_similarity_ratio
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.rolling_window.rst b/docs/source/_autosummary/semantic_router.splitters.rolling_window.rst
new file mode 100644
index 0000000000000000000000000000000000000000..58ce6558b48f2b677b75951a014f50f6fdb34019
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.rolling_window.rst
@@ -0,0 +1,32 @@
+semantic\_router.splitters.rolling\_window
+==========================================
+
+.. automodule:: semantic_router.splitters.rolling_window
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      RollingWindowSplitter
+      SplitStatistics
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.rst b/docs/source/_autosummary/semantic_router.splitters.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d9ee3e36ff3ad2f1762ca80d7d56a63586cd58d1
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.rst
@@ -0,0 +1,36 @@
+semantic\_router.splitters
+==========================
+
+.. automodule:: semantic_router.splitters
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.splitters.base
+   semantic_router.splitters.consecutive_sim
+   semantic_router.splitters.cumulative_sim
+   semantic_router.splitters.rolling_window
+   semantic_router.splitters.utils
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.utils.rst b/docs/source/_autosummary/semantic_router.splitters.utils.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fd956ba754597415f7f9206088dbc4aa66a1a20b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.utils.rst
@@ -0,0 +1,31 @@
+semantic\_router.splitters.utils
+================================
+
+.. automodule:: semantic_router.splitters.utils
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      split_to_sentences
+      tiktoken_length
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.splitters.utils.split_to_sentences.rst b/docs/source/_autosummary/semantic_router.splitters.utils.split_to_sentences.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fa30150cde2e2448d3ca8c249ca1032bbbf7d7c8
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.utils.split_to_sentences.rst
@@ -0,0 +1,6 @@
+semantic\_router.splitters.utils.split\_to\_sentences
+=====================================================
+
+.. currentmodule:: semantic_router.splitters.utils
+
+.. autofunction:: split_to_sentences
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.splitters.utils.tiktoken_length.rst b/docs/source/_autosummary/semantic_router.splitters.utils.tiktoken_length.rst
new file mode 100644
index 0000000000000000000000000000000000000000..de78752d2cdc7a271a3e95b6d7c82a9199b63b6b
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.splitters.utils.tiktoken_length.rst
@@ -0,0 +1,6 @@
+semantic\_router.splitters.utils.tiktoken\_length
+=================================================
+
+.. currentmodule:: semantic_router.splitters.utils
+
+.. autofunction:: tiktoken_length
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.text.Conversation.rst b/docs/source/_autosummary/semantic_router.text.Conversation.rst
new file mode 100644
index 0000000000000000000000000000000000000000..07921466ee986e032e78fc80cfa5ebe5d244a738
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.text.Conversation.rst
@@ -0,0 +1,52 @@
+semantic\_router.text.Conversation
+==================================
+
+.. currentmodule:: semantic_router.text
+
+.. autoclass:: Conversation
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~Conversation.__init__
+      ~Conversation.add_new_messages
+      ~Conversation.append_new_topics
+      ~Conversation.configure_splitter
+      ~Conversation.construct
+      ~Conversation.copy
+      ~Conversation.determine_topic_start_index
+      ~Conversation.dict
+      ~Conversation.from_orm
+      ~Conversation.get_last_message_and_topic_id
+      ~Conversation.json
+      ~Conversation.parse_file
+      ~Conversation.parse_obj
+      ~Conversation.parse_raw
+      ~Conversation.remove_topics
+      ~Conversation.schema
+      ~Conversation.schema_json
+      ~Conversation.split_by_topic
+      ~Conversation.update_forward_refs
+      ~Conversation.validate
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~Conversation.messages
+      ~Conversation.topics
+      ~Conversation.splitter
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.text.rst b/docs/source/_autosummary/semantic_router.text.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9cca9e7cb01784fc0cf4f70228b782afbac919d8
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.text.rst
@@ -0,0 +1,31 @@
+semantic\_router.text
+=====================
+
+.. automodule:: semantic_router.text
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      Conversation
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.utils.defaults.EncoderDefault.rst b/docs/source/_autosummary/semantic_router.utils.defaults.EncoderDefault.rst
new file mode 100644
index 0000000000000000000000000000000000000000..47d8b21f117c7d9785d3df2e678ff31bf6465ede
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.defaults.EncoderDefault.rst
@@ -0,0 +1,31 @@
+semantic\_router.utils.defaults.EncoderDefault
+==============================================
+
+.. currentmodule:: semantic_router.utils.defaults
+
+.. autoclass:: EncoderDefault
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~EncoderDefault.FASTEMBED
+      ~EncoderDefault.OPENAI
+      ~EncoderDefault.COHERE
+      ~EncoderDefault.MISTRAL
+      ~EncoderDefault.AZURE
+      ~EncoderDefault.GOOGLE
+      ~EncoderDefault.BEDROCK
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.defaults.rst b/docs/source/_autosummary/semantic_router.utils.defaults.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5dd094fd60126d1af7a82f63d22dc21fc3dd8dea
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.defaults.rst
@@ -0,0 +1,31 @@
+semantic\_router.utils.defaults
+===============================
+
+.. automodule:: semantic_router.utils.defaults
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      EncoderDefault
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.utils.function_call.convert_python_type_to_json_type.rst b/docs/source/_autosummary/semantic_router.utils.function_call.convert_python_type_to_json_type.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a53d0fdc216f4676404db3977dbf584cb30d8192
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.function_call.convert_python_type_to_json_type.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.function\_call.convert\_python\_type\_to\_json\_type
+===========================================================================
+
+.. currentmodule:: semantic_router.utils.function_call
+
+.. autofunction:: convert_python_type_to_json_type
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.function_call.get_schema.rst b/docs/source/_autosummary/semantic_router.utils.function_call.get_schema.rst
new file mode 100644
index 0000000000000000000000000000000000000000..592fa226020053d72d8a2443985e50a1d469afac
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.function_call.get_schema.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.function\_call.get\_schema
+=================================================
+
+.. currentmodule:: semantic_router.utils.function_call
+
+.. autofunction:: get_schema
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.function_call.get_schema_list.rst b/docs/source/_autosummary/semantic_router.utils.function_call.get_schema_list.rst
new file mode 100644
index 0000000000000000000000000000000000000000..14d78cab467eebb9c9d1f2281a288f754035d66f
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.function_call.get_schema_list.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.function\_call.get\_schema\_list
+=======================================================
+
+.. currentmodule:: semantic_router.utils.function_call
+
+.. autofunction:: get_schema_list
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.function_call.route_and_execute.rst b/docs/source/_autosummary/semantic_router.utils.function_call.route_and_execute.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a529599162b927cec84868b10a6c86da1a5b78f0
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.function_call.route_and_execute.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.function\_call.route\_and\_execute
+=========================================================
+
+.. currentmodule:: semantic_router.utils.function_call
+
+.. autofunction:: route_and_execute
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.function_call.rst b/docs/source/_autosummary/semantic_router.utils.function_call.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7df22f9a8fbbf6a9891d53cc66142a73642ce04d
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.function_call.rst
@@ -0,0 +1,33 @@
+semantic\_router.utils.function\_call
+=====================================
+
+.. automodule:: semantic_router.utils.function_call
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      convert_python_type_to_json_type
+      get_schema
+      get_schema_list
+      route_and_execute
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.utils.llm.llm.rst b/docs/source/_autosummary/semantic_router.utils.llm.llm.rst
new file mode 100644
index 0000000000000000000000000000000000000000..79768e50497855a699cfcf4406767dd399fc8316
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.llm.llm.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.llm.llm
+==============================
+
+.. currentmodule:: semantic_router.utils.llm
+
+.. autofunction:: llm
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.llm.rst b/docs/source/_autosummary/semantic_router.utils.llm.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7b1dccf0cc7c05c68aa952bb22754710b1bbc8d9
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.llm.rst
@@ -0,0 +1,30 @@
+semantic\_router.utils.llm
+==========================
+
+.. automodule:: semantic_router.utils.llm
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      llm
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.utils.logger.CustomFormatter.rst b/docs/source/_autosummary/semantic_router.utils.logger.CustomFormatter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cf6971d81830630144fa2ab3f270d30d10c51599
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.logger.CustomFormatter.rst
@@ -0,0 +1,39 @@
+semantic\_router.utils.logger.CustomFormatter
+=============================================
+
+.. currentmodule:: semantic_router.utils.logger
+
+.. autoclass:: CustomFormatter
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   
+   .. automethod:: __init__
+
+   
+   .. rubric:: Methods
+
+   .. autosummary::
+   
+      ~CustomFormatter.__init__
+      ~CustomFormatter.converter
+      ~CustomFormatter.format
+      ~CustomFormatter.formatException
+      ~CustomFormatter.formatMessage
+      ~CustomFormatter.formatStack
+      ~CustomFormatter.formatTime
+      ~CustomFormatter.usesTime
+   
+   
+
+   
+   
+   .. rubric:: Attributes
+
+   .. autosummary::
+   
+      ~CustomFormatter.default_msec_format
+      ~CustomFormatter.default_time_format
+   
+   
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.logger.add_coloured_handler.rst b/docs/source/_autosummary/semantic_router.utils.logger.add_coloured_handler.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f2ba4922682d6a6d568a466ab74e9cdd3ef62fdf
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.logger.add_coloured_handler.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.logger.add\_coloured\_handler
+====================================================
+
+.. currentmodule:: semantic_router.utils.logger
+
+.. autofunction:: add_coloured_handler
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.logger.rst b/docs/source/_autosummary/semantic_router.utils.logger.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f6c6c1758ad547bef7e1acddaa7c0e2082efe80e
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.logger.rst
@@ -0,0 +1,39 @@
+semantic\_router.utils.logger
+=============================
+
+.. automodule:: semantic_router.utils.logger
+  
+   
+   
+   
+
+   
+   
+   .. rubric:: Functions
+
+   .. autosummary::
+      :toctree:
+   
+      add_coloured_handler
+      setup_custom_logger
+   
+   
+
+   
+   
+   .. rubric:: Classes
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   
+      CustomFormatter
+   
+   
+
+   
+   
+   
+
+
+
diff --git a/docs/source/_autosummary/semantic_router.utils.logger.setup_custom_logger.rst b/docs/source/_autosummary/semantic_router.utils.logger.setup_custom_logger.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fdb58cae6305cdfe2a24b1a0d65bb7e632e76e6a
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.logger.setup_custom_logger.rst
@@ -0,0 +1,6 @@
+semantic\_router.utils.logger.setup\_custom\_logger
+===================================================
+
+.. currentmodule:: semantic_router.utils.logger
+
+.. autofunction:: setup_custom_logger
\ No newline at end of file
diff --git a/docs/source/_autosummary/semantic_router.utils.rst b/docs/source/_autosummary/semantic_router.utils.rst
new file mode 100644
index 0000000000000000000000000000000000000000..826b2770fc38c23fc3d0a884bc55f9e075374457
--- /dev/null
+++ b/docs/source/_autosummary/semantic_router.utils.rst
@@ -0,0 +1,35 @@
+semantic\_router.utils
+======================
+
+.. automodule:: semantic_router.utils
+  
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+   
+   
+   
+
+
+
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router.utils.defaults
+   semantic_router.utils.function_call
+   semantic_router.utils.llm
+   semantic_router.utils.logger
+
diff --git a/docs/source/_templates/custom-class-template.rst b/docs/source/_templates/custom-class-template.rst
new file mode 100644
index 0000000000000000000000000000000000000000..16ebb2f3386d241198f4c0c214561a1154170f9d
--- /dev/null
+++ b/docs/source/_templates/custom-class-template.rst
@@ -0,0 +1,32 @@
+{{ fullname | escape | underline}}
+
+.. currentmodule:: {{ module }}
+
+.. autoclass:: {{ objname }}
+   :members:
+   :show-inheritance:
+   :inherited-members:
+
+   {% block methods %}
+   .. automethod:: __init__
+
+   {% if methods %}
+   .. rubric:: {{ _('Methods') }}
+
+   .. autosummary::
+   {% for item in methods %}
+      ~{{ name }}.{{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block attributes %}
+   {% if attributes %}
+   .. rubric:: {{ _('Attributes') }}
+
+   .. autosummary::
+   {% for item in attributes %}
+      ~{{ name }}.{{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
\ No newline at end of file
diff --git a/docs/source/_templates/custom-module-template.rst b/docs/source/_templates/custom-module-template.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ef2c09a5444b330bd88ab79f04511a68c325e3e1
--- /dev/null
+++ b/docs/source/_templates/custom-module-template.rst
@@ -0,0 +1,66 @@
+{{ fullname | escape | underline}}
+
+.. automodule:: {{ fullname }}
+  
+   {% block attributes %}
+   {% if attributes %}
+   .. rubric:: Module Attributes
+
+   .. autosummary::
+      :toctree:
+   {% for item in attributes %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block functions %}
+   {% if functions %}
+   .. rubric:: {{ _('Functions') }}
+
+   .. autosummary::
+      :toctree:
+   {% for item in functions %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block classes %}
+   {% if classes %}
+   .. rubric:: {{ _('Classes') }}
+
+   .. autosummary::
+      :toctree:
+      :template: custom-class-template.rst
+   {% for item in classes %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+   {% block exceptions %}
+   {% if exceptions %}
+   .. rubric:: {{ _('Exceptions') }}
+
+   .. autosummary::
+      :toctree:
+   {% for item in exceptions %}
+      {{ item }}
+   {%- endfor %}
+   {% endif %}
+   {% endblock %}
+
+{% block modules %}
+{% if modules %}
+.. rubric:: Modules
+
+.. autosummary::
+   :toctree:
+   :template: custom-module-template.rst
+   :recursive:
+{% for item in modules %}
+   {{ item }}
+{%- endfor %}
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/docs/source/api.rst b/docs/source/api.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7ddaf33c8ffdfe823a9d3d5fad985b7c8188ec01
--- /dev/null
+++ b/docs/source/api.rst
@@ -0,0 +1,9 @@
+API
+===
+
+.. autosummary::
+   :toctree: _autosummary
+   :template: custom-module-template.rst
+   :recursive:
+
+   semantic_router
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
index badb608c0270e48a1543ae2bbd8395e8173870a1..618cdfc93cb3da39176799996c6412ff85472b41 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,4 +1,8 @@
 from typing import List
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath("../.."))  # Source code dir relative to this file
 
 # Configuration file for the Sphinx documentation builder.
 #
@@ -18,8 +22,10 @@ release = "0.0.55"
 
 extensions = ["sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinxawesome_theme"]
 
-# templates_path = ["_templates"]
+templates_path = ["_templates"]
 exclude_patterns: List[str] = []
+autosummary_generate = True
+numpydoc_show_class_members = True
 
 
 # -- Options for HTML output -------------------------------------------------
diff --git a/docs/source/index.rst b/docs/source/index.rst
index bd67018c7cc50808319833c1f02ef3ed165bfa19..7978059288617ec677b4e2754cc47bca4a5ccdcb 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -11,7 +11,9 @@ The *encoders* of semantic router include easy-to-use integrations with `Cohere
 Our utterance vector space also integrates with `Pinecone <https://github.com/aurelio-labs/semantic-router/blob/main/docs/indexes/pinecone.ipynb>`_ and `Qdrant <https://github.com/aurelio-labs/semantic-router/blob/main/docs/indexes/qdrant.ipynb>`_!
 
 .. toctree::
-   :maxdepth: 2
-   :caption: Contents:
+   :hidden:
 
-   quickstart
+   Home page <self>
+   Quickstart <quickstart>
+   Jupyter tutorials <tutorials>
+   API reference <_autosummary/semantic_router>
diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt
index b53de8f71c8fd9c1a9b38eab15cd1548da894f1e..eec6c5560f73532f9655ec55b9cbbcc78a0e7782 100644
--- a/docs/source/requirements.txt
+++ b/docs/source/requirements.txt
@@ -1 +1,4 @@
-sphinxawesome-theme==5.2.0
\ No newline at end of file
+sphinx
+sphinxawesome-theme==5.2.0
+sphinx-autodoc-typehints
+.
\ No newline at end of file
diff --git a/tests/unit/llms/test_llm_base.py b/tests/unit/llms/test_llm_base.py
index 3699ded0590f2798633d14305c1f1b3409655685..7fe8c0f06e3d153f17c589c086267690c703aa9a 100644
--- a/tests/unit/llms/test_llm_base.py
+++ b/tests/unit/llms/test_llm_base.py
@@ -4,7 +4,6 @@ from unittest.mock import patch
 
 
 class TestBaseLLM:
-
     @pytest.fixture
     def base_llm(self):
         return BaseLLM(name="TestLLM")