The runtime, written in Rust

The engine runs on your machine. Your agents are plain Python.

Apollia OS installs like any other application and leaves behind a program that runs in the background with no window of its own. That program is the one that talks to the model, runs the tools, applies your rules and counts the steps.

Three doors, one engine, and it sits on your disk.

Exactly what the preview covers

0.2.0-preview · Rust and Python · Apache 2.0 or MIT

digest.py Python
from apollia import agent, skill
from apollia.types import Ctx


@agent(name="digest", version="0.1.0", description="Sums up a page for you.")
class Digest:
    @skill("digest.summarize", description="Sums up a web page in five points.")
    async def summarize(self, url: str, ctx: Ctx) -> str:
        page = await ctx.tools.call("web_read", {"url": url})
        reply = await ctx.llm.chat("Sum it up in five points.", page["content"])
        return reply.content
A complete Apollia agent: a Python class, one decorator above it, one async method inside, nothing to inherit from. What each piece does
YOUR FIRST AGENT

A whole agent fits in ten lines.

Here is the file from the top of the page, this time annotated. This is not an excerpt picked to look good. It is the whole file, and every piece of it is explained opposite.

  • @agent

    The decorator that sits on the class. It carries the name, the version, the description, and whatever the agent needs in order to work.

  • @skill

    One capability, with its identifier. The schema of the parameters is derived from your method signature.

  • ctx

    The context the runtime hands to your method. Fifteen services are already wired into it. You instantiate none of them.

  • The example agent, in the repository The step by step guide to a first agent
digest.py Python
from apollia import agent, skill
from apollia.types import Ctx


@agent(name="digest", version="0.1.0", description="Sums up a page for you.")
class Digest:
    @skill("digest.summarize", description="Sums up a web page in five points.")
    async def summarize(self, url: str, ctx: Ctx) -> str:
        page = await ctx.tools.call("web_read", {"url": url})
        reply = await ctx.llm.chat("Sum it up in five points.", page["content"])
        return reply.content
WHAT RUNS WHILE YOU WORK

One program in the background, two it watches, one folder on your disk.

There is no fourth piece, no service waking up somewhere else, no account to attach. Here are the three, in the order they matter to you.

What runs on your machine when Apollia runs. No remote service at the other end, no account to create before you begin.

The journal What an agent does is written to an append only register, chained by hash and signed. What it proves, and what bounds it

In detail The building blocks of the system, in the documentation

What it changes that all of this runs at your place

THREE WAYS TO TALK TO IT

By clicking, by typing, or from your own programs.

The choice commits you to nothing: the three doors open onto the same engine, with the same rules and the same journal.

  1. The desktop app

    Tauri 2 · Svelte 5

    This is the door by default, the one that opens after the install and walks you through picking your model. You hold your conversations in it, you connect your accounts, and you set what an agent may do and what it may keep.

  2. The command line

    apollia-os · --json

    The binary is called apollia-os. Forty families of commands, a hundred and ninety nine invocable commands, named noun first and verb second, which you guess more than you learn.

    A --json flag, accepted at any position, gives you output written to be read by a program rather than by you.

  3. Your own code

    127.0.0.1:7771 · local socket

    This is the integrator door, and it is exactly the one the other two go through: the app and the terminal talk to this interface. A hundred and nine HTTP routes, described by an OpenAPI specification generated from the code rather than maintained beside it.

    Two ways in. A file socket, where the permissions of the operating system do the work. And local port 7771, where a token is mandatory, the equivalent of a password.

And a run does not need you in order to start.

A time of day, a regular interval, one single date, a file landing in a watched folder, or an incoming call whose signature is checked.

BETWEEN YOUR SENTENCE AND THE RESULT

It chains steps on its own, it asks before the ones that matter, it stops where you said.

Three mechanisms, in the order they apply.

The loop
and it starts again from the top
  1. It reads
  2. It picks a move
  3. Apollia runs it, or asks you
  4. It reads the result

It stops: answer handed back, or limit reached.

Four beats that repeat: it reads, it picks a move, Apollia runs it or asks for your go-ahead, it reads the result. The loop stops when the answer is handed back, or when the limit you set is reached.
  1. It reads

    Your request, what it has already done, and the tools it is allowed to call.

  2. It picks a move

    Rather than answering you, it asks for a tool.

  3. Apollia runs it, or asks you

    Your rules are re-read at that exact moment. If none of them covers the call, everything stops and waits for your go-ahead.

  4. It reads the result

    It works out what follows, and goes round again, or hands you its answer.

The decision, on every tool call
  1. Your rules come first. They are re-read on every call, not once when the conversation opens.
  2. A refusal wins. Always, including over a tool you allowed somewhere else.
  3. An authorisation runs the call directly.
  4. And if nothing settles it, the question comes back to you.

Two tools escape every shortcut: the one that runs a command and the one that executes Python. Those two are put to you every single time.

The three limits, and you are the one who sets them
The number of steps
How many times it may think before handing control back to you.
The number of tool calls
How many moves it may make in total.
The duration
The point at which the run stops, finished or not.
Steps 10 left
Tool calls 10 left
Time 10 s left

Three limits, counted by Apollia and out of the agent’s reach: the number of steps, the number of tool calls, the duration. When one reaches zero the run stops, finished or not. The figures are the example’s; yours are set in the app.

One thing worth knowing before you install an agent that is not yours: this checkpoint covers the conversation. An installed agent that calls its own tools never meets it. Apollia bounds it, it does not lock it up, and the practical rule fits in one sentence: only install agents you wrote, or agents whose code you have read.

What an agent does, in plain language

WHAT AN AGENT CAN ACT ON

Tools inside the binary, your accounts above them, the rest through a standard.

Eighteen native tools are registered at startup, and the model knows how to use them from the first conversation.

FamilyToolsWhat they do
Your filessixRead, write, edit, list, search by name or by content.
Running codetwoA command, a Python script. Your go-ahead on every call.
The webtwoA search, then reading the page it found.
Your rulesthreeAdd, remove and list permission rules.
Jupyter notebookstwoRead a notebook, edit one of its cells.
Its memoryoneFind what it noted down, in full text.
YouoneWhen a piece of information is missing, it asks you instead of guessing.

Above them, your accounts.

Fifty one operations across Google Workspace and Microsoft 365. You connect from the app, by clicking, and your password never passes through Apollia.

And the rest of your tools, through a standard.

Apollia speaks MCP. Eighteen integrations arrive preconfigured, and the public catalogue of the standard is browsable from the app.

The native tools reference The accounts, the catalogue, and how they connect

IF YOU WRITE YOUR OWN

Four decorators, fifteen services, no library to install.

The development kit has no third party dependency: what you install in order to write an agent is Python, and nothing else.

  • @agent on the class

    The name, the version, the description, and what the agent declares it needs in order to work.

  • @skill on a method

    One identified capability, callable by you, by a trigger, or by another agent.

  • @on_message on a method

    The answer inside a conversation, with the history of the thread as a parameter.

  • @orchestrated on a method

    For an agent that draws up a plan before acting rather than chaining its moves as it goes.

And the context your method receives

One parameter, ctx, and fifteen services behind it. You instantiate none of them, you configure none of them, and you do not have to know which one talks to what.

  • ctx.llm The model: one answer, a stream, or a batch.
  • ctx.memory What it noted down, found in full text.
  • ctx.tools The tools, native and plugged in.
  • ctx.a2a Call a skill of another agent.
  • ctx.mail Drop a message to another agent, without waiting.
  • ctx.datasources The data sets declared in the decorator.
  • ctx.templates The text templates it declared, rendered with its variables.
  • ctx.secrets A secret, read at the moment of use.
  • ctx.events Publish on the stream the interface listens to live.
  • ctx.logger Write to the runtime journal.
  • ctx.profile What you have said about yourself.
  • ctx.workspace The rules of the working folder.
  • ctx.stt Turn sound into text.
  • ctx.notify Tell you on your desktop.
  • ctx.budget How many steps it has left. Read only, and that is the point.

The full reference for the kit, service by service

BEFORE YOU BUILD ON IT

What 0.1.0 covers, and how far.

A young product costs nothing. What costs is finding its edge once you have already built on it. Here are the four that matter, said now rather than in three weeks.

Text, and text only.

Source code, an accounting export, a mail thread, a contract, a spreadsheet exported to text: anything that is text goes through, and that is most of what you work on. Images and scanned documents are outside the scope of this version.

A memory that finds words.

It searches in full text and ranks by relevance, which makes it exact and predictable: you always know why a memory came back. It does not connect two different phrasings of the same idea, so you have to speak to it with the words it has already seen.

One install, one person.

Apollia runs under your account, with your rights, and works for you alone. There is no instance shared between several people, so there are no accounts to administer and no roles to hand out before you start.

What is written stays written.

There is no button that takes back an action already carried out. What protects you sits before and after: the go-ahead asked at the moment of the action, and the journal that keeps a record of every move.

The rest, including the answers that do me no favours, sits on a page of its own, written to be read before the install rather than after. The 23 questions, and my answers

Reading stops here. The rest you see for yourself.

You will learn more in one evening on your own files than by reading this page again. The download page tells you what you are about to run into before you run into it: the security warning your system raises on the first launch, what your machine needs, and the model you will have to pick.

0.2.0-preview · macOS, Windows, Linux · Apache 2.0 or MIT