Skip to content

chnghia/atomic-stateful-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Atomic Stateful Agent (ASA)

A structured boilerplate for building Stateful Agentic Systems using LangGraph.

This project acts as the "Heart" of the A.S.G Stack (Atomic - Stateful - Generative). It is designed to bridge the gap between probabilistic LLM outputs and deterministic business processes. Unlike typical chatbots that rely on ephemeral conversation history, ASA treats user interactions as Stateful Business Transactions.

Philosophy

This project implements the "Controlled AI" paradigm, ensuring that agents follow strict architectural patterns rather than free-form conversation:

  1. Sticky Routing (Contextual Integrity): We prevent "hallucinated context switching." Once a sub-agent (e.g., Daily Log) locks onto a user intent, the router enforces a "Sticky Lock" (active_intent). The conversation stays within that specific domain until the task is explicitly completed or canceled.

  2. The Draft-Commit Protocol: Database writes are never immediate. User intent acts on a "Draft" layer first (an isolated sandbox state). This allows for multi-turn refinement, validation, and correction loops before any data is persisted to the "Real World" (Database/ERP).

  3. Recall & Hydrate Pattern: We treat past data as "Living Entities," not dead text. To edit a past record, the system "Recalls" it from the database and "Hydrates" it back into the Active Draft state. This unifies the logic for Creating New and Editing Old data into a single, consistent workflow.

Quick Start

# 1. Install dependencies
cd atomic-stateful-agent
pip install -e .
# or
poetry install

# 2. Configure environment
cp .env.example .env
# Edit .env with your LLM API keys

# 3. Run interactive console
python main.py

Architecture

┌───────────────────────────────────────────────────────────────┐
│                    ORCHESTRATION LAYER                        │
│                       (LangGraph)                             │
│  ┌──────────────────────────────────────────────────────┐     │
│  │                    Orchestrator                      │     │
│  │         (Sticky Router + Intent Classification)      │     │
│  └───────────────────────┬──────────────────────────────┘     │
│                          │                                    │
│           ┌──────────────┼─────────────┐                      │
│           │              │             │                      │
│      ┌────▼─────┐   ┌────▼────┐   ┌────▼────┐                 │
│      │ DailyLog │   │ Finance │   │   END   │                 │
│      │  Agent   │   │  Agent  │   │         │                 │
│      └──────────┘   └─────────┘   └─────────┘                 │
│                                                               │
└───────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────▼─────────────────────────────────┐
│                    EXECUTION LAYER                            │
│                  (Atomic Inference)                           │
│                                                               │
│  ┌─────────────────┐  ┌─────────────────┐                     │
│  │   AtomicUnit    │  │   AtomicUnit    │                     │
│  │ (Intent Class.) │  │ (Task Extract)  │                     │
│  └─────────────────┘  └─────────────────┘                     │
└───────────────────────────────────────────────────────────────┘

Project Structure

atomic-stateful-agent/
├── src/
│   ├── core/                  # Core abstractions
│   │   ├── client.py          # LLM Client wrapper
│   │   ├── renderer.py        # Response rendering
│   │   ├── types.py           # Core types
│   │   └── unit.py            # AtomicUnit definition
│   ├── nodes/
│   │   ├── orchestrator.py    # Sticky Router
│   │   ├── daily_log.py       # Draft lifecycle for tasks
│   │   └── finance.py         # Finance agent (placeholder)
│   ├── schemas/
│   │   ├── intents.py         # Intent classification
│   │   ├── daily_log.py       # Task schemas
│   │   └── finance.py         # Finance schemas
│   ├── prompts/               # Jinja2 templates
│   ├── state.py               # AgentState TypedDict
│   ├── mock_db.py             # In-Memory Database
│   └── graph.py               # LangGraph builder
├── main.py                    # CLI entry point
├── pyproject.toml             # Project dependencies
└── README.md                  # Project documentation

Key Patterns

Sticky Router

When a user starts a task, the active_intent gets "locked" to that sub-agent. This prevents mid-draft context switches:

# State during drafting
{
    "active_intent": "daily_log",  # Locked!
    "active_draft": {"title": "Review PR"},
    "record_id": None
}

Draft-Commit Protocol

Changes go through a draft phase before being committed:

  1. Create: Initialize active_draft from user input
  2. Refine: Update active_draft based on corrections
  3. Commit: Persist to database (INSERT or UPDATE)
  4. Cancel: Discard draft

Recall & Hydrate

Editing existing records:

  1. User says "edit the previous task"
  2. System searches MockDB for matching record
  3. Hydrate: Load record data into active_draft, set record_id
  4. User refines the draft
  5. Commit triggers UPDATE (not INSERT)

Console Commands

Command Description
quit Exit the console
debug Show current state
reset Clear all state and database
db Show MockDB contents

Draft-Commit Protocol Example

This demonstrates how the Draft-Commit Protocol prevents accidental writes and allows context-aware refinement.

You: Log task: Review PR for auth feature
Agent: ✅ Task recorded:
  - Title: Review PR for auth feature
  - Priority: Normal
  - Status: Pending

You: Change priority to high
Agent: 📝 Draft updated:
  - Title: Review PR for auth feature
  - Priority: High ← (changed)

You: Done
Agent: 💾 Task saved successfully!
  - ID: task-abc123

Recall & Hydrate Example

This demonstrates how Recall & Hydrate allows Natural Language Editing of existing records.

You: Edit the PR review task from earlier
Agent: 🔍 Task found:
  - ID: task-abc123
  - Title: Review PR for auth feature
  - Priority: High
  
  Open for editing. What do you want to change?

You: Change title to Review PR implementation plan
Agent: 📝 Draft updated:
  - Title: Review PR implementation plan ← (changed)
  - Priority: High
  
You: Ok save it
Agent: 💾 Task updated successfully!
  - ID: task-abc123

License

MIT

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors