Mobile-Agent / README.md
Sabithulla's picture
Switch to Docker SDK to avoid Gradio init DNS failures
b891612
---
title: Jarvis Mobile Agent
emoji: πŸ€–
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false
---
# πŸ€– Jarvis β€” AI Automation Planner for Mobile Devices
Jarvis is an intelligent AI automation planner that converts user voice/text commands into structured JSON task plans for mobile device automation.
## Architecture
```
Mobile Application
↓
HTTP POST β†’ /v1/chat/completions
↓
Jarvis AI (Reason β†’ Plan β†’ Output)
↓
JSON automation plan returned
↓
Mobile automation engine executes locally
```
## Project Structure
```
AI-Agent/
β”œβ”€β”€ app.py # Main app β€” Gradio UI + FastAPI endpoints
β”œβ”€β”€ jarvis/
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ agent.py # Core agent (Reason β†’ Plan β†’ Execute)
β”‚ β”œβ”€β”€ tools.py # Dynamic tool registry
β”‚ β”œβ”€β”€ security.py # Restricted-action enforcement
β”‚ └── prompts.py # System prompt builder
β”œβ”€β”€ tool_registry.json # Tool definitions (editable without code changes)
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
└── README.md
```
## API Endpoint
### `POST /v1/chat/completions`
OpenAI-compatible chat completions endpoint.
**Request:**
```json
{
"messages": [
{ "role": "user", "content": "Download a galaxy image and send it to Arun" }
]
}
```
**Response:**
```json
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "Qwen/Qwen2-1.5B-Instruct",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"steps\":[{\"tool\":\"download_image\",\"query\":\"galaxy\"},{\"tool\":\"send_message\",\"contact\":\"Arun\",\"message\":\"Sending the galaxy image\"}]}"
},
"finish_reason": "stop"
}
]
}
```
### `GET /health`
Returns service status and available tools.
### `GET /v1/models`
Lists the currently loaded model.
## Supported Tools
| Tool | Description | Parameters |
|------|-------------|------------|
| `open_app` | Open a device application | `app_name` |
| `search_google` | Internet search | `query` |
| `download_image` | Download an image | `query` |
| `download_video` | Download a video | `url` |
| `send_message` | Send a message to a contact | `contact`, `message` |
| `product_search` | Search e-commerce platforms | `query` |
| `set_alarm` | Create alarm/reminder | `time` |
| `save_file` | Download and store a file | `url` |
New tools can be added by editing `tool_registry.json` β€” no code changes needed.
## Security Restrictions
Jarvis refuses to automate:
- Banking / payment apps (GPay, PhonePe, Paytm, etc.)
- Financial transactions
- Password managers
- Personal identity data (Aadhaar, PAN, SSN, etc.)
Restricted requests return:
```json
{ "error": "This action is restricted for security reasons." }
```
## Deployment to Hugging Face Spaces
### Option A β€” Gradio SDK (recommended)
1. Create a new Space at [huggingface.co/new-space](https://huggingface.co/new-space)
2. Choose **SDK: Gradio**
3. Push this repository to the Space
4. Add your `HF_TOKEN` as a Space secret (Settings β†’ Secrets)
5. The Space will be available at:
```
POST https://<your-space>.hf.space/v1/chat/completions
```
### Option B β€” Docker SDK
1. Create a new Space with **SDK: Docker**
2. Push this repository (the `Dockerfile` is included)
3. Add `HF_TOKEN` as a Space secret
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `JARVIS_MODEL` | `Qwen/Qwen2-1.5B-Instruct` | HF model ID for the planner LLM |
| `HF_TOKEN` | *(none)* | Hugging Face API token for gated models |
| `PORT` | `7860` | Server port |
## Local Development
```bash
pip install -r requirements.txt
export HF_TOKEN="hf_..."
python app.py
```
The Gradio UI will be available at `http://localhost:7860` and the API at `http://localhost:7860/v1/chat/completions`.
## Mobile Integration (Android Example)
```kotlin
val client = OkHttpClient()
val json = """{"messages":[{"role":"user","content":"$userCommand"}]}"""
val body = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("https://Valtry-mobile-agent.hf.space/v1/chat/completions")
.post(body)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val plan = JSONObject(response.body!!.string())
.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("message")
.getString("content")
// Parse and execute the automation plan
}
override fun onFailure(call: Call, e: IOException) { /* handle */ }
})
```