My current vision, and prototype, is that it should be as close as possible to a "real" language as possible so that both the user and the agent know immediately how to use it and how it functions.
So for `pi` it means using typescript.
Then the UI is derived from the AST / code as much as possible and for things that aren't neatly possible like that I eventually add small semantic helpers that define the UI.
For example "plan -> execute" is:
await flow.unroll(
remaining.map(point => ({
key: point.id,
label: point.objective,
})),
async () => {
for (const point of remaining) {
await flow.item(point.id, async () =>
await flow.agent(executePoint, {
title: `Point ${point.id}`,
prompt: point.objective,
}));
}
},
{ title: `Plan r${planRevision}` },
);
( simplified code )
in my implementation and `unroll` is only there to have a nice ● Plan r1 · 1/3 · active
1. Inspect parser behavior
● 2. Add empty-input coverage
○ 3. Run focused checks
UI instead of a plain "Plan · 1/3" UI with no detail (which would happen if I just used a for loop, yes it works)I don’t know yet if it’s a good solution. But only thinking in terms of files / filesystem sure make things easier.
Also makes branching “easier”: no handling of merging or conflicts, the receiving agent just gets N file systems and decides how to handle things.
Congratulations, and wishing you the best with this release!