![Logo](https://github.com/0xnenlabs/SageAI/assets/45445790/750fb3f9-0830-4948-9a86-61e59d933b45)
<p align="center">
<em>Folder-based functions for ChatGPT's function calling with Pydantic support 🚀</em>
</p>
<p align="center">
<a href="https://pypi.org/project/sageai" target="_blank">
<img src="https://img.shields.io/pypi/v/sageai?label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/sageai" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/sageai.svg" alt="Supported Python versions">
</a>
</p>
SageAI is a framework for GPT 3.5/4 function calling for creating folder-based functions that is easy to organize and
scale.
With a built-in vector database used to store and retrieve functions, the number of tokens sent to the model is
significantly reduced, making it faster and cheaper to call your functions.
Read the blog post for a more in-depth explanation of the motivation behind SageAI [here](https://0xnen.com/blog/sageai).
## Table of Contents
- [Key Features](#key-features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Design](#design)
- [Setup](#setup)
- [Convention](#convention)
- [API](#api)
- [SageAI Initialize](#sageai-initialize)
- [SageAI Methods](#sageai-methods)
- [Vector DB](#vector-db)
- [Testing](#testing)
- [Unit Tests](#unit-tests)
- [Integration Tests](#integration-tests)
- [Output Equality](#output-equality)
- [CLI](#cli)
- [Examples](#examples)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
## Key Features
- Function organization through folder-centric functions.
- Strong typing for functions using Pydantic.
- Built-in Qdrant vector database with in-memory support for function storage and retrieval, with the option to
integrate your own.
- Easily test each function with an associated `test.json` file, supporting both unit and integration tests.
- Built with CI/CD in mind, ensuring synchronicity between your vector db and the functions directory across all
environments using the `index` method.
- Lightweight implementation with only three dependencies:
- `openai`
- `pydantic`
- `qdrant-client`
## Requirements
```
python >=3.9, <3.12
pydantic >=1.6, <=1.10.12
openai >=0.27.0
qdrant-client >=1.4.0
```
## Installation
```bash
# pip
$ pip install sageai
# poetry
$ poetry add sageai
```
## Design
![Design](https://github.com/0xnenlabs/SageAI/assets/45445790/eb81d280-5b69-472a-b45a-4a9275fcf341)
SageAI is built around the concept of a `functions` directory, which contains all of your functions. Each function is
defined in a Python file `function.py`, and is associated with an optional `test.json` file for testing.
The format of the `function.py` file must contain two things in order for SageAI to work:
1. The function itself
2. The `Function` object
Input and output types may be defined using Pydantic models, and are automatically validated by SageAI. They can also be
defined outside the `function.py` file, and imported into the file.
Here is a simplified example of how SageAI might handle a function that fetches the current weather for a given
location.
```python
# functions/get_current_weather/function.py
from enum import Enum
from typing import Optional
from pydantic import BaseModel, Field
from sage_func.types.function import Function
class UnitTypes(str, Enum):
CELSIUS = "Celsius"
FAHRENHEIT = "Fahrenheit"
class FunctionInput(BaseModel):
location: str = Field(
..., description="The city, e.g. San Francisco"
)
unit: Optional[UnitTypes] = Field(
UnitTypes.CELSIUS, description="The unit of temperature."
)
class FunctionOutput(BaseModel):
weather: str
def __eq__(self, other):
if not isinstance(other, FunctionOutput):
return False
return self.weather == other.weather
def get_current_weather(params: FunctionInput) -> FunctionOutput:
weather = (
f"The weather in {params.location} is currently 22 degrees {params.unit.value}."
)
return FunctionOutput(weather=weather)
function = Function(
function=get_current_weather,
description="Get the current weather in a given location.",
)
```
We'll break down the above example into its components below.
## Setup
Create a `functions` directory in the root directory, and add your functions as described in [Design](#design).
Then initialize `SageAI`.
```python
from sage_func import SageAI
sage = SageAI(openai_key="")
```
Then index the vector database.
```python
sage.index()
```
That's it! You're now set up and ready to interact with SageAI through natural language queries. 🚀
```python
message = "What's the weather like in Toronto right now?"
response = sage.chat(
messages=[dict(role="user", content=message)],
model="gpt-3.5-turbo-0613",
top_n=5,
)
# response:
# {
# 'name': 'get_current_weather',
# 'args': {'location': 'Toronto'},
# 'result': {'weather': 'The weather in Toronto is currently 22 degrees Celsius.'}
# }
```
## Convention
SageAI follows a convention over configuration approach to make it easy to define functions.
Ensure that your `function.py` file contains the following:
1. A `function` object that is an instance of `Function`.
2. A function that is the actual function that will be called by ChatGPT.
3. The function **must** have typed input and output Pydantic models.
4. Each field in the input model **must** have a description.
Minimal example:
```python
def my_function(params: PydanticInput) -> PydanticOutput:
return PydanticOutput(...)
function = Function(
function=my_function,
description="My function description.",
)
```
## API
### SageAI Initialize
The `SageAI` constructor accepts the following parameters:
| Parameter | Description | Defaults |
|-------------------------|-----------------------------------------------------------------------------|--------------------------|
| **openai_key** | The API key for OpenAI. | _Required_ |
| **functions_directory** | Directory containing functions. | `/functions` |
| **vectordb** | An implementation of the `AbstractVectorDB` for vector database operations. | `DefaultVectorDBService` |
| **log_level** | Desired log level for the operations. | `ERROR` |
### SageAI Methods
#### 1. `chat`
Initiate a chat using OpenAI's API and the provided parameters.
**Parameters**:
| Parameter | Description | Defaults |
|-----------|---------------------------------------------------------------------------------------------------------------------|------------|
| - | Accepts the same parameters as OpenAI's [chat endpoint](https://platform.openai.com/docs/api-reference/chat/create) | - |
| **top_n** | The number of top functions to consider from the vector database. | _Required_ |
**Returns**:
```python
dict(
name="function_name",
args={"arg1": "value1", "arg2": "value2"},
result={"out1": "value1", "out2": "value2"}, # Optional
error="", # Optional
)
```
> Either `result` or `error` will be present in the response, but not both.
---
#### 2. `get_top_n_functions`
Get the top `n` functions from the vector database based on a query.
**Parameters**:
| Parameter | Description | Defaults |
|-----------|------------------------------------|------------|
| **query** | The query to search against. | _Required_ |
| **top_n** | The number of functions to return. | _Required_ |
**Returns**:
- A dict of function names to `Function` definitions.
---
#### 3. `run_function`
Execute a function based on its name and provided arguments.
**Parameters**:
| Parameter | Description | Defaults |
|-----------|------------------------------------|------------|
| **name** | Name of the function. | _Required_ |
| **args** | Arguments to pass to the function. | _Required_ |
**Returns**:
- The function result as a dict.
---
#### 4. `call_openai`
Calls the OpenAI API with the provided parameters.
**Parameters**:
| Parameter | Description | Defaults |
|-------------------|---------------------------------------------------------------------------------------------------------------------|------------|
| **openai_args** | Accepts the same parameters as OpenAI's [chat endpoint](https://platform.openai.com/docs/api-reference/chat/create) | _Required_ |
| **top_functions** | List of dicts that is a representation of your functions. | _Required_ |
**Returns**:
- A tuple of the function name and the function args.
---
#### 5. `index`
Index the vector database based on the functions directory.
This method is useful to update the vectordb when new functions are added or existing ones are updated.
---
Want more control?
> The `chat` function uses `get_top_n_functions`, `run_function`, and `call_openai` internally.
> However, we also expose these methods incase you wish to use them directly to implement your own `chat` logic.
---
### Vector DB
SageAI comes with a built-in in-memory vector database, Qdrant, which is used to store and retrieve functions.
If you wish to use your own vector database, you can implement the `AbstractVectorDB` class and pass it into the
`SageAI` constructor.
See the [advanced example](/examples/advanced) for an example of how to integrate your own vector database.
## Testing
As for the optional `test.json` file in each function, follow this structure:
```json
[
{
"message": "What's the weather like in Toronto right now?",
"input": {
"location": "Toronto",
"unit": "Celsius"
},
"output": {
"weather": "The weather in Toronto is currently 22 degrees Celsius."
}
}
]
```
- Each object in the array represents a test case.
- The `message` field is the natural language message that will be sent
to ChatGPT, and the `input` field is the expected input that will be passed to the function.
- The `output` field is the
expected output of the function.
SageAI offers unit and integration tests.
---
### Unit Tests
> Unit tests do not call the vector database nor ChatGPT, and **will not** cost you OpenAI credits.
- Unit tests are used to ensure your functions directory is valid, and it tests the function in isolation.
- It tests whether:
- the `functions` directory exists.
- each function has a `function.py` file.
- each `function.py` file has a `Function` object.
- and more!
- It also tests whether the input and output types are valid, and whether the function returns the expected output based
on
the input alone by calling `func(test_case["input"]) == test_case["output"]`.
---
### Integration Tests
> Integration tests will call the vector database and ChatGPT, and **will** cost you OpenAI credits.
- Integration tests are used to test the function by calling ChatGPT and the vector database.
- They test whether the vector database is able to retrieve the function, and whether ChatGPT can call the function
with the given input and return the expected output.
> Because ChatGPT's responses can vary, integration tests may return different results each time.
> It's important to use integration tests as a tool to ensure ChatGPT is able to call the right function with the right
> input, and not as a definitive test to measure the test rate of your functions.
---
### Output Equality
You can customize how to determine equality between the expected and actual output by overriding the `__eq__`
method in the output model.
```python
class FunctionOutput(BaseModel):
weather: str
temperature: int
def __eq__(self, other):
if not isinstance(other, FunctionOutput):
return False
return self.weather == other.weather
```
In the case above, we only care about the `weather` field, and not the `temperature` field. Therefore, we only compare
the `weather` field in the `__eq__` method.
This is especially useful when you are returning an object from a database, for example, and you only care to test
against a subset of the fields (for example, the `id` field).
---
### CLI
```bash
# To run unit and integration tests for all functions:
poetry run sageai-tests --apikey=openapikey --directory=path/to/functions
# To run unit tests only for all functions:
poetry run sageai-tests --apikey=openapikey --directory=path/to/functions --unit
# To run integration tests only for all functions:
poetry run sageai-tests --apikey=openapikey --directory=path/to/functions --integration
# To run unit and integration tests for a specific function:
poetry run sageai-tests --apikey=openapikey --directory=path/to/functions/get_current_weather
```
| Parameter | Description | Defaults |
|-------------------|---------------------------------------------------------------|--------------|
| **--apikey** | OpenAI API key. | _Required_ |
| **--directory** | Directory of the functions or of the specific function to run | _/functions_ |
| **--unit** | Only run unit tests | false |
| **--integration** | Only run integration tests | false |
## Examples
1. [Basic](/examples/basic) - Get started with a simple SageAI function.
2. [Advanced](/examples/advanced) - Dive deeper with more intricate functionalities and use-cases.
## Roadmap
- [ ] Add tests and code coverage
- [ ] Support multiple function calls
- [ ] Support streaming
- [ ] Support asyncio
- [ ] Support Pydantic V2
- [ ] Write Chainlit example
- [ ] Write fullstack example
## Contributing
Interested in contributing to SageAI? Please see our [CONTRIBUTING.md](/CONTRIBUTING.md) for guidelines, coding
standards, and other details.
Raw data
{
"_id": null,
"home_page": "",
"name": "sage-func",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.9,<3.12",
"maintainer_email": "",
"keywords": "python,openai,functions,chatgpt,gpt4,genai,function-calling",
"author": "JUNIORCO",
"author_email": "sami@lasso.gg",
"download_url": "https://files.pythonhosted.org/packages/81/a0/f33304a963af7f9cc49c23d820f6212a2e48d52184bec2eacd95c5e3424c/sage_func-0.1.5.tar.gz",
"platform": null,
"description": "![Logo](https://github.com/0xnenlabs/SageAI/assets/45445790/750fb3f9-0830-4948-9a86-61e59d933b45)\n\n<p align=\"center\">\n <em>Folder-based functions for ChatGPT's function calling with Pydantic support \ud83d\ude80</em>\n</p>\n\n<p align=\"center\">\n<a href=\"https://pypi.org/project/sageai\" target=\"_blank\">\n <img src=\"https://img.shields.io/pypi/v/sageai?label=pypi%20package\" alt=\"Package version\">\n</a>\n<a href=\"https://pypi.org/project/sageai\" target=\"_blank\">\n <img src=\"https://img.shields.io/pypi/pyversions/sageai.svg\" alt=\"Supported Python versions\">\n</a>\n</p>\n\nSageAI is a framework for GPT 3.5/4 function calling for creating folder-based functions that is easy to organize and\nscale.\n\nWith a built-in vector database used to store and retrieve functions, the number of tokens sent to the model is\nsignificantly reduced, making it faster and cheaper to call your functions.\n\nRead the blog post for a more in-depth explanation of the motivation behind SageAI [here](https://0xnen.com/blog/sageai).\n\n## Table of Contents\n\n- [Key Features](#key-features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Design](#design)\n- [Setup](#setup)\n- [Convention](#convention)\n- [API](#api)\n - [SageAI Initialize](#sageai-initialize)\n - [SageAI Methods](#sageai-methods)\n - [Vector DB](#vector-db)\n- [Testing](#testing)\n - [Unit Tests](#unit-tests)\n - [Integration Tests](#integration-tests)\n - [Output Equality](#output-equality)\n - [CLI](#cli)\n- [Examples](#examples)\n- [Roadmap](#roadmap)\n- [Contributing](#contributing)\n\n## Key Features\n\n- Function organization through folder-centric functions.\n- Strong typing for functions using Pydantic.\n- Built-in Qdrant vector database with in-memory support for function storage and retrieval, with the option to\n integrate your own.\n- Easily test each function with an associated `test.json` file, supporting both unit and integration tests.\n- Built with CI/CD in mind, ensuring synchronicity between your vector db and the functions directory across all\n environments using the `index` method.\n- Lightweight implementation with only three dependencies:\n - `openai`\n - `pydantic`\n - `qdrant-client`\n\n## Requirements\n\n```\npython >=3.9, <3.12\npydantic >=1.6, <=1.10.12\nopenai >=0.27.0\nqdrant-client >=1.4.0\n```\n\n## Installation\n\n```bash\n# pip\n$ pip install sageai\n\n# poetry\n$ poetry add sageai\n```\n\n## Design\n\n![Design](https://github.com/0xnenlabs/SageAI/assets/45445790/eb81d280-5b69-472a-b45a-4a9275fcf341)\n\nSageAI is built around the concept of a `functions` directory, which contains all of your functions. Each function is\ndefined in a Python file `function.py`, and is associated with an optional `test.json` file for testing.\n\nThe format of the `function.py` file must contain two things in order for SageAI to work:\n\n1. The function itself\n2. The `Function` object\n\nInput and output types may be defined using Pydantic models, and are automatically validated by SageAI. They can also be\ndefined outside the `function.py` file, and imported into the file.\n\nHere is a simplified example of how SageAI might handle a function that fetches the current weather for a given\nlocation.\n\n```python\n# functions/get_current_weather/function.py\nfrom enum import Enum\nfrom typing import Optional\n\nfrom pydantic import BaseModel, Field\n\nfrom sage_func.types.function import Function\n\n\nclass UnitTypes(str, Enum):\n CELSIUS = \"Celsius\"\n FAHRENHEIT = \"Fahrenheit\"\n\n\nclass FunctionInput(BaseModel):\n location: str = Field(\n ..., description=\"The city, e.g. San Francisco\"\n )\n unit: Optional[UnitTypes] = Field(\n UnitTypes.CELSIUS, description=\"The unit of temperature.\"\n )\n\n\nclass FunctionOutput(BaseModel):\n weather: str\n\n def __eq__(self, other):\n if not isinstance(other, FunctionOutput):\n return False\n return self.weather == other.weather\n\n\ndef get_current_weather(params: FunctionInput) -> FunctionOutput:\n weather = (\n f\"The weather in {params.location} is currently 22 degrees {params.unit.value}.\"\n )\n return FunctionOutput(weather=weather)\n\n\nfunction = Function(\n function=get_current_weather,\n description=\"Get the current weather in a given location.\",\n)\n```\n\nWe'll break down the above example into its components below.\n\n## Setup\n\nCreate a `functions` directory in the root directory, and add your functions as described in [Design](#design).\n\nThen initialize `SageAI`.\n\n```python\nfrom sage_func import SageAI\n\nsage = SageAI(openai_key=\"\")\n```\n\nThen index the vector database.\n\n```python\nsage.index()\n```\n\nThat's it! You're now set up and ready to interact with SageAI through natural language queries. \ud83d\ude80\n\n```python\nmessage = \"What's the weather like in Toronto right now?\"\nresponse = sage.chat(\n messages=[dict(role=\"user\", content=message)],\n model=\"gpt-3.5-turbo-0613\",\n top_n=5,\n)\n# response:\n# {\n# 'name': 'get_current_weather',\n# 'args': {'location': 'Toronto'},\n# 'result': {'weather': 'The weather in Toronto is currently 22 degrees Celsius.'}\n# }\n```\n\n## Convention\n\nSageAI follows a convention over configuration approach to make it easy to define functions.\n\nEnsure that your `function.py` file contains the following:\n\n1. A `function` object that is an instance of `Function`.\n2. A function that is the actual function that will be called by ChatGPT.\n3. The function **must** have typed input and output Pydantic models.\n4. Each field in the input model **must** have a description.\n\nMinimal example:\n\n```python\ndef my_function(params: PydanticInput) -> PydanticOutput:\n return PydanticOutput(...)\n\n\nfunction = Function(\n function=my_function,\n description=\"My function description.\",\n)\n```\n\n## API\n\n### SageAI Initialize\n\nThe `SageAI` constructor accepts the following parameters:\n\n| Parameter | Description | Defaults |\n|-------------------------|-----------------------------------------------------------------------------|--------------------------|\n| **openai_key** | The API key for OpenAI. | _Required_ |\n| **functions_directory** | Directory containing functions. | `/functions` |\n| **vectordb** | An implementation of the `AbstractVectorDB` for vector database operations. | `DefaultVectorDBService` |\n| **log_level** | Desired log level for the operations. | `ERROR` |\n\n### SageAI Methods\n\n#### 1. `chat`\n\nInitiate a chat using OpenAI's API and the provided parameters.\n\n**Parameters**:\n\n| Parameter | Description | Defaults |\n|-----------|---------------------------------------------------------------------------------------------------------------------|------------|\n| - | Accepts the same parameters as OpenAI's [chat endpoint](https://platform.openai.com/docs/api-reference/chat/create) | - |\n| **top_n** | The number of top functions to consider from the vector database. | _Required_ |\n\n**Returns**:\n\n```python\ndict(\n name=\"function_name\",\n args={\"arg1\": \"value1\", \"arg2\": \"value2\"},\n result={\"out1\": \"value1\", \"out2\": \"value2\"}, # Optional\n error=\"\", # Optional\n)\n```\n\n> Either `result` or `error` will be present in the response, but not both.\n\n---\n\n#### 2. `get_top_n_functions`\n\nGet the top `n` functions from the vector database based on a query.\n\n**Parameters**:\n\n| Parameter | Description | Defaults |\n|-----------|------------------------------------|------------|\n| **query** | The query to search against. | _Required_ |\n| **top_n** | The number of functions to return. | _Required_ |\n\n**Returns**:\n\n- A dict of function names to `Function` definitions.\n\n---\n\n#### 3. `run_function`\n\nExecute a function based on its name and provided arguments.\n\n**Parameters**:\n\n| Parameter | Description | Defaults |\n|-----------|------------------------------------|------------|\n| **name** | Name of the function. | _Required_ |\n| **args** | Arguments to pass to the function. | _Required_ |\n\n**Returns**:\n\n- The function result as a dict.\n\n---\n\n#### 4. `call_openai`\n\nCalls the OpenAI API with the provided parameters.\n\n**Parameters**:\n\n| Parameter | Description | Defaults |\n|-------------------|---------------------------------------------------------------------------------------------------------------------|------------|\n| **openai_args** | Accepts the same parameters as OpenAI's [chat endpoint](https://platform.openai.com/docs/api-reference/chat/create) | _Required_ |\n| **top_functions** | List of dicts that is a representation of your functions. | _Required_ |\n\n**Returns**:\n\n- A tuple of the function name and the function args.\n\n---\n\n#### 5. `index`\n\nIndex the vector database based on the functions directory.\nThis method is useful to update the vectordb when new functions are added or existing ones are updated.\n\n---\n\nWant more control?\n\n> The `chat` function uses `get_top_n_functions`, `run_function`, and `call_openai` internally.\n> However, we also expose these methods incase you wish to use them directly to implement your own `chat` logic.\n\n---\n\n### Vector DB\n\nSageAI comes with a built-in in-memory vector database, Qdrant, which is used to store and retrieve functions.\n\nIf you wish to use your own vector database, you can implement the `AbstractVectorDB` class and pass it into the\n`SageAI` constructor.\n\nSee the [advanced example](/examples/advanced) for an example of how to integrate your own vector database.\n\n## Testing\n\nAs for the optional `test.json` file in each function, follow this structure:\n\n```json\n[\n {\n \"message\": \"What's the weather like in Toronto right now?\",\n \"input\": {\n \"location\": \"Toronto\",\n \"unit\": \"Celsius\"\n },\n \"output\": {\n \"weather\": \"The weather in Toronto is currently 22 degrees Celsius.\"\n }\n }\n]\n```\n\n- Each object in the array represents a test case.\n- The `message` field is the natural language message that will be sent\n to ChatGPT, and the `input` field is the expected input that will be passed to the function.\n- The `output` field is the\n expected output of the function.\n\nSageAI offers unit and integration tests.\n\n---\n\n### Unit Tests\n\n> Unit tests do not call the vector database nor ChatGPT, and **will not** cost you OpenAI credits.\n\n- Unit tests are used to ensure your functions directory is valid, and it tests the function in isolation.\n- It tests whether:\n - the `functions` directory exists.\n - each function has a `function.py` file.\n - each `function.py` file has a `Function` object.\n - and more!\n- It also tests whether the input and output types are valid, and whether the function returns the expected output based\n on\n the input alone by calling `func(test_case[\"input\"]) == test_case[\"output\"]`.\n\n---\n\n### Integration Tests\n\n> Integration tests will call the vector database and ChatGPT, and **will** cost you OpenAI credits.\n\n- Integration tests are used to test the function by calling ChatGPT and the vector database.\n- They test whether the vector database is able to retrieve the function, and whether ChatGPT can call the function\n with the given input and return the expected output.\n\n> Because ChatGPT's responses can vary, integration tests may return different results each time.\n> It's important to use integration tests as a tool to ensure ChatGPT is able to call the right function with the right\n> input, and not as a definitive test to measure the test rate of your functions.\n\n---\n\n### Output Equality\n\nYou can customize how to determine equality between the expected and actual output by overriding the `__eq__`\nmethod in the output model.\n\n```python\nclass FunctionOutput(BaseModel):\n weather: str\n temperature: int\n\n def __eq__(self, other):\n if not isinstance(other, FunctionOutput):\n return False\n return self.weather == other.weather\n```\n\nIn the case above, we only care about the `weather` field, and not the `temperature` field. Therefore, we only compare\nthe `weather` field in the `__eq__` method.\n\nThis is especially useful when you are returning an object from a database, for example, and you only care to test\nagainst a subset of the fields (for example, the `id` field).\n\n---\n\n### CLI\n\n```bash\n# To run unit and integration tests for all functions:\npoetry run sageai-tests --apikey=openapikey --directory=path/to/functions\n\n# To run unit tests only for all functions:\npoetry run sageai-tests --apikey=openapikey --directory=path/to/functions --unit\n\n# To run integration tests only for all functions:\npoetry run sageai-tests --apikey=openapikey --directory=path/to/functions --integration\n\n# To run unit and integration tests for a specific function:\npoetry run sageai-tests --apikey=openapikey --directory=path/to/functions/get_current_weather\n```\n\n| Parameter | Description | Defaults |\n|-------------------|---------------------------------------------------------------|--------------|\n| **--apikey** | OpenAI API key. | _Required_ |\n| **--directory** | Directory of the functions or of the specific function to run | _/functions_ |\n| **--unit** | Only run unit tests | false |\n| **--integration** | Only run integration tests | false |\n\n## Examples\n\n1. [Basic](/examples/basic) - Get started with a simple SageAI function.\n2. [Advanced](/examples/advanced) - Dive deeper with more intricate functionalities and use-cases.\n\n## Roadmap\n\n- [ ] Add tests and code coverage\n- [ ] Support multiple function calls\n- [ ] Support streaming\n- [ ] Support asyncio\n- [ ] Support Pydantic V2\n- [ ] Write Chainlit example\n- [ ] Write fullstack example\n\n## Contributing\n\nInterested in contributing to SageAI? Please see our [CONTRIBUTING.md](/CONTRIBUTING.md) for guidelines, coding\nstandards, and other details.\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Folder-based functions for GPT 3.5/4 function calling with Pydantic support",
"version": "0.1.5",
"project_urls": null,
"split_keywords": [
"python",
"openai",
"functions",
"chatgpt",
"gpt4",
"genai",
"function-calling"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "96de714936dd630a17c5caacbc6dede0be34534857f07c369563636294daa95f",
"md5": "af44ebab6cca69fe6be61592c9e835ae",
"sha256": "fbf936e4364778190ceea6f48df520b9502323b48798b60bdc999417166f9d29"
},
"downloads": -1,
"filename": "sage_func-0.1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "af44ebab6cca69fe6be61592c9e835ae",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9,<3.12",
"size": 20834,
"upload_time": "2023-10-13T07:50:22",
"upload_time_iso_8601": "2023-10-13T07:50:22.184387Z",
"url": "https://files.pythonhosted.org/packages/96/de/714936dd630a17c5caacbc6dede0be34534857f07c369563636294daa95f/sage_func-0.1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "81a0f33304a963af7f9cc49c23d820f6212a2e48d52184bec2eacd95c5e3424c",
"md5": "57a30de5e51ed3ad48582d4e06f43a6a",
"sha256": "7ca411883a10807c4c3e66ede9836d6416e52e23c6899ae807231bd6a19d5960"
},
"downloads": -1,
"filename": "sage_func-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "57a30de5e51ed3ad48582d4e06f43a6a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9,<3.12",
"size": 19407,
"upload_time": "2023-10-13T07:50:23",
"upload_time_iso_8601": "2023-10-13T07:50:23.883694Z",
"url": "https://files.pythonhosted.org/packages/81/a0/f33304a963af7f9cc49c23d820f6212a2e48d52184bec2eacd95c5e3424c/sage_func-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-13 07:50:23",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "sage-func"
}