-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b3a86f6
Showing
51 changed files
with
19,216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
## Node | ||
|
||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
.pnpm-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Snowpack dependency directory (https://snowpack.dev/) | ||
web_modules/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional stylelint cache | ||
.stylelintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variable files | ||
.env | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
.env.local | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
.parcel-cache | ||
|
||
# Next.js build output | ||
.next | ||
out | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and not Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# vuepress v2.x temp and cache directory | ||
.temp | ||
.cache | ||
|
||
# Docusaurus cache and generated files | ||
.docusaurus | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
|
||
# Stores VSCode versions used for testing VSCode extensions | ||
.vscode-test | ||
|
||
# yarn v2 | ||
.yarn/cache | ||
.yarn/unplugged | ||
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
printWidth = 99 | ||
tabWidth = 2 | ||
singleQuote = true | ||
arrowParens = 'avoid' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# React/Redux apps powered by ChatGPT! | ||
|
||
*See the [blog post](https://spindas.dreamwidth.org/4207.html) for more information!* | ||
|
||
This is an experiment in prototyping webapps with [ChatGPT](https://chat.openai.com) as a universal Redux reducer. The idea is you implement your app's frontend in [React](https://reactjs.org/) and [Redux](https://redux.js.org/), but skip initially implementing the backend and Redux reducers (i.e., the business logic). Instead, your app's initial state and actions are fed through the AI, which predicts future states automagically. After training the AI by interacting with your frontend, you can even ask it to implement the reducer function for you. | ||
|
||
This repo has multiple parts: | ||
|
||
- [`react-redux-chatgpt/`](react-redux-chatgpt) - The main event. A client-side plugin implementing a Redux store whose actions are reduced by ChatGPT. | ||
- [`counter-example/`](counter-example) - The basic React/Redux counter app example, with the reducing handled by ChatGPT. | ||
- [`todomvc-example/`](todomvc-example) - A more advanced example, implementing the [TodoMVC](https://todomvc.com/) todo app challenge with React/Redux and ChatGPT. | ||
- [`chatgpt-relay-server/`](chatgpt-relay-server) - A simple REST API server for proxying messages through ChatGPT. | ||
|
||
## Watch the Demo Videos! | ||
|
||
### Counter | ||
|
||
[![Counter demo video on YouTube](https://img.youtube.com/vi/u9rE7sfCmj8/mqdefault.jpg)](https://www.youtube.com/watch?v=u9rE7sfCmj8) | ||
|
||
### TodoMVC | ||
|
||
[![Demo video on YouTube](https://img.youtube.com/vi/GgR1QiPPie4/mqdefault.jpg)](https://www.youtube.com/watch?v=GgR1QiPPie4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Copyright (c) 2022 Michael Smith <[email protected]> (https://spinda.net) | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any purpose | ||
with or without fee is hereby granted. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||
THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# `chatgpt-relay-server` | ||
|
||
*See the [blog post](https://spindas.dreamwidth.org/4207.html) for more information!* | ||
|
||
[ChatGPT](https://chat.openai.com) doesn't have an official API yet, so this is a simple REST API server that proxies messages to a ChatGPT session running in a [Puppeteer](https://pptr.dev)-controlled browser instance (by way of the [`chatgpt`](https://www.npmjs.com/package/chatgpt) package). For ease of experimentation, the REST API server is [CORS-enabled](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), ***and will respond to requests from any origin, without authentication***. | ||
|
||
***Use at your own risk!*** I'm not responsible if this gets your account banned! | ||
|
||
## Usage | ||
|
||
[Google Chrome](https://www.google.com/chrome/) must be installed on your system, as required by the [`chatgpt`](https://www.npmjs.com/package/chatgpt) package. | ||
|
||
`chatgpt-relay-server` accepts configuration via environment variables: | ||
|
||
- `OPENAI_EMAIL`: Email address to auto-populate into the login form. If not supplied via environment variable, will be prompted for interactively. | ||
- `OPENAI_PASSWORD`: Password to auto-populate into the login form. If not supplied via environment variable, will be prompted for interactively. | ||
- `OPENAI_IS_GOOGLE_LOGIN`: Whether this is a Google account or an OpenAI account. Accepts anything truthy (`true`, `1`, ...) or falsey (`false`, `0`, ...) when parsed as JSON. If not supplied via environment variable, will be prompted for interactively. | ||
- `CHATGPT_RELAY_SERVER_HOST`: Host for the REST API server to bind to. *Default:* `127.0.0.1` | ||
- `CHATGPT_RELAY_SERVER_PORT`: Host for the REST API server to bind to. *Default:* `3000` | ||
|
||
You can also supply additional environment variables containing tokens for CAPTCHA-bypassing services, as described in the documentation for the [`chatgpt`](https://github.com/transitive-bullshit/chatgpt-api/tree/77d1d8e0896a3ed087c70c0b71ed2091eb262717#captchas) package. | ||
|
||
When running the server on the command line, it will first prompt you interactively for any configuration without a default not supplied via environment variables, and will then start up a browser instance and attempt to log into ChatGPT. You may have to complete one or more CAPTCHAs. On successful login, the REST API server will launch and start serving requests. | ||
|
||
## API | ||
|
||
### POST `/query` | ||
|
||
**Request:** A JSON object with the following fields: | ||
|
||
- `prompt`: The prompt to pass to ChatGPT. | ||
- `conversationId`: *(optional)* The ID of the conversation thread this message should be a part of, if continuing an existing conversation. | ||
- `parentMessageId`: *(optional)* The ID of the message this new message is in response to, if continuing an existing conversation. Can be used to fork off multiple conversation sub-threads. | ||
|
||
**Success Response:** A JSON object with the following fields: | ||
|
||
- `response`: The text of the response from ChatGPT. Usually Markdown. | ||
- `conversationId`: The ID of the conversation containing the response message. Retain to continue the thread. | ||
- `messageId`: The ID of the response message. Retain to continue the thread. | ||
|
||
**Failure Response:** A JSON object with the following fields: | ||
|
||
- `error`: The error message. | ||
|
||
## Development | ||
|
||
[pnpm](https://pnpm.io/) is the recommended package manager. Available scripts: | ||
|
||
- `pnpm run fmt:check` - Check code style. | ||
- `pnpm run fmt:write` - Auto-format all code. | ||
- `pnpm run server:start` - Run the REST API server. | ||
|
||
## License | ||
|
||
[0BSD](LICENSE) | ||
|
||
### Contribution | ||
|
||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you shall be licensed as above, without any additional terms or conditions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "chatgpt-relay-server", | ||
"version": "0.1.0", | ||
"private": true, | ||
"description": "Simple REST API server for proxying commands to ChatGPT", | ||
"author": "Michael Smith <[email protected]> (https://spinda.net)", | ||
"license": "0BSD", | ||
"homepage": "https://github.com/spinda/react-redux-chatgpt/tree/main/chatgpt-relay-server#readme", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/spinda/react-redux-chatgpt.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/spinda/react-redux-chatgpt/issues" | ||
}, | ||
"keywords": [ | ||
"chatgpt", | ||
"unofficial", | ||
"rest", | ||
"api", | ||
"server" | ||
], | ||
"bin": "server.mjs", | ||
"scripts": { | ||
"fmt:check": "prettier --check .", | ||
"fmt:write": "prettier --write .", | ||
"server:start": "node server.mjs" | ||
}, | ||
"dependencies": { | ||
"body-parser": "^1.20.1", | ||
"chatgpt": "^3.3.1", | ||
"cors": "^2.8.5", | ||
"dotenv": "^16.0.3", | ||
"express": "^4.18.2", | ||
"inquirer": "^9.1.4", | ||
"puppeteer": "^19.4.1" | ||
}, | ||
"devDependencies": { | ||
"prettier": "^2.8.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#!/usr/bin/env node | ||
|
||
// vim: set tw=99 ts=2 sts=2 sw=2 et: | ||
|
||
'use strict'; | ||
|
||
import * as dotenv from 'dotenv'; | ||
dotenv.config(); | ||
|
||
import bodyParser from 'body-parser'; | ||
import { ChatGPTAPIBrowser, ChatGPTError } from 'chatgpt'; | ||
import cors from 'cors'; | ||
import express from 'express'; | ||
import inquirer from 'inquirer'; | ||
|
||
const credentials = {}; | ||
const questions = []; | ||
|
||
if (Object.hasOwn(process.env, 'OPENAI_EMAIL')) { | ||
credentials.email = process.env.OPENAI_EMAIL; | ||
} else { | ||
questions.push({ name: 'email', message: 'OpenAI Email:' }); | ||
} | ||
|
||
if (Object.hasOwn(process.env, 'OPENAI_PASSWORD')) { | ||
credentials.password = process.env.OPENAI_PASSWORD; | ||
} else { | ||
questions.push({ name: 'password', message: 'OpenAI Password:', type: 'password', mask: true }); | ||
} | ||
|
||
if (Object.hasOwn(process.env, 'OPENAI_IS_GOOGLE_LOGIN')) { | ||
credentials.isGoogleLogin = !!JSON.parse(process.env.OPENAI_IS_GOOGLE_LOGIN); | ||
} else { | ||
questions.push({ | ||
name: 'isGoogleLogin', | ||
message: 'Is this a Google login?', | ||
type: 'confirm', | ||
default: false, | ||
}); | ||
} | ||
|
||
if (questions.length > 0) { | ||
Object.assign(credentials, await inquirer.prompt(questions)); | ||
} | ||
|
||
console.log('Launching browser for ChatGPT session...'); | ||
const client = new ChatGPTAPIBrowser(credentials); | ||
await client.initSession(); | ||
|
||
const app = express(); | ||
|
||
app.use(bodyParser.json()); | ||
app.use(cors()); | ||
|
||
app.post('/query', async (req, res) => { | ||
if (typeof req.body !== 'object' || !req.body) { | ||
res.status(400).json({ error: 'Request must be a JSON object' }); | ||
return; | ||
} | ||
if (typeof req.body.prompt !== 'string') { | ||
res.status(400).json({ error: 'Request must include string key "prompt"' }); | ||
return; | ||
} | ||
|
||
const options = {}; | ||
if (req.body.conversationId) { | ||
options.conversationId = req.body.conversationId; | ||
} | ||
if (req.body.parentMessageId) { | ||
options.parentMessageId = req.body.parentMessageId; | ||
} | ||
|
||
const prompt = req.body.prompt; | ||
console.log('<', options, prompt); | ||
let result; | ||
try { | ||
result = await client.sendMessage(req.body.prompt, options); | ||
} catch (error) { | ||
if (error instanceof ChatGPTError) { | ||
console.error('ChatGPT error:', error); | ||
res.status(500).json({ error: error.message }); | ||
return; | ||
} | ||
} | ||
console.log('>', result); | ||
res.json({ | ||
response: result.response, | ||
conversationId: result.conversationId, | ||
messageId: result.messageId, | ||
}); | ||
}); | ||
|
||
const host = Object.hasOwn(process.env, 'CHATGPT_RELAY_SERVER_HOST') | ||
? process.env.CHATGPT_RELAY_SERVER_HOST | ||
: '127.0.0.1'; | ||
const port = Object.hasOwn(process.env, 'CHATGPT_RELAY_SERVER_PORT') | ||
? JSON.parse(process.env.CHATGPT_RELAY_SERVER_PORT) | ||
: 3000; | ||
const server = app.listen(port, host, () => { | ||
const address = server.address(); | ||
console.log(`Server listening on http://${address.address}:${address.port}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Copyright (c) 2022 Michael Smith <[email protected]> (https://spinda.net) | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any purpose | ||
with or without fee is hereby granted. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||
THIS SOFTWARE. |
Oops, something went wrong.