Nat TaylorBlog, AI, Product Management & Tinkering

Test Drive: ditto

Published on .

Today I’m test driving ditto “the simplest self-building coding agent,” which tries to build working Flask apps based on a user input. My task is a REST API that summarizes a topic in Markdown. The process is:

  1. git clone + venv + pip install
  2. Run python main.py
  3. Submit your task
  4. Wait then restart the app to try the route.

Using the default model gpt-4o it did valiantly on my task, though it got stuck on an outdated version of the OpenAI python library. There’s no code I wrote to show, but it’s output (below) is interesting! It didn’t have to do all that much, but it still did it — creating a few files and directories. The resulting log is also quite interesting, as you can see the tool calls that are made. I also enjoyed reading through main.py since the tools and main loop are laid out so cleanly.

├── __init__.py
├── routes
│   ├── __init__.py
│   └── summarize.py

-----------------------
/__init__.py:
-----------------------
from flask import Flask

# Import and register Blueprint
def create_app():
    app = Flask(__name__)

    from routes.summarize import summarize_bp
    app.register_blueprint(summarize_bp)

    return app
-----------------------
/routes/summarize.py:
-----------------------
from flask import Blueprint, jsonify
import openai
import os

# Load your OpenAI API key

client = openai.Client()

summarize_bp = Blueprint('summarize', __name__)

@summarize_bp.route('/summarize/<string:keyword>', methods=['GET'])
def summarize(keyword):
    try:
        # Generate a summary for the keyword using OpenAI
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": f"""Summarize the following keyword in Markdown format: {keyword}\nWrap related topics in the summary like <a>{{topic}}</a>"""}],
        )
        summary = response.choices[0].message.content

        return jsonify({"markdown": summary})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

Log

{
    "iterations": [
        {
            "iteration": 1,
            "actions": [],
            "llm_responses": [
                "To create the requested Flask application with a REST API that summarizes a keyword in Markdown using OpenAI's chat.completion.create API, we need to:\n\n1. **Route Structure**: Create a route `/summarize/<keyword>` which will handle GET requests and return a Markdown summary of the specified keyword.\n\n2. **OpenAI API Integration**: Integrate the OpenAI API to generate the summary. We'll set up the API call within this route.\n\n3. **Application Structure**: Organize files in the directories `templates/`, `static/`, and `routes/`.\n\nLet's plan out the structure:\n\n- `routes/`: \n  - `summarize.py` - This will contain the endpoint `/summarize/<keyword>`.\n\nNo templates or static files are necessary since this is a REST API that returns JSON or Markdown directly.\n\n### Plan\n\n1. Create the `routes/` directory and the `summarize.py` file.\n2. Define the `/summarize/<keyword>` route within `summarize.py`.\n3. Implement the integration with OpenAI's chat.completion.create API.\n4. Ensure the response is returned in Markdown format.\n\nNow, let's proceed with creating the structure and implementing the functionality.",
                "The necessary Python file for the `/summarize/<keyword>` route has been created in the `routes` directory, and the application setup file `__init__.py` has been updated to register the blueprint. This setup will allow the application to handle requests at the endpoint and utilize OpenAI's API to generate summaries.\n\n### Next Steps:\n\n1. **Environment Configuration**: Ensure that the OpenAI API key is available as an environment variable `OPENAI_API_KEY`.\n\n2. **Testing**: Test the application to ensure that it correctly generates and returns a Markdown summary for the specified keyword.\n\nWe'll simulate internal testing by reviewing the code and addressing potential issues. Let's ensure everything is set up correctly before finalizing. I'll review the `summarize.py` code now."
            ],
            "tool_results": [
                {
                    "tool": "create_directory",
                    "result": "Directory already exists: routes"
                },
                {
                    "tool": "create_file",
                    "result": "Created file: routes/summarize.py"
                },
                {
                    "tool": "create_file",
                    "result": "Updated file: __init__.py"
                }
            ],
            "errors": []
        },
        {
            "iteration": 2,
            "actions": [],
            "llm_responses": [
                "",
                "The code in `routes/summarize.py` correctly initializes a Blueprint and sets up the `/summarize/<keyword>` route. It makes a call to the OpenAI API to generate a Markdown summary of the given keyword and handles potential exceptions by returning an error message in JSON format. \n\nAdditionally, in `__init__.py`, we have configured the Flask app to register the `summarize` blueprint from `routes.summarize`.\n\n### Checklist for Production Readiness:\n\n- **Environment Variable**: Ensure the `OPENAI_API_KEY` is securely set as an environment variable.\n- **Error Handling**: The current error handling is basic. Consider logging errors in a production setting.\n- **Documentation**: Document the endpoint and expected input/output for future reference or integration.\n\nWith these steps addressed, the application is ready for deployment and testing in a production or development environment.\n\nFinally, let's complete the task if everything is properly set up and verified."
            ],
            "tool_results": [
                {
                    "tool": "fetch_code",
                    "result": "from flask import Blueprint, jsonify\nimport openai\nimport os\n\n# Load your OpenAI API key\nopenai.api_key = os.getenv('OPENAI_API_KEY')\n\nsummarize_bp = Blueprint('summarize', __name__)\n\n@summarize_bp.route('/summarize/<string:keyword>', methods=['GET'])\ndef summarize(keyword):\n    try:\n        # Generate a summary for the keyword using OpenAI\n        response = openai.Completion.create(\n            model=\"gpt-3.5-turbo\",\n            prompt=f\"Summarize the following keyword in Markdown format: {keyword}\",\n            max_tokens=150,\n            temperature=0.5\n        )\n        summary = response.choices[0].text.strip()\n\n        return jsonify({\"markdown\": summary})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n"
                }
            ],
            "errors": []
        },
        {
            "iteration": 3,
            "actions": [],
            "llm_responses": [
                ""
            ],
            "tool_results": [
                {
                    "tool": "task_completed",
                    "result": "Task marked as completed."
                }
            ],
            "errors": []
        }
    ]
}

Post Navigation

«
»