![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?color=%2334D058&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?color=%2334D058" alt="Supported Python versions">
</a>
</p>
SageAI lets you connect custom Python functions to ChatGPT. It organizes these functions in folders
and allows you to call them with natural language.
## 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 sageai.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 sageai 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 money.
- 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 money.
- 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": "sageai",
"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/20/64/9fa5fa6596cfbf46c5302056632a0df547e1f6e183dd692b8ff991e0e866/sageai-1.0.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?color=%2334D058&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?color=%2334D058\" alt=\"Supported Python versions\">\n</a>\n</p>\n\nSageAI lets you connect custom Python functions to ChatGPT. It organizes these functions in folders\nand allows you to call them with natural language.\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 sageai.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 sageai 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 money.\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 money.\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",
"bugtrack_url": null,
"license": "MIT",
"summary": "File-based functions for ChatGPT's function calling with Pydantic support",
"version": "1.0.5",
"project_urls": null,
"split_keywords": [
"python",
"openai",
"functions",
"chatgpt",
"gpt4",
"genai",
"function-calling"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "952304edcf76ac46e1ec3696e9a1b0dc5e12ffec0143d679f4ae26a802529e86",
"md5": "4ceaa80280859f5e475a556147374c33",
"sha256": "e12fe38c747a9e98ca2929ce23c69f7dbe43fb207a39796a0f6c8809c0ef9afb"
},
"downloads": -1,
"filename": "sageai-1.0.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4ceaa80280859f5e475a556147374c33",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9,<3.12",
"size": 20219,
"upload_time": "2023-11-15T16:24:58",
"upload_time_iso_8601": "2023-11-15T16:24:58.422004Z",
"url": "https://files.pythonhosted.org/packages/95/23/04edcf76ac46e1ec3696e9a1b0dc5e12ffec0143d679f4ae26a802529e86/sageai-1.0.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "20649fa5fa6596cfbf46c5302056632a0df547e1f6e183dd692b8ff991e0e866",
"md5": "42253d9b617a668f91169910bfd7b877",
"sha256": "1947865b43076738d52896c32ea778c628973f064abb8fbdbe5a103dbfbc6039"
},
"downloads": -1,
"filename": "sageai-1.0.5.tar.gz",
"has_sig": false,
"md5_digest": "42253d9b617a668f91169910bfd7b877",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9,<3.12",
"size": 19184,
"upload_time": "2023-11-15T16:24:59",
"upload_time_iso_8601": "2023-11-15T16:24:59.780807Z",
"url": "https://files.pythonhosted.org/packages/20/64/9fa5fa6596cfbf46c5302056632a0df547e1f6e183dd692b8ff991e0e866/sageai-1.0.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-15 16:24:59",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "sageai"
}