Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasp ai cli mage #1601

Merged
merged 20 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ to install Wasp on OSX/Linux/WSL(Win). From there, just follow the instructions

For more details, check out [the docs](https://wasp-lang.dev/docs).

# Wasp AI / Mage

Wasp comes with experimental AI code generator to help you kickstart your next Wasp project -> you can use it via `wasp new` in the CLI (choose "AI" option) if you can provide your OpenAI keys or you can do it via our [Mage web app](https://usemage.ai) in which case our OpenAI keys are used in the background.

# This repository

This is the main repo of the Wasp universe, containing core code (mostly `waspc` - Wasp compiler) and the supporting materials.
Expand Down
3 changes: 3 additions & 0 deletions wasp-ai/.gitignore → mage/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
# or modify/delete these two lines.
*.env
*.env.*

# Emacs specific
.projectile
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion wasp-ai/Dockerfile → mage/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ RUN cd server && PRISMA_CLIENT_OUTPUT_DIR=../server/node_modules/.prisma/client/
RUN cd server && npm run build

FROM base AS server-production
RUN curl -sSL https://get.wasp-lang.dev/installer.sh | sh -s -- -v 0.11.4-wasp-ai-12
RUN curl -sSL https://get.wasp-lang.dev/installer.sh | sh -s -- -v 0.12.0
ENV PATH "$PATH:/root/.local/bin"
ENV NODE_ENV production
WORKDIR /app
Expand Down
44 changes: 44 additions & 0 deletions mage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Mage

This directory contains the source code of Mage (aka "GPT Web App Generator" aka "Wasp AI"): a Wasp app (so a full-stack web app) that allows you to create a new Wasp app (inception :)!) from just a short description. It uses ChatGPT in a smart way to accomplish this (so it would be clasified as an AI code agent).

Mage is hosted at https://usemage.ai and you can use it there for free.

You can learn more about it [here](https://wasp-lang.dev/blog/2023/07/10/gpt-web-app-generator) and [here](https://wasp-lang.dev/blog/2023/07/17/how-we-built-gpt-web-app-generator).

## Running locally

Mage is really just a client / UI for calling "Wasp AI", which is AI logic that does all the heavy lifting, and is integrated into Wasp's CLI: `wasp`.
So, if you want to generate Wasp apps via AI locally, on your machine, with your OpenAI keys and your choice of models/parameters, we recommend NOT running the Mage app locally, because it is not so easy, instead we recommend you to do it directly via `wasp` CLI, with `wasp new` or `wasp new:ai` commands. Check our docs on how to install `wasp` CLI: https://wasp-lang.dev/docs/quick-start#installation .

If you still want to run Mage web app locally for some specific reason, most likely because you want to contribute, you will need to do the following:

1. Copy `.env.server.example` into `.env.server` and fill in the missing values. You will basically need to provide Github and Google OAuth creds (and first create OAuth apps on both Github and Google if you don't have them yet - if you are a member of Wasp team ask for dev creds, if not you will have to create your own OAuth apps).
2. Run `wasp db start` and then `wasp start`! It might ask you to do `wasp db migrate-dev`, do that if needed.
3. When running Mage locally, it will be looking for `wasp-cli` binary on your machine to use. To satisfy this requirement, you can go to `waspc/` dir (just next to this one) and run `./run install` there. You will want to check though if that Wasp version matches the version Mage expects (check its Dockerfile to see which version of Wasp it expects).
If building `waspc/` is too complex for you (you don't have Haskell toolchain set up, taking too long, ...), you can go into the code of Mage, find where it calls `wasp-cli` and modify that temporarily to call `wasp` instead.

## Developing

### Updating Wasp version in Dockerfile

Keep in mind that Mage, when deployed, will install the version of Wasp specified in its Dockerfile.
So, make sure to update that version to be in sync with the version of Wasp that it was developed against.
Most often that should be the current version of Wasp on `main`, even if not released yet.

## Deployment

Mage is currently deployed on Wasp's Fly.io cloud.

Same as the rest of Wasp (blog/docs, CLI, ...), the latest deployed version is tracked on `release` branch.

So if you want to deploy new version of Mage, you should get it in wanted state on `release` branch, and then deploy from there.

Also, before deploying, check that version of `wasp` in `Dockerfile` makes sense.

To deploy it, just run `wasp deploy fly deploy`. You might want to add `--org wasp` if needed.

## FAQ

Q: What is the difference between Wasp AI and Mage? Are those the same thing?
A: When we say "Wasp AI" we refer to logic implemented in `wasp` CLI, while when we say "Mage" we refer to the Mage web app that really serves as a client for "Wasp AI" (calls it in the background). That said, we sometimes use these interchangeably.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function RootComponent({ children }) {
cursor-pointer flex-row
space-x-3
text-white bg-gradient-to-r from-pink-400 to-amber-400"
onClick={() => window.open("https://github.com/wasp-lang/wasp/tree/wasp-ai")}
onClick={() => window.open("https://github.com/wasp-lang/wasp")}
>
<div
className={`
Expand Down Expand Up @@ -103,7 +103,7 @@ export function RootComponent({ children }) {
<p className="text-center text-slate-500 text-sm mt-2">
This whole app is open-source, you can find the code{" "}
<a
href="https://github.com/wasp-lang/wasp/tree/wasp-ai/wasp-ai"
href="https://github.com/wasp-lang/wasp/tree/main/mage"
target="_blank"
rel="noopener noreferrer"
className="text-sky-500 hover:text-sky-600"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { FiChevronDown, FiChevronRight } from 'react-icons/fi'
function l(title, overrideTitle) {
const links = {
"Wasp": "https://wasp-lang.dev/",
"web app": "https://github.com/wasp-lang/wasp/tree/wasp-ai/wasp-ai",
"GPT code agent": "https://github.com/wasp-lang/wasp/tree/wasp-ai/waspc/src/Wasp/AI",
"web app": "https://github.com/wasp-lang/wasp/tree/main/mage",
"GPT code agent": "https://github.com/wasp-lang/wasp/tree/main/waspc/src/Wasp/AI",
"blog post": "https://wasp-lang.dev/blog/2023/07/10/gpt-web-app-generator"
};

Expand Down Expand Up @@ -46,7 +46,7 @@ const faqs = [

<br/><br/>

With GPT4 increasing its availability and with LLMs improving in general, the quality of generated code will only get better!
With LLMs improving in general, the quality of generated code will only get better!
</p>
},
{
Expand Down Expand Up @@ -80,26 +80,28 @@ const faqs = [

<br/><br/>

However, in the future, when GPT4 becomes cheaper / more available, it would make sense to switch to it completely, since it does generate better code!
However, in the future, when GPT4 becomes cheaper / faster, it would make sense to switch to it completely, since it does generate better code!
</p>
},
{
question: '[Advanced] Can I use GPT4 for the whole app?',
question: '[Advanced] Can I use GPT4 for the whole app? / Can I run Mage locally?',
answer: <p>
As mentioned above, we use GPT4 + GPT3.5 for practical reasons, even though using GPT4 exclusively does give better results.<br/>
<br/>
However, if you have access yourself to the OpenAI API, you can use GPT4 for the whole app, or play with adjusting the temperature, by running the Wasp GPT code agent locally!<br/>
However, if you have access yourself to the OpenAI API, you can use GPT4 for the whole app, or play with adjusting the temperature, by running the Wasp GPT code agent locally! So same thing like Mage, but via CLI.<br/>
Note: generating an app usually consumes from 20k to 50k tokens, which is then approximately $1 to $2 per app with the current GPT4 pricing (Jul 11th 2023).<br/>
<br/>
You will need to install special version of Wasp:<br/>
To run Wasp AI (Mage) locally, make sure you have wasp {'>='}v0.12 installed and just run:<br/>
<span className="bg-slate-800 text-slate-200 p-1 rounded">
curl -sSL https://get.wasp-lang.dev/installer.sh | sh -s -- -v 0.11.1-wasp-ai-11
wasp new
</span><br/>
When asked, choose AI generation, answer some questions, and your app will start generating!<br/>
<br/>
Now you can run app generation locally via:<br/>
There is also a command for running the same thing programmatically, without interactive questions:<br/>
<span className="bg-slate-800 text-slate-200 p-1 rounded">
wasp new-ai:disk MyAwesomeApp "Description of my awesome app." {'"{ \\"defaultGptModel\\": \\"gpt-4\\" }"'}
</span>
wasp new:ai
</span><br/>
Run it with no arguments (as above) to see its usage instructions.
</p>
},
]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export const ResultPage = () => {
>
<span
className="item-center flex gap-2 p-1 px-2 cursor-pointer text-pink-800 bg-pink-200 rounded"
onClick={() => window.open("https://github.com/wasp-lang/wasp/tree/wasp-ai")}
onClick={() => window.open("https://github.com/wasp-lang/wasp")}
>
<span>
🔮 This is a Wasp powered project. If you like it,{" "}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const generateApp: GenerateAppJob<
const stdoutMutex = new Mutex();
let waspCliProcess = null;
const waspCliProcessArgs = [
"new-ai",
"new:ai",
"--stdout",
project.name,
project.description,
JSON.stringify(projectConfig),
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion waspc/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## 0.12.0
## [WIP] 0.12.0

### ⚠️ Breaking changes

Expand Down
17 changes: 11 additions & 6 deletions waspc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,23 +326,24 @@ NOTE: When you run it for the first time it might take a while (~10 minutes) for
We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) convention when creating commits.

## Branching and merging strategy
This repo contains both the source code that makes up a Wasp release (under `waspc`), as well as our website containing documentation and blog posts (under `web`). In order to facilitate the development of Wasp code while still allowing for website updates or hotfixes of the current release, we have decided on the following minimal branching strategy.
This repo contains both the source code that makes up a Wasp release (under `waspc`), as well as our website containing documentation and blog posts (under `web`), and also Mage web app (under `mage`). In order to facilitate the development of Wasp code while still allowing for website / Mage updates or hotfixes of the current release, we have decided on the following minimal branching strategy.

All Wasp development should be done on feature branches. They form the basis of PRs that will target one of the two following branches:

- `main`: this branch contains all the actively developed new features and corresponding documentation updates. Some of these things may not yet be released, but anything merged into `main` should be in a release-ready state.
- This is the default branch to target for any Wasp feature branches.
- `release`: this branch contains the source code of current/latest Wasp release, as well as the documentation and blog posts currently published and therefore visible on the website.
- `release`: this branch contains the source code of current/latest Wasp release, as well as the documentation and blog posts currently published and therefore visible on the website, and also currently published version of Mage.
- When doing a full release, which means making a new release based on what we have currently on `main`, we do the following:
1. Update `main` branch by merging `release` into it. There might be conflicts but they shouldn't be too hard to fix. Once `main` is updated, you can create a new waspc release from it, as well as deploy the website from it.
2. Update `release` branch to this new `main` by merging `main` into it. There will be no conflicts since we already resolved all of them in the previous step.

How do I know where I want to target my PR, to `release` or `main`?
- If you have a change that you want to publish right now or very soon, certainly earlier than waiting till `main` is ready for publishing, then you want to target `release`. This could be website content update, new blog post, documentation (hot)fix, compiler hotfix that we need to release quickly via a new patch version, ... .
- If you have a change that you want to publish right now or very soon, certainly earlier than waiting till `main` is ready for publishing, then you want to target `release`. This could be website content update, new blog post, documentation (hot)fix, compiler hotfix that we need to release quickly via a new patch version, update for Mage that needs to go out now, ... .
- If you have a change that is not urgent and can wait until the next "normal" Wasp release is published, then target `main`. These are new features, refactorings, docs accompanying new features, ... .
- Stuff published on `release` (docs, Mage) uses/references version of `wasp` that was last released (so one that is also on `release`).
- TLDR;
- `release` is for changes to the already published stuff (the present).
- `main` is for changes to the to-be-published stuff (the future).
- `release` represents the present, and is for changes to the already published stuff.
- `main` represents near future, and is for changes to the to-be-published stuff.

## Deployment / CI
We use Github Actions for CI.
Expand Down Expand Up @@ -375,6 +376,7 @@ If it happens just once every so it is probably nothing to worry about. If it ha
- Publish the draft release when ready.
- Merge `release` back into `main` (`git merge release` while on the `main` branch), if needed.
- Publish new [docs](/web#deployment) from the `release` branch as well.
- Publish new [Mage](/mage#deployment) from the `release` branch as well, if needed.
- Announce new release in Discord.

#### Determining next version
Expand All @@ -393,7 +395,10 @@ If doing this, steps are the following:


## Documentation
External documentation, for users of Wasp, is hosted at https://wasp-lang.dev/docs, and its source is available at [web/docs](/web/docs), next to the website and blog.
External documentation, for users of Wasp, is hosted at https://wasp-lang.dev/docs, and its source is available at [web/docs](/web/docs), next to the website and blog.

## Mage
Wasp's magic GPT web app generator aka Wasp AI aka Mage is hosted at https://usemage.ai and its source is available at [mage](/mage).

Make sure to update it when changes modify how Wasp works.

Expand Down
55 changes: 44 additions & 11 deletions waspc/cli/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,7 @@ main = withUtf8 . (`E.catch` handleInternalErrors) $ do
args <- getArgs
let commandCall = case args of
("new" : newArgs) -> Command.Call.New newArgs
-- new-ai / new-ai:stdout is meant to be called and consumed programatically (e.g. by our Wasp AI
-- web app), while new-ai:disk is useful for us for testing.
[newAiCmd, projectName, appDescription, projectConfigJson]
| newAiCmd `elem` ["new-ai", "new-ai:stdout"] ->
Command.Call.NewAiToStdout projectName appDescription projectConfigJson
| newAiCmd == "new-ai:disk" ->
Command.Call.NewAiToDisk projectName appDescription projectConfigJson
("new:ai" : newAiArgs) -> Command.Call.NewAi newAiArgs
["start"] -> Command.Call.Start
["start", "db"] -> Command.Call.StartDb
["clean"] -> Command.Call.Clean
Expand Down Expand Up @@ -88,10 +82,20 @@ main = withUtf8 . (`E.catch` handleInternalErrors) $ do

case commandCall of
Command.Call.New newArgs -> runCommand $ createNewProject newArgs
Command.Call.NewAiToStdout projectName appDescription projectConfigJson ->
runCommand $ Command.CreateNewProject.AI.createNewProjectNonInteractiveToStdout projectName appDescription projectConfigJson
Command.Call.NewAiToDisk projectName appDescription projectConfigJson ->
runCommand $ Command.CreateNewProject.AI.createNewProjectNonInteractiveOnDisk projectName appDescription projectConfigJson
Command.Call.NewAi newAiArgs -> case newAiArgs of
["--stdout", projectName, appDescription, projectConfigJson] ->
runCommand $
Command.CreateNewProject.AI.createNewProjectNonInteractiveToStdout
projectName
appDescription
projectConfigJson
[projectName, appDescription, projectConfigJson] ->
runCommand $
Command.CreateNewProject.AI.createNewProjectNonInteractiveOnDisk
projectName
appDescription
projectConfigJson
_ -> printWaspNewAiUsage
Command.Call.Start -> runCommand start
Command.Call.StartDb -> runCommand Command.Start.Db.start
Command.Call.Clean -> runCommand clean
Expand Down Expand Up @@ -141,6 +145,11 @@ printUsage =
" -t|--template <template-name>",
" Check out the templates list here: https://github.com/wasp-lang/starters",
"",
cmd " new:ai <app-name> <app-description> [<config-json>]",
" Uses AI to create a new Wasp project just based on the app name and the description.",
" You can do the same thing with `wasp new` interactively.",
" Run `wasp new:ai` for more info.",
"",
cmd " version Prints current version of CLI.",
cmd " waspls Run Wasp Language Server. Add --help to get more info.",
cmd " completion Prints help on bash completion.",
Expand Down Expand Up @@ -230,6 +239,30 @@ printDbUsage =
]
{- ORMOLU_ENABLE -}

{- ORMOLU_DISABLE -}
printWaspNewAiUsage :: IO ()
printWaspNewAiUsage =
putStrLn $
unlines
[ title "USAGE",
" wasp new:ai <app-name> <app-description> <config-json>",
"",
" Config JSON:",
" It is used to provide additional configuration to Wasp AI.",
" Following fields are supported:",
" {",
" \"defaultGptTemperature\"?: number (from 0 to 2)",
" \"planningGptModel\"?: string (OpenAI model name)",
" \"codingGptModel\"?: string (OpenAI model name)",
" \"primaryColor\"?: string (Tailwind color name)",
" }",
"",
title "EXAMPLES",
" wasp new:ai ButtonApp \"One page with button\" \"{}\"",
" wasp new:ai ButtonApp \"One page with button\" \"{ \\\"defaultGptTemperature\\\": 0.5, \\\"codingGptModel\\\": \\\"gpt-4-1106-preview\\\" }\""
]
{- ORMOLU_ENABLE -}

cmd :: String -> String
cmd = mapFirstWord (Term.applyStyles [Term.Yellow, Term.Bold])

Expand Down
3 changes: 1 addition & 2 deletions waspc/cli/src/Wasp/Cli/Command/Call.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ module Wasp.Cli.Command.Call where

data Call
= New Arguments
| NewAiToStdout String String String -- projectName, appDescription, projectConfigJson
| NewAiToDisk String String String -- projectName, appDescription, projectConfigJson
| NewAi Arguments
| Start
| StartDb
| Clean
Expand Down
Loading
Loading