From 39680f1007be49b94334b4ee790fc381cb958ef4 Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 20:39:20 +0100 Subject: [PATCH 001/162] Remove unused enum --- llm-server/routes/copilot/copilot_controller.py | 1 - 1 file changed, 1 deletion(-) diff --git a/llm-server/routes/copilot/copilot_controller.py b/llm-server/routes/copilot/copilot_controller.py index e929020b1..a87f96245 100644 --- a/llm-server/routes/copilot/copilot_controller.py +++ b/llm-server/routes/copilot/copilot_controller.py @@ -22,7 +22,6 @@ SessionLocal, update_copilot, ) -from utils.llm_consts import EXPERIMENTAL_FEATURES_ENABLED from utils.swagger_parser import SwaggerParser logger = CustomLogger(module_name=__name__) From 418b71fcaba9efbe5b8e206fcb36dd64b09c48b3 Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 20:39:42 +0100 Subject: [PATCH 002/162] Code format --- llm-server/routes/copilot/copilot_controller.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/llm-server/routes/copilot/copilot_controller.py b/llm-server/routes/copilot/copilot_controller.py index a87f96245..d63325f11 100644 --- a/llm-server/routes/copilot/copilot_controller.py +++ b/llm-server/routes/copilot/copilot_controller.py @@ -5,11 +5,7 @@ from flask import Blueprint, jsonify, request, Response from prance import ValidationError from sqlalchemy.exc import SQLAlchemyError -from routes.root_service import get_swagger_doc -from routes._swagger import reindex_service from werkzeug.utils import secure_filename -from utils.base import resolve_abs_local_file_path_from -from utils.get_logger import CustomLogger import routes._swagger.service as swagger_service from enums.initial_prompt import ChatBotInitialPromptEnum @@ -22,6 +18,10 @@ SessionLocal, update_copilot, ) +from routes._swagger import reindex_service +from routes.root_service import get_swagger_doc +from utils.base import resolve_abs_local_file_path_from +from utils.get_logger import CustomLogger from utils.swagger_parser import SwaggerParser logger = CustomLogger(module_name=__name__) @@ -74,8 +74,8 @@ def handle_swagger_file(): jsonify( { "failure": "The copilot was created, but we failed to handle the swagger file duo to some" - " validation issues, your copilot will work fine but without the ability to" - " talk with any APIs. error: {}".format(str(e)) + " validation issues, your copilot will work fine but without the ability to" + " talk with any APIs. error: {}".format(str(e)) } ), 400, @@ -179,7 +179,7 @@ def validator(copilot_id): jsonify( { "error": "Failed to load the swagger file for validation. error: " - + str(e) + + str(e) } ), 400, From 27e81c611a03ce72076ddf192dbbd2892d22a6f1 Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 20:47:52 +0100 Subject: [PATCH 003/162] Add new actions table --- .../copilot/_parts/swagger-form/index.tsx | 4 ++++ .../routes/copilot/copilot_controller.py | 2 +- .../shared/models/opencopilot_db/actions.py | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 llm-server/shared/models/opencopilot_db/actions.py diff --git a/dashboard/app/(main)/create/copilot/_parts/swagger-form/index.tsx b/dashboard/app/(main)/create/copilot/_parts/swagger-form/index.tsx index c25ee81ca..9c49c57c4 100644 --- a/dashboard/app/(main)/create/copilot/_parts/swagger-form/index.tsx +++ b/dashboard/app/(main)/create/copilot/_parts/swagger-form/index.tsx @@ -42,6 +42,10 @@ export function SwaggerUi() { swaggerUrls.length === 0 ?
+ + No endpoints added yet.
diff --git a/llm-server/routes/copilot/copilot_controller.py b/llm-server/routes/copilot/copilot_controller.py index d63325f11..5b6a9ba54 100644 --- a/llm-server/routes/copilot/copilot_controller.py +++ b/llm-server/routes/copilot/copilot_controller.py @@ -46,7 +46,7 @@ def handle_swagger_file(): data=request.get_data(), # Assuming request is available in the scope ) file = request.files["swagger_file"] - if file.filename == "": + if file.filename == "": # Nothing was uploaded return jsonify({"error": "No selected file."}), 400 if file: try: diff --git a/llm-server/shared/models/opencopilot_db/actions.py b/llm-server/shared/models/opencopilot_db/actions.py new file mode 100644 index 000000000..eb3e0fd25 --- /dev/null +++ b/llm-server/shared/models/opencopilot_db/actions.py @@ -0,0 +1,21 @@ +import datetime +import uuid + +from opencopilot_db.database_setup import Base, engine +from sqlalchemy import Column, String, DateTime, JSON, Text + + +class Flow(Base): + __tablename__ = 'actions' + + id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + name = Column(String(255), nullable=True, default="") + description = Column(Text, nullable=True, default="") + payload = Column(JSON, nullable=False, default={}) + status = Column(String(255), default='live') + created_at = Column(DateTime, default=datetime.datetime.utcnow) + updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) + deleted_at = Column(DateTime, nullable=True) + + +Base.metadata.create_all(engine) From 64a8c507faf5402685992c801de4074b29f0370f Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 20:57:25 +0100 Subject: [PATCH 004/162] Add repo --- llm-server/models/repository/action_repo.py | 73 +++++++++++++++++++ .../shared/models/opencopilot_db/actions.py | 5 +- 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 llm-server/models/repository/action_repo.py diff --git a/llm-server/models/repository/action_repo.py b/llm-server/models/repository/action_repo.py new file mode 100644 index 000000000..efcc00765 --- /dev/null +++ b/llm-server/models/repository/action_repo.py @@ -0,0 +1,73 @@ +# action_repo.py +import datetime +import uuid +from typing import Optional, List, Type + +from sqlalchemy import exc +from sqlalchemy.orm import sessionmaker, Session +from opencopilot_db.database_setup import engine + +from shared.models.opencopilot_db.actions import Action +from utils.get_logger import CustomLogger + +# Create a Session factory +SessionLocal = sessionmaker(bind=engine) +logger = CustomLogger(module_name=__name__) + + +def create_action(name: str, description: str, payload: dict, status: str) -> dict: + """ + Creates a new Action instance and adds it to the database. + """ + with SessionLocal() as session: + new_action = Action( + id=str(uuid.uuid4()), + name=name, + description=description, + payload=payload, + status=status, + created_at=datetime.datetime.utcnow(), + updated_at=datetime.datetime.utcnow(), + ) + try: + session.add(new_action) + session.commit() + return action_to_dict(new_action) + except Exception as e: + session.rollback() + logger.error("An exception occurred", error=str(e)) + raise + + +def list_all_actions() -> list[Type[Action]]: + """ + Retrieves all actions from the database. + """ + with SessionLocal() as session: + return session.query(Action).all() + + +def find_action_by_id(action_id: str) -> Optional[Action]: + """ + Finds an Action instance by its ID. + """ + with SessionLocal() as session: + return session.query(Action).filter(Action.id == action_id).first() + + +# Additional functions like update_action, delete_action, etc., can be added as needed + +def action_to_dict(action: Action) -> dict: + """ + Converts an Action object to a dictionary. + """ + return { + "id": action.id, + "name": action.name, + "description": action.description, + "payload": action.payload, + "status": action.status, + "created_at": action.created_at.isoformat(), + "updated_at": action.updated_at.isoformat(), + "deleted_at": action.deleted_at.isoformat() if action.deleted_at else None, + } diff --git a/llm-server/shared/models/opencopilot_db/actions.py b/llm-server/shared/models/opencopilot_db/actions.py index eb3e0fd25..7af87e95f 100644 --- a/llm-server/shared/models/opencopilot_db/actions.py +++ b/llm-server/shared/models/opencopilot_db/actions.py @@ -5,14 +5,15 @@ from sqlalchemy import Column, String, DateTime, JSON, Text -class Flow(Base): +class Action(Base): __tablename__ = 'actions' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + chatbot_id = Column(String(36), nullable=False) name = Column(String(255), nullable=True, default="") description = Column(Text, nullable=True, default="") payload = Column(JSON, nullable=False, default={}) - status = Column(String(255), default='live') + status = Column(String(255), default='live') # live, draft created_at = Column(DateTime, default=datetime.datetime.utcnow) updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) deleted_at = Column(DateTime, nullable=True) From 748a95bf49e6b54ece99bd786c01cbe62c0ff931 Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 20:59:27 +0100 Subject: [PATCH 005/162] Add chatbot_id --- llm-server/models/repository/action_repo.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llm-server/models/repository/action_repo.py b/llm-server/models/repository/action_repo.py index efcc00765..0d544b0eb 100644 --- a/llm-server/models/repository/action_repo.py +++ b/llm-server/models/repository/action_repo.py @@ -1,11 +1,10 @@ # action_repo.py import datetime import uuid -from typing import Optional, List, Type +from typing import Optional, Type -from sqlalchemy import exc -from sqlalchemy.orm import sessionmaker, Session from opencopilot_db.database_setup import engine +from sqlalchemy.orm import sessionmaker from shared.models.opencopilot_db.actions import Action from utils.get_logger import CustomLogger @@ -15,13 +14,14 @@ logger = CustomLogger(module_name=__name__) -def create_action(name: str, description: str, payload: dict, status: str) -> dict: +def create_action(chatbot_id: str, name: str, description: str, payload: dict, status: str) -> dict: """ Creates a new Action instance and adds it to the database. """ with SessionLocal() as session: new_action = Action( id=str(uuid.uuid4()), + chatbot_id=chatbot_id, name=name, description=description, payload=payload, @@ -55,14 +55,13 @@ def find_action_by_id(action_id: str) -> Optional[Action]: return session.query(Action).filter(Action.id == action_id).first() -# Additional functions like update_action, delete_action, etc., can be added as needed - def action_to_dict(action: Action) -> dict: """ Converts an Action object to a dictionary. """ return { "id": action.id, + "chatbot_id": action.chatbot_id, "name": action.name, "description": action.description, "payload": action.payload, From cd1f0dec61f9fd66bb40277cb9c02af8aaa71ead Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 21:05:13 +0100 Subject: [PATCH 006/162] Add the conroller --- llm-server/models/repository/action_repo.py | 20 ++++++++--- llm-server/routes/action/action_controller.py | 36 +++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 llm-server/routes/action/action_controller.py diff --git a/llm-server/models/repository/action_repo.py b/llm-server/models/repository/action_repo.py index 0d544b0eb..8acd4bd52 100644 --- a/llm-server/models/repository/action_repo.py +++ b/llm-server/models/repository/action_repo.py @@ -1,7 +1,7 @@ # action_repo.py import datetime import uuid -from typing import Optional, Type +from typing import Optional from opencopilot_db.database_setup import engine from sqlalchemy.orm import sessionmaker @@ -16,8 +16,15 @@ def create_action(chatbot_id: str, name: str, description: str, payload: dict, status: str) -> dict: """ - Creates a new Action instance and adds it to the database. + Creates a new Action instance and adds it to the database with validations. """ + # Explicit Validations + if not chatbot_id or not isinstance(chatbot_id, str): + raise ValueError("Invalid chatbot_id provided") + if not name or not isinstance(name, str): + raise ValueError("Invalid name provided") + # Add other necessary validations as needed + with SessionLocal() as session: new_action = Action( id=str(uuid.uuid4()), @@ -39,12 +46,15 @@ def create_action(chatbot_id: str, name: str, description: str, payload: dict, s raise -def list_all_actions() -> list[Type[Action]]: +def list_all_actions(chatbot_id: Optional[str] = None) -> List[Action]: """ - Retrieves all actions from the database. + Retrieves actions from the database, optionally filtered by chatbot_id. """ with SessionLocal() as session: - return session.query(Action).all() + query = session.query(Action) + if chatbot_id is not None: + query = query.filter(Action.chatbot_id == chatbot_id) + return query.all() def find_action_by_id(action_id: str) -> Optional[Action]: diff --git a/llm-server/routes/action/action_controller.py b/llm-server/routes/action/action_controller.py new file mode 100644 index 000000000..aeadea66b --- /dev/null +++ b/llm-server/routes/action/action_controller.py @@ -0,0 +1,36 @@ +from flask import Blueprint, jsonify, request + +from models.repository.action_repo import list_all_actions, action_to_dict, create_action, find_action_by_id + +action = Blueprint('action', __name__) + + +@action.route('/bot/', methods=['GET']) +def get_actions(chatbot_id): + actions = list_all_actions(chatbot_id) + return jsonify([action_to_dict(action) for action in actions]) + + +@action.route('/bot/', methods=['POST']) +def add_action(chatbot_id): + data = request.json + data['chatbot_id'] = chatbot_id # Add chatbot_id to the data dictionary + + # Validate incoming data + if not data.get("name"): + return jsonify({"error": "name is required"}), 400 + + try: + action = create_action(**data) + except ValueError as e: + return jsonify({"error": str(e)}), 400 + + return jsonify(action), 201 + + +@action.route('/', methods=['GET']) +def get_action(action_id): + action = find_action_by_id(action_id) + if action is None: + return jsonify({'error': 'Action not found'}), 404 + return jsonify(action_to_dict(action)) From c06479ed8deb7dddf5530a3dd0bd43c591c3752f Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 21:14:55 +0100 Subject: [PATCH 007/162] Add base uri to the model --- llm-server/models/repository/action_repo.py | 9 ++++++--- .../models/opencopilot_db/{actions.py => action.py} | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) rename llm-server/shared/models/opencopilot_db/{actions.py => action.py} (85%) diff --git a/llm-server/models/repository/action_repo.py b/llm-server/models/repository/action_repo.py index 8acd4bd52..5a1143163 100644 --- a/llm-server/models/repository/action_repo.py +++ b/llm-server/models/repository/action_repo.py @@ -1,12 +1,12 @@ # action_repo.py import datetime import uuid -from typing import Optional +from typing import Optional, List from opencopilot_db.database_setup import engine from sqlalchemy.orm import sessionmaker -from shared.models.opencopilot_db.actions import Action +from shared.models.opencopilot_db.action import Action from utils.get_logger import CustomLogger # Create a Session factory @@ -14,7 +14,8 @@ logger = CustomLogger(module_name=__name__) -def create_action(chatbot_id: str, name: str, description: str, payload: dict, status: str) -> dict: +def create_action(chatbot_id: str, name: str, description: str = None, base_uri: str = None, payload: dict = None, + status: str = None) -> dict: """ Creates a new Action instance and adds it to the database with validations. """ @@ -31,6 +32,7 @@ def create_action(chatbot_id: str, name: str, description: str, payload: dict, s chatbot_id=chatbot_id, name=name, description=description, + base_uri=base_uri, payload=payload, status=status, created_at=datetime.datetime.utcnow(), @@ -74,6 +76,7 @@ def action_to_dict(action: Action) -> dict: "chatbot_id": action.chatbot_id, "name": action.name, "description": action.description, + "base_uri": action.base_uri, "payload": action.payload, "status": action.status, "created_at": action.created_at.isoformat(), diff --git a/llm-server/shared/models/opencopilot_db/actions.py b/llm-server/shared/models/opencopilot_db/action.py similarity index 85% rename from llm-server/shared/models/opencopilot_db/actions.py rename to llm-server/shared/models/opencopilot_db/action.py index 7af87e95f..f27ffd725 100644 --- a/llm-server/shared/models/opencopilot_db/actions.py +++ b/llm-server/shared/models/opencopilot_db/action.py @@ -12,7 +12,8 @@ class Action(Base): chatbot_id = Column(String(36), nullable=False) name = Column(String(255), nullable=True, default="") description = Column(Text, nullable=True, default="") - payload = Column(JSON, nullable=False, default={}) + base_uri = Column(String(255), nullable=True, default="") + payload = Column(JSON, nullable=False, default={}) # Swagger path status = Column(String(255), default='live') # live, draft created_at = Column(DateTime, default=datetime.datetime.utcnow) updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) From d02cc36e9d842976e135bf755263c36566127c0a Mon Sep 17 00:00:00 2001 From: gharbat Date: Wed, 6 Dec 2023 21:36:57 +0100 Subject: [PATCH 008/162] Add base uri to the model --- llm-server/utils/swagger_parser.py | 44 ++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/llm-server/utils/swagger_parser.py b/llm-server/utils/swagger_parser.py index 552699955..f5e1fd85b 100644 --- a/llm-server/utils/swagger_parser.py +++ b/llm-server/utils/swagger_parser.py @@ -1,8 +1,6 @@ -import json - - class Endpoint: - def __init__(self, operation_id, endpoint_type, name, description, request_body, request_parameters, response, path): + def __init__(self, operation_id, endpoint_type, name, description, request_body, request_parameters, response, + path): self.operation_id = operation_id self.type = endpoint_type self.name = name @@ -95,9 +93,43 @@ def get_authorization_type(self): def get_validations(self): endpoints = self.get_endpoints() validations = { - 'endpoints_without_operation_id': [endpoint.to_dict() for endpoint in get_endpoints_without_operation_id(endpoints)], - 'endpoints_without_description': [endpoint.to_dict() for endpoint in get_endpoints_without_description(endpoints)], + 'endpoints_without_operation_id': [endpoint.to_dict() for endpoint in + get_endpoints_without_operation_id(endpoints)], + 'endpoints_without_description': [endpoint.to_dict() for endpoint in + get_endpoints_without_description(endpoints)], 'endpoints_without_name': [endpoint.to_dict() for endpoint in get_endpoints_without_name(endpoints)], 'auth_type': self.get_authorization_type() } return validations + + def get_base_uri(self): + """ + Retrieves the base URI from the Swagger file's "servers" object, specific to OpenAPI 3.0.0. + """ + servers = self.swagger_data.get('servers', []) + if servers: + # Use the first server's URL as the base URI + return servers[0].get('url', '') + return '' + + def get_all_actions(self): + """ + Retrieves all actions defined in the Swagger file. + Each action represents a path and includes details like base_uri, path, name, summary, and operation_id. + """ + actions = [] + base_uri = self.get_base_uri() + paths = self.swagger_data.get('paths', {}) + + for path, path_data in paths.items(): + for method, method_data in path_data.items(): + action = { + "base_uri": base_uri, + "path": path, + "name": method_data.get('summary'), + "summary": method_data.get('description'), + "operation_id": method_data.get('operationId') + } + actions.append(action) + + return actions From 7ced97721844db4825dd8a6696aba5d611a32362 Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 16:07:16 +0200 Subject: [PATCH 009/162] Add new flow renderer component --- .../(copilot)/copilot/[copilot_id]/workflow/page.tsx | 9 +++++++++ .../components/domain/new-flows-editor/Renderer.tsx | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx create mode 100644 dashboard/components/domain/new-flows-editor/Renderer.tsx diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx new file mode 100644 index 000000000..5c546d394 --- /dev/null +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx @@ -0,0 +1,9 @@ +import { FlowRenderer } from '@/components/domain/new-flows-editor/Renderer' +import React from 'react' + + +export default function WorkflowPage() { + return ( + + ) +} diff --git a/dashboard/components/domain/new-flows-editor/Renderer.tsx b/dashboard/components/domain/new-flows-editor/Renderer.tsx new file mode 100644 index 000000000..685af46f5 --- /dev/null +++ b/dashboard/components/domain/new-flows-editor/Renderer.tsx @@ -0,0 +1,10 @@ +'use client'; +import { Background, ReactFlow } from 'reactflow'; + +export function FlowRenderer() { + return ( + + + + ) +} \ No newline at end of file From 9eb788a7369b0079d5181d6aa526f7685ca4c68b Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 16:07:16 +0200 Subject: [PATCH 010/162] Add new flow renderer component --- .../(copilot)/copilot/[copilot_id]/workflow/page.tsx | 9 +++++++++ .../components/domain/new-flows-editor/Renderer.tsx | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx create mode 100644 dashboard/components/domain/new-flows-editor/Renderer.tsx diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx new file mode 100644 index 000000000..5c546d394 --- /dev/null +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx @@ -0,0 +1,9 @@ +import { FlowRenderer } from '@/components/domain/new-flows-editor/Renderer' +import React from 'react' + + +export default function WorkflowPage() { + return ( + + ) +} diff --git a/dashboard/components/domain/new-flows-editor/Renderer.tsx b/dashboard/components/domain/new-flows-editor/Renderer.tsx new file mode 100644 index 000000000..685af46f5 --- /dev/null +++ b/dashboard/components/domain/new-flows-editor/Renderer.tsx @@ -0,0 +1,10 @@ +'use client'; +import { Background, ReactFlow } from 'reactflow'; + +export function FlowRenderer() { + return ( + + + + ) +} \ No newline at end of file From a7aa97d2f1ad0279b3ddd2d72bfc2475ef0f0dbe Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 16:07:16 +0200 Subject: [PATCH 011/162] Add new flow renderer component --- .../(copilot)/copilot/[copilot_id]/workflow/page.tsx | 9 +++++++++ .../components/domain/new-flows-editor/Renderer.tsx | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx create mode 100644 dashboard/components/domain/new-flows-editor/Renderer.tsx diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx new file mode 100644 index 000000000..5c546d394 --- /dev/null +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/page.tsx @@ -0,0 +1,9 @@ +import { FlowRenderer } from '@/components/domain/new-flows-editor/Renderer' +import React from 'react' + + +export default function WorkflowPage() { + return ( + + ) +} diff --git a/dashboard/components/domain/new-flows-editor/Renderer.tsx b/dashboard/components/domain/new-flows-editor/Renderer.tsx new file mode 100644 index 000000000..685af46f5 --- /dev/null +++ b/dashboard/components/domain/new-flows-editor/Renderer.tsx @@ -0,0 +1,10 @@ +'use client'; +import { Background, ReactFlow } from 'reactflow'; + +export function FlowRenderer() { + return ( + + + + ) +} \ No newline at end of file From ff32ab1d64c76272c08c76060dbe9591a8e671e2 Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 17:54:34 +0200 Subject: [PATCH 012/162] Update lucide-react and reactflow versions --- dashboard/package.json | 4 +-- dashboard/pnpm-lock.yaml | 62 ++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index 4c27ed8ed..e486d85e1 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -40,7 +40,7 @@ "immer": "^10.0.3", "jotai": "^2.4.3", "lodash": "^4.17.21", - "lucide-react": "^0.284.0", + "lucide-react": "^0.294.0", "next": "14.0.0", "nprogress": "^0.2.0", "react": "^18", @@ -54,7 +54,7 @@ "react-textarea-autosize": "^8.5.3", "react-use": "^17.4.0", "react-use-wizard": "^2.2.3", - "reactflow": "^11.9.4", + "reactflow": "^11.10.1", "swr": "^2.2.4", "tailwind-merge": "^1.14.0", "tailwindcss-animate": "^1.0.7", diff --git a/dashboard/pnpm-lock.yaml b/dashboard/pnpm-lock.yaml index 44bbf9537..6ea2a6f24 100644 --- a/dashboard/pnpm-lock.yaml +++ b/dashboard/pnpm-lock.yaml @@ -96,8 +96,8 @@ dependencies: specifier: ^4.17.21 version: 4.17.21 lucide-react: - specifier: ^0.284.0 - version: 0.284.0(react@18.2.0) + specifier: ^0.294.0 + version: 0.294.0(react@18.2.0) next: specifier: 14.0.0 version: 14.0.0(react-dom@18.2.0)(react@18.2.0) @@ -138,8 +138,8 @@ dependencies: specifier: ^2.2.3 version: 2.2.3(react-dom@18.2.0)(react@18.2.0) reactflow: - specifier: ^11.9.4 - version: 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + specifier: ^11.10.1 + version: 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) swr: specifier: ^2.2.4 version: 2.2.4(react@18.2.0) @@ -1669,13 +1669,13 @@ packages: '@babel/runtime': 7.23.2 dev: false - /@reactflow/background@11.3.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-bgwvqWxF09chwmdkyClpYEMaewBspdwjgLbbFlLf4SpWPFMYyuvCBQrcISsvy/EDEWO9i3Uj9ktgGAhvtSQsmA==} + /@reactflow/background@11.3.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-06FPlSUOOMALEEs+2PqPAbpqmL7WDjrkbG2UsDr2d6mbcDDhHiV4tu9FYoz44SQvXo7ma9VRotlsaR4OiRcYsg==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1685,13 +1685,13 @@ packages: - immer dev: false - /@reactflow/controls@11.2.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-x6e5p9iHjC6gd+4SoZ3DOOp0F1MefGKQ8hT6yPVdqxfo1+rV2WhrWvrX/MCoEu12Dp7457LdLfa0giy3aho8tQ==} + /@reactflow/controls@11.2.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-4QHT92/ACVlZkvV+Hq44bAPV8WbMhkJl+/J0EbXcqQ1+an7cWJsF84eeelJw7R5J76RoaSSpKdsWsL2v7HAVlw==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1701,8 +1701,8 @@ packages: - immer dev: false - /@reactflow/core@11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Ko7nKPOYalwDTTbRHi2+QXDiidSAcpUzGN3G+0B+QysLZkcaPCkpkMjjHiDC4c/Z1BJBzs1FRJg/T6BXaBnYkg==} + /@reactflow/core@11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GIh3usY1W3eVobx//OO9+Cwm+5evQBBdPGxDaeXwm25UqPMWRI240nXQA5F/5gL5Mwpf0DUC7DR2EmrKNQy+Rw==} peerDependencies: react: '>=17' react-dom: '>=17' @@ -1723,13 +1723,13 @@ packages: - immer dev: false - /@reactflow/minimap@11.7.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Jo1R+uDey9IV7O2s3m0gK2+cZpg9M8hq2EZJb3NGfOSzMAPhj3mby0fNJIgTzycreuht0TpA51c2YfjGI3YIOw==} + /@reactflow/minimap@11.7.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-kJEtyeQkTZYViLGebVWHVUJROMAGcvejvT+iX4DqKnFb5yK8E8LWlXQpRx2FrL9gDy80mJJaciy7IxnnQKE1bg==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) '@types/d3-selection': 3.0.8 '@types/d3-zoom': 3.0.6 classcat: 5.0.4 @@ -1743,13 +1743,13 @@ packages: - immer dev: false - /@reactflow/node-resizer@2.2.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+p271/hAsM5M1+RQTWW/02pbNkCHeGXwxGimIlL1tMIagyuko0NX2vOz2B8jxJnPKlF09Wj18BcXBNUm3nDcSg==} + /@reactflow/node-resizer@2.2.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1Xb6q97uP7hRBLpog9sRCNfnsHdDgFRGEiU+lQqGgPEAeYwl4nRjWa/sXwH6ajniKxBhGEvrdzOgEFn6CRMcpQ==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 d3-drag: 3.0.0 d3-selection: 3.0.0 @@ -1761,13 +1761,13 @@ packages: - immer dev: false - /@reactflow/node-toolbar@1.3.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-TfcmpXHRBb2mUfzKGjburiU6FWqRME9pPFs1OwIC1z5e9BjupQhNDEKEk8XHi7PKL/mAiDfwuGXaM1BVVFuPqw==} + /@reactflow/node-toolbar@1.3.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-JXDEuZ0wKjZ8z7qK2bIst0eZPzNyVEsiHL0e93EyuqT4fA9icoyE0fLq2ryNOOp7MXgId1h7LusnH6ta45F0yQ==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3755,8 +3755,8 @@ packages: yallist: 4.0.0 dev: true - /lucide-react@0.284.0(react@18.2.0): - resolution: {integrity: sha512-dVSMHYAya/TeY3+vsk+VQJEKNQN2AhIo0+Dp09B2qpzvcBuu93H98YZykFcjIAfmanFiDd8nqfXFR38L757cyQ==} + /lucide-react@0.294.0(react@18.2.0): + resolution: {integrity: sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 dependencies: @@ -4430,18 +4430,18 @@ packages: loose-envify: 1.4.0 dev: false - /reactflow@11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-IHAKBkJngNvU9y1vZ5Nw9rvA3Z+zc9geTgQQIi9qq9Y9knGLlDDr9KfsjbFMew9AycAAgVg8TvBEakF4IT5lqg==} + /reactflow@11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Q616fElAc5/N37tMwjuRkkgm/VgmnLLTNNCj61z5mvJxae+/VXZQMfot1K6a5LLz9G3SVKqU97PMb9Ga1PRXew==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/background': 11.3.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/controls': 11.2.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/core': 11.9.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/minimap': 11.7.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-resizer': 2.2.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-toolbar': 1.3.4(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/background': 11.3.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/controls': 11.2.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.10.1(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/minimap': 11.7.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-resizer': 2.2.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-toolbar': 1.3.6(@types/react@18.2.28)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: From 538cdae72ea4cd2e7516bd395f9fca32030e183a Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 17:54:53 +0200 Subject: [PATCH 013/162] Add Copilot workflow layout and new flows editor components --- .../(copilot)/copilot/[copilot_id]/layout.tsx | 2 +- .../copilot/[copilot_id]/workflow/layout.tsx | 27 ++++++++++ .../domain/new-flows-editor/ActionBlock.tsx | 19 +++++++ .../new-flows-editor/FloatingActionBar.tsx | 54 +++++++++++++++++++ .../domain/new-flows-editor/Renderer.tsx | 15 ++++-- 5 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 dashboard/app/(copilot)/copilot/[copilot_id]/workflow/layout.tsx create mode 100644 dashboard/components/domain/new-flows-editor/ActionBlock.tsx create mode 100644 dashboard/components/domain/new-flows-editor/FloatingActionBar.tsx diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/layout.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/layout.tsx index b77ec0cad..4990e94c7 100644 --- a/dashboard/app/(copilot)/copilot/[copilot_id]/layout.tsx +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/layout.tsx @@ -124,7 +124,7 @@ export default function CopilotLayout({ children, params }: Props) {
-
+
{children}
diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/layout.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/layout.tsx new file mode 100644 index 000000000..8e736f90f --- /dev/null +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/layout.tsx @@ -0,0 +1,27 @@ +import { HeaderShell } from '@/components/domain/HeaderShell' +import { Button } from '@/components/ui/button' +import React from 'react' + +type Props = { + children: React.ReactNode +} + +function WorkflowLayout({ + children +}: Props) { + return ( +
+ +

Workflow

+ +
+
+ {children} +
+
+ ) +} + +export default WorkflowLayout \ No newline at end of file diff --git a/dashboard/components/domain/new-flows-editor/ActionBlock.tsx b/dashboard/components/domain/new-flows-editor/ActionBlock.tsx new file mode 100644 index 000000000..7270ce8b1 --- /dev/null +++ b/dashboard/components/domain/new-flows-editor/ActionBlock.tsx @@ -0,0 +1,19 @@ +import React, { memo } from 'react'; +import { Handle, Position } from 'reactflow'; +import type { NodeProps } from 'reactflow'; + +type Props = NodeProps<{}> + +function ActionBlock({ }: Props) { + return ( + <> + +
+ + +
+ + + ) +} +export default memo(ActionBlock) \ No newline at end of file diff --git a/dashboard/components/domain/new-flows-editor/FloatingActionBar.tsx b/dashboard/components/domain/new-flows-editor/FloatingActionBar.tsx new file mode 100644 index 000000000..40fc8f0ee --- /dev/null +++ b/dashboard/components/domain/new-flows-editor/FloatingActionBar.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import { Cuboid, Workflow } from 'lucide-react' +import { Panel } from 'reactflow'; +import { Button } from '@/components/ui/button'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; + +function Group({ children }: { children: React.ReactNode }) { + return ( +
+ {children} +
+ ) +} +function Actions() { + return + + + + + Actions + + +} + +export function FloatingActionBar() { + return ( + + + + + + + + + + + ) +} diff --git a/dashboard/components/domain/new-flows-editor/Renderer.tsx b/dashboard/components/domain/new-flows-editor/Renderer.tsx index 685af46f5..05e47361f 100644 --- a/dashboard/components/domain/new-flows-editor/Renderer.tsx +++ b/dashboard/components/domain/new-flows-editor/Renderer.tsx @@ -1,10 +1,17 @@ 'use client'; -import { Background, ReactFlow } from 'reactflow'; - +import ReactFlow, { Background, Controls } from 'reactflow'; +import actionBlock from './ActionBlock'; +import 'reactflow/dist/style.css'; +import { FloatingActionBar } from './FloatingActionBar'; +const nodeTypes = { + actionBlock +} export function FlowRenderer() { return ( - - + + + + ) } \ No newline at end of file From 70da793b25e32de63181ba72d0d16c40c68d57a9 Mon Sep 17 00:00:00 2001 From: ah7255703 Date: Thu, 7 Dec 2023 21:19:20 +0200 Subject: [PATCH 014/162] Add CreateWorkflowForm component --- .../workflow/_parts/CreateWorkflowForm.tsx | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 dashboard/app/(copilot)/copilot/[copilot_id]/workflow/_parts/CreateWorkflowForm.tsx diff --git a/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/_parts/CreateWorkflowForm.tsx b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/_parts/CreateWorkflowForm.tsx new file mode 100644 index 000000000..fe575137c --- /dev/null +++ b/dashboard/app/(copilot)/copilot/[copilot_id]/workflow/_parts/CreateWorkflowForm.tsx @@ -0,0 +1,120 @@ +'use client'; +import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; +import { Button } from '@/components/ui/button'; +import React from 'react' +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Switch } from '@/components/ui/switch'; + + +const formSchema = z.object({ + title: z.string().min(2, { + message: "title must be at least 2 characters.", + }), + description: z.string().min(2, { + message: "description must be at least 2 characters.", + }), + edit_after_creation: z.boolean().default(false), +}) + + +export default function CreateWorkflowForm() { + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + title: '', + description: '', + edit_after_creation: false, + } + }) + function onSubmit(values: z.infer) { + console.log(values) + } + return ( + + + + + + + Create Flow + + Flows are a sequence of steps that are executed when a user interacts with your bot. + + +
+ + ( + + + Title + + + + + + + )} + /> + ( + + + Description + + +