Pinky and the Brain: my agent/subagent duo

OpenCode‘s agents configuration and Beads. A match made in heaven.

My flow until now

Working on a task starts with the Plan agent. I provide an initial prompt of what I want to achieve and the agent responds with a plan. If the plan needs adjustments I ask the agent to update it. When I’m satisfied with the final outcome I move to the execution of the plan. This will happen in one of two ways:

  1. If the context window is still small I simply change agents1 (move to Build) and ask it to proceed with the execution.
  2. If the context window is already big I ask the agent to save the plan in a markdown file, start a new session and ask the Build agent to read the file and execute the plan.

This flow works but there are a few drawbacks that bother me:

  • There is no human in the loop. I end up reviewing all changes at the end of the execution.
  • Even if I start a new session, depending on the size of the plan, the context window might get big causing the agent to misbehave. Especially in changes that must be repeated.
  • I usually use Opus for planning and Haiku for execution. There are times though that I forget to make the change ending up using Opus for everything. Opus is good but is also expensive!
  • You can’t easily pause the flow and continue from where you stopped.

My new flow

My new flow is based on one agent, one subagent and a database. In particular:

  1. Like before I start with an agent that will help me build a detailed plan that consists from a number of tasks.
  2. When I’m happy with the plan I ask the agent to use Beads and save each task under an epic.
  3. Then I ask the agent to start the execution loop.

Execution loop

  1. The agent uses Beads to figure out which task must be executed. It changes its status to in_progress and asks the subagent to execute it.
  2. The subagent reads the task, makes the necessary changes and informs the agent that it finished.
  3. The agent asks me to review the changes and approve them or not.
  4. If I approve the changes, the agent commits them, close the task and move to the next one.
  5. If I request changes, the agent asks the subagent to make them. At this point we move to step 2 again. We remain at this inner loop until I give my approval.

Pinky and the Brain2

If you didn’t make the connection yet, Brain is the name I gave to the agent (type primary) and Pinky is the subagent.

I did not created them on my own. I asked OpenCode to help me by describing the flow I wanted. OpenCode read its own docs, asked me a couple of clarifying questions and came up with these:
Brain: https://gist.github.com/le0nidas/aae1c9f1b35110a00b7157b6c2437444
Pinky: https://gist.github.com/le0nidas/b8a3a89131a639e39e42f7aaf794cf33

Benefits

  • I am finally in the loop. I review fewer changes at a time and sooner!
  • Using subagents for each task keeps both the agent’s and the subagent’s context window smaller and cleaner ending up in fewer, to none, misbehaviors.
  • Brain is tied with Opus and Pinky with Haiku. No need to remember to change anything!
  • The best of all, with Beads I can pause and resume whenever I want. The agent knows where to start from!

PS: if you are part of team and don’t want to pollute the codebase with various configurations, you can (a) init beads in stealth mode and (b) exclude .opencode folder from git

  1. according to the docs, all primary agents share the main conversation hence share the same context window ↩︎
  2. https://www.imdb.com/title/tt0112123/ ↩︎

Working with checkpoints

There are times that my workflow involves a lot of small and consecutive commits. Commits that their message does not really matter since I will squash them into one that describes my work.

An example is when TDDing a certain functionality. In that case I usually write the test, make it pass and finally make a commit.

Why am I doing that? I see it like small checkpoints. I conclude a part of the functionality so I save it. This helps in restoring my code back to last point that I was happy with its state.

One commit

When I first started working this way I was making a distinct checkpoint for each part. Soon enough I realized that these commits didn’t provide any value. I was making them quick for just saving the code and their message was something like save or checkpoint or t.

So instead of doing this and having to squash lots of commits I started using amend. One commit for the first checkpoint and amend for the rest of them. This way, when I’m finished, I rename the HEAD of the branch to something descriptive and move on.

Lots of steps for one commit

I write my code using an IDE (Android Studio or Intellij IDEA) but when it comes to git I move to a terminal.

This means that for committing I have to (1) move to the terminal, (2) make the proper commit/amend and (3) move back to the IDE. Three steps for one save!

Alt + P

So I decided to fix it.

First the bash script that makes the commit:

#!/bin/bash
CHECKPOINT="checkpoint"
git add .
if [[ "$(git log –format=%B -n 1 HEAD | cat)" == "$CHECKPOINT" ]]; then
git commit –amend –no-edit
else
git commit -m"$CHECKPOINT"
fi
view raw checkpoint.sh hosted with ❤ by GitHub

A simple script that either makes a commit with the message checkpoint or amends the staged changes.

Second the import of this script to the IDE:

The Intellij platform provides a functionality called External Tools:
– Go to Settings -> Tools -> External Tools and click on the add button.
– Set the path of your script where it says Program .
– Disable the Open console for tool output if you don’t want to see the result of your script.

At this point you can either use checkpoint as an action (double shift, type checkpoint) or you can go a step further and create a keyboard shortcut:

Go to Settings -> Keymap -> External Tools -> Right click on the script -> Add Keyboard shortcut.

So now every time I want to create a checkpoint I simple press `Alt + P` and continue working without moving from one program to another!

This is how I use Todoist

Disclaimer: this is not a paid post. I wrote it because I like the app and find it helpful. I also want to see, in a year, what has changed in the way I use it.

I always have a notebook next to my keyboard. I use it when trying to solve a bug or put in place a new feature. There was also a time that I used it to plan my day or keep notes for things that I wanted to ask or communicate. That didn’t last long since it wasn’t scaling!

That’s when I decided to move to a digital solution and search for the best to-do app. To be honest I can’t remember how I found out about Todoist. What I do remember though was that I did not check any other apps. Both its amazing human language parser and its shortcuts got me hooked immediately!

My usage

A little context. I use Todoist for over a year and only for work. That means that I don’t take advantage of their projects support. Every task gets added to the #Inbox which is my main driver. Throughout this year I’ve tried many setups and ways to incorporate my needs into the app. Here is how I use it:

Plan my day by setting the tasks that need completion

Every morning I see what needs to be done and create a task for it.

That does not mean that I open the company’s project management tool and copy whatever is assigned to me. I add only what cannot be tracked by the management tool. For instance, if a PR of mine got approved I add a task to merge my work in the main branch.

Also, if a meeting ends up with a couple of actionable items for me, I make sure to add them to Todoist. For example, talk to product about blah blah, comment on this thread, read that article, etc.

Another great source of action items is email. I go by them one by one and if something requires my attention I make a task for it.

Help me build habits

I try to cut down any distractions and one of them is looking at my emails every once in a while. What seems to work for me is to check them in the morning and create, if needed, tasks from them.

To force me in making it a habit I created a task that reminds me every weekday at 8:55 am to check my emails. This is 5 minutes earlier than when I start working so it gets registered, in my mind, as the first thing to do.

To show you the power of Todoist, for creating this task you need to write:

Check emails every weekday at 8:55

It will know what to do:

Reminders

Having a recurring task with a reminder is a good way to document things that do not belong anywhere else.

For example, every two weeks, on a Monday, I need to archive a column in our team’s board and create a new one.

Again, you can write it down

Archive column, create new every two weeks starting mon

and Todoist will understand it:

Write topics, questions, thoughts

Not everything is a task that needs completion. There will be topics and questions that must be communicated in a recurring meeting.

This is where I use labels for each meeting type and a task, with no date, for the topic/question.

This way, every time I am in one of these meetings, I open the label and have a list of what I wanted to discuss.

A task with no date and no label is also my way to write down my thoughts/ideas about the project. A possible refactoring, research for a new tool. Things that I need to get off my head but without setting a deadline.

Filters

I couldn’t close this post without mentioning filters. A feature that took me a while to use but can’t live without it anymore.

Better show you what I mean:

So, this is a filter I run every morning to see:

  • today’s high-priority (P1) tasks or
  • what needs discussion in the team’s stand-up

Another example is

that I use to resurface the thoughts and ideas that I mentioned before.