Revert "try fix pre commit hook bug in app.py"
This reverts commit 2fcad5f0972fc617482fac391f2ff2beeac0bfd6.
This commit is contained in:
parent
2fcad5f097
commit
a256d5589a
109
app.py
109
app.py
@ -1,5 +1,7 @@
|
||||
import asyncio
|
||||
import threading
|
||||
import uuid
|
||||
import webbrowser
|
||||
from datetime import datetime
|
||||
from json import dumps
|
||||
|
||||
@ -10,6 +12,7 @@ from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
@ -23,6 +26,7 @@ app.add_middleware(
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
class Task(BaseModel):
|
||||
id: str
|
||||
prompt: str
|
||||
@ -32,9 +36,10 @@ class Task(BaseModel):
|
||||
|
||||
def model_dump(self, *args, **kwargs):
|
||||
data = super().model_dump(*args, **kwargs)
|
||||
data['created_at'] = self.created_at.isoformat()
|
||||
data["created_at"] = self.created_at.isoformat()
|
||||
return data
|
||||
|
||||
|
||||
class TaskManager:
|
||||
def __init__(self):
|
||||
self.tasks = {}
|
||||
@ -43,61 +48,55 @@ class TaskManager:
|
||||
def create_task(self, prompt: str) -> Task:
|
||||
task_id = str(uuid.uuid4())
|
||||
task = Task(
|
||||
id=task_id,
|
||||
prompt=prompt,
|
||||
created_at=datetime.now(),
|
||||
status="pending"
|
||||
id=task_id, prompt=prompt, created_at=datetime.now(), status="pending"
|
||||
)
|
||||
self.tasks[task_id] = task
|
||||
self.queues[task_id] = asyncio.Queue()
|
||||
return task
|
||||
|
||||
async def update_task_step(self, task_id: str, step: int, result: str, step_type: str = "step"):
|
||||
async def update_task_step(
|
||||
self, task_id: str, step: int, result: str, step_type: str = "step"
|
||||
):
|
||||
if task_id in self.tasks:
|
||||
task = self.tasks[task_id]
|
||||
task.steps.append({"step": step, "result": result, "type": step_type})
|
||||
await self.queues[task_id].put({
|
||||
"type": step_type,
|
||||
"step": step,
|
||||
"result": result
|
||||
})
|
||||
await self.queues[task_id].put({
|
||||
"type": "status",
|
||||
"status": task.status,
|
||||
"steps": task.steps
|
||||
})
|
||||
await self.queues[task_id].put(
|
||||
{"type": step_type, "step": step, "result": result}
|
||||
)
|
||||
await self.queues[task_id].put(
|
||||
{"type": "status", "status": task.status, "steps": task.steps}
|
||||
)
|
||||
|
||||
async def complete_task(self, task_id: str):
|
||||
if task_id in self.tasks:
|
||||
task = self.tasks[task_id]
|
||||
task.status = "completed"
|
||||
await self.queues[task_id].put({
|
||||
"type": "status",
|
||||
"status": task.status,
|
||||
"steps": task.steps
|
||||
})
|
||||
await self.queues[task_id].put(
|
||||
{"type": "status", "status": task.status, "steps": task.steps}
|
||||
)
|
||||
await self.queues[task_id].put({"type": "complete"})
|
||||
|
||||
async def fail_task(self, task_id: str, error: str):
|
||||
if task_id in self.tasks:
|
||||
self.tasks[task_id].status = f"failed: {error}"
|
||||
await self.queues[task_id].put({
|
||||
"type": "error",
|
||||
"message": error
|
||||
})
|
||||
await self.queues[task_id].put({"type": "error", "message": error})
|
||||
|
||||
|
||||
task_manager = TaskManager()
|
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request):
|
||||
return templates.TemplateResponse("index.html", {"request": request})
|
||||
|
||||
|
||||
@app.post("/tasks")
|
||||
async def create_task(prompt: str = Body(..., embed=True)):
|
||||
task = task_manager.create_task(prompt)
|
||||
asyncio.create_task(run_task(task.id, prompt))
|
||||
return {"task_id": task.id}
|
||||
|
||||
|
||||
from app.agent.manus import Manus
|
||||
|
||||
|
||||
@ -108,17 +107,21 @@ async def run_task(task_id: str, prompt: str):
|
||||
agent = Manus(
|
||||
name="Manus",
|
||||
description="A versatile agent that can solve various tasks using multiple tools",
|
||||
max_steps=30
|
||||
max_steps=30,
|
||||
)
|
||||
|
||||
async def on_think(thought):
|
||||
await task_manager.update_task_step(task_id, 0, thought, "think")
|
||||
|
||||
async def on_tool_execute(tool, input):
|
||||
await task_manager.update_task_step(task_id, 0, f"Executing tool: {tool}\nInput: {input}", "tool")
|
||||
await task_manager.update_task_step(
|
||||
task_id, 0, f"Executing tool: {tool}\nInput: {input}", "tool"
|
||||
)
|
||||
|
||||
async def on_action(action):
|
||||
await task_manager.update_task_step(task_id, 0, f"Executing action: {action}", "act")
|
||||
await task_manager.update_task_step(
|
||||
task_id, 0, f"Executing action: {action}", "act"
|
||||
)
|
||||
|
||||
async def on_run(step, result):
|
||||
await task_manager.update_task_step(task_id, step, result, "run")
|
||||
@ -133,7 +136,7 @@ async def run_task(task_id: str, prompt: str):
|
||||
import re
|
||||
|
||||
# 提取 - 后面的内容
|
||||
cleaned_message = re.sub(r'^.*? - ', '', message)
|
||||
cleaned_message = re.sub(r"^.*? - ", "", message)
|
||||
|
||||
event_type = "log"
|
||||
if "✨ Manus's thoughts:" in cleaned_message:
|
||||
@ -147,7 +150,9 @@ async def run_task(task_id: str, prompt: str):
|
||||
elif "🏁 Special tool" in cleaned_message:
|
||||
event_type = "complete"
|
||||
|
||||
await task_manager.update_task_step(self.task_id, 0, cleaned_message, event_type)
|
||||
await task_manager.update_task_step(
|
||||
self.task_id, 0, cleaned_message, event_type
|
||||
)
|
||||
|
||||
sse_handler = SSELogHandler(task_id)
|
||||
logger.add(sse_handler)
|
||||
@ -158,6 +163,7 @@ async def run_task(task_id: str, prompt: str):
|
||||
except Exception as e:
|
||||
await task_manager.fail_task(task_id, str(e))
|
||||
|
||||
|
||||
@app.get("/tasks/{task_id}/events")
|
||||
async def task_events(task_id: str):
|
||||
async def event_generator():
|
||||
@ -169,11 +175,9 @@ async def task_events(task_id: str):
|
||||
|
||||
task = task_manager.tasks.get(task_id)
|
||||
if task:
|
||||
yield f"event: status\ndata: {dumps({
|
||||
'type': 'status',
|
||||
'status': task.status,
|
||||
'steps': task.steps
|
||||
})}\n\n"
|
||||
message = {"type": "status", "status": task.status, "steps": task.steps}
|
||||
json_message = dumps(message)
|
||||
yield f"event: status\ndata: {json_message}\n\n"
|
||||
|
||||
while True:
|
||||
try:
|
||||
@ -191,11 +195,13 @@ async def task_events(task_id: str):
|
||||
elif event["type"] == "step":
|
||||
task = task_manager.tasks.get(task_id)
|
||||
if task:
|
||||
yield f"event: status\ndata: {dumps({
|
||||
'type': 'status',
|
||||
'status': task.status,
|
||||
'steps': task.steps
|
||||
})}\n\n"
|
||||
message = {
|
||||
"type": "status",
|
||||
"status": task.status,
|
||||
"steps": task.steps,
|
||||
}
|
||||
json_message = dumps(message)
|
||||
yield f"event: status\ndata: {json_message}\n\n"
|
||||
yield f"event: {event['type']}\ndata: {formatted_event}\n\n"
|
||||
elif event["type"] in ["think", "tool", "act", "run"]:
|
||||
yield f"event: {event['type']}\ndata: {formatted_event}\n\n"
|
||||
@ -216,35 +222,42 @@ async def task_events(task_id: str):
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no"
|
||||
}
|
||||
"X-Accel-Buffering": "no",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@app.get("/tasks")
|
||||
async def get_tasks():
|
||||
sorted_tasks = sorted(
|
||||
task_manager.tasks.values(),
|
||||
key=lambda task: task.created_at,
|
||||
reverse=True
|
||||
task_manager.tasks.values(), key=lambda task: task.created_at, reverse=True
|
||||
)
|
||||
return JSONResponse(
|
||||
content=[task.model_dump() for task in sorted_tasks],
|
||||
headers={"Content-Type": "application/json"}
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
|
||||
|
||||
@app.get("/tasks/{task_id}")
|
||||
async def get_task(task_id: str):
|
||||
if task_id not in task_manager.tasks:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
return task_manager.tasks[task_id]
|
||||
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def generic_exception_handler(request: Request, exc: Exception):
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"message": f"Server error: {str(exc)}"}
|
||||
status_code=500, content={"message": f"Server error: {str(exc)}"}
|
||||
)
|
||||
|
||||
|
||||
def open_local_browser():
|
||||
webbrowser.open_new_tab("http://localhost:5172")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
threading.Timer(3, open_local_browser).start()
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host="localhost", port=5172)
|
Loading…
x
Reference in New Issue
Block a user