feat
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
import os, sys, functools
|
||||
print = functools.partial(print, flush=True) # 全局 flush
|
||||
sys.stdout.reconfigure(line_buffering=True) # 3.7+ 有效
|
||||
import asyncio
|
||||
|
||||
from flask import Flask, request, jsonify
|
||||
import json
|
||||
from DataProcess import Add_Collaboration_Brief_FrontEnd
|
||||
@@ -19,11 +26,12 @@ import argparse
|
||||
|
||||
# initialize global variables
|
||||
yaml_file = os.path.join(os.getcwd(), "config", "config.yaml")
|
||||
yaml_data = {}
|
||||
try:
|
||||
with open(yaml_file, "r", encoding="utf-8") as file:
|
||||
yaml_data = yaml.safe_load(file)
|
||||
except Exception:
|
||||
yaml_file = {}
|
||||
yaml_data = {}
|
||||
USE_CACHE: bool = os.getenv("USE_CACHE")
|
||||
if USE_CACHE is None:
|
||||
USE_CACHE = yaml_data.get("USE_CACHE", False)
|
||||
@@ -35,14 +43,98 @@ Request_Cache: dict[str, str] = {}
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
from jsonschema import validate, ValidationError
|
||||
|
||||
AGENT_SELECTION_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"AgentSelectionPlan": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1, # 不允许空字符串
|
||||
"pattern": r"^\S+$" # 不允许仅空白
|
||||
},
|
||||
"minItems": 1 # 至少选一个
|
||||
}
|
||||
},
|
||||
"required": ["AgentSelectionPlan"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
|
||||
BASE_PLAN_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Plan_Outline": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"StepName": {"type": "string"},
|
||||
"TaskContent": {"type": "string"},
|
||||
"InputObject_List":{"type": "array", "items": {"type": "string"}},
|
||||
"OutputObject": {"type": "string"},
|
||||
},
|
||||
"required": ["StepName", "TaskContent", "InputObject_List", "OutputObject"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
}
|
||||
},
|
||||
"required": ["Plan_Outline"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
def safe_join(iterable, sep=""):
|
||||
"""保证 join 前全是 str,None 变空串"""
|
||||
return sep.join("" if x is None else str(x) for x in iterable)
|
||||
|
||||
def clean_agent_board(board):
|
||||
"""把 AgentBoard 洗成只含 str 的字典列表"""
|
||||
if not board:
|
||||
return []
|
||||
return [
|
||||
{"Name": (a.get("Name") or "").strip(),
|
||||
"Profile": (a.get("Profile") or "").strip()}
|
||||
for a in board
|
||||
if a and a.get("Name")
|
||||
]
|
||||
|
||||
def clean_plan_outline(outline):
|
||||
"""清洗 Plan_Outline 里的 None"""
|
||||
if not isinstance(outline, list):
|
||||
return []
|
||||
for step in outline:
|
||||
if not isinstance(step, dict):
|
||||
continue
|
||||
step["InputObject_List"] = [
|
||||
str(i) for i in step.get("InputObject_List", []) if i is not None
|
||||
]
|
||||
step["OutputObject"] = str(step.get("OutputObject") or "")
|
||||
step["StepName"] = str(step.get("StepName") or "")
|
||||
step["TaskContent"] = str(step.get("TaskContent") or "")
|
||||
return outline
|
||||
|
||||
@app.route("/fill_stepTask_TaskProcess", methods=["post"])
|
||||
def Handle_fill_stepTask_TaskProcess():
|
||||
incoming_data = request.get_json()
|
||||
# print(f"[DEBUG] fill_stepTask_TaskProcess received data: {incoming_data}", flush=True)
|
||||
|
||||
# 验证必需参数
|
||||
General_Goal = incoming_data.get("General Goal", "").strip()
|
||||
stepTask_lackTaskProcess = incoming_data.get("stepTask_lackTaskProcess")
|
||||
|
||||
if not General_Goal:
|
||||
return jsonify({"error": "General Goal is required and cannot be empty"}), 400
|
||||
if not stepTask_lackTaskProcess:
|
||||
return jsonify({"error": "stepTask_lackTaskProcess is required"}), 400
|
||||
|
||||
requestIdentifier = str(
|
||||
(
|
||||
"/fill_stepTask_TaskProcess",
|
||||
incoming_data["General Goal"],
|
||||
incoming_data["stepTask_lackTaskProcess"],
|
||||
General_Goal,
|
||||
stepTask_lackTaskProcess,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -50,40 +142,54 @@ def Handle_fill_stepTask_TaskProcess():
|
||||
if requestIdentifier in Request_Cache:
|
||||
return jsonify(Request_Cache[requestIdentifier])
|
||||
|
||||
filled_stepTask = fill_stepTask_TaskProcess(
|
||||
General_Goal=incoming_data["General Goal"],
|
||||
stepTask=incoming_data["stepTask_lackTaskProcess"],
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
)
|
||||
try:
|
||||
filled_stepTask = fill_stepTask_TaskProcess(
|
||||
General_Goal=General_Goal,
|
||||
stepTask=stepTask_lackTaskProcess,
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[ERROR] fill_stepTask_TaskProcess failed: {e}", flush=True)
|
||||
return jsonify({"error": str(e)}), 500
|
||||
filled_stepTask = Add_Collaboration_Brief_FrontEnd(filled_stepTask)
|
||||
Request_Cache[requestIdentifier] = filled_stepTask
|
||||
response = jsonify(filled_stepTask)
|
||||
return response
|
||||
|
||||
|
||||
@app.route("/agentSelectModify_init", methods=["post"])
|
||||
@app.route("/agentSelectModify_init", methods=["POST"])
|
||||
def Handle_agentSelectModify_init():
|
||||
incoming_data = request.get_json()
|
||||
requestIdentifier = str(
|
||||
(
|
||||
"/agentSelectModify_init",
|
||||
incoming_data["General Goal"],
|
||||
incoming_data["stepTask"],
|
||||
)
|
||||
)
|
||||
incoming = request.get_json(silent=True) or {}
|
||||
general_goal = (incoming.get("General Goal") or "").strip()
|
||||
step_task = incoming.get("stepTask")
|
||||
if not general_goal or not step_task:
|
||||
return jsonify({"error": "Missing field"}), 400
|
||||
|
||||
if not AgentBoard: # 空 Board 直接返回
|
||||
return jsonify({"AgentSelectionPlan": []})
|
||||
|
||||
req_id = str(("/agentSelectModify_init", general_goal, step_task))
|
||||
if USE_CACHE and req_id in Request_Cache:
|
||||
return jsonify(Request_Cache[req_id])
|
||||
|
||||
try:
|
||||
clean_board = clean_agent_board(AgentBoard)
|
||||
raw = AgentSelectModify_init(stepTask=step_task,
|
||||
General_Goal=general_goal,
|
||||
Agent_Board=clean_board)
|
||||
if not isinstance(raw, dict):
|
||||
raise ValueError("model returned non-dict")
|
||||
plan = raw.get("AgentSelectionPlan") or []
|
||||
cleaned = [str(x).strip() for x in plan if x is not None and str(x).strip()]
|
||||
raw["AgentSelectionPlan"] = cleaned
|
||||
validate(instance=raw, schema=AGENT_SELECTION_SCHEMA)
|
||||
except Exception as exc:
|
||||
print(f"[ERROR] AgentSelectModify_init: {exc}")
|
||||
return jsonify({"error": str(exc)}), 500
|
||||
|
||||
if USE_CACHE:
|
||||
if requestIdentifier in Request_Cache:
|
||||
return jsonify(Request_Cache[requestIdentifier])
|
||||
|
||||
scoreTable = AgentSelectModify_init(
|
||||
stepTask=incoming_data["stepTask"],
|
||||
General_Goal=incoming_data["General Goal"],
|
||||
Agent_Board=AgentBoard,
|
||||
)
|
||||
Request_Cache[requestIdentifier] = scoreTable
|
||||
response = jsonify(scoreTable)
|
||||
return response
|
||||
Request_Cache[req_id] = raw
|
||||
return jsonify(raw)
|
||||
|
||||
|
||||
@app.route("/agentSelectModify_addAspect", methods=["post"])
|
||||
@@ -98,7 +204,7 @@ def Handle_agentSelectModify_addAspect():
|
||||
return jsonify(Request_Cache[requestIdentifier])
|
||||
|
||||
scoreTable = AgentSelectModify_addAspect(
|
||||
aspectList=incoming_data["aspectList"], Agent_Board=AgentBoard
|
||||
aspectList=incoming_data["aspectList"], Agent_Board=AgentBoard or []
|
||||
)
|
||||
Request_Cache[requestIdentifier] = scoreTable
|
||||
response = jsonify(scoreTable)
|
||||
@@ -108,11 +214,22 @@ def Handle_agentSelectModify_addAspect():
|
||||
@app.route("/fill_stepTask", methods=["post"])
|
||||
def Handle_fill_stepTask():
|
||||
incoming_data = request.get_json()
|
||||
# print(f"[DEBUG] fill_stepTask received data: {incoming_data}", flush=True)
|
||||
|
||||
# 验证必需参数
|
||||
General_Goal = incoming_data.get("General Goal", "").strip()
|
||||
stepTask = incoming_data.get("stepTask")
|
||||
|
||||
if not General_Goal:
|
||||
return jsonify({"error": "General Goal is required and cannot be empty"}), 400
|
||||
if not stepTask:
|
||||
return jsonify({"error": "stepTask is required"}), 400
|
||||
|
||||
requestIdentifier = str(
|
||||
(
|
||||
"/fill_stepTask",
|
||||
incoming_data["General Goal"],
|
||||
incoming_data["stepTask"],
|
||||
General_Goal,
|
||||
stepTask,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -120,12 +237,16 @@ def Handle_fill_stepTask():
|
||||
if requestIdentifier in Request_Cache:
|
||||
return jsonify(Request_Cache[requestIdentifier])
|
||||
|
||||
filled_stepTask = fill_stepTask(
|
||||
General_Goal=incoming_data["General Goal"],
|
||||
stepTask=incoming_data["stepTask"],
|
||||
Agent_Board=AgentBoard,
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
)
|
||||
try:
|
||||
filled_stepTask = fill_stepTask(
|
||||
General_Goal=General_Goal,
|
||||
stepTask=stepTask,
|
||||
Agent_Board=AgentBoard,
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[ERROR] fill_stepTask failed: {e}", flush=True)
|
||||
return jsonify({"error": str(e)}), 500
|
||||
filled_stepTask = Add_Collaboration_Brief_FrontEnd(filled_stepTask)
|
||||
Request_Cache[requestIdentifier] = filled_stepTask
|
||||
response = jsonify(filled_stepTask)
|
||||
@@ -198,31 +319,46 @@ def Handle_branch_TaskProcess():
|
||||
return response
|
||||
|
||||
|
||||
@app.route("/generate_basePlan", methods=["post"])
|
||||
@app.route("/generate_basePlan", methods=["POST"])
|
||||
def Handle_generate_basePlan():
|
||||
incoming_data = request.get_json()
|
||||
requestIdentifier = str(
|
||||
(
|
||||
"/generate_basePlan",
|
||||
incoming_data["General Goal"],
|
||||
incoming_data["Initial Input Object"],
|
||||
incoming = request.get_json(silent=True) or {}
|
||||
general_goal = (incoming.get("General Goal") or "").strip()
|
||||
initial_objs = incoming.get("Initial Input Object") or []
|
||||
|
||||
if not general_goal:
|
||||
return jsonify({"error": "General Goal is required"}), 400
|
||||
|
||||
# 1. 空 Board 直接短路
|
||||
if not AgentBoard:
|
||||
print("[SKIP] AgentBoard empty")
|
||||
out = Add_Collaboration_Brief_FrontEnd({"Plan_Outline": []})
|
||||
return jsonify(out)
|
||||
|
||||
req_id = str(("/generate_basePlan", general_goal, initial_objs))
|
||||
if USE_CACHE and req_id in Request_Cache:
|
||||
return jsonify(Request_Cache[req_id])
|
||||
|
||||
try:
|
||||
# 2. 洗 Board → 调模型 → 洗返回
|
||||
clean_board = clean_agent_board(AgentBoard)
|
||||
raw_plan = asyncio.run(
|
||||
generate_basePlan(
|
||||
General_Goal=general_goal,
|
||||
Agent_Board=clean_board,
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
InitialObject_List=initial_objs,
|
||||
)
|
||||
)
|
||||
)
|
||||
raw_plan["Plan_Outline"] = clean_plan_outline(raw_plan.get("Plan_Outline"))
|
||||
validate(instance=raw_plan, schema=BASE_PLAN_SCHEMA) # 可选,二次校验
|
||||
except Exception as exc:
|
||||
print(f"[ERROR] generate_basePlan failed: {exc}")
|
||||
return jsonify({"error": "model call failed", "detail": str(exc)}), 500
|
||||
|
||||
out = Add_Collaboration_Brief_FrontEnd(raw_plan)
|
||||
if USE_CACHE:
|
||||
if requestIdentifier in Request_Cache:
|
||||
return jsonify(Request_Cache[requestIdentifier])
|
||||
|
||||
basePlan = generate_basePlan(
|
||||
General_Goal=incoming_data["General Goal"],
|
||||
Agent_Board=AgentBoard,
|
||||
AgentProfile_Dict=AgentProfile_Dict,
|
||||
InitialObject_List=incoming_data["Initial Input Object"],
|
||||
)
|
||||
basePlan_withRenderSpec = Add_Collaboration_Brief_FrontEnd(basePlan)
|
||||
Request_Cache[requestIdentifier] = basePlan_withRenderSpec
|
||||
response = jsonify(basePlan_withRenderSpec)
|
||||
return response
|
||||
Request_Cache[req_id] = out
|
||||
return jsonify(out)
|
||||
|
||||
|
||||
@app.route("/executePlan", methods=["post"])
|
||||
@@ -267,13 +403,11 @@ def Handle_saveRequestCashe():
|
||||
@app.route("/setAgents", methods=["POST"])
|
||||
def set_agents():
|
||||
global AgentBoard, AgentProfile_Dict
|
||||
AgentBoard = request.json
|
||||
AgentProfile_Dict = {}
|
||||
for item in AgentBoard:
|
||||
name = item["Name"]
|
||||
profile = item["Profile"]
|
||||
AgentProfile_Dict[name] = profile
|
||||
return jsonify({"code": 200, "content": "set agentboard successfully"})
|
||||
board_in = request.json or []
|
||||
# 先清洗再赋值
|
||||
AgentBoard = clean_agent_board(board_in)
|
||||
AgentProfile_Dict = {a["Name"]: a["Profile"] for a in AgentBoard}
|
||||
return jsonify({"code": 200, "content": "AgentBoard set successfully"})
|
||||
|
||||
|
||||
def init():
|
||||
|
||||
Reference in New Issue
Block a user