Package: chat2func
chat2funcchat2funcautomatically generates JSON schemas from Python, allowing ChatGPT to talk to your code.Installationpipinstallchat2func# Or install with developer dependenciespipinstallchat2func[develop]Quick StartAnnotate your function with@json_schemafromchat2funcimportjson_schema@json_schemadefmy_function(x:float,y:float)->bool:"""This is a sample function.Args:x: The first float.y: Another float."""returnx>yAfter this,my_functionwill have an additional.__schema__attribute containing its JSON schema.print(my_function.__schema__){'description':'This is a sample function.','name':'my_function','parameters':{'properties':{'x':{'description':'The first float.','type':'number'},'y':{'description':'Another float.','type':'number'}},'required':['x','y'],'type':'object'},'responses':{'200':{'content':{'application/json':{'schema':{'type':'boolean'}}},'description':'OK'}}}JSON SchemaYou can generate a JSON schema from any type of callable: classes, functions, or dataclasses.Using Custom Classesjson_schemaworks with classes or dataclasses too. Setdescriptions=Falseto not generate object descriptions from docstrings.@json_schema(descriptions=False)@dataclassclassData:a:int=0print(Data.__schema__){'name':'Data','parameters':{'type':'object','properties':{'a':{'type':'integer',"default":0}}}}Creating a ChatGPT PluginYou can easily create and demo a ChatGPT plugin using the included Flask server. First, define the functions you want ChatGPT to be able to use, expose them with the server and connect to them from ChatGPT.fromchat2func.serverimportFunctionServerdefaddition(x:float,y:float)->float:"Add two floats."returnx+yserver=FunctionServer({"addition":addition})server.run()# Visit http://localhost:3333/ to see the available functions.Deploy a PluginThePluginServeris a simple Flask app, so you can deploy easily using any method that works for Flask. The server provides an additionalexportfunction that generates the necessary files to deploy a plugin using firebase.# ...server.export("./my-plugin")After export, double check that all necessary code and imports are insidemain.py. Also add a logo to/public.cdmy-plugin
python3.11-mvenvfunctions/venv&&sourcefunctions/venv/bin/activate
pipinstall-rfunctions/requirements.txt
firebaseemulators:start# test the function locallyfirebasedeploy# deploy to firebaseDon't forget to update the urls inai-plugin.jsononce you've deployed.Calling Functions with JSON Argumentsfunction_callprovides additional functionality for calling and validating functions with JSON arguments. It also validates the function call, raisingFunctionCallErrorif something is unexpected.importjsonfromchat2funcimportfunction_calldefaddition(x:float,y:float)->float:"Add two floats."returnx+y# Arguments are passed as a JSON string.arguments=json.dumps({"x":1.0,"y":2.0})result=function_call(addition,arguments)print(result)# 3.0# We can optionally validate the function arguments too. Defaults to on.arguments=json.dumps({"x":"a","y":2.0})result=function_call(addition,arguments)# FunctionCallError: Arguments do not match the schema. 'a' is not of type 'number'Using OpenAI's Function Calling APIexperimentalWe can use the function calling API directly too. Here we demonstrate using ChatGPT to generate structured data (in the form of dataclasses) from unstructured knowledge about the bookDune.fromchat2funcimportfunction_callsfromchat2func.apiimportFunctionCallingAPI,Role@json_schema@dataclassclassCharacter:name:strage:Optional[int]=Nonehouse:Optional[str]=None# Setup our function calling APIapi=FunctionCallingAPI({"Character":Character})api.chat.add_message(Role.USER.value,"List the heads of houses in the Dune series. Give best estimates of age's where appropriate.")# Generate 5 different Characters (remember the samples are stochastic!)for_inrange(5):# Force the API to call a functionmessage=api.reply(force_function="Character")api.chat.messages.append(message)# Call the function (and validate the inputs!)fn_name=message.function_call["name"]args=message.function_call["arguments"]result=function_calls(fn_name,functions,args,return_json=False)# Add the result to the chatapi.chat.add_message(Role.FUNCTION.value,str(result),name="character")print(result)# Character(name='Duke Leto Atreides', age=50, house='Atreides')# Character(name='Baron Vladimir Harkonnen', age=80, house='Harkonnen')# Character(name='Emperor Shaddam Corrino IV', age=70, house='Corrino')# Character(name='Lady Jessica', age=36, house='Atreides')# Character(name='Paul Atreides', age=15, house='Atreides')ContributingI'm happy to accept contributions! Please open an issue or pull request if you have any ideas or find any bugs.