What an agent is made of
I restarted a two-year project and refused to look at any of it. What I kept was one equation about what an agent is made of.
Most agent frameworks describe an agent as a prompt plus a set of tools. You write the instructions, you attach the functions it may call, and the framework runs the loop. That description is easy to explain and it stops being useful the moment an agent needs to remember anything, because memory is not a tool and it is not a prompt, and it ends up living somewhere outside the agent in a database you have to set up and connect yourself.
Motivation
In November 2025 I restarted the project on a different definition, and the whole of it fits on one line written on the first day:
I want to make Agent = AgentFlow (program) + module-configs. And then black-box the module interface as we will reverse engineer what has to occur. I think this is the clearest articulation of it yet.
An agent is a program, plus a set of installed modules that the program draws on. The rest of this is what a module turned out to be and why the interface was deliberately left undefined.
The restart rule
The restart came with a rule at the top of the first day's log, written in capitals:
THE PAST IS IRRELEVANT MEMORYLESSNESS MARKOV PROPERTY
A Markov process is one where the next step depends only on the current state and not on the path that produced it. Applying that to the prior work is a decision rather than an observation, and it is a useful one, because the alternative is carrying every earlier commitment into the new design as a constraint nobody has re-examined.
The same log is honest about what the restart was reacting to, which is that trying to get everything at once had been too much pressure without the speed to support it. The mission for day zero was a chat that passed messages back and forth, and a first prototype of the module system.
The module
The definition came out over an evening of me rejecting increasingly abstract descriptions until the mechanical one arrived:
they are prepacked units of functionality that bring their own model (database, all managed on idyllic), state, prompts, flows / functions and export methods, functions, tools, context that can be used within the agent builder
The package brings a data model, some state, prompts, and flows. What it hands back to the agent's program is tools, functions, methods, and context. A worked example makes it concrete:
install the telegram module and it creates a messages table, a contacts table, stores conversation state, includes prompts for handling telegram conversations, and exports tools like "send_message" and "get_conversation_history" that show up in your agent builder. you drag those tools into your flow, configure them, done.
The load-bearing detail is the tables. Installing the module creates them, on the platform, and you do not go and provision a database, because the module brought its own. That is the difference from a tool protocol, where what you get is a set of callable functions and everything they need to remember is somebody else's problem.
The derivation arrived from a direction I did not expect:
I think it basically is creating digital assets / resources, similar to creating a database or imagine a mini AWS. These resources would be stateful and they would have operations on them (this is the semantic objects thing again). So we give the agent a virtual environment
A mini cloud provider for one agent. Stateful resources with operations on them, which I noted in the same breath was an idea I had been circling since January under a different name.
Modules against agents
An aside from the same month says why modules are the right unit, and it disagrees with most of the field:
modules take advantage of the fact that multi-agent systems are already the most compatible composability layer but people are focused on the wrong thing, making them "multi-agent teams" when in fact they are separate functional units of a single agent
The common framing puts several agents in a room and gives them roles, a researcher and a writer and a critic, and has them talk to each other. The claim here is that this is a misreading of what the decomposition is for. Splitting the work is useful because each part gets its own context, its own data, and its own instructions, not because the parts are colleagues. Once you say it that way, the unit to package and share is a functional unit rather than a persona, and that is what a module is.
The module interface
The second clause of the founding line is the methodological one. I black-boxed the module interface and planned to reverse engineer what had to occur, which means the exact shape of the boundary was left undefined and allowed to be discovered by building against it.
That is the opposite of specifying an interface first, and it is right when you do not yet know what will cross the boundary. A specification written before any use is a guess with a commitment attached. Leaving it black and building three modules tells you what they all needed.
The form factor
Two weeks later the packaging question got answered by comparison to tools outside this field:
it's not a component library or a typescript framework it's a thing that uses typescript as a DSL substrate that leverages all of typescript flexibility while being embedded in a folder within another project
And more plainly:
i want to be convex for agents. drop it in your app you get a folder that defines code for your agent. cloud runtime on by default
A domain-specific language is a small notation built for one job. Using an existing language as the substrate for one, rather than inventing new syntax, is the same conclusion the notation work reached two months earlier from the other side. You do not need new syntax. You need an existing notation, used in a constrained way, with a runtime that gives the constraint meaning.
The infrastructure decision at the end of the month was made on the same priority:
I don't want to focus on infra I want to focus on dx, they upload code to us I want to wrap it and manage it
What shipped
The module system stayed a design. What shipped in the repository is the other half of the definition, which is the program, and it is a TypeScript class:
export default class SimpleSystem extends AgenticSystem {
@field query = '';
@field count = 0;
@action()
async increment(amount?: number) {
this.count += amount ?? 1;
}
}Two decorators carry the whole runtime. A @field is state that synchronises to every connected
client without anybody writing the synchronisation, and an @action is a method the browser can
call with its types intact. Streaming fields exist too, so a value can be appended to while a
model generates and the interface updates as it fills.
The reason this reads as a plain class is the argument the README makes for it, which is that a game developer does not implement networking or rendering before writing what happens when a character eats an apple. The infrastructure is not what distinguishes one game from another, so an engine absorbs it. The same claim about AI applications is that history, context, prediction, streaming and persistence are common to nearly all of them, and what differs is the intelligence design on top.
The substrate
By February the runtime underneath had become the thing in the way, and the diagnosis is specific rather than a change of heart:
i was stuck on the durable objects platform, cuz that's just the streaming runtime for the web but it actually needs complex agent code or cool agent ideas and i was stuck trying to come up with something cuz "10 agents streaming!" doesn't resonate anymore
The platform was Cloudflare Workers for Platforms with Durable Objects underneath, chosen in November over the alternatives I had been weighing for the realtime channel, which were server-sent events, plain WebSockets and Upstash. Durable Objects solve delivery, and they solve it well: a Durable Object is a single addressable instance that stays alive near its own storage, so state lives in one place and results stream out to a browser without a queue in the middle.
That is the right primitive for a collaborative document or a chat room. What it does not supply is the interesting part of an agent, and building on it had produced a demo whose most impressive property was concurrency. Ten agents streaming is a fact about the infrastructure, not about what the agents did.
The pull that replaced it was toward local agents, on the grounds that the use cases expand and the iteration is faster, and I named the problem with that direction in the same breath, which is that an open source framework for local agents is hard to sell. Leaving that tension unresolved is the honest place to stop, because it was unresolved.
The definition
The definition is the part I would keep. An agent as a program plus installed modules, where a module brings its own tables and its own state and exports the handful of things the program can call, is a sharper answer than a prompt plus tools, and the reason is that it puts memory inside the unit you install rather than outside it in infrastructure you assemble.