Astra

Astra Agent

The agent that knows you. A hosted, multi-tenant Distributed Enriched-Persona Agent (D.E.P.A.) — coherent, accountable, and private by default.

open source Python 3.12+

A different kind of agent

Astra Agent separates five concerns that most AI agents collapse together: persona (how it should behave), memory (what durable context it may recall), conversation (what you're asking right now), delegation (what bounded work a remote agent may execute), and policy (what's allowed and who approved it). That separation is the source of everything else.

How it fits together

Astra Agent Control Plane
Persona Contract Memory Engine Conversation Orchestrator Delegation Planner
Policy Engine Audit Trail ARA Registry
MariaDB Qdrant S3 / MinIO
Astra Remote Agent
mTLS identity bounded lease explicit capabilities read-only repo

What sets it apart

Memory you control

Every memory has source provenance. You can inspect, promote, reject, replace, and delete records. Candidates stay excluded until approved. Contradictions replace priors atomically — no silent drift. MariaDB is always the authorization authority; Qdrant only ranks what's already authorized.

Remote execution as a security boundary

Remote agents (ARAs) authenticate with mTLS certificates. They pull bounded, capability-scoped leases. The implemented repository ARA is read-only and cannot escape its configured root. No ambient access — only explicit task-scoped packets.

Append-only audit

Conversation receipt, context compilation, model requests, task creation, ARA progress, approvals, memory transitions, and artifacts — all produce structured audit events. You can trace why something happened, not just what was said.

Your input is never lost

Raw messages persist before any optional processing. If memory extraction, Qdrant sync, or delegation fails, your input remains durable. Conversation latency is independent of local-model or vector database availability.

Bounded context, not unlimited prompt

Persona and memory are compiled into a bounded briefing — not an ever-growing transcript. This reduces model cost, improves coherence, and keeps sensitive context contained. Persona profiles are versioned, auditable, and immune to automatic memory modification.

Multi-tenant by design

Every durable entity is tenant-scoped. MariaDB enforces ownership. Qdrant payload filters include tenant metadata as defense-in-depth. ARA certificates encode tenant identity. Cross-tenant isolation is an architectural guarantee, not a prompt convention.


The core loop

1

User sends a message

Raw input is persisted immediately — before any processing. If anything fails downstream, your message is never lost.

2

Persona and memory are compiled

A bounded context briefing is assembled from the stable persona contract, authorized memory records (MariaDB), and conversation history — not an ever-growing prompt.

3

Conversation is orchestrated

The main model (OpenRouter) receives the compiled briefing. Policy evaluation determines what's allowed. If the request needs external work, a typed delegation plan is created.

4

ARA executes with a bounded lease

An Astra Remote Agent authenticates via mTLS, pulls a capability-scoped, time-limited lease, and executes only the work it's authorized to do. No ambient access.

5

Evidence is synthesized into a response

ARA results — with file and line evidence — are compiled with provenance. Partial failures are transparent. Every system action appends an audit event.


A governed record, not opaque vectors

Raw Message Structured Extraction Candidate Review MariaDB Authority Qdrant Ranking Bounded Briefing
1

Every memory has provenance

Source message, extraction event, and lifecycle transitions are all recorded. You can trace why a memory exists — or who deleted it.

2

You control what stays

Candidates are excluded until promoted or explicitly high-confidence. You can inspect, reject, replace, and delete records. Contradictions atomically replace priors — no silent drift.

3

MariaDB is always the authority

Qdrant ranks memories but never authorizes them. Deleted records are immediately unauthorized even if vectors remain stale. Payload filters include tenant metadata as defense-in-depth.

4

Persona is protected from memory drift

The authored persona core is versioned, auditable, and immune to automatic memory modification. Learned adaptations are attributable, inspectable, and reversible.


How it compares

ConcernPrompt-centric agentVector-memory chatbotAstra Agent
PersonaLarge mutable promptPrompt textStructured stable kernel
MemoryTranscript / historyNearest chunksStructured records + provenance
Memory controlDelete historyOften coarseInspect, review, replace, delete
Retrieval authApplication-dependentVector filtersMariaDB authority + vector intersection
Remote executionAmbient processUsually nonemTLS ARA + capabilities + lease
ApprovalsPrompt conventionUsually noneDurable policy and approval state
AuditLogsChat historyAppend-only domain events
Failure recoveryRetry whole promptRetry queryRaw input durable; queue planned
Context costGrows with historyChunk injectionBounded compiled briefing

Built with

Control Plane

FastAPI · Python 3.12+ · uv monorepo · OpenRouter main model · swappable local model for memory extraction

Persistence

MariaDB (authoritative state + authorization) · Qdrant (semantic ranking) · S3/MinIO (artifact storage) · Alembic migrations

Identity & Security

OIDC user auth · mTLS ARA identity · Vault PKI · default-deny capabilities · tenant isolation

Clients

Textual TUI (terminal interface) · ARA SDK for remote agents · REST API with versioned routes

Run it yourself

# Clone and sync
git clone https://github.com/jcplaboratory/astra-agent.git
cd astra-agent
uv sync --all-packages

# Start the control plane
uv run astra-agent

# In another terminal, launch the TUI
uv run astra-tui

# API docs at http://127.0.0.1:8000/docs
# Health check at http://127.0.0.1:8000/health

The full secure stack (MariaDB, Qdrant, MinIO, Keycloak, nginx mTLS, Vault PKI) is available via the interactive installer: bash install.sh. See the README for complete documentation.