Skip to main content

An AI-native web framework built for streaming LLM agents, tool calling, RAG, and HITL approval gates.

Project description

🛡️ Tank — AI-Native Web Framework

Tank is a batteries-included Python web framework built on Starlette and Pydantic for building, serving, and streaming LLM Agents with tool execution, memory persistence, structured output validation, RAG primitives, and Human-in-the-Loop approval gates.


✨ Key Features

  • Starlette-Powered ASGI Engine: Stream structured events via Server-Sent Events (SSE) out of the box with zero boilerplate.
  • 🛠️ Dynamic Tool Calling: Define tools using clean @tool decorators with automatic Google/Sphinx docstring parameter parsing and runtime Pydantic schema validation.
  • 🎯 Structured Output Enforcement (response_model): Validate agent final answers against Pydantic models with automatic self-correction loops on schema mismatches.
  • 🛡️ Human-in-the-Loop (HITL) Approval Gates: Mark sensitive tools with @tool(requires_approval=True) to pause execution mid-turn, stream an approval_required SSE event, and seamlessly resume via agent.resume().
  • 🧠 Tiered Memory System: Built-in SimpleMemory (in-memory), SQLAlchemyMemory (SQLite/PostgreSQL persistence), and TokenBufferMemory (sliding context window token limits).
  • 🔍 RAG Primitives: Built-in embeddings (MockEmbeddings, OpenAIEmbeddings), vector stores (SimpleVectorStore), and Retriever tools.
  • 📊 Built-in Observability & Dashboard: Track run latency, token counts, step counts, and active sessions visually via /tank-admin.
  • 🚀 CLI Scaffolding: tank startproject, tank startagent, and tank runserver with dev hot-reloading.

🏗️ Architecture Flow

sequenceDiagram
    autonumber
    actor Client
    participant TankApp as Tank ASGI App
    participant Agent as Agent Execution Loop
    participant LLM as LLM Provider (OpenAI/Anthropic/Mock)
    participant Memory as Session Memory
    participant Tool as Tool / HITL Gate

    Client->>TankApp: POST /chat (prompt, session_id)
    TankApp->>Agent: Instantiate & Agent.run(query)
    Agent->>Memory: Load session history
    loop Iterative Execution Loop
        Agent->>LLM: astream(messages, tools)
        LLM-->>Agent: Yield Thoughts / Tokens / Tool Calls
        Agent-->>Client: Stream SSE Events (thought, token, tool_call)
        
        alt Normal Tool
            Agent->>Tool: Execute function
            Tool-->>Agent: Return result
            Agent->>Memory: Save tool response
        else HITL Tool (requires_approval=True)
            Agent-->>Client: Stream event: approval_required & Pause Loop
            Note over Agent,Client: Paused waiting for approval
            Client->>Agent: agent.resume(session_id, tool_call_id, approved=True)
            Agent->>Tool: Execute approved tool
            Tool-->>Agent: Return result
        end
    end
    Agent-->>Client: Stream event: done (Final Response)

📦 Installation

pip install tank-ai

Or install locally in editable mode:

git clone https://github.com/yasirusman85/Tank.git
cd Tank
pip install -e .

Publishing

Build and publish releases with GitHub Actions:

  1. Update the version in pyproject.toml.
  2. Commit and tag a release, for example v0.1.1.
  3. Push the tag to GitHub.

The workflow in .github/workflows/publish.yml builds the sdist and wheel and uploads them to PyPI using the PYPI_API_TOKEN repository secret.


🚀 Quickstart

1. Scaffold a New Project

tank startproject my_ai_app
cd my_ai_app
tank startagent research_bot

2. Define your Agent & Server

app.py:

import uvicorn
from pydantic import BaseModel, Field
from tank import Tank, Agent, LLM, tool

app = Tank()

class UserProfile(BaseModel):
    name: str
    age: int = Field(description="Age in years")
    interests: list[str]

@tool(requires_approval=True)
def delete_user_account(user_id: str) -> str:
    """Deletes a user account from the database. Requires approval."""
    return f"User account {user_id} deleted successfully."

@app.agent_route("/profile")
class ProfileAgent(Agent):
    llm = LLM(provider="mock")
    tools = [delete_user_account]
    response_model = UserProfile

@app.route("/")
async def homepage(request):
    from starlette.responses import JSONResponse
    return JSONResponse({"status": "active", "framework": "Tank"})

if __name__ == "__main__":
    uvicorn.run("app:app", host="127.0.0.1", port=8000, reload=True)

3. Run the Development Server

tank runserver

📊 Observability & Telemetry

Tank automatically traces execution runs. Open your browser and navigate to:

http://localhost:8000/tank-admin

To view live metrics on request latency, total steps, active sessions, and detailed run traces.


🧪 Running Tests

pytest tests/

📜 License

This project is licensed under the MIT License.

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

tank_ai-0.1.1.tar.gz (49.7 kB view details)

Uploaded Source

Built Distribution

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

tank_ai-0.1.1-py3-none-any.whl (45.1 kB view details)

Uploaded Python 3

File details

Details for the file tank_ai-0.1.1.tar.gz.

File metadata

  • Download URL: tank_ai-0.1.1.tar.gz
  • Upload date:
  • Size: 49.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for tank_ai-0.1.1.tar.gz
Algorithm Hash digest
SHA256 aa9a0f9f6b2e92ff79a6315efee5b2d75e9d3f9b4d081a985ef79f50341040cc
MD5 026e615e1de5041f47415dcf10de6a4b
BLAKE2b-256 8b12dc694f997f32dda48e557a41ef0bb84a041aae0c67b390ee930777089367

See more details on using hashes here.

Provenance

The following attestation bundles were made for tank_ai-0.1.1.tar.gz:

Publisher: publish.yml on yasirusman85/Tank

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

File details

Details for the file tank_ai-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tank_ai-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 45.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for tank_ai-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d79999dfa59c1acb93d654fcfbbe0700af8e3bd0bd5b15b72b9d6694af7e5b19
MD5 1b0c19fb2024f34a4754c53b533f6bbf
BLAKE2b-256 76868f30cc99c56fda8ac3c0545f9456e8df4eee851791b28585a609520f0464

See more details on using hashes here.

Provenance

The following attestation bundles were made for tank_ai-0.1.1-py3-none-any.whl:

Publisher: publish.yml on yasirusman85/Tank

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