Sabithulla commited on
Commit
3f392e0
·
1 Parent(s): ea98cdb

Fix: remove Dockerfile, restructure app for Gradio SDK on HF Spaces

Browse files
Files changed (3) hide show
  1. Dockerfile +0 -12
  2. app.py +38 -80
  3. requirements.txt +0 -3
Dockerfile DELETED
@@ -1,12 +0,0 @@
1
- FROM python:3.11-slim
2
-
3
- WORKDIR /app
4
-
5
- COPY requirements.txt .
6
- RUN pip install --no-cache-dir -r requirements.txt
7
-
8
- COPY . .
9
-
10
- EXPOSE 7860
11
-
12
- CMD ["python", "app.py"]
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -2,8 +2,8 @@
2
  Jarvis AI Automation Planner — Hugging Face Space Application
3
 
4
  Exposes two interfaces:
5
- 1. Gradio chat UI for browser-based testing
6
- 2. OpenAI-compatible POST /v1/chat/completions API for mobile clients
7
  """
8
 
9
  import json
@@ -11,10 +11,8 @@ import logging
11
  import os
12
  import time
13
  import uuid
14
- from contextlib import asynccontextmanager
15
 
16
  import gradio as gr
17
- import uvicorn
18
  from fastapi import FastAPI, Request
19
  from fastapi.middleware.cors import CORSMiddleware
20
  from fastapi.responses import JSONResponse
@@ -36,25 +34,44 @@ logger = logging.getLogger("jarvis.app")
36
  # ---------------------------------------------------------------------------
37
  registry = ToolRegistry()
38
  agent = JarvisAgent(registry=registry)
 
39
 
40
  # ---------------------------------------------------------------------------
41
- # FastAPI application
42
  # ---------------------------------------------------------------------------
43
 
44
 
45
- @asynccontextmanager
46
- async def lifespan(application: FastAPI):
47
- logger.info("Jarvis agent ready • model=%s • tools=%s", agent.model, registry.tool_names())
48
- yield
49
 
50
 
51
- api = FastAPI(
52
- title="Jarvis – AI Automation Planner",
53
- version="1.0.0",
54
- lifespan=lifespan,
 
 
 
 
 
 
 
 
 
 
 
 
55
  )
56
 
57
- api.add_middleware(
 
 
 
 
 
 
58
  CORSMiddleware,
59
  allow_origins=["*"],
60
  allow_methods=["*"],
@@ -62,20 +79,9 @@ api.add_middleware(
62
  )
63
 
64
 
65
- # ---------- POST /v1/chat/completions (OpenAI-compatible) ---------------
66
-
67
-
68
- @api.post("/v1/chat/completions")
69
  async def chat_completions(request: Request):
70
- """
71
- OpenAI-compatible chat completions endpoint.
72
-
73
- Expects:
74
- { "messages": [ {"role": "user", "content": "..."} ] }
75
-
76
- Returns an OpenAI-shaped response whose assistant content is
77
- the Jarvis JSON automation plan.
78
- """
79
  try:
80
  body = await request.json()
81
  except Exception:
@@ -85,7 +91,6 @@ async def chat_completions(request: Request):
85
  if not messages:
86
  return JSONResponse({"error": "No messages provided."}, status_code=400)
87
 
88
- # Use the last user message as the command
89
  user_msg = ""
90
  for m in reversed(messages):
91
  if m.get("role") == "user":
@@ -95,10 +100,8 @@ async def chat_completions(request: Request):
95
  if not user_msg:
96
  return JSONResponse({"error": "No user message found."}, status_code=400)
97
 
98
- # Run the Jarvis planning pipeline
99
  plan = agent.plan(user_msg)
100
 
101
- # Wrap in OpenAI-compatible response shape
102
  return JSONResponse({
103
  "id": f"chatcmpl-{uuid.uuid4().hex[:12]}",
104
  "object": "chat.completion",
@@ -118,65 +121,20 @@ async def chat_completions(request: Request):
118
  })
119
 
120
 
121
- # ---------- GET /v1/models -----------------------------------------------
122
-
123
- @api.get("/v1/models")
124
  async def list_models():
125
  return {
126
  "object": "list",
127
- "data": [
128
- {
129
- "id": agent.model,
130
- "object": "model",
131
- "owned_by": "jarvis",
132
- }
133
- ],
134
  }
135
 
136
 
137
- # ---------- GET /health --------------------------------------------------
138
-
139
- @api.get("/health")
140
  async def health():
141
  return {"status": "ok", "model": agent.model, "tools": registry.tool_names()}
142
 
143
 
144
  # ---------------------------------------------------------------------------
145
- # Gradio chat interface (mounted on the same server)
146
- # ---------------------------------------------------------------------------
147
-
148
-
149
- def chat_fn(message: str, _history: list) -> str:
150
- """Gradio handler — takes a user message and returns the JSON plan."""
151
- plan = agent.plan(message)
152
- return json.dumps(plan, indent=2)
153
-
154
-
155
- gradio_app = gr.ChatInterface(
156
- fn=chat_fn,
157
- title="🤖 Jarvis — AI Automation Planner",
158
- description=(
159
- "Type a command (e.g. *\"download a galaxy image\"*) and Jarvis will "
160
- "return a structured JSON automation plan for your mobile device."
161
- ),
162
- examples=[
163
- "Download a galaxy image",
164
- "Open YouTube",
165
- "Search water bottle for boys",
166
- "Download a galaxy image and send it to Arun",
167
- "Set an alarm for 7 AM",
168
- "Search Google for latest AI news",
169
- ],
170
- type="messages",
171
- )
172
-
173
- # Mount Gradio inside FastAPI
174
- app = gr.mount_gradio_app(api, gradio_app, path="/")
175
-
176
- # ---------------------------------------------------------------------------
177
- # Entry point
178
  # ---------------------------------------------------------------------------
179
-
180
- if __name__ == "__main__":
181
- port = int(os.getenv("PORT", "7860"))
182
- uvicorn.run("app:app", host="0.0.0.0", port=port, log_level="info")
 
2
  Jarvis AI Automation Planner — Hugging Face Space Application
3
 
4
  Exposes two interfaces:
5
+ 1. Gradio chat UI at / (browser testing)
6
+ 2. OpenAI-compatible POST /v1/chat/completions (mobile clients)
7
  """
8
 
9
  import json
 
11
  import os
12
  import time
13
  import uuid
 
14
 
15
  import gradio as gr
 
16
  from fastapi import FastAPI, Request
17
  from fastapi.middleware.cors import CORSMiddleware
18
  from fastapi.responses import JSONResponse
 
34
  # ---------------------------------------------------------------------------
35
  registry = ToolRegistry()
36
  agent = JarvisAgent(registry=registry)
37
+ logger.info("Jarvis agent ready • model=%s • tools=%s", agent.model, registry.tool_names())
38
 
39
  # ---------------------------------------------------------------------------
40
+ # Gradio chat interface
41
  # ---------------------------------------------------------------------------
42
 
43
 
44
+ def chat_fn(message: str, _history: list) -> str:
45
+ """Gradio handler takes a user message and returns the JSON plan."""
46
+ plan = agent.plan(message)
47
+ return json.dumps(plan, indent=2)
48
 
49
 
50
+ demo = gr.ChatInterface(
51
+ fn=chat_fn,
52
+ title="🤖 Jarvis — AI Automation Planner",
53
+ description=(
54
+ "Type a command (e.g. *\"download a galaxy image\"*) and Jarvis will "
55
+ "return a structured JSON automation plan for your mobile device."
56
+ ),
57
+ examples=[
58
+ "Download a galaxy image",
59
+ "Open YouTube",
60
+ "Search water bottle for boys",
61
+ "Download a galaxy image and send it to Arun",
62
+ "Set an alarm for 7 AM",
63
+ "Search Google for latest AI news",
64
+ ],
65
+ type="messages",
66
  )
67
 
68
+ # ---------------------------------------------------------------------------
69
+ # Custom FastAPI routes (mounted alongside Gradio)
70
+ # ---------------------------------------------------------------------------
71
+
72
+ app = FastAPI(title="Jarvis – AI Automation Planner", version="1.0.0")
73
+
74
+ app.add_middleware(
75
  CORSMiddleware,
76
  allow_origins=["*"],
77
  allow_methods=["*"],
 
79
  )
80
 
81
 
82
+ @app.post("/v1/chat/completions")
 
 
 
83
  async def chat_completions(request: Request):
84
+ """OpenAI-compatible chat completions endpoint for mobile clients."""
 
 
 
 
 
 
 
 
85
  try:
86
  body = await request.json()
87
  except Exception:
 
91
  if not messages:
92
  return JSONResponse({"error": "No messages provided."}, status_code=400)
93
 
 
94
  user_msg = ""
95
  for m in reversed(messages):
96
  if m.get("role") == "user":
 
100
  if not user_msg:
101
  return JSONResponse({"error": "No user message found."}, status_code=400)
102
 
 
103
  plan = agent.plan(user_msg)
104
 
 
105
  return JSONResponse({
106
  "id": f"chatcmpl-{uuid.uuid4().hex[:12]}",
107
  "object": "chat.completion",
 
121
  })
122
 
123
 
124
+ @app.get("/v1/models")
 
 
125
  async def list_models():
126
  return {
127
  "object": "list",
128
+ "data": [{"id": agent.model, "object": "model", "owned_by": "jarvis"}],
 
 
 
 
 
 
129
  }
130
 
131
 
132
+ @app.get("/health")
 
 
133
  async def health():
134
  return {"status": "ok", "model": agent.model, "tools": registry.tool_names()}
135
 
136
 
137
  # ---------------------------------------------------------------------------
138
+ # Mount Gradio onto the FastAPI app at root
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  # ---------------------------------------------------------------------------
140
+ app = gr.mount_gradio_app(app, demo, path="/")
 
 
 
requirements.txt CHANGED
@@ -1,4 +1 @@
1
- gradio>=4.0.0
2
- fastapi>=0.110.0
3
- uvicorn[standard]>=0.29.0
4
  huggingface_hub>=0.23.0
 
 
 
 
1
  huggingface_hub>=0.23.0