SPOC_V1 / app.py
JatsTheAIGen's picture
patch
06947bf
raw
history blame
3.76 kB
import patch_gradio_jsonschema # MUST be first - patches boolean JSON Schema handling
import patch_gradio_jsonschema # MUST be first - patches boolean JSON Schema handling
import patch_gradio_jsonschema # MUST be first - patches boolean JSON Schema handling\n
# app.py (Updated with Triage Orchestration)
import os
import math
from flask import Flask, render_template, request, jsonify
from dotenv import load_dotenv
from graph import triage_app, planner_app, main_app # Import all three compiled apps
from utils import generate_mermaid_diagram
load_dotenv()
app = Flask(__name__)
# Create necessary directories on startup
os.makedirs("outputs", exist_ok=True)
os.makedirs("uploads", exist_ok=True)
os.makedirs("memory", exist_ok=True)
os.makedirs("logs", exist_ok=True)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/estimate', methods=['POST'])
def estimate():
data = request.json
user_input = data.get('message', '').strip()
if not user_input:
return jsonify({"error": "Message cannot be empty."}), 400
# --- NEW TRIAGE STEP ---
# First, check if the input is a simple greeting
triage_inputs = {"userInput": user_input}
triage_result = triage_app.invoke(triage_inputs)
# If the triage agent provided a direct response, it's a greeting.
if triage_result.get("draftResponse"):
# We add a special key to let the frontend know to just display the message
return jsonify({"is_greeting": True, "response": triage_result["draftResponse"]})
# --- If not a greeting, proceed to the planner ---
planner_inputs = {"userInput": user_input}
try:
estimate_result = planner_app.invoke(planner_inputs)
estimate_result['pmPlan']['is_greeting'] = False
return jsonify(estimate_result.get('pmPlan', {}))
except Exception as e:
return jsonify({"error": "An unexpected error occurred during planning."}), 500
@app.route('/chat', methods=['POST'])
def chat():
data = request.json
user_input = data.get('message', '').strip()
try:
user_budget = float(data.get('user_budget', 0.0))
cost_per_loop = float(data.get('cost_per_loop', 0.05))
except (ValueError, TypeError):
return jsonify({"error": "Invalid budget or cost format."}), 400
if not user_input:
return jsonify({"error": "Message cannot be empty."}), 400
if cost_per_loop > 0:
total_runs_affordable = max(1, math.floor(user_budget / cost_per_loop))
max_loops_calibrated = total_runs_affordable - 1
else:
max_loops_calibrated = 0
initial_state = {
"userInput": user_input, "chatHistory": [], "coreObjectivePrompt": "",
"retrievedMemory": "", "pmPlan": {}, "experimentCode": None,
"experimentResults": None, "draftResponse": "", "qaFeedback": None,
"approved": False, "execution_path": [], "rework_cycles": 0,
"max_loops": max_loops_calibrated
}
try:
final_state = main_app.invoke(initial_state)
except Exception as e:
return jsonify({"response": "An unexpected error occurred during execution. Please check the logs."}), 500
run_path = final_state.get('execution_path', [])
if run_path:
mermaid_syntax = generate_mermaid_diagram(run_path)
with open("outputs/last_run_flow.md", "w") as f:
f.write("# Last Run Execution Flow\n\n")
f.write("```mermaid\n")
f.write(mermaid_syntax)
f.write("```\n")
response = final_state.get('draftResponse', "An error occurred, and no response was generated.")
return jsonify({"response": response})
if __name__ == '__main__':
app.run(debug=True, port=5001)