Spaces:
Sleeping
Sleeping
File size: 6,964 Bytes
12b9f26 83fe4f9 b032b2d 83fe4f9 12b9f26 83fe4f9 12b9f26 83fe4f9 f0c7697 12b9f26 83fe4f9 f0c7697 12b9f26 83fe4f9 f0c7697 12b9f26 83fe4f9 f0c7697 83fe4f9 b032b2d 83fe4f9 426e9e3 83fe4f9 f0c7697 83fe4f9 12b9f26 fb38df2 12b9f26 fb38df2 12b9f26 fb38df2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | import logging
from fastapi import APIRouter, HTTPException
from backend.ai.analyzer import analyze_business_description, analyze_custom_task
from backend.ai.workflow_builder import build_workflow_definition
from backend.ai.workflow_suggester import suggest_workflow_options
from backend.engine.compiler import compile_workflow
from backend.engine.executor import WorkflowExecutor
from backend.integrations.file_parser import parse_uploaded_payload
from backend.models.schemas import (
AnalyzeRequest,
BuildWorkflowRequest,
BuildWorkflowResponse,
CustomTaskRequest,
DeployRequest,
DeploymentResponse,
EscalationReplyRequest,
EscalationResponse,
FileUploadRequest,
FileUploadResponse,
OwnerStatusResponse,
StopAutomationRequest,
StopAutomationResponse,
WorkflowSuggestionRequest,
)
from backend.storage.database import db
router = APIRouter()
executor = WorkflowExecutor()
logger = logging.getLogger(__name__)
@router.post("/analyze")
def analyze(request: AnalyzeRequest) -> dict:
try:
analysis = analyze_business_description(request.description)
except Exception as exc:
logger.exception("Analyze request failed")
raise HTTPException(status_code=500, detail=f"Analyze failed: {exc}") from exc
owner = db.ensure_owner(request.owner_id, request.owner_email)
owner["business_description"] = request.description
owner["business_analysis"] = analysis
db.save_owner(owner)
return analysis
@router.post("/custom-task")
def custom_task(request: CustomTaskRequest) -> dict:
try:
owner = db.get_owner(request.owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
try:
return analyze_custom_task(
business_description=owner.get("business_description", ""),
existing_workflows=db.list_workflows(request.owner_id),
custom_task=request.custom_task,
)
except Exception as exc:
logger.exception("Custom task analysis failed")
raise HTTPException(status_code=500, detail=f"Custom task analysis failed: {exc}") from exc
@router.post("/suggest-workflows")
def suggest_workflows(request: WorkflowSuggestionRequest) -> dict:
try:
owner = db.get_owner(request.owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
try:
return suggest_workflow_options(
task_name=request.task_name,
task_description=request.task_description,
category=request.category,
spreadsheet_info=owner.get("spreadsheet_config", {"connected": False}),
uploaded_files=db.list_data_files(request.owner_id),
)
except Exception as exc:
logger.exception("Workflow suggestion failed")
raise HTTPException(status_code=500, detail=f"Workflow suggestion failed: {exc}") from exc
@router.post("/build-workflow", response_model=BuildWorkflowResponse)
def build_workflow(request: BuildWorkflowRequest) -> BuildWorkflowResponse:
try:
owner = db.get_owner(request.owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
try:
workflow_json = build_workflow_definition(request=request, owner=owner)
compiled = compile_workflow(workflow_json)
except Exception as exc:
logger.exception("Workflow build failed")
raise HTTPException(status_code=500, detail=f"Workflow build failed: {exc}") from exc
return BuildWorkflowResponse(workflow=compiled)
@router.post("/deploy", response_model=DeploymentResponse)
def deploy_workflow(request: DeployRequest) -> DeploymentResponse:
try:
owner = db.get_owner(request.owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
deployments = []
for workflow in request.workflows:
compiled = compile_workflow(workflow.model_dump())
saved = db.save_workflow(request.owner_id, compiled)
deployments.append(saved)
owner["state"] = "live"
db.save_owner(owner)
return DeploymentResponse(
status="deployed",
workflows=deployments,
message="All workflows are live.",
)
@router.post("/stop", response_model=StopAutomationResponse)
def stop_automation(request: StopAutomationRequest) -> StopAutomationResponse:
try:
owner = db.get_owner(request.owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
workflows = db.deactivate_workflows(request.owner_id)
owner["state"] = "paused"
db.save_owner(owner)
return StopAutomationResponse(
status="stopped",
workflows=workflows,
message="Automation stopped.",
)
@router.post("/upload-data", response_model=FileUploadResponse)
def upload_data(request: FileUploadRequest) -> FileUploadResponse:
parsed = parse_uploaded_payload(request.filename, request.content, request.purpose)
record = db.save_data_file(request.owner_id, request.filename, request.file_type, request.purpose, parsed)
return FileUploadResponse(file=record)
@router.post("/reset")
def reset_data() -> dict[str, str]:
db.reset()
return {"status": "ok", "message": "In-memory data reset."}
@router.get("/status", response_model=OwnerStatusResponse)
def status(owner_id: str) -> OwnerStatusResponse:
try:
owner = db.get_owner(owner_id)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
return OwnerStatusResponse(
owner=owner,
workflows=db.list_workflows(owner_id),
recent_executions=db.list_execution_logs(owner_id),
)
@router.get("/escalations")
def escalations(owner_id: str) -> dict:
return {"items": db.list_escalations(owner_id)}
@router.post("/escalation-reply", response_model=EscalationResponse)
def escalation_reply(request: EscalationReplyRequest) -> EscalationResponse:
escalation = db.resolve_escalation(request.escalation_id, request.response)
return EscalationResponse(escalation=escalation)
@router.post("/simulate-run")
def simulate_run(owner_id: str, workflow_id: str, trigger: dict) -> dict:
workflow = db.get_workflow(owner_id, workflow_id)
result = executor.execute(workflow, trigger, db=db, owner_id=owner_id)
db.save_execution_log(owner_id, workflow_id, trigger, result["steps"], result["outcome"], result.get("error"))
return result
@router.get("/debug/groq")
def debug_groq() -> dict:
from backend.ai.client import llm_client
try:
text = llm_client.generate_text("Reply with exactly: Groq debug ok")
return {"status": "ok", "response": text}
except Exception as exc:
logger.exception("Groq debug call failed")
raise HTTPException(status_code=500, detail=f"Groq debug failed: {exc}") from exc
|