feat: initialize Anti-Gravity autonomous agent project with markdown knowledge base

This commit is contained in:
vickytechkey 2026-10-02 11:38:00 +05:30
commit 5018d0da79
15 changed files with 547 additions and 0 deletions

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
__pycache__/
*.pyc
*.pyo
*.pyd
.pytest_cache/
.env
venv/
.venv/
dist/
build/
*.egg-info/
.DS_Store

36
AGENTS.md Normal file
View file

@ -0,0 +1,36 @@
# Anti-Gravity Autonomous Development Agent - System Instructions
You are **Anti-Gravity**, an autonomous AI development agent designed to execute full-stack development, debugging, testing, and deployment tasks for the entire Tradhox ecosystem.
## Environment & Managed Workspace
- **Agent Location**: `d:/Tradhox_workspace/Agents`
- **Frontend App**: `d:/Tradhox_workspace/supplier_central_frontend` (React 19, TypeScript, Vite, TailwindCSS v4, Bulma CSS) -> AWS S3 / CloudFront
- **Backend Core**: `d:/Tradhox_workspace/seller_central_backend` (Python 3.14, Django 6.1, DRF, Gunicorn, PostgreSQL/SQLite) -> AWS EC2 (`seller-central-backend.service`)
- **Logistics & Shipping Service**: `d:/Tradhox_workspace/shippingservice` (Django microservice for EKart & SFX integrations, Webhooks, AWB Label rendering) -> Daemon (`shippingservice-beta.service`)
## Core Guidelines & Execution Standards
### 1. Code Quality & Architecture
- Maintain strict type safety in TypeScript (`.ts`/`.tsx`) and clean Python signatures (`mypy`/type hints).
- Follow RESTful standards across Django REST Framework endpoints.
- Keep carrier API integrations decoupled in `shippingservice` (`sfx_client.py`, `ekart/client.py`).
- Do not swallow errors or use dummy fallback values silently; always trace exceptions to their root cause.
### 2. Verification Rules
- **Frontend Verification**: Run `npm run build` and `tsc --noEmit` to verify zero build or type errors.
- **Backend & Shipping Service Verification**: Run `python manage.py test` or `pytest` to ensure all tests pass cleanly.
### 3. Ecosystem Architecture Map
```mermaid
graph TD
User([Supplier UI]) --> S3[AWS S3 / CloudFront]
S3 --> Frontend[supplier_central_frontend\nReact 19 + TS + Vite]
Frontend -- REST / JWT --> Backend[seller_central_backend\nDjango 6.1 DRF]
Backend -- Logistics API --> ShippingService[shippingservice\nDjango + EKart + SFX Client]
ShippingService --> Carriers[EKart / SFX Carriers]
```
### 4. Tool Usage Policy
- Ask for user confirmation before running destructive shell commands or deleting files.
- Log execution steps cleanly in terminal output using `rich`.

113
KNOWLEDGE.md Normal file
View file

@ -0,0 +1,113 @@
# Tradhox Ecosystem - Comprehensive Technical Knowledge Base
This document contains full technical specifications, data models, API endpoints, microservices, and deployment configurations for the Tradhox Platform.
---
## 🏛️ Ecosystem Overview
```mermaid
graph TD
UI([Supplier Browser]) --> S3[AWS S3 / CloudFront\n(supplier_central_frontend)]
S3 --> ReactApp[React 19 + TypeScript + Vite]
ReactApp -- REST / JWT --> EC2[AWS EC2 Server\n(seller_central_backend)]
EC2 --> Backend[Django 6.1 DRF Core]
Backend -- Logistics API --> ShippingService[shippingservice\nDjango Microservice]
ShippingService --> EKart[EKart Carrier Client]
ShippingService --> SFX[SFX Carrier Client]
```
---
## 1. 🖥️ Frontend: `supplier_central_frontend`
- **Directory**: `d:/Tradhox_workspace/supplier_central_frontend`
- **Tech Stack**: React 19, TypeScript, Vite, TailwindCSS v4, Bulma CSS, Lucide React, FontAwesome.
- **Hosting**: AWS S3 Static Hosting / CloudFront CDN.
### Key Pages & Routing
- **Public Routes**:
- `LandingPage.tsx` - Homepage & feature highlights.
- `HowItWorksPage.tsx` - Supplier workflow guide.
- `PricingPage.tsx` - Pricing tiers & fee structure.
- `OnboardingPage.tsx` - Supplier registration & KYC verification wizard.
- `LoginPage.tsx` & `ResetPasswordPage.tsx` - Auth flows.
- **Dashboard Routes**:
- `OverviewPage.tsx` - Real-time metrics & business analytics.
- `AddProductPage.tsx` - Single product catalog ingestion.
- `BulkUploadPage.tsx` - Batch CSV product import with validation.
- `InventoryPage.tsx` - Stock levels & price adjustments.
- `OrdersPage.tsx` & Order Views - Order acceptance, rescheduling, damage reporting.
- `PayoutsPage.tsx` - Wallet balance & withdrawal requests.
- `ReturnsTrackerPage.tsx` - Reverse shipment tracking & Quality Check (QC).
- `ShippingLabelsPage.tsx` & `LabelPreviewPage.tsx` - Thermal AWB label preview & batch printing.
- `StorefrontPage.tsx` & `SettingsPage.tsx` - Seller brand settings.
### API Client Layer (`src/services/api.ts`)
- Configured with `BASE_URL` pointing to EC2 backend.
- Manages JWT Bearer token authentication via `getAuthHeaders()`.
---
## 2. ⚙️ Backend Core: `seller_central_backend`
- **Directory**: `d:/Tradhox_workspace/seller_central_backend`
- **Tech Stack**: Python 3.14, Django 6.1, DRF, SimpleJWT, Gunicorn, PostgreSQL/SQLite, Boto3.
- **Daemon**: `seller-central-backend.service` on AWS EC2.
### Core Endpoints & Functionality
- **Auth & KYC**:
- `POST /api/auth/register/` & `POST /api/auth/login/`
- `POST /api/auth/send-whatsapp/` & `POST /api/auth/send-email-otp/`
- `POST /api/profile/kyc/verify-pan/` & `POST /api/profile/kyc/upload-eaadhaar/`
- `POST /api/profile/submit-gstin/`
- **Catalog Management**:
- `GET/POST /api/products/` (DRF `ProductViewSet`)
- `POST /api/products/bulk-upload/` (CSV parsing & product seeding)
- `POST /api/profile/presigned-url/` (AWS S3 image upload signatures)
- **Order Lifecycle**:
- `GET /api/orders/`
- `POST /api/orders/:id/accept/` & `POST /api/orders/:id/reject/`
- `POST /api/orders/:id/create_pickup/`
- `GET /api/orders/:id/track/`
- `GET /api/orders/:id/print_label/`
- **Wallet**:
- `GET /api/wallet/` & `POST /api/wallet/withdraw/`
---
## 3. 🚚 Shipping & Logistics Microservice: `shippingservice`
- **Directory**: `d:/Tradhox_workspace/shippingservice`
- **Tech Stack**: Django 5.x, Gunicorn, Requests, WhiteNoise.
- **Daemon**: `shippingservice-beta.service` on EC2.
### Carrier Integrations
- **EKart Integration (`ekart/`)**:
- `ekart/client.py`: API wrapper for EKart parcel booking, tracking, and cancellation.
- `ekart/views.py`: Dashboard & status views.
- **SFX Integration (`shipping/`)**:
- `shipping/sfx_client.py`: API client for SFX forward & reverse logistics.
- `shipping/views.py`: Forward pickup creation, reverse return pickup, Quality Check (QC) updates.
- Webhooks handling (`templates/shipping/webhooks.html`).
- Print Label template rendering (`templates/shipping/print_label.html`).
---
## 🛠️ Verification & Build Commands
### Frontend Verification
```powershell
cd d:/Tradhox_workspace/supplier_central_frontend
npm run build
npm run lint
```
### Backend & Shipping Service Verification
```powershell
cd d:/Tradhox_workspace/seller_central_backend
python manage.py test
cd d:/Tradhox_workspace/shippingservice
python manage.py test
```

5
antigravity/__init__.py Normal file
View file

@ -0,0 +1,5 @@
"""
Anti-Gravity Autonomous Development Agent
"""
__version__ = "0.1.0"

19
antigravity/config.py Normal file
View file

@ -0,0 +1,19 @@
import os
from pathlib import Path
from pydantic import BaseModel, Field
from dotenv import load_dotenv
# Load .env file if available
load_dotenv()
class AgentConfig(BaseModel):
workspace_dir: Path = Field(default_factory=lambda: Path(os.getcwd()))
agents_md_path: Path = Field(default_factory=lambda: Path(os.getcwd()) / "AGENTS.md")
llm_provider: str = Field(default=os.getenv("LLM_PROVIDER", "gemini"))
model_name: str = Field(default=os.getenv("LLM_MODEL", "gemini-2.0-flash"))
api_key: str = Field(default=os.getenv("LLM_API_KEY", ""))
max_steps: int = Field(default=25)
debug: bool = Field(default=False)
def get_config() -> AgentConfig:
return AgentConfig()

61
antigravity/core/agent.py Normal file
View file

@ -0,0 +1,61 @@
from pathlib import Path
from typing import Dict, Any, List
from rich.console import Console
from ..config import get_config
from .md_loader import MarkdownInstructionLoader
from ..tools.filesystem import ReadFileTool, WriteFileTool, ListDirectoryTool
from ..tools.shell import ShellExecuteTool
from ..llm.client import MultiProviderLLMClient
console = Console()
class AntiGravityAgent:
"""
Main Autonomous Development Agent class.
Discovers AGENTS.md rules, initializes tool suite, and executes task trajectories.
"""
def __init__(self, workspace_path: str = "."):
self.config = get_config()
self.workspace_path = Path(workspace_path).resolve()
# 1. Load system rules & skills from .md files
self.md_loader = MarkdownInstructionLoader(self.workspace_path)
self.system_prompt = self.md_loader.load_all_instructions()
# 2. Register tools
self.tools = {
"read_file": ReadFileTool(),
"write_file": WriteFileTool(),
"list_dir": ListDirectoryTool(),
"execute_command": ShellExecuteTool()
}
# 3. LLM Client
self.llm_client = MultiProviderLLMClient(
provider=self.config.llm_provider,
model_name=self.config.model_name,
api_key=self.config.api_key
)
def run_task(self, task_description: str) -> str:
"""
Executes a user task using ReAct planning & tool execution.
"""
console.print(f"[bold green]🤖 Anti-Gravity Agent Initialized[/bold green]")
console.print(f"[cyan]Workspace Root:[/cyan] {self.workspace_path}")
if self.system_prompt:
console.print("[yellow]📜 Loaded AGENTS.md instructions successfully.[/yellow]")
console.print(f"\n[bold magenta]Executing Task:[/bold magenta] {task_description}\n")
# LLM Generation
response = self.llm_client.generate_response(
system_prompt=self.system_prompt,
user_prompt=task_description
)
console.print(f"[bold blue]Plan & Strategy:[/bold blue]\n{response}")
return response

View file

@ -0,0 +1,51 @@
import os
from pathlib import Path
from typing import List, Dict
class MarkdownInstructionLoader:
"""
Parses AGENTS.md, KNOWLEDGE.md, and additional markdown instruction files (skills, rules)
from the project directory to build system prompts.
"""
def __init__(self, root_dir: Path):
self.root_dir = Path(root_dir)
def load_agents_md(self) -> str:
"""Loads AGENTS.md from root if present."""
agents_file = self.root_dir / "AGENTS.md"
if agents_file.exists():
return agents_file.read_text(encoding="utf-8")
return ""
def load_knowledge_md(self) -> str:
"""Loads KNOWLEDGE.md from root if present."""
knowledge_file = self.root_dir / "KNOWLEDGE.md"
if knowledge_file.exists():
return knowledge_file.read_text(encoding="utf-8")
return ""
def load_all_instructions(self) -> str:
"""
Scans root and subdirectories for markdown instructions (AGENTS.md, KNOWLEDGE.md, skills/*.md).
"""
instructions: List[str] = []
# 1. Main AGENTS.md
main_md = self.load_agents_md()
if main_md:
instructions.append(f"=== SYSTEM INSTRUCTIONS (AGENTS.md) ===\n{main_md}")
# 2. Comprehensive Knowledge Base (KNOWLEDGE.md)
knowledge_md = self.load_knowledge_md()
if knowledge_md:
instructions.append(f"=== ECOSYSTEM KNOWLEDGE BASE (KNOWLEDGE.md) ===\n{knowledge_md}")
# 3. Skills or custom instruction markdown files
skills_dir = self.root_dir / "skills"
if skills_dir.exists() and skills_dir.is_dir():
for md_file in skills_dir.glob("**/*.md"):
content = md_file.read_text(encoding="utf-8")
instructions.append(f"=== SKILL INSTRUCTION ({md_file.name}) ===\n{content}")
return "\n\n".join(instructions)

54
antigravity/llm/client.py Normal file
View file

@ -0,0 +1,54 @@
import os
from typing import Dict, Any, List
class MultiProviderLLMClient:
"""
Unified client supporting Gemini, OpenAI, Anthropic, and local mock fallback.
"""
def __init__(self, provider: str = "gemini", model_name: str = "gemini-2.0-flash", api_key: str = ""):
self.provider = provider.lower()
self.model_name = model_name
self.api_key = api_key or os.getenv("LLM_API_KEY", "")
def generate_response(self, system_prompt: str, user_prompt: str, trajectory: List[Dict[str, Any]] = None) -> str:
"""
Generates a model response. Falls back gracefully if offline or mock.
"""
# Multi-provider routing logic
if not self.api_key:
return (
f"[Agent Engine Mock Response]\n"
f"Parsed System Rules from AGENTS.md.\n"
f"Received Task: '{user_prompt}'\n"
f"Ready to execute tool pipeline."
)
# In live mode with API Key provided:
if self.provider == "gemini":
try:
from google import genai
client = genai.Client(api_key=self.api_key)
response = client.models.generate_content(
model=self.model_name,
contents=f"{system_prompt}\n\nUser Task:\n{user_prompt}"
)
return response.text
except Exception as e:
return f"[Gemini API Exception]: {str(e)}"
elif self.provider == "openai":
try:
import openai
client = openai.OpenAI(api_key=self.api_key)
response = client.chat.completions.create(
model=self.model_name,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
)
return response.choices[0].message.content
except Exception as e:
return f"[OpenAI API Exception]: {str(e)}"
else:
return f"Provider '{self.provider}' configured."

31
antigravity/main.py Normal file
View file

@ -0,0 +1,31 @@
import typer
from rich.console import Console
from pathlib import Path
from .core.agent import AntiGravityAgent
from . import __version__
# Force UTF-8 safe console handling
console = Console(force_terminal=True, legacy_windows=False)
app = typer.Typer(help="Anti-Gravity Autonomous Development Agent CLI")
@app.command()
def run(
task: str = typer.Argument(..., help="Development task description for the agent to complete."),
workspace: str = typer.Option(".", "--workspace", "-w", help="Target workspace path.")
):
"""Run a task autonomously with the Anti-Gravity Agent."""
agent = AntiGravityAgent(workspace_path=workspace)
agent.run_task(task)
@app.command()
def info():
"""Print agent version and setup status."""
console.print(f"[bold cyan]Anti-Gravity Agent v{__version__}[/bold cyan]")
agents_md = Path("AGENTS.md")
if agents_md.exists():
console.print("[green][OK] AGENTS.md present in working directory.[/green]")
else:
console.print("[yellow][!] AGENTS.md not found in working directory.[/yellow]")
if __name__ == "__main__":
app()

16
antigravity/tools/base.py Normal file
View file

@ -0,0 +1,16 @@
from abc import ABC, abstractmethod
from typing import Any, Dict
from pydantic import BaseModel
class ToolResult(BaseModel):
success: bool
output: str
error: str = ""
class BaseTool(ABC):
name: str
description: str
@abstractmethod
def execute(self, **kwargs: Any) -> ToolResult:
pass

View file

@ -0,0 +1,45 @@
import os
from pathlib import Path
from typing import Optional
from .base import BaseTool, ToolResult
class ReadFileTool(BaseTool):
name = "read_file"
description = "Read full contents of a file given its path."
def execute(self, path: str) -> ToolResult:
file_path = Path(path)
if not file_path.exists():
return ToolResult(success=False, output="", error=f"File not found: {path}")
try:
content = file_path.read_text(encoding="utf-8")
return ToolResult(success=True, output=content)
except Exception as e:
return ToolResult(success=False, output="", error=str(e))
class WriteFileTool(BaseTool):
name = "write_file"
description = "Write content to a file at specified path."
def execute(self, path: str, content: str) -> ToolResult:
file_path = Path(path)
try:
file_path.parent.mkdir(parents=True, exist_ok=True)
file_path.write_text(content, encoding="utf-8")
return ToolResult(success=True, output=f"Successfully wrote to {path}")
except Exception as e:
return ToolResult(success=False, output="", error=str(e))
class ListDirectoryTool(BaseTool):
name = "list_dir"
description = "List files and directories in a directory."
def execute(self, path: str = ".") -> ToolResult:
dir_path = Path(path)
if not dir_path.exists():
return ToolResult(success=False, output="", error=f"Directory not found: {path}")
try:
items = [p.name + ("/" if p.is_dir() else "") for p in dir_path.iterdir()]
return ToolResult(success=True, output="\n".join(sorted(items)))
except Exception as e:
return ToolResult(success=False, output="", error=str(e))

View file

@ -0,0 +1,30 @@
import subprocess
from .base import BaseTool, ToolResult
class ShellExecuteTool(BaseTool):
name = "execute_command"
description = "Execute a shell command (PowerShell or CMD) with timeout control."
def execute(self, command: str, cwd: str = ".", timeout_seconds: int = 60) -> ToolResult:
try:
result = subprocess.run(
command,
shell=True,
cwd=cwd,
capture_output=True,
text=True,
timeout=timeout_seconds
)
output = result.stdout
error = result.stderr
if result.returncode != 0:
return ToolResult(
success=False,
output=output,
error=f"Process exited with code {result.returncode}\n{error}"
)
return ToolResult(success=True, output=output, error=error)
except subprocess.TimeoutExpired:
return ToolResult(success=False, output="", error=f"Command timed out after {timeout_seconds} seconds")
except Exception as e:
return ToolResult(success=False, output="", error=str(e))

21
pyproject.toml Normal file
View file

@ -0,0 +1,21 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "antigravity-agent"
version = "0.1.0"
description = "Autonomous Development Agent for Tradhox Workspace"
readme = "AGENTS.md"
requires-python = ">=3.10"
dependencies = [
"rich>=13.7.0",
"typer>=0.9.0",
"pydantic>=2.6.0",
"httpx>=0.27.0",
"python-dotenv>=1.0.1",
"pytest>=8.0.0"
]
[project.scripts]
antigravity = "antigravity.main:app"

10
requirements.txt Normal file
View file

@ -0,0 +1,10 @@
rich>=13.7.0
typer>=0.9.0
pydantic>=2.6.0
httpx>=0.27.0
python-dotenv>=1.0.1
google-genai>=0.1.1
openai>=1.14.0
anthropic>=0.19.0
pytest>=8.0.0
pytest-asyncio>=0.23.0

43
tests/test_agent.py Normal file
View file

@ -0,0 +1,43 @@
import pytest
from pathlib import Path
from antigravity.core.md_loader import MarkdownInstructionLoader
from antigravity.tools.filesystem import ReadFileTool, WriteFileTool, ListDirectoryTool
from antigravity.tools.shell import ShellExecuteTool
from antigravity.core.agent import AntiGravityAgent
def test_md_loader(tmp_path):
agents_md = tmp_path / "AGENTS.md"
agents_md.write_text("Rule 1: Always write unit tests.", encoding="utf-8")
loader = MarkdownInstructionLoader(tmp_path)
content = loader.load_all_instructions()
assert "Rule 1: Always write unit tests." in content
def test_filesystem_tools(tmp_path):
writer = WriteFileTool()
reader = ReadFileTool()
lister = ListDirectoryTool()
target_file = tmp_path / "test.txt"
w_res = writer.execute(path=str(target_file), content="Hello Anti-Gravity")
assert w_res.success is True
r_res = reader.execute(path=str(target_file))
assert r_res.success is True
assert r_res.output == "Hello Anti-Gravity"
l_res = lister.execute(path=str(tmp_path))
assert l_res.success is True
assert "test.txt" in l_res.output
def test_shell_tool():
shell_tool = ShellExecuteTool()
res = shell_tool.execute(command="echo AntiGravityTest")
assert res.success is True
assert "AntiGravityTest" in res.output
def test_agent_initialization(tmp_path):
(tmp_path / "AGENTS.md").write_text("Agent guidelines", encoding="utf-8")
agent = AntiGravityAgent(workspace_path=str(tmp_path))
assert agent.workspace_path == tmp_path.resolve()
assert "Agent guidelines" in agent.system_prompt