Painless Agent is a self-hosted autonomous agent runtime designed for long-running workflows, persistent memory, and structured task execution. The runtime is built in Go with PostgreSQL, pgvector, and Redis as the persistence and caching layer, and abstracts across multiple LLM providers through a single interface.
The Reliability Problem
Most agent frameworks are stateless. They run until the context window fills, the process restarts, or the workflow deviates from the happy path. That works for short conversations. It breaks down for tasks that need to plan across sessions, recall prior decisions, and recover from partial failures.
The system needed a durable execution model: explicit task state, persistent memory that outlasts the process, and failure recovery that does not require starting over.
What I Built
- Designed and implemented a task runtime in Go with structured decomposition, dependency-aware scheduling, and a finite-state execution model covering success, failure, and abandonment.
- Built a dual-layer memory system using Redis for short-term session state and pgvector for long-term semantic retrieval across sessions.
- Implemented a reflection system that evaluates task outcomes after completion and writes structured notes back to long-term memory to improve future runs.
- Built a skill registry that allows new tools and capabilities to be registered without modifying the core runtime.
- Designed an LLM provider abstraction supporting OpenAI, Anthropic, and GitHub Copilot through the same interface, enabling per-task model routing.
- Implemented SSE streaming for real-time task progress updates with Redis-backed event buffering for reconnecting clients.
- Managed schema evolution across PostgreSQL and pgvector using Goose migrations with versioned, reviewable history.
Durable Shape
The architecture became reliable once each layer had a single, clear responsibility. The task store owns execution state. The memory system owns recall. The skill registry owns tool access. The LLM abstraction owns model routing. None of those responsibilities overlap.
That separation made it possible to evolve each layer independently. The reflection system was added after the core runtime was stable. The provider abstraction made it straightforward to route planning tasks to a reasoning model and execution tasks to a faster one, without touching the task logic.
The next phase is containerized sandboxed execution, browser tooling, and a web dashboard for workflow visibility.