Is anyone developing a ChatGPT plugin that uses an SWI-Prolog server?

Is anyone developing a ChatGPT plugin that uses an SWI-Prolog server?


Currently have TODO demo based on Python working using server on localhost. (ref)
Converted TODO demo based on Python (ChatGPT did conversation) to SWI-Prolog but had to work around lack of HTTP method delete. (ref)

Having problems getting CORS to work so using TODO demo based on Python to see what is happening and recreate commands using cURL for testing with TODO demo based on SWI-Prolog.


Output when using TODO demo based on Python.

Click triangle to expand
C:\Users\Groot\plugins-quickstart-main>python main.py
 * Serving Quart app 'main'
 * Environment: production
 * Please use an ASGI server (e.g. Hypercorn) directly in production
 * Debug mode: True
 * Running on http://0.0.0.0:5003 (CTRL + C to quit)
[2023-05-18 07:01:32 -0400] [15008] [INFO] Running on http://0.0.0.0:5003 (CTRL + C to quit)
[2023-05-18 07:03:06 -0400] [15008] [INFO] 127.0.0.1:63017 OPTIONS /.well-known/ai-plugin.json 1.1 200 0 19001
[2023-05-18 07:03:06 -0400] [15008] [INFO] 127.0.0.1:63017 GET /.well-known/ai-plugin.json 1.1 200 641 18982
[2023-05-18 07:03:06 -0400] [15008] [INFO] 127.0.0.1:63017 OPTIONS /openapi.yaml 1.1 200 0 10976
[2023-05-18 07:03:06 -0400] [15008] [INFO] 127.0.0.1:63017 GET /openapi.yaml 1.1 200 2337 17019
[2023-05-18 07:03:07 -0400] [15008] [INFO] 127.0.0.1:63017 OPTIONS /logo.png 1.1 200 0 15002
[2023-05-18 07:03:07 -0400] [15008] [INFO] 127.0.0.1:63025 GET /logo.png 1.1 200 1268 139032
[2023-05-18 07:03:15 -0400] [15008] [INFO] 127.0.0.1:63029 OPTIONS /.well-known/ai-plugin.json 1.1 200 0 10003
[2023-05-18 07:03:15 -0400] [15008] [INFO] 127.0.0.1:63029 GET /.well-known/ai-plugin.json 1.1 200 641 12006
[2023-05-18 07:03:15 -0400] [15008] [INFO] 127.0.0.1:63029 OPTIONS /openapi.yaml 1.1 200 0 11006
[2023-05-18 07:03:15 -0400] [15008] [INFO] 127.0.0.1:63029 GET /openapi.yaml 1.1 200 2337 9989
[2023-05-18 07:03:37 -0400] [15008] [INFO] 127.0.0.1:63038 OPTIONS /.well-known/ai-plugin.json 1.1 200 0 9002
[2023-05-18 07:03:37 -0400] [15008] [INFO] 127.0.0.1:63038 GET /.well-known/ai-plugin.json 1.1 200 641 12001
[2023-05-18 07:03:37 -0400] [15008] [INFO] 127.0.0.1:63038 OPTIONS /openapi.yaml 1.1 200 0 10998
[2023-05-18 07:03:37 -0400] [15008] [INFO] 127.0.0.1:63038 GET /openapi.yaml 1.1 200 2337 11988
[2023-05-18 07:04:06 -0400] [15008] [INFO] 127.0.0.1:63046 OPTIONS /todos/user 1.1 200 0 9979
[2023-05-18 07:04:06 -0400] [15008] [INFO] 127.0.0.1:63046 POST /todos/user 1.1 200 2 19988
[2023-05-18 07:04:24 -0400] [15008] [INFO] 127.0.0.1:63052 OPTIONS /todos/user 1.1 200 0 10002
[2023-05-18 07:04:24 -0400] [15008] [INFO] 127.0.0.1:63052 POST /todos/user 1.1 200 2 19999
[2023-05-18 07:04:37 -0400] [15008] [INFO] 127.0.0.1:63056 OPTIONS /todos/user 1.1 200 0 11027
[2023-05-18 07:04:37 -0400] [15008] [INFO] 127.0.0.1:63056 GET /todos/user 1.1 200 27 13002
[2023-05-18 07:05:04 -0400] [15008] [INFO] 127.0.0.1:63060 OPTIONS /todos/user 1.1 200 0 11005
[2023-05-18 07:05:04 -0400] [15008] [INFO] 127.0.0.1:63060 DELETE /todos/user 1.1 200 2 16987
[2023-05-18 07:05:20 -0400] [15008] [INFO] 127.0.0.1:63066 OPTIONS /todos/user 1.1 200 0 10980
[2023-05-18 07:05:20 -0400] [15008] [INFO] 127.0.0.1:63066 GET /todos/user 1.1 200 15 13015

Recreation of ChatGPT HTTP request (cURL commands) to TODO server. Created these to test the SWI-Prolog TODO server independent of ChatGPT.

Click triangle to expand
C:\Users\Groot>curl -X OPTIONS "http://localhost:5003/.well-known/ai-plugin.json" -i
HTTP/1.1 200
allow: OPTIONS, HEAD, GET
content-type: text/html; charset=utf-8
content-length: 0
date: Thu, 18 May 2023 11:45:09 GMT
server: hypercorn-h11

Server log

[2023-05-18 07:45:09 -0400] [15008] [INFO] 127.0.0.1:63214 OPTIONS /.well-known/ai-plugin.json 1.1 200 0 11011

C:\Users\Groot>curl -X GET "http://localhost:5003/.well-known/ai-plugin.json"
{
    "schema_version": "v1",
    "name_for_human": "TODO Plugin (no auth)",
    "name_for_model": "todo",
    "description_for_human": "Plugin for managing a TODO list, you can add, remove and view your TODOs.",
    "description_for_model": "Plugin for managing a TODO list, you can add, remove and view your TODOs.",
    "auth": {
      "type": "none"
    },
    "api": {
      "type": "openapi",
      "url": "http://localhost:5003/openapi.yaml",
      "is_user_authenticated": false
    },
    "logo_url": "http://localhost:5003/logo.png",
    "contact_email": "legal@example.com",
    "legal_info_url": "http://example.com/legal"
  }

Server log

[2023-05-18 07:48:03 -0400] [15008] [INFO] 127.0.0.1:63218 GET /.well-known/ai-plugin.json 1.1 200 641 24988

C:\Users\Groot>curl -X OPTIONS "http://localhost:5003/openapi.yaml" -i
HTTP/1.1 200
allow: OPTIONS, HEAD, GET
content-type: text/html; charset=utf-8
content-length: 0
date: Thu, 18 May 2023 11:57:13 GMT
server: hypercorn-h11

Server log

[2023-05-18 07:57:13 -0400] [15008] [INFO] 127.0.0.1:63246 OPTIONS /openapi.yaml 1.1 200 0 9999

C:\Users\Groot>curl -X GET "http://localhost:5003/openapi.yaml"
openapi: 3.0.1
info:
  title: TODO Plugin
  description: A plugin that allows the user to create and manage a TODO list using ChatGPT. If you do not know the user's username, ask them first before making queries to the plugin. Otherwise, use the username "global".
  version: 'v1'
servers:
  - url: http://localhost:5003
paths:
  /todos/{username}:
    get:
      operationId: getTodos
      summary: Get the list of todos
      parameters:
      - in: path
        name: username
        schema:
            type: string
        required: true
        description: The name of the user.
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/getTodosResponse'
    post:
      operationId: addTodo
      summary: Add a todo to the list
      parameters:
      - in: path
        name: username
        schema:
            type: string
        required: true
        description: The name of the user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/addTodoRequest'
      responses:
        "200":
          description: OK
    delete:
      operationId: deleteTodo
      summary: Delete a todo from the list
      parameters:
      - in: path
        name: username
        schema:
            type: string
        required: true
        description: The name of the user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/deleteTodoRequest'
      responses:
        "200":
          description: OK

components:
  schemas:
    getTodosResponse:
      type: object
      properties:
        todos:
          type: array
          items:
            type: string
          description: The list of todos.
    addTodoRequest:
      type: object
      required:
      - todo
      properties:
        todo:
          type: string
          description: The todo to add to the list.
          required: true
    deleteTodoRequest:
      type: object
      required:
      - todo_idx
      properties:
        todo_idx:
          type: integer
          description: The index of the todo to delete.
          required: true

Server log

[2023-05-18 07:59:22 -0400] [15008] [INFO] 127.0.0.1:63250 GET /openapi.yaml 1.1 200 2337 19989

C:\Users\Groot>curl -X OPTIONS "http://localhost:5003/logo.png" -i
HTTP/1.1 200
allow: OPTIONS, HEAD, GET
content-type: text/html; charset=utf-8
content-length: 0
date: Thu, 18 May 2023 12:07:48 GMT
server: hypercorn-h11

Server log

[2023-05-18 08:07:48 -0400] [15008] [INFO] 127.0.0.1:63273 OPTIONS /logo.png 1.1 200 0 11997

C:\Users\Groot>curl -X GET "http://localhost:5003/logo.png"
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.

Server log

[2023-05-18 08:10:47 -0400] [15008] [INFO] 127.0.0.1:63281 GET /logo.png 1.1 200 1268 35994

C:\Users\Groot>curl -X OPTIONS "http://localhost:5003/todos/user" -i
HTTP/1.1 200
allow: DELETE, OPTIONS, HEAD, POST, GET
content-type: text/html; charset=utf-8
content-length: 0
date: Thu, 18 May 2023 12:12:24 GMT
server: hypercorn-h11

Server log

[2023-05-18 08:12:24 -0400] [15008] [INFO] 127.0.0.1:63287 OPTIONS /todos/user 1.1 200 0 9999

C:\Users\Groot>curl -X POST -H "Content-Type: application/json" -d "{\"todo\":\"Send flowers\"}" http://localhost:5003/todos/user?username=john
OK

Server log

[2023-05-18 08:30:42 -0400] [15008] [INFO] 127.0.0.1:63351 POST /todos/user 1.1 200 2 13999

C:\Users\Groot>curl -X GET http://localhost:5003/todos/user?username=john
["Buy flowers", "Send flowers"]

Server log

[2023-05-18 08:32:28 -0400] [15008] [INFO] 127.0.0.1:63356 GET /todos/user 1.1 200 31 11022

C:\Users\Groot>curl -X DELETE -H "Content-Type: application/json" -d "{\"todo_idx\":1}" http://localhost:5003/todos/user?username=johnn
OK

Server log

[2023-05-18 08:35:30 -0400] [15008] [INFO] 127.0.0.1:63361 DELETE /todos/user 1.1 200 2 14014

EDIT May 19,2023

Since the OpenAI TODO API spec (openapi.yml) is an OpenAPI (not to be confused with OpenAI) and Jan W. created a SWI-Prolog repository some years ago for OpenAPI will give it a try.

One really nice feature, cross my fingers, is that given an spec.yaml file this can generate the code for an SWI-Prolog HTTP server, e.g. swi-openapi --server=server.pl spec.yaml (ref).


EDIT May 20, 2023

The SWI-Prolog OpenAPI code (ref) was created for Linux and as I use Windows ran into a problem with library(uri) not working as expected with Windows. The specific problem AFAIK is that uri_components/2 is converting
'file:///c%3A/users/Groot/projects/swi-prolog%20openapi/examples/petstore/petstore.yaml#/components/schemas/Pets' into

uri_components(file,'','/c%3A/users/Groot/projects/swi-prolog%20openapi/examples/petstore/petstore.yaml',A,'/components/schemas/Pets')

with the Path component being invalid on Windows, e.g. starts with /. Not even sure if there is more problems after that but stopped at that point.

Unrelated note - I read your glossary, great work. I have a simple correction - Byrd Box was created by a man named Lawrence Byrd not Rodney Byrd.

1 Like

What helps is understanding the design philosophy of JSON REST.

I guess one can build a SWI-Prolog server that acts as a ChatGPT relay,
accepting some request, and in turn making a request on the OpenAI API.
So the bearer token from OpenAI API remains in the SWI-Prolog relay,

and doesn’t become visible to the end user browser client. It seems it
is possibly to make the afforementioned request via http_open/3, since
server side no CORS in relation to the OpenAI API needs to be in effect.

This example code worked for me:

:- use_module(library(http/http_open)).
:- use_module(library(http/json)).

quizzswi :-
   atom_json_term(Request, _{model:'text-davinci-003',
      prompt:'Generate a single random multiple choice quizz about Switzerland',
      max_tokens:100,
      temperature:0.7,
      n:1}, []),
   http_open('https://api.openai.com/v1/completions', Stream, [authorization(
        bearer('###########')),
        post(atom('application/json', Request))]),
   json_read(Stream, Response),
   close(Stream),
   write(Response), nl.

You need to replace ########### by your API token. It gives me:

/* SWI-Prolog 9.1.9 */
?- quizzswi.
json([id=cmpl-7J4ek6NK0ICXXKv0P69F7uHWOx3jg,object=text_completion,
created=1684780486,model=text-davinci-003,choices=[json([text=

Q. What is the official language of Switzerland? 
A. A. French 
B. German 
C. Italian 
D. Swiss German,index=0,logprobs= @(null),finish_reason=stop])],
usage=json([prompt_tokens=10,completion_tokens=35,total_tokens=45])])
true.

Have Fun!

One would probably hand over the generator part to Swagger. Not sure
whether this is possible, how does Swagger implement generators?
Is the value "prolog" for the place holder <language> supported?

So that it can be offered through this end-point:

http://generator.swagger.io/api/gen/clients/<language>

The POST request payload is:

var postBody = {
        spec: swaggerObj,
        options: {
            modelPropertyNaming: 'camelCase',
            apiPackage: 'api.clients.settings',
            modelPackage: 'api.clients.settings'
        }
    };

But besides Swagger, there is now a booming community around langchain:

LangChain - Wikipedia
LangChain is a software development framework
designed to simplify the creation of applications
using large language models (LLMs). As a language
model integration framework, LangChain’s use-cases
largely overlap with those of language models in
general, including document analysis and summarization,
chatbots, and code analysis.

LangChain was launched in October 2022 as an
open source project by Harrison Chase, while
working at machine learning startup Robust
Intelligence. The project quickly garnered
popularity, with improvements from hundreds
of contributors on GitHub
https://blog.langchain.dev/

Whats their approach?

I also found an old CL Cloud paper by Torbjörn Lager, which fiddled with JSON.

But Torbjörn Lager is emeritius now?