Skip to main content

Personal AI OS — kernel, drivers, skills, tools, and a web API

Project description

Macroa

CI codecov PyPI Python 3.11+ License: MIT

Your personal AI operating system. It runs on your machine, remembers everything you tell it, schedules tasks, routes to the right AI model automatically, and exposes a full HTTP API — all from a single command.

Core design rule: deterministic operations never call an LLM. AI is reserved for ambiguity, reasoning, and generation — keeping costs low and behavior predictable.

Star History

Star History Chart


What it does for you

It talks to you and remembers

macroa> what is the capital of France
macroa> remember my server IP is 192.168.1.100
macroa> what is my server IP?       ← answers instantly, no AI call, reads from memory

Facts you give it are stored locally in SQLite and persist forever. Close the terminal, come back in a month — it still knows.

It runs shell commands on your behalf

macroa> !df -h
macroa> !ls -la /var/log

The ! prefix bypasses AI entirely. Zero API cost, instant result. Shell output is captured and returned cleanly.

It picks the right model without you thinking about it

Say something complex and it escalates automatically. Use keywords to force it:

macroa> think carefully about the tradeoffs of microservices   → Sonnet (P-cores)
macroa> use the best model to analyze this architecture        → Opus (GPU)
macroa> what time is it in Tokyo                               → Haiku (E-cores)

Routing itself always uses the cheapest model (Gemini Flash Lite). You only pay for heavy AI when you actually need it.

It handles multi-step tasks end-to-end

macroa> write a comprehensive guide on home lab security hardening, networking, and monitoring

It automatically decomposes this into research steps, writing steps, and review steps — each running at the appropriate model tier — then combines everything into one coherent output.

It remembers sessions by name, across restarts

macroa --session work
# ... have a full conversation ...
# close the terminal, reopen tomorrow
macroa --session work    # full context restored

Named sessions persist to disk. Without a name, sessions are ephemeral.

macroa sessions list
macroa sessions delete old-project

It schedules commands to run automatically

macroa schedule add "morning-brief" "summarize my tasks for the day" "daily:08:00"
macroa schedule add "cleanup"       "!rm -rf /tmp/scratch"           "every:3600"
macroa schedule add "reminder"      "remind me to call John"         "once:1741600000"
macroa schedule list
macroa schedule delete <id>

The scheduler runs in the background and survives restarts. Supports once:, every:, daily:, and full 5-field cron expressions.

It extends with tools you install

Tools are Python scripts that integrate any API or service. The OS routes to them automatically based on what you say.

macroa install /path/to/my_twilio_tool     # from local directory
macroa install https://github.com/user/repo  # from git
macroa tools list
macroa uninstall my_tool

Once installed, just say "call me" or "send a message" — the kernel figures out which tool to use.

It has an HTTP API for other apps

macroa serve                          # starts at http://localhost:8000
macroa serve --host 0.0.0.0 --port 9000
curl -X POST localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{"input": "what is my server IP", "session": "work"}'

Your scripts, automation, and other apps can all talk to the same AI OS with the same persistent sessions.

It has a web dashboard

Open http://localhost:8000/dashboard after running macroa serve:

  • Total runs, failure rate, plan calls
  • Model tier distribution (how much went cheap vs expensive)
  • Active sessions and their turn counts
  • Scheduled task queue with next-run times
  • Audit log of recent activity

What it costs

Operation Cost Why
Shell command (!ls) $0 No AI involved
Memory read/write $0 Deterministic SQL
Routing (what do you want?) ~$0.0001 Gemini Flash Lite
Simple chat Low Haiku
"think carefully…" Medium Sonnet
"best model…" Higher Opus

Routing and memory operations — which are the majority of calls in normal use — cost nearly nothing. You only pay Opus prices when you explicitly ask for it.


Installation

git clone https://github.com/aniolowie/Macroa.git
cd Macroa
python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

# For the web API and dashboard:
pip install -e ".[web]"

cp .env.example .env
# Edit .env and add: OPENROUTER_API_KEY=sk-or-v1-...

Usage

REPL

macroa                           # ephemeral session
macroa --session work            # named persistent session
macroa --debug                   # show model tier and metadata

Built-in commands: clear · debug · help · exit / quit / q

Single-shot

macroa run "!uname -a"
macroa run "remember my timezone is UTC+2"
macroa run "think carefully about the CAP theorem"
macroa run --session work "what did we discuss yesterday?"

Sessions

macroa sessions list
macroa sessions delete <name>

Scheduler

macroa schedule add "label" "command" "every:3600"
macroa schedule add "label" "command" "daily:09:00"
macroa schedule add "label" "command" "once:1741600000"
macroa schedule add "label" "command" "cron:0 9 * * 1"   # 9am every Monday
macroa schedule list
macroa schedule delete <id-prefix>

Tools

macroa install /path/to/tool
macroa install https://github.com/user/repo
macroa install https://github.com/user/repo#subdir/tool
macroa tools list
macroa uninstall <name>

Web server

macroa serve
macroa serve --host 0.0.0.0 --port 9000 --reload

API endpoints:

Method Path Description
POST /run Run a command, get full response
GET /run/stream Run a command, stream via SSE
GET /sessions List named sessions
DELETE /sessions/{name} Delete a session
POST /schedule Add a scheduled task
GET /schedule List scheduled tasks
DELETE /schedule/{id} Remove a task
GET /audit/stats Aggregate usage stats
GET /audit/recent Recent run log
GET /dashboard Web dashboard UI
GET /health Health check

Writing a tool

Drop a directory into ~/.macroa/tools/ — or use macroa install — and it's picked up automatically on the next run:

~/.macroa/tools/
  my_tool/
    tool.py      ← required
    .env         ← optional: MY_API_KEY=... (loaded automatically)
    helpers.py   ← optional: any other files

tool.py template:

from macroa.tools.base import BaseTool, ToolManifest
from macroa.stdlib.schema import Context, DriverBundle, Intent, SkillResult

MANIFEST = ToolManifest(
    name="my_tool",
    description="Does X when the user asks for Y.",
    triggers=["do X", "run Y"],
    persistent=False,   # True = heartbeat() fires every 60s
    timeout=30,
)

class MyTool(BaseTool):
    def setup(self, drivers):
        pass  # called once on load

    def execute(self, intent: Intent, context: Context, drivers: DriverBundle) -> SkillResult:
        # never raise — always return SkillResult
        return SkillResult(output="done", success=True, turn_id=intent.turn_id)

    def heartbeat(self, drivers):
        pass  # only called if persistent=True

    def teardown(self, drivers):
        pass  # called on shutdown

See macroa/tools/examples/call_me/ for a complete reference implementation (Twilio phone call).


Tests

pytest tests/ -v
pytest tests/ --cov=macroa --cov-report=term-missing

170 tests, zero external dependencies required (unit tests mock all LLM calls).


Configuration

All settings are environment variables. Copy .env.example for the full reference.

Variable Default Description
OPENROUTER_API_KEY Required
MACROA_MODEL_NANO google/gemini-2.5-flash-lite Routing tier
MACROA_MODEL_HAIKU anthropic/claude-haiku-4-5 E-cores tier
MACROA_MODEL_SONNET anthropic/claude-sonnet-4-6 P-cores tier
MACROA_MODEL_OPUS anthropic/claude-opus-4-6 GPU tier
MACROA_CONTEXT_WINDOW 20 Rolling turns kept in RAM
MACROA_MEMORY_BACKEND sqlite sqlite or json
MACROA_TOOLS_DIR ~/.macroa/tools User-installed tools
MACROA_HEARTBEAT_INTERVAL 60 Seconds between heartbeat ticks
MACROA_SESSIONS_DB_PATH ~/.macroa/sessions.db Named session store
MACROA_SCHEDULER_DB_PATH ~/.macroa/scheduler.db Scheduled task store
MACROA_SCHEDULER_POLL 10 Seconds between scheduler ticks
MACROA_AUDIT_DB_PATH ~/.macroa/audit.db Audit log
MACROA_NETWORK_TIMEOUT 30 HTTP timeout for tools

Architecture

User input
    │
    ▼
┌─────────────────────────────────────────────────────┐
│  CLI  (macroa / macroa run "...")                   │
│  macroa serve → FastAPI (HTTP + SSE + Dashboard)    │
└───────────────────────────┬─────────────────────────┘
                            │ kernel.run()
                            ▼
┌─────────────────────────────────────────────────────┐
│  KERNEL                                             │
│  Router(NANO) → hard-route (!cmd) or LLM classify  │
│  Planner(NANO) → decompose complex tasks            │
│  Dispatcher → skill.run() with escalation loop     │
│  Combiner(HAIKU) → assemble multi-step results      │
│  SessionStore → named sessions, context persistence │
│  Scheduler → cron/once/every/daily background tasks │
│  AuditLog → every call recorded automatically       │
│  EventBus → pub/sub for tools and heartbeat         │
└──────────────┬──────────────────────────────────────┘
               │
     ┌─────────┴──────────┐
     ▼                    ▼
┌─────────┐     ┌──────────────────────────────────┐
│ SKILLS  │     │ TOOLS (userspace programs)       │
│ shell   │     │ ~/.macroa/tools/<name>/tool.py   │
│ file    │     │ BaseTool: setup/execute/heartbeat │
│ memory  │     │ HeartbeatManager (persistent)    │
│ chat    │     │ Installer: local path or git URL  │
└────┬────┘     └──────────────────────────────────┘
     ▼
┌─────────────────────────────────────────────────────┐
│  DRIVERS (hardware abstraction)                     │
│  llm     → OpenRouter (NANO/HAIKU/SONNET/OPUS)     │
│  llm     → streaming variant (SSE)                 │
│  shell   → subprocess, stdout/stderr capture        │
│  fs      → filesystem, $HOME-scoped                 │
│  memory  → SQLite (facts + episodes) or JSON        │
│  network → HTTP client (stdlib, no extra deps)      │
└─────────────────────────────────────────────────────┘

Model tiers — hardware analogy

Tier Hardware Default model Role
NANO Microcontroller google/gemini-2.5-flash-lite All routing, trivial ops
HAIKU Efficiency cores (E-cores) anthropic/claude-haiku-4-5 Lightweight tasks
SONNET Performance cores (P-cores) anthropic/claude-sonnet-4-6 Quality work
OPUS GPU anthropic/claude-opus-4-6 Heavy reasoning

Escalation is automatic: if a skill returns needs_reasoning=True, the kernel promotes to the next tier and retries — up to two escalations per call.

Memory layers

Layer Storage Contents
Working RAM (ContextManager deque) Current conversation turns
Semantic SQLite facts table User facts, preferences — expirable, confidence-scored
Episodic SQLite episodes table Session summaries, searchable by topic
Session SQLite sessions.db Named sessions + persisted context (survives restarts)

Project layout

macroa/
├── stdlib/
│   ├── schema.py          # All shared dataclasses
│   └── text.py            # Deterministic string utilities
├── config/
│   ├── settings.py        # Env/settings singleton
│   └── skill_registry.py  # Auto-discovery of skills/tools
├── drivers/
│   ├── llm_driver.py      # OpenRouter via openai SDK (+ streaming)
│   ├── shell_driver.py
│   ├── fs_driver.py
│   ├── memory_driver.py   # SQLite (facts + episodes) or JSON
│   └── network_driver.py  # HTTP client (stdlib)
├── skills/                # Kernel built-ins (deterministic)
│   ├── shell_skill.py
│   ├── file_skill.py
│   ├── memory_skill.py
│   └── chat_skill.py
├── kernel/
│   ├── context.py         # Rolling context window
│   ├── escalation.py      # Tier selection and promotion
│   ├── router.py          # Intent classification
│   ├── planner.py         # Task decomposition
│   ├── dispatcher.py      # Escalation loop
│   ├── sessions.py        # Named sessions + context persistence
│   ├── scheduler.py       # Cron/once/every/daily task scheduler
│   ├── events.py          # Pub/sub event bus
│   ├── audit.py           # Immutable run log
│   └── __init__.py        # Public: kernel.run()
├── tools/
│   ├── base.py            # BaseTool + ToolManifest
│   ├── registry.py        # Tool discovery and loading
│   ├── runner.py          # Timeout + error isolation
│   ├── installer.py       # Package manager (local + git)
│   ├── heartbeat.py       # Persistent tool daemon
│   └── examples/
│       └── call_me/       # Reference implementation (Twilio)
├── web/
│   ├── app.py             # FastAPI app (REST + SSE)
│   └── static/
│       └── dashboard.html # Web dashboard UI
└── cli/
    ├── renderer.py        # Rich terminal output
    └── main.py            # Click CLI + REPL

Phase 3 (planned)

  • Vector memory — semantic search via embeddings replacing substring match
  • Streaming chat in the REPL — output appears token by token
  • Multi-user web sessions with auth
  • Cost tracking per session — dollar amounts in the dashboard
  • Tool marketplace — curated index of installable tools

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macroa-0.2.1.tar.gz (112.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

macroa-0.2.1-py3-none-any.whl (94.0 kB view details)

Uploaded Python 3

File details

Details for the file macroa-0.2.1.tar.gz.

File metadata

  • Download URL: macroa-0.2.1.tar.gz
  • Upload date:
  • Size: 112.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for macroa-0.2.1.tar.gz
Algorithm Hash digest
SHA256 9eba00372b3e7299ed75b3c708a83ace3719672da9df8ed95c42f5242cd4c318
MD5 a20ab5848f304e1fb4541b77a14f4f07
BLAKE2b-256 5aa243cb5d4670ea6b4a6a4c20fff1481db327c7bb2ff1a089fdc12020f88716

See more details on using hashes here.

Provenance

The following attestation bundles were made for macroa-0.2.1.tar.gz:

Publisher: release.yml on aniolowie/Macroa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file macroa-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: macroa-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 94.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for macroa-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 51f75616f400a2fc3c499d45c8c2063017494fc7ebe326278b9d2a2ecb68e969
MD5 6005492f32bb65eff8f6747fce28b9ed
BLAKE2b-256 09dac8b5310e5ba66d56c9b098d487494b518532cd61b5babc9a959f3ad27880

See more details on using hashes here.

Provenance

The following attestation bundles were made for macroa-0.2.1-py3-none-any.whl:

Publisher: release.yml on aniolowie/Macroa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page