| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #
- # Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- import logging
- import json
- import traceback
- from functools import partial
- from flask import request, Response
- from flask_login import login_required, current_user
- from api.db.services.canvas_service import CanvasTemplateService, UserCanvasService
- from api.settings import RetCode
- from api.utils import get_uuid
- from api.utils.api_utils import get_json_result, server_error_response, validate_request, get_data_error_result
- from agent.canvas import Canvas
- from peewee import MySQLDatabase, PostgresqlDatabase
-
-
- @manager.route('/templates', methods=['GET'])
- @login_required
- def templates():
- return get_json_result(data=[c.to_dict() for c in CanvasTemplateService.get_all()])
-
-
- @manager.route('/list', methods=['GET'])
- @login_required
- def canvas_list():
- return get_json_result(data=sorted([c.to_dict() for c in \
- UserCanvasService.query(user_id=current_user.id)], key=lambda x: x["update_time"]*-1)
- )
-
-
- @manager.route('/rm', methods=['POST'])
- @validate_request("canvas_ids")
- @login_required
- def rm():
- for i in request.json["canvas_ids"]:
- if not UserCanvasService.query(user_id=current_user.id,id=i):
- return get_json_result(
- data=False, message='Only owner of canvas authorized for this operation.',
- code=RetCode.OPERATING_ERROR)
- UserCanvasService.delete_by_id(i)
- return get_json_result(data=True)
-
-
- @manager.route('/set', methods=['POST'])
- @validate_request("dsl", "title")
- @login_required
- def save():
- req = request.json
- req["user_id"] = current_user.id
- if not isinstance(req["dsl"], str): req["dsl"] = json.dumps(req["dsl"], ensure_ascii=False)
-
- req["dsl"] = json.loads(req["dsl"])
- if "id" not in req:
- if UserCanvasService.query(user_id=current_user.id, title=req["title"].strip()):
- return server_error_response(ValueError("Duplicated title."))
- req["id"] = get_uuid()
- if not UserCanvasService.save(**req):
- return get_data_error_result(message="Fail to save canvas.")
- else:
- if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
- return get_json_result(
- data=False, message='Only owner of canvas authorized for this operation.',
- code=RetCode.OPERATING_ERROR)
- UserCanvasService.update_by_id(req["id"], req)
- return get_json_result(data=req)
-
-
- @manager.route('/get/<canvas_id>', methods=['GET'])
- @login_required
- def get(canvas_id):
- e, c = UserCanvasService.get_by_id(canvas_id)
- if not e:
- return get_data_error_result(message="canvas not found.")
- return get_json_result(data=c.to_dict())
-
-
- @manager.route('/completion', methods=['POST'])
- @validate_request("id")
- @login_required
- def run():
- req = request.json
- stream = req.get("stream", True)
- e, cvs = UserCanvasService.get_by_id(req["id"])
- if not e:
- return get_data_error_result(message="canvas not found.")
- if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
- return get_json_result(
- data=False, message='Only owner of canvas authorized for this operation.',
- code=RetCode.OPERATING_ERROR)
-
- if not isinstance(cvs.dsl, str):
- cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
-
- final_ans = {"reference": [], "content": ""}
- message_id = req.get("message_id", get_uuid())
- try:
- canvas = Canvas(cvs.dsl, current_user.id)
- if "message" in req:
- canvas.messages.append({"role": "user", "content": req["message"], "id": message_id})
- canvas.add_user_input(req["message"])
- except Exception as e:
- return server_error_response(e)
-
- if stream:
- def sse():
- nonlocal answer, cvs
- try:
- for ans in canvas.run(stream=True):
- if ans.get("running_status"):
- yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n"
- continue
- for k in ans.keys():
- final_ans[k] = ans[k]
- ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
- yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n"
-
- canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
- canvas.history.append(("assistant", final_ans["content"]))
- if final_ans.get("reference"):
- canvas.reference.append(final_ans["reference"])
- cvs.dsl = json.loads(str(canvas))
- UserCanvasService.update_by_id(req["id"], cvs.to_dict())
- except Exception as e:
- cvs.dsl = json.loads(str(canvas))
- UserCanvasService.update_by_id(req["id"], cvs.to_dict())
- traceback.print_exc()
- yield "data:" + json.dumps({"code": 500, "message": str(e),
- "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
- ensure_ascii=False) + "\n\n"
- yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
-
- resp = Response(sse(), mimetype="text/event-stream")
- resp.headers.add_header("Cache-control", "no-cache")
- resp.headers.add_header("Connection", "keep-alive")
- resp.headers.add_header("X-Accel-Buffering", "no")
- resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
- return resp
-
- for answer in canvas.run(stream=False):
- if answer.get("running_status"): continue
- final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else ""
- canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
- if final_ans.get("reference"):
- canvas.reference.append(final_ans["reference"])
- cvs.dsl = json.loads(str(canvas))
- UserCanvasService.update_by_id(req["id"], cvs.to_dict())
- return get_json_result(data={"answer": final_ans["content"], "reference": final_ans.get("reference", [])})
-
-
- @manager.route('/reset', methods=['POST'])
- @validate_request("id")
- @login_required
- def reset():
- req = request.json
- try:
- e, user_canvas = UserCanvasService.get_by_id(req["id"])
- if not e:
- return get_data_error_result(message="canvas not found.")
- if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
- return get_json_result(
- data=False, message='Only owner of canvas authorized for this operation.',
- code=RetCode.OPERATING_ERROR)
-
- canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id)
- canvas.reset()
- req["dsl"] = json.loads(str(canvas))
- UserCanvasService.update_by_id(req["id"], {"dsl": req["dsl"]})
- return get_json_result(data=req["dsl"])
- except Exception as e:
- return server_error_response(e)
-
-
- @manager.route('/test_db_connect', methods=['POST'])
- @validate_request("db_type", "database", "username", "host", "port", "password")
- @login_required
- def test_db_connect():
- req = request.json
- try:
- if req["db_type"] in ["mysql", "mariadb"]:
- db = MySQLDatabase(req["database"], user=req["username"], host=req["host"], port=req["port"],
- password=req["password"])
- elif req["db_type"] == 'postgresql':
- db = PostgresqlDatabase(req["database"], user=req["username"], host=req["host"], port=req["port"],
- password=req["password"])
- db.connect()
- db.close()
- return get_json_result(data="Database Connection Successful!")
- except Exception as e:
- return server_error_response(e)
|