Skip to content

Commit

Permalink
Adds pages fixing. Improve JSON fixing prompt.
Browse files Browse the repository at this point in the history
  • Loading branch information
infomiho committed Jun 29, 2023
1 parent 20c06bc commit 3e6e89d
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 6 deletions.
14 changes: 11 additions & 3 deletions waspc/src/Wasp/AI/GenerateNewProject.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import Wasp.AI.GenerateNewProject.Common (NewProjectDetails (..))
import Wasp.AI.GenerateNewProject.Entity (writeEntitiesToWaspFile)
import Wasp.AI.GenerateNewProject.Operation (OperationType (..), generateAndWriteOperation, getOperationJsFilePath)
import Wasp.AI.GenerateNewProject.OperationsJsFile (fixOperationsJsFile)
import Wasp.AI.GenerateNewProject.Page (generateAndWritePage)
import Wasp.AI.GenerateNewProject.Page (generateAndWritePage, getPageComponentPath)
import Wasp.AI.GenerateNewProject.PageComponentFile (fixPageComponent)
import Wasp.AI.GenerateNewProject.Plan (generatePlan)
import qualified Wasp.AI.GenerateNewProject.Plan as Plan
import Wasp.AI.GenerateNewProject.Skeleton (generateAndWriteProjectSkeletonAndPresetFiles)
Expand Down Expand Up @@ -56,7 +57,7 @@ generateNewProject newProjectDetails waspProjectSkeletonFiles = do
generateAndWriteOperation Query newProjectDetails waspFilePath plan

writeToLog "Generating pages..."
_pages <-
pages <-
forM (Plan.pages plan) $
generateAndWritePage newProjectDetails waspFilePath (Plan.entities plan) queries actions

Expand All @@ -73,7 +74,14 @@ generateNewProject newProjectDetails waspProjectSkeletonFiles = do
writeToLog $ T.pack $ "Fixed NodeJS operations file '" <> opFp <> "'."
writeToLog "NodeJS operations files fixed."

-- TODO: Also try fixing Pages / JSX files.
writeToLog "Fixing any mistakes in pages..."
forM_ (getPageComponentPath <$> pages) $ \pageFp -> do
fixPageComponent newProjectDetails waspFilePath pageFp
writeToLog $ T.pack $ "Fixed '" <> pageFp <> "' page."
-- forM_ getPageComponentPath pages $ \pageFp -> do
-- fixPageComponent newProjectDetails waspFilePath pageFp
-- writeToLog $ T.pack $ "Fixed '" <> pageFp <> "' page."
writeToLog "Pages fixed."

(promptTokensUsed, completionTokensUsed) <- getTotalTokensUsage
writeToLog $
Expand Down
1 change: 1 addition & 0 deletions waspc/src/Wasp/AI/GenerateNewProject/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ queryChatGPTForJSON chatGPTParams = doQueryForJSON 0
<> " valid JSON, no other text or explanations. Error I got parsing JSON"
<> " from your last message: "
<> T.pack errMsg
<> ". Newlines should be escaped as \\n."
}
]
else do
Expand Down
14 changes: 11 additions & 3 deletions waspc/src/Wasp/AI/GenerateNewProject/Page.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Wasp.AI.GenerateNewProject.Page
( generateAndWritePage,
pageDocPrompt,
getPageComponentPath,
Page (..),
)
where
Expand Down Expand Up @@ -100,8 +102,9 @@ generatePage newProjectDetails entityPlans actions queries pPlan = do
${appDescriptionBlock}
|]

pageDocPrompt =
[trimming|
pageDocPrompt :: Text
pageDocPrompt =
[trimming|
Page is implemented via Wasp declaration and corresponding NodeJS implementation.

Example of Wasp declaration:
Expand Down Expand Up @@ -160,8 +163,13 @@ writePageToJsFile :: Page -> CodeAgent ()
writePageToJsFile page =
writeToFile path $ (<> "\n\n" <> jsImpl) . fromMaybe ""
where
path = resolvePath $ Plan.componentPath $ pagePlan page
path = getPageComponentPath page
jsImpl = T.pack $ pageJsImpl $ pageImpl page

getPageComponentPath :: Page -> String
getPageComponentPath page = path
where
path = resolvePath $ Plan.componentPath $ pagePlan page
pathPrefix = "@client/"
resolvePath p | pathPrefix `isPrefixOf` p = "src/" <> drop (length ("@" :: String)) p
resolvePath _ = error "path incorrectly formatted, should start with " <> pathPrefix <> "."
Expand Down
90 changes: 90 additions & 0 deletions waspc/src/Wasp/AI/GenerateNewProject/PageComponentFile.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AI.GenerateNewProject.PageComponentFile
( fixPageComponent,
)
where

import Data.Aeson (FromJSON)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics (Generic)
import NeatInterpolation (trimming)
import Wasp.AI.CodeAgent (CodeAgent, getFile, writeToFile)
import Wasp.AI.GenerateNewProject.Common
( NewProjectDetails (..),
defaultChatGPTParams,
queryChatGPTForJSON,
)
import Wasp.AI.GenerateNewProject.Common.Prompts (appDescriptionBlock)
import qualified Wasp.AI.GenerateNewProject.Common.Prompts as Prompts
import Wasp.AI.GenerateNewProject.Page (pageDocPrompt)
import Wasp.AI.OpenAI.ChatGPT (ChatMessage (..), ChatRole (..))

fixPageComponent :: NewProjectDetails -> FilePath -> FilePath -> CodeAgent ()
fixPageComponent newProjectDetails waspFilePath pageComponentPath = do
currentWaspFileContent <- fromMaybe (error "couldn't find wasp file") <$> getFile waspFilePath
currentPageComponentContent <- fromMaybe (error "couldn't find page file to fix") <$> getFile pageComponentPath
fixedPageComponent <-
queryChatGPTForJSON
defaultChatGPTParams
[ ChatMessage {role = System, content = Prompts.systemPrompt},
ChatMessage {role = User, content = fixPageComponentPrompt currentWaspFileContent currentPageComponentContent}
]
writeToFile pageComponentPath (const $ pageComponentImpl fixedPageComponent)
where
fixPageComponentPrompt currentWaspFileContent currentPageContent =
[trimming|
${basicWaspLangInfoPrompt}

${pageDocPrompt}

===============

We are together building a new Wasp app (description at the end of prompt).

Here is a wasp file that we generated together so far:
```wasp
${currentWaspFileContent}
```

Here is a React component (${pageComponentPathText}) containing some frontend code
that we generated together earlier:
```js
${currentPageContent}
```

===============

The NodeJS file with operations likely has some mistakes: let's fix it!

Some common mistakes to look for:
- "TODO" comments or "..." that should be replaced with actual implementation.
Fix these by replacing them with actual implementation.
- Duplicate imports. If there are any, make sure to remove them.
- There might be some invalid JS or JSX syntax -> fix it if there is any.
- If there is some obvious refactoring that could improve code quality, go for it.
- Make sure to use valid queries and actions that are defined in the Wasp file.
- You should import queries from "@wasp/queries/{queryName}" like import getTask from '@wasp/queries/getTasks';
- You should import actions from "@wasp/actions/{actionName}" like import createTask from '@wasp/actions/createTask';
- Use Tailwind CSS to style the page if you didn't.
- Use <Link /> component from "react-router-dom" to link to other pages where needed.

With this in mind, generate a new, fixed React component (${pageComponentPathText}).
Do actual fixes, don't leave comments with "TODO"!
Please respond ONLY with a valid JSON of the format { pageComponentImpl: string }.
There should be no other text in your response. Don't wrap content with the "```" code delimiters.

${appDescriptionBlockText}
|]
appDescriptionBlockText = appDescriptionBlock newProjectDetails
basicWaspLangInfoPrompt = Prompts.basicWaspLangInfo
pageComponentPathText = T.pack pageComponentPath

data PageComponent = PageComponent
{ pageComponentImpl :: Text
}
deriving (Generic, Show)

instance FromJSON PageComponent
1 change: 1 addition & 0 deletions waspc/waspc.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ library
Wasp.AI.GenerateNewProject.Operation
Wasp.AI.GenerateNewProject.OperationsJsFile
Wasp.AI.GenerateNewProject.Page
Wasp.AI.GenerateNewProject.PageComponentFile
Wasp.AI.GenerateNewProject.Plan
Wasp.AI.GenerateNewProject.Skeleton
Wasp.AI.GenerateNewProject.WaspFile
Expand Down

0 comments on commit 3e6e89d

Please # to comment.