← Portfolio
2026–Present In progress

Aura

A personal agentic assistant platform — one core, many channels.

Solo build — architecture, code & ops.

Aura is my own agentic LLM assistant platform, built from scratch to get hands-on with real-time APIs, speech pipelines, agentic LLM integration and hexagonal architecture in practice. The agent uses tools, reads files and operates on the file system to complete tasks; multiple client channels — web, voice, messaging — consume one shared core. Single-user, green-field, designed in the open with ADRs and a written design diary.

  • AgentGateway: defines, configures and executes agents through pluggable adapters (Claude Code CLI, Codex CLI…).

  • Web chat with multi-turn memory, a sidebar and multi-chat — four user journeys live.

  • Speech pipeline: speech-to-text via OpenAI Whisper and text-to-speech via OpenAI.

  • Pluggable persistence: in-memory and SQLite repositories behind the same ports.

The choices I made, and what they cost.

  1. Hexagonal architecture (ports & adapters)

    Decision

    A clean domain split into bounded contexts — AgentGateway, Chats, Assistants, Schedulers, Speech, Files, Notifications — with every external concern behind a port.

    Why

    Keeps the agent runtime, storage and channels swappable without touching the core — the whole point of a platform meant to grow new clients and providers.

    Trade-off

    More upfront ceremony and indirection than a layered MVC app; it pays off the moment the second adapter lands.

  2. Agents as adapters (ADR-001)

    Decision

    The agent runtime itself is an adapter. The first one wraps the Claude Code CLI; a Codex CLI adapter is next.

    Why

    Lets Aura host different agent backends through one gateway interface instead of hard-coding a single vendor.

  3. .NET 10 + Blazor Server (ADR-002)

    Decision

    ASP.NET Core on .NET 10, with a Blazor Server composition root and UI.

    Why

    A deliberately locked learning vehicle — staying on my core platform to go deep rather than chase a new stack.

  4. API-first, multi-channel core

    Decision

    One shared core exposed API-first, with web, voice and messaging as thin clients.

    Why

    So adding a channel is a new client, not a new backend.

  5. Deterministic acceptance tests over Kestrel

    Decision

    Playwright acceptance tests run against a real Kestrel host by default; opt-in E2E tests hit the real Claude CLI.

    Why

    Fast, deterministic feedback on every change, with realistic end-to-end coverage available on demand.

Aura is where I get to be the architect on a green-field system: no legacy, no deadlines, just the decisions. ADRs and a written design diary keep me honest — and building my own agent platform turns out to be the fastest way to actually understand the tools I use every day.