├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── assets │ ├── amazon.gif │ ├── chatbot.gif │ ├── demo1.gif │ ├── hf_multimodal.gif │ ├── otto-m8.png │ └── otto.png └── docs │ ├── .gitignore │ ├── README.md │ ├── docs │ ├── conceptual-guide │ │ ├── _category_.json │ │ ├── blocks │ │ │ ├── _category_.json │ │ │ ├── advance.md │ │ │ ├── basics.md │ │ │ └── custom_blocks.md │ │ ├── imgs │ │ │ ├── block_advanced_ex.png │ │ │ ├── code.png │ │ │ ├── deployable.png │ │ │ ├── ipo.png │ │ │ ├── lambdaspage.png │ │ │ ├── run_config.png │ │ │ ├── static-dropdown.png │ │ │ ├── template.png │ │ │ ├── tracer.png │ │ │ ├── viewcode.png │ │ │ └── workflow.png │ │ ├── lambdas.md │ │ ├── template.md │ │ ├── tracer.md │ │ └── workflow.md │ ├── getting-started.md │ ├── integrations │ │ ├── _category_.json │ │ └── gcloud.md │ ├── introduction.md │ └── tutorials │ │ ├── _category_.json │ │ ├── custom-block-weather │ │ └── custom-block-weather.mdx │ │ ├── modify-chatbot │ │ └── modify-chatbot.mdx │ │ ├── simple-chatbot │ │ └── simple-chatbot.mdx │ │ └── weather-agent │ │ └── weather-agent.mdx │ ├── docusaurus.config.js │ ├── package-lock.json │ ├── package.json │ ├── sidebars.js │ ├── src │ ├── components │ │ ├── HomepageFeatures │ │ │ ├── index.js │ │ │ └── styles.module.css │ │ └── OttoDisplay │ │ │ ├── OttoDisplay.js │ │ │ ├── chatbot.gif │ │ │ └── styles.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ ├── index.module.css │ │ └── markdown-page.md │ └── static │ ├── .nojekyll │ ├── img │ ├── blockconfig.png │ ├── blocks.png │ ├── code.png │ ├── docusaurus-social-card.jpg │ ├── docusaurus.png │ ├── favicon.ico │ ├── logo.svg │ ├── otto-m8_logo.png │ ├── undraw_docusaurus_mountain.svg │ ├── undraw_docusaurus_react.svg │ └── undraw_docusaurus_tree.svg │ └── robots.txt ├── lib ├── dashboard │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── assets │ │ │ ├── hugging_face_model_card.png │ │ │ ├── ollama.png │ │ │ ├── openai.png │ │ │ ├── otto-2.png │ │ │ └── otto.png │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── api │ │ ├── blocks │ │ │ └── index.js │ │ ├── gcloud │ │ │ └── index.js │ │ └── health_check.js │ │ ├── components │ │ ├── Block │ │ │ ├── Block.css │ │ │ ├── BlockTypes.js │ │ │ ├── InputBlocks │ │ │ │ └── types.tsx │ │ │ ├── PlaceholderBlock.js │ │ │ └── ProcessBlock.js │ │ ├── BlockCode │ │ │ ├── APIReference.js │ │ │ └── index.js │ │ ├── BlockConfigBar │ │ │ ├── AddBlockSidebar.js │ │ │ └── NodeSidebar.js │ │ ├── Extras │ │ │ ├── CustomAlert.js │ │ │ ├── EditableTextBox.js │ │ │ └── TopErrorBar.js │ │ ├── FormFields │ │ │ ├── DatePickerField.js │ │ │ ├── Fields.js │ │ │ ├── GCloudAuth.js │ │ │ ├── LambdasDropdown.js │ │ │ ├── MultimodalSelector.js │ │ │ ├── PromptTemplate.js │ │ │ └── ToolCalling.js │ │ ├── InputHandles │ │ │ ├── ChatTextInput.js │ │ │ ├── TextInput.js │ │ │ ├── UploadFile.js │ │ │ ├── createInputPayload.js │ │ │ └── utils.js │ │ ├── InstantRuns │ │ │ └── InstantRun.js │ │ ├── LLMToolCalling │ │ │ ├── BlockConnection.js │ │ │ ├── ToolConfig.js │ │ │ ├── exampleTools.json │ │ │ ├── index.js │ │ │ └── styles.css │ │ ├── NavigationBar │ │ │ ├── HeadNavigationBar.css │ │ │ ├── HeadNavigationBar.js │ │ │ └── NavigationBar.js │ │ ├── Pages │ │ │ ├── Auth │ │ │ │ ├── Login.js │ │ │ │ └── Signup.js │ │ │ ├── Chat │ │ │ │ ├── Chat.js │ │ │ │ ├── DropUpUtility.js │ │ │ │ └── Utils │ │ │ │ │ └── fetchUtils.js │ │ │ ├── Home │ │ │ │ ├── Home.js │ │ │ │ ├── examples.json │ │ │ │ └── newTemplate.js │ │ │ ├── Lambdas │ │ │ │ ├── CodeEditor.js │ │ │ │ └── LambdasPage.js │ │ │ ├── RunTemplate │ │ │ │ └── RunTemplate.js │ │ │ ├── TemplatePage │ │ │ │ ├── TemplatePage.css │ │ │ │ └── TemplatePage.js │ │ │ ├── Tracer │ │ │ │ ├── AllTrace.js │ │ │ │ ├── TraceView.js │ │ │ │ └── WorkflowTrace.js │ │ │ └── Workflows │ │ │ │ ├── TestWorkflow.js │ │ │ │ ├── Utils │ │ │ │ ├── CreateRunConfig.js │ │ │ │ └── ProcessDataForBackend.js │ │ │ │ └── Workflow.js │ │ ├── RunTemplate │ │ │ └── Run.js │ │ └── Terminal │ │ │ └── index.js │ │ ├── contexts │ │ ├── AuthContext.js │ │ ├── RequireAuth.js │ │ └── theme.js │ │ ├── hooks │ │ ├── input_handlers.js │ │ └── use_loading.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ ├── types │ │ ├── blocks │ │ │ ├── field.tsx │ │ │ └── initialData.tsx │ │ └── input.tsx │ │ └── utils │ │ ├── health_check.js │ │ └── workflow │ │ └── BlockRepositioning.js ├── docker-compose.privilleged.yml ├── docker-compose.yml ├── otto_backend │ ├── .dockerignore │ ├── .gitignore │ ├── base.Dockerfile │ ├── client.py │ ├── core │ │ ├── blocks │ │ │ ├── __init__.py │ │ │ ├── field.py │ │ │ └── metadata.py │ │ ├── connections.py │ │ ├── container_utils │ │ │ ├── __init__.py │ │ │ └── docker_tools.py │ │ ├── data_loaders │ │ │ └── image.py │ │ ├── implementations │ │ │ ├── base.py │ │ │ └── registry.py │ │ ├── input_parser │ │ │ ├── hf_multimodal_parser.py │ │ │ ├── integration_inp_parser.py │ │ │ └── prompt_template.py │ │ ├── types.py │ │ └── utils │ │ │ └── __init__.py │ ├── db │ │ ├── auth.py │ │ ├── base.py │ │ ├── db_engine.py │ │ └── models │ │ │ ├── __init__.py │ │ │ ├── lambdas.py │ │ │ ├── temporary_workflow.py │ │ │ ├── tracer.py │ │ │ ├── users.py │ │ │ └── workflow_templates.py │ ├── engine │ │ ├── blocks.py │ │ └── workflow.py │ ├── extensions │ │ ├── experimental │ │ │ ├── __init__.py │ │ │ └── terminal.py │ │ ├── llm_memory │ │ │ ├── base.py │ │ │ ├── basic_memory.py │ │ │ ├── chat_memory.py │ │ │ └── types.py │ │ └── llm_tools │ │ │ ├── ollama_tool.py │ │ │ ├── openai_tool.py │ │ │ └── tool.py │ ├── implementations │ │ ├── __init__.py │ │ ├── base.py │ │ ├── custom │ │ │ ├── blocks │ │ │ │ └── README.md │ │ │ ├── catalog.py │ │ │ └── implementer.py │ │ ├── integrations │ │ │ ├── __init__.py │ │ │ ├── catalog.py │ │ │ ├── http │ │ │ │ └── post_requests │ │ │ │ │ └── post_request.py │ │ │ ├── implementer.py │ │ │ └── lambda_function │ │ │ │ └── lambda_function.py │ │ └── tasks │ │ │ ├── catalog.py │ │ │ ├── custom │ │ │ └── basic_block.py │ │ │ ├── dependencies │ │ │ ├── hugging_face_model_card.txt │ │ │ ├── ollama_server_chat.txt │ │ │ ├── ollama_server_generate.txt │ │ │ └── openai_chat.txt │ │ │ ├── experimental │ │ │ └── openai_chat_vision.py │ │ │ ├── gcloud │ │ │ ├── calendar │ │ │ │ ├── create_event.py │ │ │ │ └── upcoming_events.py │ │ │ └── gmail │ │ │ │ ├── create_draft.py │ │ │ │ ├── read_emails.py │ │ │ │ └── send_email.py │ │ │ ├── hugging_face │ │ │ ├── hugging_face_model_card.py │ │ │ └── hugging_face_multimodal.py │ │ │ ├── implementer.py │ │ │ ├── input_blocks │ │ │ ├── image_input │ │ │ │ └── image.py │ │ │ └── text_input │ │ │ │ └── text_input.py │ │ │ ├── ollama │ │ │ ├── ollama_server_chat.py │ │ │ └── ollama_server_generate.py │ │ │ ├── openai │ │ │ └── openai_chat.py │ │ │ ├── output_blocks │ │ │ ├── chat_output_block.py │ │ │ └── output_block.py │ │ │ └── pdf_loader │ │ │ └── langchain_pdf_loader.py │ ├── integrations │ │ ├── gcloud │ │ │ └── auth_flow.py │ │ ├── hugging_face │ │ │ └── hugging_face_api.py │ │ ├── langchain │ │ │ └── pdf_loader.py │ │ └── openai │ │ │ └── openai.py │ ├── lambdas │ │ ├── Dockerfile │ │ ├── handler.py │ │ └── server.py │ ├── pyproject.toml │ ├── requirements.txt │ ├── routers │ │ ├── __init__.py │ │ ├── auth_router.py │ │ ├── block_types_router.py │ │ ├── dependency.py │ │ ├── draft_router.py │ │ ├── experimental.py │ │ ├── gcloud_router.py │ │ ├── instant_run_router.py │ │ ├── lambdas_router.py │ │ ├── template_router.py │ │ ├── tracer_router.py │ │ └── workflow_router.py │ ├── server.Dockerfile │ ├── server.py │ ├── slim-base.Dockerfile │ └── tracer │ │ ├── __init__.py │ │ ├── tracer.py │ │ └── types.py ├── pyproject.toml ├── setup.py └── tooklit │ ├── LICENSE │ ├── README.md │ ├── otto_m8 │ ├── core │ │ └── config.py │ └── run.py │ ├── poetry.lock │ └── pyproject.toml └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | build 3 | *.egg* 4 | dist 5 | __pycache__ 6 | poetry.lock 7 | lib/otto_backend/implementations/custom/blocks/*.py -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to otto-m8 2 | 3 | Thank you for your interest in contributing to otto-m8]! We appreciate your help in making this project better. Please take a moment to review this guide to ensure your contributions align with our goals and standards. 4 | 5 | ## How to Contribute 6 | As a new project with a lot that needs to be done, we welcome all kinds of contributions. Here are a few ways you can help: 7 | 8 | - **New Integrations**: Since this is a workflow automation platform, integrations with other providers are key. If there's a particular integration you want to integrate into otto-m8, feel free to let us know. 9 | - **Bug Reports & Fixes**: If you encounter any issues or unexpected behavior, please report them. Bug fixes are highly appreciated! 10 | - **Workflow Orchestration & Refactoring**: Improvements to the underlying workflow orchestration engine and/or refactoring the codebase for better efficiency and maintainability are welcome. 11 | - **Better UI/UX**: If you think the user experience can be improved, let us know! 12 | 13 | ## Getting Started 14 | 1. **Fork the repository** on GitHub. 15 | 2. **Clone your fork**: 16 | ```sh 17 | git clone https://github.com/farhan0167/otto-m8.git 18 | cd otto-m8 19 | ``` 20 | 3. Run the script: 21 | ```sh 22 | chmod +x run.sh 23 | ./run.sh 24 | ``` 25 | At this point, it would help to read up on the existing documentation to navigate the project or feel free to leave a comment under the issue by tagging the maintainers. 26 | 4. **Create a new branch** for your feature or fix: 27 | ```sh 28 | git checkout -b feature-or-bugfix-name 29 | ``` 30 | 5. **Make your changes**, ensuring they follow the project's coding standards. 31 | 6. **Commit your changes**: 32 | ```sh 33 | git commit -m "Describe your change concisely" 34 | ``` 35 | 7. **Push to your fork**: 36 | ```sh 37 | git push origin feature-or-bugfix-name 38 | ``` 39 | 8. **Open a Pull Request (PR)** on GitHub and provide a clear description of your changes. 40 | 41 | ## Bug Reports 42 | If you've found a bug, please open an issue with the following details: 43 | - A clear and concise description of the bug. 44 | - Steps to reproduce the issue. 45 | - Expected vs. actual behavior. 46 | - Logs or screenshots, if applicable. 47 | 48 | ## Code Guidelines 49 | - Follow [PEP 8](https://peps.python.org/pep-0008/) for Python code. 50 | - Ensure your code is well-documented and includes necessary comments. 51 | - Write tests for any new features or bug fixes. 52 | 53 | ## Communication 54 | If you have any questions, feel free to start a discussion in the issues section or reach out on [Discord](https://discord.gg/g47wvNprfq). 55 | 56 | Thank you for contributing to otto-m8! 57 | 58 | -------------------------------------------------------------------------------- /docs/assets/amazon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/amazon.gif -------------------------------------------------------------------------------- /docs/assets/chatbot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/chatbot.gif -------------------------------------------------------------------------------- /docs/assets/demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/demo1.gif -------------------------------------------------------------------------------- /docs/assets/hf_multimodal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/hf_multimodal.gif -------------------------------------------------------------------------------- /docs/assets/otto-m8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/otto-m8.png -------------------------------------------------------------------------------- /docs/assets/otto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/assets/otto.png -------------------------------------------------------------------------------- /docs/docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Conceptual Guide", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "This section contains a conceptual guide on the building blocks of Otto-m8." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/blocks/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Blocks", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Blocks are what the user sees when interacting with Otto-m8, which encapsulates the logic for running a unit of software. Use this section as a guide to understand Blocks." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/block_advanced_ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/block_advanced_ex.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/code.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/deployable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/deployable.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/ipo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/ipo.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/lambdaspage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/lambdaspage.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/run_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/run_config.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/static-dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/static-dropdown.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/template.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/tracer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/tracer.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/viewcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/viewcode.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/imgs/workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/docs/conceptual-guide/imgs/workflow.png -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/tracer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tracer 3 | sidebar_position: 6 4 | --- 5 | 6 | Every interaction that the user has with a deployed workflow gets logged into a table by the Tracer. 7 | 8 | ![tracer](./imgs/tracer.png) 9 | 10 | For a simple workflow, where there is only 1 input, process and output block, a tracer doesn't add much. 11 | However, when there are multiple stages of process blocks, the user would only see the output of the last 12 | block, and therefore the tracer would allow the user to inspect the input and output of every block in 13 | the workflow. -------------------------------------------------------------------------------- /docs/docs/docs/conceptual-guide/workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Workflow and Deployables 3 | sidebar_position: 4 4 | --- 5 | 6 | ## Workflow 7 | 8 | A workflow is what the user creates using Blocks and interconnecting them. For the user this means 9 | creating their AI/ML workload by interweaving different models and integrations together, and deploying 10 | it as a REST API. 11 | 12 | ![workflow](./imgs/workflow.png) 13 | 14 | At its core, it's simply a graph that consists of nodes(the Blocks) and edges(the connections). The 15 | workflow is responsible for initializing resources and running all the blocks's implementation during 16 | an execution or user run. To learn more about how everything's working, check this [blog](https://medium.com/@farhanishraq82/building-a-no-code-platform-and-the-bfs-algorithm-6555f2bac3e5) out. 17 | A workflow depends on the Template, and together they make a deployable. 18 | 19 | 20 | ## Deployable 21 | When a user creates a workflow, under the hood a Docker image is created. The image contains the 22 | template and the workflow module, interfaced via a FastAPI server. This server is the entry point for 23 | all user interaction with the live workflow. 24 | 25 | import Deployable from './imgs/deployable.png'; 26 | 27 | 28 |
29 |

A visual of all the components of a deployable.

30 |
31 | 32 | 33 | What this means is that, this image can be used to run a Docker container to interact with the user workflow. 34 | And as with every Docker container, it can be deployed on various cloud services. 35 | 36 | ### Endpoints that are available 37 | | endpoint | description | 38 | -----------|-------------- 39 | | POST `/workflow_run` | Main endpoint to hit to interact with the workflow. This will only return output for any Output Block available. | 40 | | POST `/workflow_run/run_chat` | This endpoint is used by the Chat Interface and is only available if a Chat Output Block is available. | 41 | | GET `/workflow_run/get_chat_history` | If a Chat Output Block is present, querying this endpoint will return all the chat history. | 42 | | DELETE `/workflow_run/clear_chat_history` | If a Chat Output Block is present, this endpoint will clear any chat history. | 43 | 44 | For most parts, the fist endpoint is the endpoint that the user will be using since the other one's were built specifically 45 | for the Chat Interface. -------------------------------------------------------------------------------- /docs/docs/docs/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | description: Documentation on how to get started with otto-m8. 4 | keywords: [python, node, docker, ollama] 5 | sidebar_position: 2 6 | --- 7 | 8 | ## First Steps 9 | 10 | | System Requirements | - | 11 | | ---------- | ------- | 12 | | RAM | 8GB | 13 | | Python | > v3.10 | 14 | | Node.js | > v23.3.0 | 15 | 16 | ### Docker 17 | Otto-m8 relies on Docker to deploy workflows, since every workflow created is a 18 | docker image. Make sure you have Docker installed on your system. It helps to 19 | have Docker Desktop installed. That way you'll minimize time spent on writing shell 20 | commands. 21 | - Docker Install: https://docs.docker.com/engine/install/ 22 | - Docker Desktop: https://docs.docker.com/desktop/ 23 | 24 | ## Launch Otto-m8 25 | ### Prerequisite: 26 | 1. Clone the repository 27 | ```bash 28 | git clone https://github.com/farhan0167/otto-m8.git 29 | cd otto-m8/ 30 | ``` 31 | 2. Make sure to have Docker or Docker Desktop Installed on your computer. 32 | 3. In order to run Ollama blocks, make sure you have the Ollama server running in the background. 33 | 34 | ### Run the project 35 | 1. Run the following command to make `run.sh` executable 36 | ```bash 37 | chmod +x run.sh 38 | ``` 39 | 2. **Lauching the application** 40 | Once the script has the right permissions, you'll then need to run the `run.sh` script. This script will build all the necessary docker containers, including that of the frontend and backend. Since the server is hosted on a docker container, in order to deploy workflow containers, you'll need to mount your docker daemon to the server container which will allow the server to launch containers. You will therefore have two ways to launch: 41 | 42 | 1. **Without mounting** the docker daemon. This will mean that you won't be able to deploy your workflows as a docker container but you can still interact with it(build workflows and testing them). Similarly, you won't be able to launch Lambdas but you should still be able to modify or create custom blocks. To run: 43 | ```bash 44 | ./run.sh 45 | ``` 46 | 2. **Mounting** the docker daemon. This will mean that you will be able to deploy your workflows as docker containers and similarly be able to launch Lambdas. To run: 47 | ```bash 48 | ./run.sh --launch-containers 49 | ``` 50 | 3. This script should launch all the containers necessary to get started with otto-m8. You can start interacting with the platform by heading to `http://localhost:3000`, once the FastAPI server started completely. You should look at something like this in your logs: 51 | ``` 52 | Otto Dashboard URL: http://localhost:3000 53 | Otto Server URL: http://localhost:8000 54 | INFO: Will watch for changes in these directories: ['/app'] 55 | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) 56 | INFO: Started reloader process [1] using StatReload 57 | INFO: Started server process [13] 58 | INFO: Waiting for application startup. 59 | INFO: Application startup complete. 60 | ``` 61 | 62 | ### Ollama 63 | If you plan to run Ollama, make sure to have Ollama installed locally. 64 | - Download: https://ollama.com/download 65 | - For any model you use, make sure to run the following: 66 | ```bash 67 | ollama run 68 | ``` 69 | To get a list of all the supported models, click [here](https://github.com/ollama/ollama?tab=readme-ov-file#model-library). -------------------------------------------------------------------------------- /docs/docs/docs/integrations/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Integrations", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Guide on all the available integrations in otto-m8." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/docs/integrations/gcloud.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Google Cloud 3 | sidebar_position: 1 4 | --- 5 | 6 | The Google Cloud integrations allow you to access Google services such as Gmail, Sheets, Drive, etc. 7 | 8 | ## Setup 9 | 10 | ### Get credentials 11 | 12 | In order to use the services, you need make sure you have a `credentials.json` file saved. Follow 13 | the steps in this [documentation](https://developers.google.com/gmail/api/quickstart/python#authorize_credentials_for_a_desktop_application) 14 | to get the credentials set up. 15 | 16 | With the `credentials.json` file, place it within `otto_backend/.cache/gcloud/` directory. 17 | 18 | ### Configuring the OAuth Consent Screen 19 | 20 | If you're using a new Google Cloud project to complete this quickstart, configure the OAuth consent screen, using 21 | the [documentation](https://developers.google.com/calendar/api/quickstart/python#configure_the_oauth_consent_screen) here. 22 | 23 | ### Enable the API's 24 | 25 | Once you got the `credentials.json` file in place, you'll need to enable the Google Cloud services to be able to use them. 26 | 27 | #### Available Integrations 28 | 29 | The following integrations are currently available: 30 | - **Gmail**: reading emails, creating drafts, and sending emails. 31 | - Enable API here: https://console.cloud.google.com/flows/enableapi?apiid=gmail.googleapis.com 32 | - **Calendar**: reading events, and creating events. 33 | - Enable API here: https://console.cloud.google.com/flows/enableapi?apiid=calendar-json.googleapis.com 34 | 35 | ### Notes on Configuring the OAuth Consent Screen 36 | 37 | When configuring the OAuth Consent Screen as per the documentation, if you select Audience as External, then you should 38 | make sure you add Test Users or else you will not be able to use the app. -------------------------------------------------------------------------------- /docs/docs/docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Introduction to Otto-m8 documentation. 3 | keywords: [chatbot, ai, openai, gpt4o-mini, gpt4, nocode, workflows, documentation] 4 | sidebar_position: 1 5 | --- 6 | 7 | # Introduction 8 | 9 | **Otto-m8** (automate) is a low code platform that allows users to build AI/ML workflows through a flowchart like UI. In other words, you can visually declare how you build AI workflows or agents. Its low code because you are still in control over the implementation of a block(yes you can not only add custom blocks but also modify out of the box blocks), and more importantly, its a platform that isn't specifically built on top of an existing AI framework like Langchain. What this means is that, you can build you workflows with any framework you see fit, whether it is Langchain, Llama Index or the AI providers sdk themselves. 10 | 11 | At its core, otto-m8 views the problem of building any AI workflow as a graph problem. As developers, we mostly build modular components where each components are responsible for a specific task (consider them as nodes), and each component sends data between each other (the edges). Together you get a workflow which consists of inputs, some transformations of the inputs(we'll call them processes), and an output. 12 | 13 | ## Key Features 14 | - Build AI/ML workflows visually through out of the box blocks and by interconnecting them. 15 | - Build custom blocks or extend existing ones through code. 16 | - Incrementally build your workflows with instant feedback loops before deploying. 17 | - Deploy your workflows to get a Docker container that serves your workflow as a REST API. 18 | - Keep a trace of every workflow run of your deployed workflows. 19 | 20 | ## Project Roadmap 21 | - [x] Basic Chatbot and HF workflows 22 | - [x] Function Calling 23 | - [x] Lambda Functions/ Custom Code blocks 24 | - [x] Multimodality for Huggingface 25 | - [x] Multimodality for OpenAI (Experimental Phase) 26 | - [x] SDK for interacting with deployed workflows 27 | - [x] Observability for every block's output like a Logger or Tracer 28 | - [ ] Memory for Chatbot and RAG. Goal is to not clutter the drawing board. 29 | - [x] Streamline workflow creation, edits and redeployment. 30 | - [x] Apart from Lambdas that deploy seperate docker containers for custom code, build a custom code block which is deployed within the workflow container. 31 | - [ ] Creating other Block types: Conditionals, Aggregators, Loops. This will require change to how workflow runs and introducing handle types in the dashboard. 32 | - [ ] **Got ideas for other integrations you think will be useful? Create a Github [Issue](https://github.com/farhan0167/otto-m8/issues)** -------------------------------------------------------------------------------- /docs/docs/docs/tutorials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorials", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Examples of how to use Otto-m8, to launch your own workflows. More coming soon." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/docs/tutorials/simple-chatbot/simple-chatbot.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using Otto-m8: Simple Chat" 3 | description: Build a simple OpenAI chatbot using otto-m8, a low code ML platform. 4 | keywords: [chatbot, ai, openai, gpt4o-mini, gpt4, nocode] 5 | sidebar_position: 1 6 | --- 7 | 8 | This tutorial is demonstration on how to use **otto-m8**, by building a simple chatbot 9 | powered by OpenAI API. 10 | 11 | ## 1. Name your Workflow 12 | 13 | The first step would be to name your workflow. Make sure its a **unique name** for each workflow 14 | you create, as the name will form the basis of the Docker image that will be created. 15 | 16 | ![workflowname](https://farhan0167-otto-m8.s3.us-east-1.amazonaws.com/tutorials/simple_chatbot/name_workflow.gif) 17 | 18 | ## 2. Select the Open AI Chat Block 19 | 20 | Now that you've named your Workflow, you'll need to select the OpenAI Chat Completion Block 21 | from the **Add Block** button. Once your block appears on the screen, configure the block. 22 | For OpenAI, you'll need an OpenAI API [key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key). 23 | 24 | ![step2](https://farhan0167-otto-m8.s3.us-east-1.amazonaws.com/tutorials/simple_chatbot/step2.gif) 25 | 26 | ## 3. Connect the blocks 27 | 28 | When you connect a block's output to another block's input, you're essentially allowing the blocks 29 | to pass data between each other. Therefore, without passing the input block to the chat block, you won't see 30 | the block's name show up. But once you do, you can then use that in the prompt template. 31 | 32 | ![connect](https://farhan0167-otto-m8.s3.us-east-1.amazonaws.com/tutorials/simple_chatbot/connectblocks.gif) 33 | 34 | In this example, we're simply gonna pass the user input as is via `{user_input}` but you could essentially 35 | use the **Prompt Template** as a way to add custom prompts. 36 | 37 | ## 4. Add a Chat Output Block 38 | 39 | Adding a **Chat Output Block** is optional. Do so if you plan to use the Chat UI, or else, the Output Block 40 | will be enough if you plan to use it as an API. 41 | 42 | ![deploy](https://farhan0167-otto-m8.s3.us-east-1.amazonaws.com/tutorials/simple_chatbot/chatanddeploy.gif) 43 | 44 | ## 5. Interact 45 | 46 | Once deployed, you can use the Chat UI to chat with your workflow. 47 | 48 | ![interact](https://farhan0167-otto-m8.s3.us-east-1.amazonaws.com/tutorials/simple_chatbot/chat.png) 49 | 50 | To use this workflow as an API, you'll need to know the names of the Input Block. This 51 | could be found when you click on the Input Block, within the Block Config side bar. 52 |
53 | 54 | 55 | 56 | 57 | The last thing you'd need to know is the endpoint for your workflow, which can be found 58 | on the **Templates** page on the left nav bar. If it's your first workflow, then it should 59 | look something like this: `http://localhost:8001/workflow_run`. With that, write the following code, 60 | and run: 61 | 62 | ```python showLineNumbers 63 | import requests 64 | import json 65 | 66 | deployment_url = "http://localhost:8001/workflow_run" 67 | payload = { 68 | # Based on the name you found, replace spaces with an underscore. 69 | "Input_Block": "Write a poem, haiku style, about otto-m8, a low code automation platform" 70 | } 71 | 72 | request = requests.post( 73 | deployment_url, 74 | json={"data": payload} 75 | ) 76 | response = request.json()['message'] 77 | 78 | response = json.loads(response) 79 | print(response) 80 | ``` 81 | 82 | -------------------------------------------------------------------------------- /docs/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "otto-m-8-docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "3.6.3", 18 | "@docusaurus/preset-classic": "3.6.3", 19 | "@mdx-js/react": "^3.0.0", 20 | "bootstrap": "^5.3.3", 21 | "clsx": "^2.0.0", 22 | "prism-react-renderer": "^2.3.0", 23 | "react": "^18.0.0", 24 | "react-dom": "^18.0.0" 25 | }, 26 | "devDependencies": { 27 | "@docusaurus/module-type-aliases": "3.6.3", 28 | "@docusaurus/types": "3.6.3" 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.5%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 3 chrome version", 38 | "last 3 firefox version", 39 | "last 5 safari version" 40 | ] 41 | }, 42 | "engines": { 43 | "node": ">=18.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/docs/sidebars.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) 4 | 5 | /** 6 | * Creating a sidebar enables you to: 7 | - create an ordered group of docs 8 | - render a sidebar for each doc of that group 9 | - provide next/previous navigation 10 | 11 | The sidebars can be generated from the filesystem, or explicitly defined here. 12 | 13 | Create as many sidebars as you want. 14 | 15 | @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} 16 | */ 17 | const sidebars = { 18 | // By default, Docusaurus generates a sidebar from the docs folder structure 19 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 20 | 21 | // But you can create a sidebar manually 22 | /* 23 | tutorialSidebar: [ 24 | 'intro', 25 | 'hello', 26 | { 27 | type: 'category', 28 | label: 'Tutorial', 29 | items: ['tutorial-basics/create-a-document'], 30 | }, 31 | ], 32 | */ 33 | }; 34 | 35 | export default sidebars; 36 | -------------------------------------------------------------------------------- /docs/docs/src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import Heading from '@theme/Heading'; 3 | import styles from './styles.module.css'; 4 | 5 | 6 | 7 | export default function HomepageFeatures() { 8 | return ( 9 | <> 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /docs/docs/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /docs/docs/src/components/OttoDisplay/OttoDisplay.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./styles.module.css"; 3 | 4 | const RoundGifContainer = ({ gifSrc, altText }) => { 5 | const containerStyle = { 6 | borderRadius: "2%", // Makes the container round 7 | overflow: "hidden", // Ensures the GIF stays within the round container 8 | display: "flex", 9 | justifyContent: "center", 10 | alignItems: "center", 11 | border: "2px solid #ccc", // Optional: Adds a border 12 | boxShadow: "4px 4px 8px rgba(0, 0, 0, 0.2)", // Optional: Adds a shadow 13 | backgroundColor: "#000", // Optional: Background color for better contrast 14 | }; 15 | 16 | const gifStyle = { 17 | width: "1000px", 18 | height: "600px", 19 | objectFit: "cover", // Ensures the GIF covers the container without distortion 20 | }; 21 | 22 | return ( 23 |
24 | 25 | 26 |
27 | ); 28 | }; 29 | 30 | export default RoundGifContainer; 31 | -------------------------------------------------------------------------------- /docs/docs/src/components/OttoDisplay/chatbot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/src/components/OttoDisplay/chatbot.gif -------------------------------------------------------------------------------- /docs/docs/src/components/OttoDisplay/styles.module.css: -------------------------------------------------------------------------------- 1 | .ottoMainDisplay{ 2 | border-radius: 8px; 3 | overflow: hidden; 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | border: 2px solid #ccc; 8 | box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; 9 | background-color: #000; 10 | } 11 | 12 | [data-theme='dark'] { 13 | .ottoMainDisplay{ 14 | box-shadow: rgba(73, 49, 88, 0.8) 2px 5px 15px; 15 | } 16 | } -------------------------------------------------------------------------------- /docs/docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | 9 | :root { 10 | /* A vibrant purple as the base */ 11 | --ifm-color-primary: #7f3dff; 12 | /* Slightly darker purple */ 13 | --ifm-color-primary-dark: #6f34e0; 14 | /* More saturation and deeper tone */ 15 | --ifm-color-primary-darker: #5f2cbf; 16 | /* Darkest of the set */ 17 | --ifm-color-primary-darkest: #4f2380; 18 | /* Slightly lighter than the base */ 19 | --ifm-color-primary-light: #8f61ff; 20 | /* Even lighter */ 21 | --ifm-color-primary-lighter: #a47aff; 22 | /* Lightest shade in the palette */ 23 | --ifm-color-primary-lightest: #c09eff; 24 | 25 | /* Keeping the code font size the same */ 26 | --ifm-code-font-size: 95%; 27 | 28 | /* Subtle purple tint for highlighted code lines */ 29 | --docusaurus-highlighted-code-line-bg: rgba(127, 61, 255, 0.1); 30 | } 31 | 32 | 33 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 34 | [data-theme='dark'] { 35 | /* Base purple */ 36 | --ifm-color-primary: #7f3dff; 37 | /* Slightly darker purple */ 38 | --ifm-color-primary-dark: #6f34e0; 39 | /* More saturated/deeper tone */ 40 | --ifm-color-primary-darker: #5f2cbf; 41 | /* Darkest of the set */ 42 | --ifm-color-primary-darkest: #4f2380; 43 | /* Slightly lighter than the base */ 44 | --ifm-color-primary-light: #8f61ff; 45 | /* Even lighter */ 46 | --ifm-color-primary-lighter: #a47aff; 47 | /* Lightest shade in the palette */ 48 | --ifm-color-primary-lightest: #c09eff; 49 | 50 | /* Subtle purple tint for highlighted code lines in dark theme */ 51 | --docusaurus-highlighted-code-line-bg: rgba(127, 61, 255, 0.3); 52 | } 53 | 54 | .otto-main-display{ 55 | border-radius: "2%"; 56 | overflow: "hidden"; 57 | display: "flex"; 58 | justify-content: "center"; 59 | align-items: "center"; 60 | border: "2px solid #ccc"; 61 | box-shadow: "4px 4px 8px rgba(0; 0; 0; 0.2)"; 62 | background-color: "#000"; 63 | } 64 | 65 | .custom-font{ 66 | font-family: 'Inter', sans-serif; 67 | font-optical-sizing: auto; 68 | font-style: normal; 69 | } -------------------------------------------------------------------------------- /docs/docs/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /docs/docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/docs/static/img/blockconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/blockconfig.png -------------------------------------------------------------------------------- /docs/docs/static/img/blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/blocks.png -------------------------------------------------------------------------------- /docs/docs/static/img/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/code.png -------------------------------------------------------------------------------- /docs/docs/static/img/docusaurus-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/docusaurus-social-card.jpg -------------------------------------------------------------------------------- /docs/docs/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/docusaurus.png -------------------------------------------------------------------------------- /docs/docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/favicon.ico -------------------------------------------------------------------------------- /docs/docs/static/img/otto-m8_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/docs/docs/static/img/otto-m8_logo.png -------------------------------------------------------------------------------- /docs/docs/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /lib/dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /lib/dashboard/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY . /app 6 | 7 | # Install dependencies 8 | RUN npm install 9 | 10 | ARG CAN_DEPLOY_WORKFLOW 11 | RUN echo Can deploy workflow: $CAN_DEPLOY_WORKFLOW 12 | ENV REACT_APP_CAN_DEPLOY_WORKFLOW=$CAN_DEPLOY_WORKFLOW 13 | 14 | 15 | # Expose env vars at runtime 16 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /lib/dashboard/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /lib/dashboard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dashboard", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/react": "^11.14.0", 7 | "@emotion/styled": "^11.14.0", 8 | "@monaco-editor/react": "^4.6.0", 9 | "@mui/icons-material": "^6.4.5", 10 | "@mui/material": "^6.4.5", 11 | "@mui/x-date-pickers": "^7.27.3", 12 | "@testing-library/jest-dom": "^5.17.0", 13 | "@testing-library/react": "^13.4.0", 14 | "@testing-library/user-event": "^13.5.0", 15 | "@xterm/xterm": "^5.5.0", 16 | "@xyflow/react": "^12.3.0", 17 | "bootstrap": "^5.3.3", 18 | "charter-webfont": "^4.1.0", 19 | "dayjs": "^1.11.13", 20 | "formik": "^2.4.6", 21 | "js-sha1": "^0.7.0", 22 | "monaco-themes": "^0.4.4", 23 | "react": "^18.3.1", 24 | "react-bootstrap": "^2.10.4", 25 | "react-dnd": "^16.0.1", 26 | "react-dnd-html5-backend": "^16.0.1", 27 | "react-dom": "^18.3.1", 28 | "react-icons": "^5.3.0", 29 | "react-json-view-lite": "^1.5.0", 30 | "react-markdown": "^9.0.1", 31 | "react-router-dom": "^6.26.2", 32 | "react-scripts": "5.0.1", 33 | "react-syntax-highlighter": "^15.6.1", 34 | "uuid": "^10.0.0", 35 | "web-vitals": "^2.1.4", 36 | "yup": "^1.4.0" 37 | }, 38 | "scripts": { 39 | "start": "react-scripts start", 40 | "build": "react-scripts build", 41 | "test": "react-scripts test", 42 | "eject": "react-scripts eject" 43 | }, 44 | "eslintConfig": { 45 | "extends": [ 46 | "react-app", 47 | "react-app/jest" 48 | ] 49 | }, 50 | "browserslist": { 51 | "production": [ 52 | ">0.2%", 53 | "not dead", 54 | "not op_mini all" 55 | ], 56 | "development": [ 57 | "last 1 chrome version", 58 | "last 1 firefox version", 59 | "last 1 safari version" 60 | ] 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/dashboard/public/assets/hugging_face_model_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/assets/hugging_face_model_card.png -------------------------------------------------------------------------------- /lib/dashboard/public/assets/ollama.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/assets/ollama.png -------------------------------------------------------------------------------- /lib/dashboard/public/assets/openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/assets/openai.png -------------------------------------------------------------------------------- /lib/dashboard/public/assets/otto-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/assets/otto-2.png -------------------------------------------------------------------------------- /lib/dashboard/public/assets/otto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/assets/otto.png -------------------------------------------------------------------------------- /lib/dashboard/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/favicon.ico -------------------------------------------------------------------------------- /lib/dashboard/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | 33 | Otto–m8 Dashboard 34 | 35 | 36 | 37 |
38 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/dashboard/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/logo192.png -------------------------------------------------------------------------------- /lib/dashboard/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhan0167/otto-m8/997e7a8fe504f5ad3c0aae015cefae8d8bb90bd0/lib/dashboard/public/logo512.png -------------------------------------------------------------------------------- /lib/dashboard/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /lib/dashboard/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /lib/dashboard/src/App.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); 2 | 3 | body { 4 | /*font-family: "Inter", sans-serif;*/ 5 | font-family: 'Inter', sans-serif; 6 | font-optical-sizing: auto; 7 | font-style: normal; 8 | } 9 | 10 | body .form-control { 11 | border-radius: 4px; 12 | } 13 | 14 | .form-group { 15 | margin-bottom: 25px; 16 | } 17 | 18 | .form-label { 19 | font-weight: 600; 20 | } 21 | 22 | .offcanvas { 23 | padding: 8px; 24 | } 25 | 26 | 27 | .form-control:focus { 28 | border: 1px solid #000000; 29 | box-shadow: none; 30 | } 31 | 32 | .parent-component{ 33 | display: flex; 34 | } 35 | 36 | 37 | .sidebar-background-color { 38 | background-color: #eeeeee; 39 | } 40 | 41 | .btn-primary { 42 | background-color: #000000; /* Green */ 43 | --bs-btn-border-color: #000000; 44 | } 45 | 46 | .custom-switch-size { 47 | margin-left: 8px; 48 | } 49 | 50 | .custom-switch-size .form-check-input { 51 | width: 2.5em; /* Adjust width as needed */ 52 | height: 1.2em; /* Adjust height as needed */ 53 | transform: scale(1.5); /* Increase scale to make it bigger */ 54 | 55 | } 56 | 57 | .custom-switch-size .form-check-label { 58 | padding-left: 25px; 59 | } 60 | 61 | /* For side bar text color */ 62 | .MuiListItemText-primary{ 63 | color: #000000; 64 | } 65 | 66 | .modal{ 67 | z-index: 9999; 68 | } 69 | 70 | .page-main-container{ 71 | margin-top: 60px; 72 | padding-right: 8%; 73 | padding-left: 2%; 74 | } 75 | .page-main-container h2{ 76 | font-weight: 600; 77 | font-size: 27px; 78 | margin-bottom: 50px; 79 | } -------------------------------------------------------------------------------- /lib/dashboard/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /lib/dashboard/src/api/gcloud/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | export const gcloudIsLoggedIn = async (scopes, service) => { 4 | try { 5 | const response = await fetch('http://localhost:8000/gcloud/auth/is_logged_in', { 6 | method: 'POST', 7 | headers: { 8 | 'Content-Type': 'application/json', 9 | }, 10 | body: JSON.stringify({ 11 | scopes: scopes, 12 | service: service 13 | }) 14 | }); 15 | const data = await response.json(); 16 | return data 17 | } catch (error) { 18 | console.error('Error fetching block codes:', error); 19 | return []; 20 | } 21 | } 22 | 23 | export const gcloudLogin = async (scopes, service) => { 24 | try { 25 | const response = await fetch('http://localhost:8000/gcloud/auth/login', { 26 | method: 'POST', 27 | headers: { 28 | 'Content-Type': 'application/json', 29 | }, 30 | body: JSON.stringify({ 31 | scopes: scopes, 32 | service: service 33 | }) 34 | }); 35 | const data = await response.json(); 36 | return data 37 | } catch (error) { 38 | console.error('Error fetching block codes:', error); 39 | return []; 40 | } 41 | } -------------------------------------------------------------------------------- /lib/dashboard/src/api/health_check.js: -------------------------------------------------------------------------------- 1 | 2 | export const health_check = async (deployment_url) => { 3 | try { 4 | const response = await fetch(`${deployment_url}/health_check`); 5 | if (!response.ok) { 6 | throw new Error('Failed to fetch health check'); 7 | } 8 | const data = await response.json(); 9 | return data; 10 | } catch (error) { 11 | console.error('Error fetching health check:', error); 12 | } 13 | } -------------------------------------------------------------------------------- /lib/dashboard/src/components/Block/Block.css: -------------------------------------------------------------------------------- 1 | .process-block { 2 | min-height: 90px; 3 | overflow: auto; 4 | word-wrap: break-word; 5 | width: 150px; 6 | border: 1px solid #000000; 7 | border-radius: 5px; 8 | background-color: #fff; 9 | } 10 | 11 | .process-block-header{ 12 | padding-left: 5px; 13 | padding-top: 2px; 14 | padding-bottom: 2px; 15 | display: flex; 16 | } 17 | 18 | .process-block-body{ 19 | padding-left: 5px; 20 | padding-top: 2px; 21 | padding-right: 5px; 22 | } 23 | .process-block-body .form-label{ 24 | font-size: 7px; 25 | margin-bottom: 0; 26 | } 27 | .process-block-body .form-control{ 28 | font-size: 7px; 29 | height: 10px; 30 | border-radius: 2px; 31 | padding-left: 5px; 32 | } 33 | .process-block-body .form-group { 34 | margin-bottom: 10px !important; 35 | } 36 | 37 | .process-block * { 38 | font-size: 8px; 39 | } 40 | 41 | .placeholder-block { 42 | height: 90px; 43 | width: 100px; 44 | padding: 5px; 45 | border: 1px solid #000000; 46 | border-radius: 5px; 47 | background: #F5EFFF; 48 | } 49 | 50 | @keyframes pulse { 51 | 0%, 100% { 52 | transform: scale(1); 53 | } 54 | 50% { 55 | transform: scale(1.2); 56 | } 57 | } 58 | 59 | .add-icon{ 60 | font-size: 24px; 61 | color: #333; 62 | transition: color 0.3s, transform 0.3s; 63 | cursor: pointer; 64 | animation: pulse 1.5s infinite; /* Apply the pulse animation */ 65 | transition: color 0.3s; /* Smooth color transition on hover */ 66 | } 67 | 68 | .add-icon:hover { 69 | color: #74039e; 70 | transform: scale(1.4); 71 | animation: none; /* Stop the pulse animation on hover */ 72 | } 73 | 74 | .block-delete-icon { 75 | top: -13px; 76 | right: -1px; 77 | color: #D3D3D3; 78 | } 79 | 80 | .block-delete-icon:hover { 81 | cursor: pointer; 82 | color: #FF5733; 83 | } -------------------------------------------------------------------------------- /lib/dashboard/src/components/Block/BlockTypes.js: -------------------------------------------------------------------------------- 1 | // Component Block Imports 2 | import PlaceholderBlock from '../Block/PlaceholderBlock'; 3 | import ProcessBlock from './ProcessBlock'; 4 | 5 | const nodeTypes = { 6 | placeholderBlock: PlaceholderBlock, 7 | process: ProcessBlock 8 | }; 9 | 10 | export default nodeTypes; -------------------------------------------------------------------------------- /lib/dashboard/src/components/Block/InputBlocks/types.tsx: -------------------------------------------------------------------------------- 1 | 2 | export enum InputBlockType { 3 | TEXT = 'text', 4 | FILE = 'file', 5 | URL = 'url', 6 | } -------------------------------------------------------------------------------- /lib/dashboard/src/components/Block/PlaceholderBlock.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | import { Handle, Position, NodeToolbar} from '@xyflow/react'; 3 | import { IoAddOutline } from "react-icons/io5"; 4 | 5 | 6 | const handleStyle = { left: 10 }; 7 | 8 | function PlaceholderBlock({ data }) { 9 | const addIconClick = () => { 10 | const addButton = document.getElementById("add-block-button"); 11 | if (addButton) { 12 | addButton.click(); // Trigger the click event on the Add button 13 | } 14 | 15 | } 16 | return ( 17 | <> 18 |
19 | 20 |
29 | 33 |

Start by pressing

34 |

Add Block

35 |
36 | 37 |
38 | 39 | 40 | ); 41 | } 42 | 43 | export default PlaceholderBlock -------------------------------------------------------------------------------- /lib/dashboard/src/components/Block/ProcessBlock.js: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useState } from 'react'; 2 | import { Handle, Position, useReactFlow} from '@xyflow/react'; 3 | import './Block.css'; 4 | import { IoIosCloseCircleOutline } from "react-icons/io"; 5 | 6 | import { BlockField } from '../FormFields/Fields'; 7 | 8 | // Colors- {purple:F5EFFF, yellow: FEF9D9, orange:F6EACB, blue:BBE9FF, green:BFF6C3, red:FFC5C5} 9 | 10 | function ProcessBlock({ id, data }) { 11 | const reactFlowInstance = useReactFlow(); 12 | const colors = ['#F5EFFF', '#FEF9D9', '#F6EACB', '#BBE9FF', '#BFF6C3', '#FFC5C5', '#C2F784']; 13 | const [backgroundColor, setBackgroundColor] = useState(colors[0]); // Set initial color 14 | 15 | useEffect(() => { 16 | // pick a random color and set background color 17 | const randomColor = colors[Math.floor(Math.random() * colors.length)]; 18 | setBackgroundColor(randomColor); 19 | }, []); 20 | 21 | const onChange = useCallback((evt) => { 22 | console.log(evt.target.value); 23 | }, []); 24 | 25 | const handleDeleteBlock = (e) => { 26 | e.stopPropagation(); // Prevent triggering node selection 27 | reactFlowInstance.setNodes((nodes) => nodes.filter((node) => node.id !== id)); 28 | }; 29 | 30 | return ( 31 | <> 32 |
36 | 45 | 46 | 55 | input 56 | 57 |
58 |
59 | {data.logo && 60 | 61 | } 62 |

{data.core_block_type}

63 |
64 | 65 |
66 | {data.block_ui_fields && data.block_ui_fields.map((field, index) => ( 67 | 72 | ))} 73 |
74 |
75 | 76 | 85 | output 86 | 87 |
88 | 89 | 90 | ); 91 | } 92 | 93 | export default ProcessBlock -------------------------------------------------------------------------------- /lib/dashboard/src/components/BlockConfigBar/NodeSidebar.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import {Offcanvas, Form, Modal } from 'react-bootstrap'; 3 | 4 | import { AiOutlineCode } from "react-icons/ai"; 5 | import { Tooltip, IconButton, Divider } from '@mui/material'; 6 | import { BlockCode } from '../BlockCode'; 7 | 8 | import { BlockField } from '../FormFields/Fields'; 9 | 10 | // TODO: Move this to a separate file 11 | const NodeSidebar = ({ show, handleClose, sideBarData, onDataChange }) => { 12 | const [blockDataConfig, setBlockDataConfig] = useState(null); 13 | const [connectedSourceNodes, setConnectedSourceNodes] = useState([]); 14 | 15 | useEffect(() => { 16 | setBlockDataConfig(sideBarData.data); 17 | setConnectedSourceNodes(sideBarData.connectedSourceNodes); 18 | }, [sideBarData]); 19 | 20 | return ( 21 | <> 22 | 30 | 31 |

Block Config

32 |
33 | 34 | {/* Sidebar content */} 35 | 40 | 41 |
42 | 43 | ); 44 | } 45 | 46 | export default NodeSidebar; 47 | 48 | 49 | export const NodeConfigurationComponent = ({ 50 | blockDataConfig, 51 | connectedSourceNodes, 52 | onDataChange 53 | }) => { 54 | const [show, setShow] = useState(false); 55 | 56 | const handleClose = () => setShow(false); 57 | const handleShow = () => setShow(true); 58 | 59 | return ( 60 |
61 | 62 | {blockDataConfig && ( 63 | 64 |
65 |

id: {blockDataConfig.label}

66 | 67 | {blockDataConfig.source_code && ( 68 |
69 | 70 | 71 | 72 | 73 | 74 | 75 |
76 | )} 77 | 78 |
79 | 80 | {blockDataConfig.sidebar_fields && blockDataConfig.sidebar_fields.map((field, index) => ( 81 | 88 | ))} 89 | 90 |
91 | )} 92 |
93 | ) 94 | } -------------------------------------------------------------------------------- /lib/dashboard/src/components/Extras/CustomAlert.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import Alert from 'react-bootstrap/Alert'; 3 | 4 | import CloseButton from 'react-bootstrap/CloseButton'; 5 | 6 | function CustomAlert( {alertText, level, dismissible=true} ) { 7 | const [show, setShow] = useState(true); 8 | 9 | return ( 10 | <> 11 | setShow(false)} 14 | dismissible={dismissible} 15 | > 16 |

17 | {alertText} 18 |

19 |
20 | 21 | ); 22 | } 23 | 24 | export default CustomAlert; -------------------------------------------------------------------------------- /lib/dashboard/src/components/Extras/EditableTextBox.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Form } from 'react-bootstrap'; 3 | 4 | const EditableText = ({ text, onTextChange, textTag }) => { 5 | const [isEditing, setIsEditing] = useState(false); 6 | const [currentText, setCurrentText] = useState(text); 7 | 8 | const handleTextClick = () => { 9 | setIsEditing(true); 10 | }; 11 | 12 | const handleChange = (e) => { 13 | setCurrentText(e.target.value); 14 | onTextChange(e.target.value); 15 | }; 16 | 17 | const handleBlur = () => { 18 | setIsEditing(false); 19 | }; 20 | 21 | const handleKeyPress = (e) => { 22 | if (e.key === 'Enter') { 23 | setIsEditing(false); 24 | } 25 | }; 26 | 27 | const Tag = textTag || 'p'; 28 | 29 | return ( 30 | <> 31 | {isEditing ? ( 32 | 40 | ) : ( 41 | 42 | {currentText || 'Click to edit...'} 43 | 44 | )} 45 | 46 | ); 47 | }; 48 | 49 | export default EditableText; 50 | -------------------------------------------------------------------------------- /lib/dashboard/src/components/Extras/TopErrorBar.js: -------------------------------------------------------------------------------- 1 | import Toast from 'react-bootstrap/Toast'; 2 | import ToastContainer from 'react-bootstrap/ToastContainer'; 3 | import { MdErrorOutline } from "react-icons/md"; 4 | import { IoMdClose } from "react-icons/io"; 5 | 6 | 7 | function TopErrorBar({errorMessage, topErrorBarShow, setTopErrorBarShow}) { 8 | return ( 9 | 10 | 11 | 12 |
13 |
14 | Error : {errorMessage} 15 |
16 |
17 | setTopErrorBarShow(false)} 19 | size={25} 20 | /> 21 |
22 |
23 |
24 |
25 |
26 | ); 27 | } 28 | 29 | export default TopErrorBar; -------------------------------------------------------------------------------- /lib/dashboard/src/components/FormFields/DatePickerField.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { TextField, Box, Typography } from "@mui/material"; 3 | import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; 4 | import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; 5 | import dayjs from "dayjs"; 6 | 7 | 8 | export const DatePickerField = ({ 9 | field, 10 | blockData, 11 | onDataChange, 12 | }) => { 13 | const [selectedDate, setSelectedDate] = useState(dayjs(blockData[field.name])); 14 | 15 | const handleDateChange = (date) => { 16 | setSelectedDate(date); 17 | onDataChange(field.name, date); 18 | }; 19 | 20 | return ( 21 | 22 | 23 |

{field.display_name}

24 | } 29 | /> 30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /lib/dashboard/src/components/FormFields/LambdasDropdown.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Form, Dropdown, Alert, Spinner } from 'react-bootstrap'; 3 | 4 | const LambdasDropdown = ({ 5 | field, 6 | blockData, 7 | onDataChange 8 | }) => { 9 | const [items, setItems] = useState([]); // State to store dropdown items 10 | const [selectedItem, setSelectedItem] = useState(blockData[field.name]); // State to store selected item 11 | const [loading, setLoading] = useState(true); // State for loading status 12 | const [error, setError] = useState(null); // State for error handling 13 | 14 | useEffect(() => { 15 | const fetchItems = async () => { 16 | try { 17 | const response = await fetch('http://localhost:8000/get_lambdas'); // Replace with your endpoint 18 | if (!response.ok) { 19 | throw new Error('Network response was not ok'); 20 | } 21 | const data = await response.json(); 22 | setItems(data); // Set fetched items 23 | } catch (err) { 24 | setError(err.message); // Handle errors 25 | } finally { 26 | setLoading(false); // Set loading to false after fetching 27 | } 28 | }; 29 | 30 | fetchItems(); 31 | }, []); 32 | 33 | return ( 34 |
35 | 36 | {field.display_name} 37 | {loading ? ( 38 | 39 | ) : error ? ( 40 | Error fetching items: {error} 41 | ) : ( 42 | 43 | 52 | {selectedItem || 'Select a Lambda Function'} 53 | 54 | 55 | {items.length > 0 ? ( 56 | items.map((item, index) => ( 57 | { 60 | setSelectedItem(item.name); 61 | onDataChange?.(field.name, item.name); 62 | }} 63 | > 64 | {item.name} 65 | 66 | )) 67 | ) : ( 68 | Nothing to select. 69 | )} 70 | 71 | 72 | )} 73 | 74 |
75 | ); 76 | }; 77 | 78 | export default LambdasDropdown; 79 | -------------------------------------------------------------------------------- /lib/dashboard/src/components/FormFields/PromptTemplate.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { Form, Button, Dropdown } from 'react-bootstrap'; 3 | 4 | export const PromptTemplate = ({ 5 | field, 6 | blockData, 7 | connectedSourceNodes, 8 | onDataChange 9 | }) => { 10 | const [inputVariables, setInputVariables] = useState([]); 11 | const [promptTemplate, setPromptTemplate] = useState(''); 12 | 13 | useEffect(() => { 14 | setPromptTemplate(blockData[field.name]); 15 | }, [blockData]); 16 | 17 | useEffect(() => { 18 | if (connectedSourceNodes && connectedSourceNodes.length > 0) { 19 | const inputVariables = connectedSourceNodes.map((node) => { 20 | return `${node.data.custom_name}`; 21 | }); 22 | setInputVariables(inputVariables); 23 | } 24 | }, [connectedSourceNodes]); 25 | 26 | const onChangePromptTemplate = (e) => { 27 | setPromptTemplate(e.target.value); 28 | onDataChange(field.name, e.target.value); 29 | } 30 | 31 | const onInsertVariable = (variable) => { 32 | const updatedPromptTemplate = promptTemplate + `{${variable}}`; 33 | setPromptTemplate(updatedPromptTemplate); 34 | onDataChange(field.name, updatedPromptTemplate); 35 | } 36 | 37 | return ( 38 | <> 39 | 40 | {field.display_name} 41 |
42 | 43 | 44 | Insert Input Variables 45 | 46 | 47 | 48 | {inputVariables.length === 0 && ( 49 | 50 |

No Input Variables.

Connect Blocks to get input variables

51 |
52 | )} 53 | {inputVariables.map((variable, index) => ( 54 | onInsertVariable(variable)}> 55 | {variable} 56 | 57 | ))} 58 |
59 |
60 |
61 | 67 |
68 | 69 | ) 70 | } -------------------------------------------------------------------------------- /lib/dashboard/src/components/InputHandles/ChatTextInput.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const ChatTextInput = ({block, inputData, setInputData}) => { 4 | const name = block.name; 5 | 6 | const handleChange = (e) => { 7 | setInputData({ 8 | ...inputData, 9 | [name]: e.target.value 10 | }) 11 | } 12 | 13 | return ( 14 | <> 15 |