From 046f508bf81e951519b7c129a6eab927be7facd6 Mon Sep 17 00:00:00 2001 From: Keith Schacht Date: Fri, 26 Apr 2024 16:20:03 -0500 Subject: [PATCH] README for v0.6 --- README.md | 80 +++++++++++++++++++++++++------------- public/logo_full_blue.jpg | Bin 0 -> 23037 bytes 2 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 public/logo_full_blue.jpg diff --git a/README.md b/README.md index 645cd7a8b..bd7a0a0fc 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,34 @@ -![](./public/logo_full_blue.png) +![](./public/logo_full_blue.jpg) -# HostedGPT +# HostedGPT v0.6 -HostedGPT is a free, open-source chat interface in the style of ChatGPT. You can run it on any server or even your own computer. It's a Ruby on Rails app. Just bring your own OpenAI API key. All the core functionality of ChatGPT is already working (e.g. GPT-3.5 and GPT-4, starting new conversations, streaming responses, asking about attached images, etc). The main thing missing is the mobile app but that's coming soon and it already works well as a mobile web app. +HostedGPT is a free, open-source alternative to ChatGPT. It's a Ruby on Rails app so you can run it on any server or even your own computer. Just bring your own OpenAI API key. -Plus, this app has extra features. You can use Anthropic's Claude 3 in the same interface as GPT-4. You can also switch assistants in the middle of a conversation. +This app is designed to be incredibly easy for ChatGPT users to switch. All the features you expect are here plus it supports Claude 3 and GPT-4 in a single app. You can also switch assistants in the middle of a conversation! -This project is actively looking for contributors to help make it great. The goal is for *every* feature that exists in ChatGPT to exist in this app along with many improvements. +This project is led by an experienced rails developer, but I'm actively looking for contributors to help! -### Some favorite features of HostedGPT +### Top features of HostedGPT -* **Enjoy chat history, but without your private conversations being used for training!** +* **Your private conversations are not being used for training!** +ChatGPT uses your private conversations history to train its models. [OpenAI disclosed this in this article](https://help.openai.com/en/articles/7730893-data-controls-faq), and if you disable it then you lose all your conversation history! +* **Use GPT-4 and Claude 3 without two $20 / month subscriptions, you don't even need a single $20 subscription!** You only pay as much as you use. HostedGPT costs nothing so you just pay for your GPT-4 and Claude 3 API usage. +* **A very polished interface with great mobile support** You can "install" on your mobile phone by opening your instance of HostedGPT in your Safari browser, tapping the Share icon, and then selecting "Add to Home Screen". +* **You will never hit the '*You've reached the current usage cap*' errors**. - Did you know that all your private, personal past conversations in the left sidebar are allowed to be used for OpenAI training? [Disclosed in this OpenAI article.](https://help.openai.com/en/articles/7730893-data-controls-faq) HostedGPT excludes your history from OpenAI training. -* **Don't commit yourself to $20 per month when you may not use ChatGPT a lot.** You only pay as much as you use! -* **You will never hit the '*You've reached the current usage cap for GPT-4*'.** You pay per mesage based on the API rates so you can keep using it as much as you want. -* **Use Claude 3 and soon Gemini in the same app as GPT-4**. You won't have your conversation history split across three apps and have different interfaces for each one. - -### Watch a demo of the app: +### Watch a short demo [![](https://p425.p0.n0.cdn.zight.com/items/qGubwRKr/c4a119a9-254d-454a-b602-610b428ee769.jpg)](https://www.youtube.com/watch?v=m1UfKGWEhFs) # Table of Contents -- [Set Up Live App](#set-up-live-app) -- [Contribute as a Developer](#contribute-as-a-developer) +- [Setup the app](#setup-the-app) +- [Contribute as a developer](#contribute-as-a-developer) +- [Changelog](#changelog) -# Set Up Live App +# Setup the app You can deploy a full version of HostedGPT to the hosting service, Render, for free. This free app works for 90 days and then the database will stop working. You will need to upgrade to a paid version of the database which is $7 / month. Alternatively, you can also run it off your local computer. Jump down to the [Developer Instructions](#contribute-as-a-developer) if you want to run it locally. @@ -46,7 +46,7 @@ You can deploy a full version of HostedGPT to the hosting service, Render, for f **NOTE: After 15 minutes of not using the app your Render server will pause. Next time you visit the first request will auto-resume the server, but this resume is slow. If this annoys you, upgrade Render for $7 per month:** -1. Go to your [Render Dashboard](https://dashboard.render.com/) +1. To upgrade, go to your [Render Dashboard](https://dashboard.render.com/) 2. Click "HostedGPT" or whatever you named your Web Service 3. Click "Upgrade" and select $7 per month @@ -54,17 +54,17 @@ You can deploy a full version of HostedGPT to the hosting service, Render, for f 1. If you encountered an error while waiting for the services to be deployed on Render, click **Dashboard** at the top of the Render screen and click the Service that failed. 2. It should take you to the Events section and the top event should explain the error. It will probably contain a link to click to the **deploy logs** -3. Scroll back up through the logs and find any instances of errors. [Open a new Issue for us](https://github.com/allyourbot/hostedgpt/issues/new) and share details. +3. Scroll back up through the logs and find any instances of errors. [Start a new discussion](https://github.com/allyourbot/hostedgpt/discussions/new?category=general) and share details. 4. When you are ready to try Render again, it's best to do the following: 5. First, ensure your repo is caught up. Open your fork in github, click the Sync Fork button so that any bug fixes are pulled in. 6. Second, in Render navigate to the Dashboard, Bluebrint, and Env Groups and delete any details associated with **hostedgpt** 7. Now you can go back to your repo and click **Deploy to Render** -# Contribute as a Developer +# Contribute as a developer -We welcome contributors! After you get your developoment environment setup, review the list of Issues. We organize the issues into Milestones and are currently working on v0.8. [View 0.8 Milestone](https://github.com/allyourbot/hostedgpt/milestone/5). Look for any issues tagged with **Good first issue** and add a comment so we know you're working on it. +We welcome contributors! After you get your developoment environment setup, review the list of Issues. We organize the issues into Milestones and are currently working on v0.7. [View 0.7 Milestone](https://github.com/allyourbot/hostedgpt/milestone/6). Look for any issues tagged with **Good first issue** and add a comment so we know you're working on it. -## Setting up Development +## Setting up development The easiest way to get up and running is to use the provided docker compose workflow. The only things you need installed on your computer are Docker and Git. @@ -73,7 +73,7 @@ The easiest way to get up and running is to use the provided docker compose work 3. `cd` into your clone. 4. Run `docker compose up` to start the app. 5. Open [http://localhost:3000](http://localhost:3000) and register as a new user. -6. Run tests: `docker compose run base rails test` +6. Run tests: `docker compose run base rails test` The app has comprehensive test coverage. 7. Open the rails console: `docker compose run base rails console` 8. Run a psql console: `docker compose run base psql` @@ -87,7 +87,35 @@ HostedGPT requires these services to be running: 1. `cd` into your local repository clone 2. `asdf install` to install the correct ruby version -4. `bundle install` to install ruby gems -5. `bin/rails db:setup` < Note: This will load the sample fixture data into your database -6. `bin/dev` < Starts up all the services -5. Open [http://localhost:3000](http://localhost:3000) and register as a new user. +3. `bundle install` to install ruby gems +4. `bin/rails db:setup` < Note: This will load the sample fixture data into your database +5. `bin/dev` < Starts up all the services +6. Open [http://localhost:3000](http://localhost:3000) and register as a new user +7. `bin/rails test` and `bin/rails test:system` to run the comprehensive tests + +# Changelog + +(Top features being developed for v0.7: voice support, Gemini Pro, pin conversations) + +v0.6 - Released on 4/26/2024 + +* Abort a long AI reply by clicking stop or simply "interrupting" it with a new question +* Edit your messages and view previous versions with the left & right arrows +* Support PWA (progressive web app) install for mobile phones (open in Safari, tap share then "Add to Home") +* Show a helpful error messages when the API responds with an error +* Re-generate an AI responses and even switch to a different assistant +* Copy-to-clipboard button (and keyboard shortcut) for messages and markdown sections +* Markdown is properly rendered in AI responses (and your own chats) +* Include images in your messages (click icon, drag & drop, or copy & paste into message) + +v0.5 - Released on 2/14/2024 + +* Anthropic's Claude 3 models can be used alongside GPT-4 and GPT-3 +* Dark mode theme is now supported (it switches automatically with your OS) +* Full keyboard shortcuts have been added (press ? to see them) +* AI assistants can be given custom instructions (under Profile > Settings) +* Delete conversations +* Ability to edit conversation title +* Conversations are automatically titled +* Sidebar can be closed +* AI responses stream in diff --git a/public/logo_full_blue.jpg b/public/logo_full_blue.jpg new file mode 100644 index 0000000000000000000000000000000000000000..80ea150c0bc1b0a64dfe0b67ec885db6f903eeae GIT binary patch literal 23037 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 literal 0 HcmV?d00001