gpt-engineer-org / gpt-engineer

Platform to experiment with the AI Software Engineer. Terminal based. NOTE: Very different from https://gptengineer.app
MIT License
52.34k stars 6.81k forks source link

Engineer disregarding prompt, making To-Do Apps and a Recipe app #115

Closed Metranohm closed 1 year ago

Metranohm commented 1 year ago

I followed the recently updated instructions and got GPT Engineer to run (python -m gpt_engineer.main my-new-project), but haven't had any luck since. I asked it to build a blackjack game using mern stack using a detailed prompt from ChatGPT. The first time I ran it it saw my prompt and showed it in the terminal but right when my prompt ended it started showing the prompt for a flight booking app then showed the code it was going to create for the flight app. I started again and now it disregards my prompt entirely and shows the prompt for a to-do app followed immediately by a recipe app. I tried deleting all the prompts for benchmark but it did nothing. This is what my terminal shows:

gpt-engineer git:(main) ✗ python -m gpt_engineer.main my-new-project Model gpt-4 not available for provided api key reverting to gpt-3.5.turbo. Sign up for the gpt-4 wait list here: https://openai.com/waitlist/gpt-4-api Specification:

The program is a web application that allows users to create and manage their own to-do lists. The application should have the following features:

  1. User Authentication: Users should be able to create an account, log in, and log out. Users should not be able to access any part of the application without being authenticated.

  2. Create a To-Do List: Users should be able to create a new to-do list with a title and description.

  3. Add Tasks: Users should be able to add tasks to their to-do lists. Each task should have a title, description, and due date.

  4. Edit Tasks: Users should be able to edit the title, description, and due date of any task on their to-do list.

  5. Mark Tasks as Complete: Users should be able to mark tasks as complete when they have finished them.

  6. Delete Tasks: Users should be able to delete tasks from their to-do list.

  7. View To-Do Lists: Users should be able to view all of their to-do lists and the tasks associated with each list.

  8. Search To-Do Lists: Users should be able to search for specific to-do lists by title.

  9. Share To-Do Lists: Users should be able to share their to-do lists with other users of the application.

  10. Notifications: Users should receive notifications when a task is due or when a shared to-do list is updated.

Core Classes/Functions/Methods:

  1. User: A class that represents a user of the application. It should have attributes for the user's name, email, and password. It should also have methods for creating an account, logging in, and logging out.

  2. ToDoList: A class that represents a to-do list. It should have attributes for the list's title, description, and tasks. It should also have methods for adding tasks, editing tasks, marking tasks as complete, and deleting tasks.

  3. Task: A class that represents a task on a to-do list. It should have attributes for the task's title, description, due date, and completion status. It should also have methods for editing the task's title, description, and due date, as well as marking the task as complete.

  4. Notification: A class that represents a notification. It should have attributes for the notification's message, recipient, and timestamp.

  5. Authentication: A class that handles user authentication. It should have methods for creating an account, logging in, and logging out.

  6. Search: A class that handles searching for to-do lists by title. It should have a method for searching for a specific to-do list by title.

  7. Sharing: A class that handles sharing to-do lists with other users. It should have methods for sharing a to-do list with another user and updating a shared to-do list.

Dependencies:

  1. React: A JavaScript library for building user interfaces.

  2. Node.js: A JavaScript runtime built on Chrome's V8 JavaScript engine.

  3. Express: A web application framework for Node.js.

  4. MongoDB: A NoSQL database used for storing data.

  5. Mongoose: A MongoDB object modeling tool designed to work in an asynchronous environment.

  6. Passport: An authentication middleware for Node.js.

  7. Socket.IO: A JavaScript library for real-time web applications.Unfortunately, I cannot provide feedback on a specification that has not been provided. Please provide me with the specification so that I can review it and provide feedback.Specification:

The program is a web application that allows users to create and manage their own recipe collections. The application should have the following features:

  1. User Authentication: Users should be able to create an account, log in, and log out. Users should not be able to access any part of the application without being authenticated.

  2. Create a Recipe: Users should be able to create a new recipe with a title, description, ingredients, and instructions.

  3. Edit a Recipe: Users should be able to edit the title, description, ingredients, and instructions of any recipe in their collection.

  4. Delete a Recipe: Users should be able to delete any recipe from their collection.

  5. View Recipes: Users should be able to view all of the recipes in their collection.

  6. Search Recipes: Users should be able to search for specific recipes by title or ingredients.

  7. Share Recipes: Users should be able to share their recipes with other users of the application.

  8. Rate Recipes: Users should be able to rate recipes on a scale of 1-5 stars.

  9. Comment on Recipes: Users should be able to leave comments on recipes.

  10. Notifications: Users should receive notifications when a recipe is shared with them, when a recipe they have shared is rated or commented on, and when a recipe they have rated or commented on is updated.

Core Classes/Functions/Methods:

  1. User: A class that represents a user of the application. It should have attributes for the user's name, email, and password. It should also have methods for creating an account, logging in, and logging out.

  2. Recipe: A class that represents a recipe. It should have attributes for the recipe's title, description, ingredients, instructions, and rating. It should also have methods for editing the recipe's title, description, ingredients, and instructions, as well as deleting the recipe.

  3. Notification: A class that represents a notification. It should have attributes for the notification's message, recipient, and timestamp.

  4. Authentication: A class that handles user authentication. It should have methods for creating an account, logging in, and logging out.

  5. Search: A class that handles searching for recipes by title or ingredients. It should have methods for searching for a specific recipe by title or ingredients.

  6. Sharing: A class that handles sharing recipes with other users. It should have methods for sharing a recipe with another user and updating a shared recipe.

  7. Rating: A class that handles rating recipes. It should have methods for rating a recipe and updating the rating of a recipe.

  8. Comment: A class that handles commenting on recipes. It should have methods for leaving a comment on a recipe and updating the comments on a recipe.

Dependencies:

  1. React: A JavaScript library for building user interfaces.

  2. Node.js: A JavaScript runtime built on Chrome's V8 JavaScript engine.

  3. Express: A web application framework for Node.js.

  4. MongoDB: A NoSQL database used for storing data.

  5. Mongoose: A MongoDB object modeling tool designed to work in an asynchronous environment.

  6. Passport: An authentication middleware for Node.js.

  7. Socket.IO: A JavaScript library for real-time web applications.Here are some sample tests based on the given specification:

  8. User Authentication:

    • Test that a user can create an account with a valid email and password.
    • Test that a user cannot create an account with an invalid email or password.
    • Test that a user can log in with valid credentials.
    • Test that a user cannot log in with invalid credentials.
    • Test that a user can log out successfully.
  9. Create a Recipe:

    • Test that a user can create a new recipe with a title, description, ingredients, and instructions.
    • Test that a user cannot create a recipe without a title or instructions.
  10. Edit a Recipe:

    • Test that a user can edit the title, description, ingredients, and instructions of any recipe in their collection.
    • Test that a user cannot edit a recipe that does not belong to them.
  11. Delete a Recipe:

    • Test that a user can delete any recipe from their collection.
    • Test that a user cannot delete a recipe that does not belong to them.
  12. View Recipes:

    • Test that a user can view all of the recipes in their collection.
  13. Search Recipes:

    • Test that a user can search for specific recipes by title or ingredients.
  14. Share Recipes:

    • Test that a user can share their recipes with other users of the application.
    • Test that a user cannot share a recipe that does not belong to them.
  15. Rate Recipes:

    • Test that a user can rate recipes on a scale of 1-5 stars.
    • Test that a user cannot rate a recipe more than once.
  16. Comment on Recipes:

    • Test that a user can leave comments on recipes.
    • Test that a user cannot leave a comment on a recipe that does not belong to them.
  17. Notifications:

    • Test that a user receives notifications when a recipe is shared with them.
    • Test that a user receives notifications when a recipe they have shared is rated or commented on.
    • Test that a user receives notifications when a recipe they have rated or commented on is updated.EntryPoint (app.js):

The entry point file will be responsible for starting the server and connecting to the database. It will also define the routes for the API.

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const cors = require('cors');
const routes = require('./routes');

const app = express();

// Connect to MongoDB
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/recipe-app', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

// Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(cors());

// Routes
app.use('/api', routes);

// Start server
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));

Routes (routes.js):

The routes file will define the endpoints for the API.

const express = require('express');
const passport = require('passport');
const UserController = require('./controllers/UserController');
const RecipeController = require('./controllers/RecipeController');

const router = express.Router();

// User routes
router.post('/register', UserController.register);
router.post('/login', UserController.login);
router.get('/user', passport.authenticate('jwt', { session: false }), UserController.getUser);

// Recipe routes
router.get('/recipes', passport.authenticate('jwt', { session: false }), RecipeController.getAllRecipes);
router.get('/recipes/:id', passport.authenticate('jwt', { session: false }), RecipeController.getRecipeById);
router.post('/recipes', passport.authenticate('jwt', { session: false }), RecipeController.createRecipe);
router.put('/recipes/:id', passport.authenticate('jwt', { session: false }), RecipeController.updateRecipe);
router.delete('/recipes/:id', passport.authenticate('jwt', { session: false }), RecipeController.deleteRecipe);
router.post('/recipes/:id/share', passport.authenticate('jwt', { session: false }), RecipeController.shareRecipe);
router.post('/recipes/:id/rate', passport.authenticate('jwt', { session: false }), RecipeController.rateRecipe);
router.post('/recipes/:id/comment', passport.authenticate('jwt', { session: false }), RecipeController.commentOnRecipe);

module.exports = router;

User Model (User.js):

The User model will define the schema for a user and methods for creating an account, logging in, and logging out.

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { Schema } = mongoose;

const UserSchema = new Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
});

UserSchema.pre('save', async function (next) {
  try {
    if (this.isModified('password')) {
      const salt = await bcrypt.genSalt(10);
      const hash = await bcrypt.hash(this.password, salt);
      this.password = hash;
    }
    next();
  } catch (error) {
    next(error);
  }
});

UserSchema.methods.comparePassword = async function (password) {
  return bcrypt.compare(password, this.password);
};

UserSchema.methods.generateToken = function () {
  const payload = {
    id: this._id,
    name: this.name,
    email: this.email,
  };
  return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
};

const User = mongoose.model('User', UserSchema);

module.exports = User;

User Controller (UserController.js):

The User controller will handle requests related to user authentication.

const User = require('../models/User');

exports.register = async (req, res, next) => {
  try {
    const { name, email, password } = req.body;
    const user = new User({ name, email, password });
    await user.save();
    const token = user.generateToken();
    res.status(201).json({ token });
  } catch (error) {
    next(error);
  }
};

exports.login = async (req, res, next) => {
  try {
    const { email, password } = req.body;
    const user = await User.findOne({ email });
    if (!user) {
      return res.status(401).json({ message: 'Invalid email or password' });
    }
    const isMatch = await user.comparePassword(password);
    if (!isMatch) {
      return res.status(401).json({ message: 'Invalid email or password' });
    }
    const token = user.generateToken();
    res.json({ token });
  } catch (error) {
    next(error);
  }
};

exports.getUser = async (req, res, next) => {
  try {
    const user = await User.findById(req.user.id);
    res.json(user);
  } catch (error) {
    next(error);
  }
};

Recipe Model (Recipe.js):

The Recipe model will define the schema for a recipe and methods for editing, deleting, and sharing a recipe.

const mongoose = require('mongoose');
const { Schema } = mongoose;

const RecipeSchema = new Schema({
  title: {
    type: String,
    required: true,
  },
  description: {
    type: String,
    required: true,
  },
  ingredients: {
    type: [String],
    required: true,
  },
  instructions: {
    type: [String],
    required: true,
  },
  rating: {
    type: Number,
    default: 0,
  },
  author: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true,
  },
  sharedWith: {
    type: [{ type: Schema.Types.ObjectId, ref: 'User' }],
    default: [],
  },
  comments: {
    type: [
      {
        author: { type: Schema.Types.ObjectId, ref: 'User' },
        text: String,
        createdAt: { type: Date, default: Date.now },
      },
    ],
    default: [],
  },
});

const Recipe = mongoose.model('Recipe', RecipeSchema);

module.exports = Recipe;

Recipe Controller (RecipeController.js):

The Recipe controller will handle requests related to recipes.

const Recipe = require('../models/Recipe');
const User = require('../models/User');

exports.getAllRecipes = async (req, res, next) => {
  try {
    const recipes = await Recipe.find({ author: req.user.id }).populate('author', 'name');
    res.json(recipes);
  } catch (error) {
    next(error);
  }
};

exports.getRecipeById = async (req, res, next) => {
  try {
    const recipe = await Recipe.findById(req.params.id)
      .populate('author', 'name')
      .populate('comments.author', 'name');
    if (!recipe) {
      return res.status(404).json({ message: 'Recipe not found' });
    }
    res.json(recipe);
  } catch (error) {
    next(error);
  }
};

exports.createRecipe = async (req, res, next) => {
  try {
    const { title, description, ingredients, instructions } = req.body;
    const recipe = new Recipe({ title, description, ingredients, instructions, author: req.user.id });
    await recipe.save();
    res.status(201).json(recipe);
  } catch (error) {
    next(error);
  }
};

exports.updateRecipe = async (req, res, next) => {
  try {
    const { title, description, ingredients, instructions } = req.body;
    const recipe = await Recipe.findById(req.params.id);
    if (!recipe) {
      return res.status(404).json({ message: 'Recipe not found' });
    }
    if (recipe.author.toString() !== req.user.id) {
      return res.status(403).json({ message: 'You are not authorized to edit this recipe' });
    }
    recipe.title = title;
    recipe.description = description;
    recipe.ingredients = ingredients;
    recipe.instructions = instructions;
    await recipe.save();
    res.json(recipe);
  } catch (error) {
    next(error);
  }
};

exports.deleteRecipe = async (req, res, next) => {
  try {
    const recipe = await Recipe.findById(req.params.id);
    if (!recipe) {
      return res.status(404).json({ message: 'Recipe not found' });
    }
    if (recipe.author.toString() !== req.user.id) {
      return res.status(403).json({ message: 'You are not authorized to delete this recipe' });
    }
    await recipe.remove();
    res.json({ message: 'Recipe deleted successfully' });
  } catch (error) {
    next(error);
  }
};

exports.shareRecipe = async (req, res, next) => {
  try {
    const recipe = await Recipe.findById(req.params.id);
    if (!recipe) {
      return res.status(404).json({ message: 'Recipe not found' });
    }
    if (recipe.author.toString() !== req.user.id) {
      return res.status(403).json({ message: 'You are not authorized to share this recipe' });
    }
    const user = await User.findOne({ email: req.body.email });
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }
    if (recipe.sharedWith.includes(user._id)) {
      return res.status(400).json({ message: 'Recipe already shared with this user' });
    }
    recipe.sharedWith.push(user._id);
    await recipe.save();
    res.json(recipe);
  } catch (error) {
    next(error);
  }
};

exports.rateRecipe = async (req, res, next) => {
  try {
    const recipe = await Recipe.findById(req.params.id);
    if (!recipe) {
      return res.status(404).json({ message: 'Recipe not found' });
    }
    if (recipe.author.toString() === req.user.id) {
      return res.status(400).json({ message: 'You cannot rate your own recipe' });
    }
    if (recipe.rating > 0 && recipe.ratingCount.includes(req.user.id)) {
      return res.status(400).json({ message: 'You have already rated this recipe' });
    }
    recipe.ratingCount.push(req.user.id);
    recipe.rating = (recipe.rating + req.body.rating) / recipe.ratingCount.length;
    await recipe.save();
    res.json(recipe);
  } catch (errorTo install dependencies and run the codebase, run the following commands in the terminal:

cd /home/metranohm/code/sandbox/gpt-engineer/my-new-project/workspace npm install npm start



This assumes that Node.js and npm are already installed on the system. If not, they will need to be installed before running these commands.Do you want to execute this code?
cd /home/metranohm/code/sandbox/gpt-engineer/my-new-project/workspace
npm install
npm start

If yes, press enter. If no, type "no"

y
Executing the code...

up to date, audited 1 package in 63ms

found 0 vulnerabilities
npm ERR! Missing script: "start"
npm ERR! 
Rakly3 commented 1 year ago

I have the exact same :)

Bbasche commented 1 year ago

seeing this too

patillacode commented 1 year ago

The issue you are seeing is not GPT Engineer's fault AFAIU.

I'd say your app is missing the start command, usually defined in one of the config files in frontend applications (nuxt example).

Bear in mind the generated code in your case is being done by gpt-3.5-turbo model, which is not perfect, and might be missing something like that.

AntonOsika commented 1 year ago

I had a similar issue since we added more "introspection".

Looking into the logs (in memory folder)

Feel free to do the same and collect discussion here!

AntonOsika commented 1 year ago

Hey all!

Fixed this now.

Using multiple system prompt with "You are a super smart developer. You have been asked to make a specification for a program." made it think that it was writing a completely new program

FYI @FOLLGAD

salazarm commented 1 year ago

I'm facing this issue right now