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
@tooldecorators 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 anapproval_requiredSSE event, and seamlessly resume viaagent.resume(). - 🧠 Tiered Memory System: Built-in
SimpleMemory(in-memory),SQLAlchemyMemory(SQLite/PostgreSQL persistence), andTokenBufferMemory(sliding context window token limits). - 🔍 RAG Primitives: Built-in embeddings (
MockEmbeddings,OpenAIEmbeddings), vector stores (SimpleVectorStore), andRetrievertools. - 📊 Built-in Observability & Dashboard: Track run latency, token counts, step counts, and active sessions visually via
/tank-admin. - 🚀 CLI Scaffolding:
tank startproject,tank startagent, andtank runserverwith 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:
- Update the version in pyproject.toml.
- Commit and tag a release, for example
v0.1.1. - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa9a0f9f6b2e92ff79a6315efee5b2d75e9d3f9b4d081a985ef79f50341040cc
|
|
| MD5 |
026e615e1de5041f47415dcf10de6a4b
|
|
| BLAKE2b-256 |
8b12dc694f997f32dda48e557a41ef0bb84a041aae0c67b390ee930777089367
|
Provenance
The following attestation bundles were made for tank_ai-0.1.1.tar.gz:
Publisher:
publish.yml on yasirusman85/Tank
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tank_ai-0.1.1.tar.gz -
Subject digest:
aa9a0f9f6b2e92ff79a6315efee5b2d75e9d3f9b4d081a985ef79f50341040cc - Sigstore transparency entry: 2248192586
- Sigstore integration time:
-
Permalink:
yasirusman85/Tank@aa405d7b89670caf46feb608a5afd7176595e1fe -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/yasirusman85
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa405d7b89670caf46feb608a5afd7176595e1fe -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d79999dfa59c1acb93d654fcfbbe0700af8e3bd0bd5b15b72b9d6694af7e5b19
|
|
| MD5 |
1b0c19fb2024f34a4754c53b533f6bbf
|
|
| BLAKE2b-256 |
76868f30cc99c56fda8ac3c0545f9456e8df4eee851791b28585a609520f0464
|
Provenance
The following attestation bundles were made for tank_ai-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on yasirusman85/Tank
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tank_ai-0.1.1-py3-none-any.whl -
Subject digest:
d79999dfa59c1acb93d654fcfbbe0700af8e3bd0bd5b15b72b9d6694af7e5b19 - Sigstore transparency entry: 2248192749
- Sigstore integration time:
-
Permalink:
yasirusman85/Tank@aa405d7b89670caf46feb608a5afd7176595e1fe -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/yasirusman85
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa405d7b89670caf46feb608a5afd7176595e1fe -
Trigger Event:
push
-
Statement type: