I’ve been tasked with adding type annotations (mypy) to a Python codebase. Let’s be honest, while it’s not the most glamorous job, it’s crucial for making our code easier to navigate and maintain. Luckily, this is exactly the kind of repetitive, high-impact work where Rovo Dev CLI shines!
I wanted to see if I could double my output by letting Rovo Dev CLI work on the side, hands-off, while I focused on other tasks.
This is a good use case for yolo mode! This mode lets Rovo Dev CLI use tools such as running file operations and bash commands without stopping for confirmation (warning! it can be destructive if used unwisely).
I started with:
Add mypy type annotation to my_project/my_app
And… it went a bit wild. Rovo Dev CLI did more than I asked: refactored code, added unnecessary future imports, using forward reference, and ignored the existing style. Does that mean it’s not capable?
A teammate (thanks Jeroen) shared a validation trick: specify the expectations. Here’s the improved prompt:
Add mypy typing to my_project/my_app
Ensure these tools pass:
uv run flake8
uv run black --check --diff .
uv run mypy my_project/my_app
uv run isort --check --diff .
Result: Night and day. The output was dramatically better! However, there is still a lot of improvements needed. But lesson learned, AI agent is only as good as the prompt you give.
I wondered if Rovo Dev CLI can write a better prompt for itself. So I decided to go full AI-ception:
“From AI, by AI, for AI”
Here’s my plan:
Start with a small untyped project and the prompt with validation above
Once Rovo Dev CLI finished, I will check the work and comments on what needs to be improved
Iterate until it was able to get the result I want
Ask Rovo Dev CLI to summarize all that it has done and craft a succinct prompt to do what it has done
Here’s the prompt for the last step
Based on my original prompt, what you have done and my feedbacks to get you to this stage,
craft me a succinct and clear prompt that I can use to ask you to do the same task next time
You might think, “Wasn’t that a lot of work just to get a good prompt?” Not at all! This investment pays off big time: now I can type bigger projects. Plus, I’ve learned how to guide the AI faster and more effectively, which is a superpower for any dev working with AI agents. (The final prompt is at the end of this article).
Also, thanks to yolo mode, Rovo Dev CLI is busy typing other projects while I’m busy perfecting my avocado toast.
Now that I’ve got my shiny new prompt, does the agent always nail it on the first try? Spoiler: nope! Just like us, Rovo Dev CLI doesn’t always produce a perfect result in one shot. In fact, I’ve found the agent can continuously improve its own work, kind of like how we (or me) as a developer learning on the job.
Let’s be real: do you always ship flawless code on your first commit? . Instead of throwing the shade “meh, your work sucks”, it’s more productive to give constructive feedback (sounds familiar?). Ask it to reflect on its own work and improve or give it a specific feedback on what needs fixing.
Example:
Review your work and improve on your annotation
You shouldn’t use future reference unless it is strictly necessary
Remember: the best results come from treating your agent like a teammate, not a super-intelligent-never-make-any-mistake being. Happy prompting and thank you for reading.
Here is my final prompt as promised
You are tasked to add, improve or correct mypy typing for the my_project/my_app folder including the test files. You are NOT to add any typing to anything outside this folder. However, you might need to see other apps or folders if there's a reference to them in order to add the correct typing. Specifically, you should look at the my_project/sample_app folder for examples of how typing is applied to maintain consistency.
Key Guidelines:
What to Type:
• Function parameters: def func(param: ConcreteType) -> ReturnType:
• Return types: -> Response, -> None, -> list[str]
• Generic types where needed: dict[str, str], list[SomeModel]
• Class method signatures: def method(self, param: Type) -> ReturnType:
What NOT to Type (unless mypy explicitly requires it):
• Function local variables: retry_count = 6, data = {"key": "value"}, response = self.api_call()
• Class attributes with obvious values: api_name = 'api-name' (not api_name: str = 'api-name')
• Variables where type is inferred: matching_models_list = [] (not matching_models_list: list[Type] = [])
• Exception classes unless they have custom behavior beyond standard Python exceptions
• Simple dataclasses that already have field type annotations
Type Improvement Priorities:
1. Replace Any with concrete types when you can determine the actual type from context, imports, or usage
2. Verify existing type annotations are accurate and not overly broad
3. Use more specific types where possible (e.g., dict[str, str] instead of dict[str, Any] if the values are always strings)
4. Use modern Python syntax: use Type1 | Type2 instead of Union[Type1, Type2]
5. Preserve existing good typing: Don't change well-typed code just for the sake of change
6. Only define custom types if necessary: Only if it's currently untyped or wrongly typed. Don't add custom types just to copy my_project/my_app
7. It is okay not do to anything: If current codes are already typed correctly, it is okay not to change anything
Code Style Requirements:
• Preserve all existing comments: Never remove or modify existing comments - they often contain important context
• Add "TODO: please check this type" comments only on lines where you are genuinely uncertain about the type
• Use direct type references: use MyClass not 'MyClass'. Use forward reference only if it's necessary
• Follow existing patterns: If a file already has a typing style, maintain consistency
What to Avoid:
• Adding types to obvious assignments: self.logger = logger doesn't need : logging.Logger
• Over-typing simple operations: result = [] doesn't need result: list[Item] = []
• Modifying working code that already has proper typing
• Adding unnecessary complexity to exception classes or simple data structures
Verification Process:
• Run mypy first to see what it actually requires
• Only add annotations for mypy errors, not for "nice to have" typing
• If mypy passes without a type annotation, don't add it
• Focus on fixing actual mypy failures, not improving already-working code
Verification: Ensure these tools pass, you might want to activate the virtual env in .venv first:
• uv run flake8
• uv run black --check --diff .
• uv run mypy my_project/my_app
• uv run isort --check --diff .
Albert Sundjaja
0 comments