Home

Awesome

Sample ChatGPT plugin in Ruby

This Ruby/Sinatra app is a ChatGPT plugin that provides a random number.

Example usage

demo1

demo2

demo3

demo4

demo5

Run locally and test on ChatGPT

To start up the application and bind to port 9292:

bundle
rerun rackup

You will need to expose the application to the internet. I use https://ngrok.com/.

ngrok http --region=au 9292

The output shows you your domain

Session Status                online
Region                        Australia (au)
Forwarding                    https://e92baeb18b8a.ngrok.app -> http://localhost:9292

The domain e92baeb18b8a.ngrok.app will be passed to ChatGPT when we register the plugin.

Register plugin with ChatGPT

Open https://chat.openai.com/chat, and switch to the ChatGPT "Plugins" model.

setup-model-plugins

Next, under the Plugins dropdown, select "Plugin Store".

setup-open-plugin-store

At the bottom of the modal, click on "Develop your own plugin".

Click the green "My manifest is ready" button.

Copy your ngrok domain e92baeb18b8a.ngrok.app into the form, and click the green "Find manifest file" button.

ChatGPT will validate the two manifest files. Click the green Next button.

setup-validate-manifests

Next, click Install for me, then Continue, then Install plugin.

Testing the plugin

Try the prompts:

testing-example-prompts

Implementation

The Sinatra app provides a POST /random endpoint that returns {random_number: 35} or similar.

export DOMAIN=e92baeb18b8a.ngrok.app
curl "https://$DOMAIN/random" -d '{}'

You can also pass min or max to override the defaults of 0 and 100 respectively.

$ curl "https://$DOMAIN/random" -d '{"min":10,"max":20}'
{"random_number":15}

But ChatGPT Plugins doesn't know the details of this API until we tell it. When you register ChatGPT it fetches two files from our plugin.

The high-level plugin definition:

curl "https://$DOMAIN/.well-known/ai-plugin.json"

And the description of our POST /random endpoint:

curl "https://$DOMAIN/.well-known/openapi.yaml"

The source files are within this repo's .well-known folder, but our app.rb sinatra script loads them, replaces DOMAIN with our $DOMAIN ngrok domain, and returns the modified file.

Writing your own openapi.yaml file

I actually asked GPT-4 to write my file:

Create an openapi.yaml for a service that has a POST /random endpoint that returns single integer which is a random number

Through debugging, I needed to manually change the result a little bit to add operationId: query_query_post to my /random paths entry.

And then I asked GPT-4 to write the initial Sinatra app:

Create a ruby sinatra app.rb that implements this endpoint

And I was half way there. Good times.