Group based ChatGPT API backend
Proxy GPT is a group based API backend for the ChatGPT API. It enables you to create teams and group chat, perform user signup and authentication, and includes a full chat API for prompting and streaming responses. All requests are forwarded using a shared key. Requests are logged in a database for filtering, auditing, etc.
- OpenAI shared proxy
- User authentication
- 1:1 and 1:N Chat API
- SQLite or Postgres storage
- In-memory or Redis caching
- Proxy request and event log
- Prompt context forwarding
- Websocket and SSE support
Built as a Go binary
go build -o proxy-gpt ./main.go
Requires an API key as env var API_KEY
for access to OpenAI.
API_KEY=xxx proxy-gpt
Runs on 8080, proxies /v1/*
to OpenAI verbatim
curl http://localhost:8080/v1/models
See OpenAI API reference for details
To use Azure's OpenAI service, provide the API_URL
environment variable in addition to the API_KEY
API_URL=https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/completions?api-version=2022-12-01
To use a custom url that supports the OpenAI API specify the API_URL
as mentioned above for azure
e.g custom local mocked LLM proxy
API_URL=http://localhost:9090
The API supports session based authentication using a sess
cookie header or Authorization: Bearer $TOKEN
header.
Example of an API call using authentication header
curl -H 'Authorization: Bearer ZDU0Nzg5ZTctMzRkMy00ZmNlLTkyYTgtZTQwYzIxZDE1YWJm' \
http://localhost:8080/v1/models
Example of a cookie based call
curl --cookie 'sess=ZDU0Nzg5ZTctMzRkMy00ZmNlLTkyYTgtZTQwYzIxZDE1YWJm' \
http://localhost:8080/v1/models
See the User API section for more on signup, login, etc.
A user admin command line is available in cmd/admin
It requires access to the database via the DB_ADDRESS
env var (if postgres is used)
List users
admin list
Get user by id
admin user user-1
Reset password
admin reset foobar Password1
Context is cached in memory by default for up-to 10 prior prompts. This can be modified by request to /chat/prompt
with
the context
field set to an integer above 0. The cache is built from the database of prior messages if no context is in
memory.
Redis can be used as an alternative persistent cache. This will enable horizontally scaling the proxy alongside the use of
the external database like postgres. To do so specify the REDIS_ADDRESS
env var with the connection string.
REDIS_ADDRESS=redis://localhost:6379
Events are stored in a database. Sqlite is used by default (local proxy.db file).
To use Postgres specify the URL as DB_ADDRESS
env var
DB_ADDRESS=postgresql://user:pass@localhost:5432/proxy
Requires the following privileges assuming user is asim
create database proxy;
create user gptio with encrypted password 'foobar';
grant all privileges on database proxy to gptio;
GRANT ALL ON SCHEMA public to gptio;
- chats - stores the chat history
- chat_users - users in the chat by id
- events - proxy events/requests/login/etc
- messages - message history within chats
- groups - all the group information
- group_members - group members by id
- users - user login information
- sessions - current login sessions
Signup and authentication is handled via cookies or token based header
The following endpoints are used
/user/signup
- register a user with username/password fields/user/login
- login with username/password fields/user/logout
- call withsess
cookie header set
A user can register via /user/signup
endpoint
curl http://localhost:8080/user/signup \
-d "username=asim&password=bazbar"
Login via /user/login
with post form data. Will set the cookie sess
with an opaque token and return as json
curl -vv http://localhost:8080/user/login \
-d "username=asim&password=bazbar"
Logout via /user/logout
with sess
cookie header set
curl --cookie "sess=YWEzZTlkYTUtZWRhNi00ODY3LWIyNzYtZGFhNGRhMmRlNmEx" \
http://localhost:8080/user/logout
Alternatively using a token
curl -XPOST http://localhost:8080/user/logout \
-d '{"token": "YWEzZTlkYTUtZWRhNi00ODY3LWIyNzYtZGFhNGRhMmRlNmEx"}'
Based on this login session calls to the /v1/*
endpoint can be made via a sess
cookie set in the header.
Stored in browser cookies or via curl --cookie
or it can be used via the Authorization: Bearer $TOKEN
header.
Example of API call
curl -H 'Authorization: Bearer ZDU0Nzg5ZTctMzRkMy00ZmNlLTkyYTgtZTQwYzIxZDE1YWJm' \
http://localhost:8080/v1/models
Example of a cookie based call
curl --cookie 'sess=ZDU0Nzg5ZTctMzRkMy00ZmNlLTkyYTgtZTQwYzIxZDE1YWJm' \
http://localhost:8080/v1/models
You can otherwise specify the username:token in the URL as basic auth.
The chat API is a slim layer on top of OpenAI endpoints to store conversations locally. It takes standard POST requests and returns JSON responses.
/chat/create
- creates a new chat (returns the chat id asid
)/chat/delete
- deletes a chat, takesid
param (returns nil response)/chat/index
- lists all chats for a given user (returnschats
as an array)/chat/read
- provides chat history, takesid
as param (returnschat
andmessages
array)/chat/prompt
- make a request usingprompt
command andid
(returnsreply
text and store in db)/chat/stream
- stream via SSE or websockets using chatid
andtoken
as params`/chat/user/add
withchat_id
anduser_id
/chat/user/remove
withchat_id
anduser_id
Create a chat and specify the model as gpt-3
or gpt-4
curl http://localhost:8080/chat/create \
-d "name=foobar&model=gpt-3"
To add users to the chat
curl http://locahost:8080/chat/user/add \
-d "chat_id=chat-1&user_id=user-1"
Send a message to the chat
curl http://localhost:8080/chat/prompt \
-d "id=chat-1&prompt=tell+me+about+spain"
The request will be made inline and response provided
To stream messages asynchonrously specify stream=bool
to the /chat/prompt
endpoint.
Messages will be streamed over the /chat/stream
endpoint which you can separately
subscribe to using server sent events or websockets.
curl http://localhost:8080/chat/stream \
-d 'id=chat-1'
Specify id
for the chat ID you want to stream from. Messages will be received in the
format below. Where partial
is set to true, this is the partial response of separated
words from the model. When this is set to false, the full message will be present.
Stream message format
{
"message": {"id": "uuid", "prompt": "your prompt", "reply": "words ..." },
"partial": true
}
Send messages to the chat which are not sent to the AI or used as context
later with the otr=true
field when calling /chat/prompt
.
The group API enables you to create organisations that have their own members and chats.
curl http://localhost:8080/group/create \
-d "name=foobar&description=my+awesome+group"
curl http://localhost:8080/group/members/add \
-d "group_id=group-1&user_ids=user-1"
curl http://localhost:8080/chat/create \
-d "name=foobar&group_id=group-1"
A full list of API endpoints
// chat api
"/chat/create": ChatCreate,
"/chat/read": ChatRead,
"/chat/update": ChatUpdate,
"/chat/delete": ChatDelete,
"/chat/prompt": ChatPrompt,
"/chat/index": ChatIndex,
"/chat/stream": ChatStream,
"/chat/user/add": ChatUserAdd,
"/chat/user/remove": ChatUserRemove,
// group api
"/group/create": GroupCreate,
"/group/delete": GroupDelete,
"/group/read": GroupRead,
"/group/update": GroupUpdate,
"/group/index": GroupIndex,
"/group/members": GroupMembers,
"/group/members/add": GroupMembersAdd,
"/group/members/remove": GroupMembersRemove,
// user api
"/user/signup": UserSignup,
"/user/login": UserLogin,
"/user/logout": UserLogout,
"/user/read": UserRead,
"/user/update": UserUpdate,
"/user/session": UserSession,
"/user/password/update": UserPasswordUpdate,
The API itself supports two formats, either POST form encoded data, or application/json
In the event you send post data, the request looks something like
curl http://localhost:8080/user/signup \
-d "username=foo&password=bar"
In the case you are using JSON then something like the following
curl http://localhost:8080/user/signup \
-H 'Content-Type: application/json'
-d '{"username": "foo", "password": "bar"}'
Responses are all of the format application/json
- Generate API Docs using Swag
- Saving prompts for sharing/reuse
- Example web app or api usage
- Basic SDKs for js, go, etc
- More documentation!!!