{"id":13791190,"url":"https://github.com/paul-gauthier/easy-chat","last_synced_at":"2025-03-17T13:31:30.004Z","repository":{"id":149510976,"uuid":"621836558","full_name":"paul-gauthier/easy-chat","owner":"paul-gauthier","description":"A ChatGPT UI for young readers, written by ChatGPT","archived":false,"fork":false,"pushed_at":"2023-04-05T21:05:16.000Z","size":1413,"stargazers_count":68,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-28T00:36:31.675Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://paul-gauthier.github.io/easy-chat/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paul-gauthier.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-31T13:46:33.000Z","updated_at":"2024-12-11T09:34:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"c9ba22d9-8a9f-44df-b182-f1fa5b7e504b","html_url":"https://github.com/paul-gauthier/easy-chat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-gauthier%2Feasy-chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-gauthier%2Feasy-chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-gauthier%2Feasy-chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paul-gauthier%2Feasy-chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paul-gauthier","download_url":"https://codeload.github.com/paul-gauthier/easy-chat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243864809,"owners_count":20360360,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T22:00:57.101Z","updated_at":"2025-03-17T13:31:29.495Z","avatar_url":"https://github.com/paul-gauthier.png","language":"JavaScript","funding_links":[],"categories":["Meta","JavaScript"],"sub_categories":[],"readme":"# Easy Chat\n\n[Easy Chat](https://paul-gauthier.github.io/easy-chat/)\nis a user interface for ChatGPT, designed specifically for young readers.\nAlmost all the code for Easy Chat was written by ChatGPT.\n\n## Features\n\n- Typography, layout and text spacing which is helpful for young, early or struggling readers.\n- Large, easy-to-read text in the Open Dyslexic font.\n- No incremental \"live typing\" of the ChatGPT response, which is distracting when trying to read. Responses display when they are fully loaded.\n- Text-to-speech of individual words by clicking on any word.\n- Text-to-speech of entire passages with Immersive Reading (highlights each word as it is read aloud at a moderate reading speed). Click on the speaker icons.\n- A system prompt that tells ChatGPT it is speaking to a child and to use common words, short sentences and short paragraphs.\n\n![Screenshot of Easy Chat](screenshot.gif)\n\n## Usage\n\nTry it out here: [Easy Chat](https://paul-gauthier.github.io/easy-chat/)\n\n## Created by ChatGPT\n\nAlmost all the code in this repository was written by ChatGPT, using what I think is a novel workflow. \n\nI started by asking it to create the html for a simple chat app, with embedded css and js. After that, I just asked for changes, bug fixes, new features and improvements in plain English.\n\nFor each change, I passed ChaptGPT the change request and a copy of the **entire codebase**.\nIt returned a new copy of the codebase, with the requested changes. \nChatGPT figured out how to make the requested changes, what parts of the code needed to be modified and what modifications to make.\nI reviewed the diffs it generated, and either accepted or rejected the proposed changes. If the changes weren't acceptable, I discarded them and improved my request to be more specific or explicit -- and tried again.\n\nIn essence, I worked with ChatGPT like it was a junior web developer.\n\n### All code in, all code out\n\nI have starting thinking about this as an \"all code in, all code out\" pattern:\n\n  - Send all the (relevant) code to GPT along with a change request\n  - Have it reply with all the code, modified to include the requested change\n  - Automatically replace the original files with the GPT edited versions\n  - Use git diff, etc to review and either accept/reject the changes.\n  \nGPT is **significantly** better at modifying code when following this \"all code in, all code out\" pattern. This pattern has downsides: you can quickly exhaust the context window, it's slow waiting for GPT to re-type your code (most of which it hasn't modified) and of course you're running up token costs. But the ability of GPT to understand and execute high level changes to the code is far superior with this approach.\n\nI have tried quite a large number of alternative workflows. Outside the \"all code in/out\" pattern, GPT gets confused, makes mistakes, implements the requested change in different ways in different sections of the code, or just plain fails.\n\nIf you're asking for self contained modifications to a single function, that's all the code that needs to go in/out.\nOn the other side of the spectrum, GPT built this entire webapp using this pattern by repeatedly feeding it all the html/css/js along with a series of feature requests. Many feature requests required coordinated changes across html/css/js.\n\n### Example prompts\n\nMost of my prompts were basically feature requests, like you might file in a JIRA ticket.\nHere's an example prompt:\n\n\u003e Use text-to-voice to speak the highlighted word.\n\nWhich resulted in\n[these changes](commits.md#user-content-62e0862ce0cf1017082e30ec7fa4034cfaf80137) to the code:\n\n```\ndiff --git a/chat.html b/chat.html\nindex 4ed5668..7d3d563 100644\n--- a/chat.html\n+++ b/chat.html\n@@ -206,8 +206,17 @@\n                         const highlightedWords = chatBox.querySelectorAll('.highlight');\n                         highlightedWords.forEach(word =\u003e word.classList.remove('highlight'));\n                         event.target.classList.add('highlight');\n+                        const textToSpeak = event.target.textContent;\n+                        const speech = new SpeechSynthesisUtterance(textToSpeak);\n+                        speechSynthesis.speak(speech);\n                     }\n                 });\n+\n+                /* New code for text-to-speech */\n+                const speak = (text) =\u003e {\n+                    const speech = new SpeechSynthesisUtterance(text);\n+                    speechSynthesis.speak(speech);\n+                };\n        \u003c/script\u003e\n \u003c/body\u003e\n \u003c/html\u003e\n```                        \n\nHere is another prompt, this time describing a bug and asking for a bug fix:\n\n\u003e The text-to-speech is saying \"speaker outputting high volume\" at the end of every message.\n\u003e I think it is reading the unicode speaker icon aloud.\n\u003e It should not.\n\u003e Fix this bug.\n\nWhich produced\n[this simple fix](commits.md#user-content-2e73c58dccc4336f53264dd6b9b5093cf88b0d20):\n\n```\ndiff --git a/chat.html b/chat.html\nindex b9f8ba3..8f6de60 100644\n--- a/chat.html\n+++ b/chat.html\n@@ -207,7 +207,7 @@\n\n                 /* New code for word highlighting */\n                 chatBox.addEventListener('click', (event) =\u003e {\n-                    if (event.target.tagName === 'SPAN') {\n+                    if (event.target.tagName === 'SPAN' \u0026\u0026 !event.target.classList.contains('speaker')) {\n                         const highlightedWords = chatBox.querySelectorAll('.highlight');\n                         highlightedWords.forEach(word =\u003e word.classList.remove('highlight'));\n                         event.target.classList.add('highlight');\n```\n\nOne of the most impressive changes was when I asked it to take what was currently a non-functional chat UI and\n[wire it up to the OpenAI chat completions API](commits.md#user-content-61326c036fa7888e58231f4bcb4f13d0f889ea0c).\nI don't have a record of the exact prompt I used, but I basically said \"wire it up like this\" and pasted\na dozen lines of the `curl` example from the [API reference docs](https://platform.openai.com/docs/api-reference/chat).\n\nAnother shocking change occured when I asked ChatGPT to add a speaker button beside each chat message bubble.\nI had previously asked it to use text-to-speech to speak individual words when clicked.\nWhen I asked it to\n[add a speaker button on every chat bubble](commits.md#user-content-cbae63b904561671b9df467584b3687a61939355)\n, it wired them up to speak all the text in the bubble without me needing to ask.\n\nI am missing the actual text of many of the earliest prompts I used.\nI didn't start recording them until I was a couple of dozen commits into the process.\nWhen I started, I didn't think I was going to make much progress using this style of \"coding\".\nI am suprised at how much I was able to accomplish by treating ChatGPT as a junior web developer.\n\nRegardless, you can review this\n[curated commit history of this repo](commits.md)\nto see many of the prompts I used.\nAny commit that starts with \"PROMPT\" was coded by ChatGPT from that specific prompt.\nIf the commit starts with \"asked for ...\", that also means ChatGPT did the coding, but I didn't record the exact prompt.\n\n### Workflow\n\nMy workflow for each change was dead simple:\n\n  - I wrote my plain English change request in a file called `prompt.txt`.\n  \n  - I fed the prompt and the entire codebase to `gpt-3.5-turbo` via the [aichat](https://github.com/sigoden/aichat) tool.\n    - `cat prompt.txt chat.html | aichat -r webdev \u003e tmp.html \u0026\u0026 cp tmp.html chat.html`\n\n  - Each time, ChatGPT returned a modified version of the codebase, implementing my requested changes.\n  \n  - I did a `git diff` to review what ChatGPT had changed and tried out the resulting system.\n    - If it was good, `git commit -F prompt.txt`\n    - If it wasn't right, I would use `git stash` to discard the changes, adjust the prompt and try again.\n\nI used the roles feature of [aichat](https://github.com/sigoden/aichat) to set up a `webdev` role with a system prompt like this:\n\n\u003e I want you to act as a web development expert.\n\u003e I want you to answer only with code.\n\u003e Make the requested change to the provided code and output the changed code.\n\u003e MAKE NO OTHER CHANGES!\n\u003e Do not provide explanations!\n\n### Limitations\n\nMy workflow broke down when the size of the prompt and codebase exceeded the context window for the `gpt-3.5-turbo` model.\nI experimented with numerous other workflows to try and work around this limit, but with little consistent success.\n\nUltimately I refactored the js and css into their own files, and began feeding ChatGPT excerpts from the code that were relevant to each change I needed.\nThis wasn't always successful, as it often wanted to (re)write the code that I wasn't showing it.\n\nI look forward to GPT-4 API access, where I can take advantage of the 32k token context window.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaul-gauthier%2Feasy-chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaul-gauthier%2Feasy-chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaul-gauthier%2Feasy-chat/lists"}