# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import json
import sys
import os
import time
sys.path.append(os.getcwd())

def test_extend_workflow():
    from lowCodeLLM import lowCodeLLM
    cases = json.load(open("./test/testcases/extend_workflow_test_cases.json", "r"))
    llm = lowCodeLLM(0.5, 0)
    for c in cases:
        task_prompt = c["task_prompt"]
        current_workflow = c["current_workflow"]
        step = c["step"]
        result = llm.extend_workflow(task_prompt, current_workflow, step)
        time.sleep(5)
        assert len(json.loads(result)) >= 1


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# coding: utf-8
import os
import gradio as gr
import random
import torch
import cv2
import re
import uuid
from PIL import Image, ImageDraw, ImageOps, ImageFont
import math
import numpy as np
import argparse
import inspect
import tempfile
from transformers import CLIPSegProcessor, CLIPSegForImageSegmentation
from transformers import pipeline, BlipProcessor, BlipForConditionalGeneration, BlipForQuestionAnswering
from transformers import AutoImageProcessor, UperNetForSemanticSegmentation


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

from openAIWrapper import OpenAIWrapper

EXECUTING_LLM_PREFIX = """Executing LLM is designed to provide outstanding responses.
Executing LLM will be given a overall task as the background of the conversation between the Executing LLM and human.
When providing response, Executing LLM MUST STICTLY follow the provided standard operating procedure (SOP).
the SOP is formatted as:
'''
STEP 1: [step name][step descriptions][[[if 'condition1'][Jump to STEP]], [[if 'condition2'][Jump to STEP]], ...]
'''
here "[[[if 'condition1'][Jump to STEP n]]]" is judgmental logic. It means when you're performing this step, and if 'condition1' is satisfied, you will perform STEP n next.

Remember:
Executing LLM is facing a real human, who does not know what SOP is.
So, Do not show him/her the SOP steps you are following, or it will make him/her confused. Just response the answer.
"""

EXECUTING_LLM_SUFFIX = """
Remember:


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import os
from flask import Flask, request, send_from_directory
from flask_cors import CORS, cross_origin
from lowCodeLLM import lowCodeLLM
from flask.logging import default_handler
import logging

app = Flask('lowcode-llm', static_folder='', template_folder='')
app.debug = True
llm = lowCodeLLM()
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger = gunicorn_logger
logging_format = logging.Formatter(
    '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
default_handler.setFormatter(logging_format)

@app.route("/")
def index():


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import os
import openai

class OpenAIWrapper:
    def __init__(self, temperature):
        self.key = os.environ.get("OPENAIKEY")
        openai.api_key = self.key

        # Access the USE_AZURE environment variable
        self.use_azure = os.environ.get('USE_AZURE')

        # Check if USE_AZURE is defined
        if self.use_azure is not None:
            # Convert the USE_AZURE value to boolean
            self.use_azure = self.use_azure.lower() == 'true'
        else:
            self.use_azure = False


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import re
import json
from openAIWrapper import OpenAIWrapper

PLANNING_LLM_PREFIX = """Planning LLM is designed to provide a standard operating procedure so that an difficult task will be broken down into several steps, and the task will be easily solved by following these steps.
Planning LLM is a powerful problem-solving assistant, and it only needs to analyze the task and provide standard operating procedure as guidance, but does not need actually to solve the problem.
Sometimes there exists some unknown or undetermined situation, thus judgmental logic is needed: some "conditions" are listed, and the next step that should be carried out if a "condition" is satisfied is also listed. The judgmental logics are not necessary.
Planning LLM MUST only provide standard operating procedure in the following format without any other words:
'''
STEP 1: [step name][step descriptions][[[if 'condition1'][Jump to STEP]], [[[if 'condition1'][Jump to STEP]], [[if 'condition2'][Jump to STEP]], ...]
STEP 2: [step name][step descriptions][[[if 'condition1'][Jump to STEP]], [[[if 'condition1'][Jump to STEP]], [[if 'condition2'][Jump to STEP]], ...]
...
'''

For example:
'''
STEP 1: [Brainstorming][Choose a topic or prompt, and generate ideas and organize them into an outline][]
STEP 2: [Research][Gather information, take notes and organize them into the outline][[[lack of ideas][Jump to STEP 1]]]


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

from planningLLM import planningLLM
from executingLLM import executingLLM
import json

class lowCodeLLM:
    def __init__(self, PLLM_temperature=0.4, ELLM_temperature=0):
        self.PLLM = planningLLM(PLLM_temperature)
        self.ELLM = executingLLM(ELLM_temperature)

    def get_workflow(self, task_prompt):
        return self.PLLM.get_workflow(task_prompt)

    def extend_workflow(self, task_prompt, current_workflow, step=''):
        ''' generate a sub-workflow for one of steps
            - input: the current workflow, the step needs to extend
            - output: sub-workflow '''
        workflow = self._json2txt(current_workflow)
        return self.PLLM.extend_workflow(task_prompt, workflow, step)


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import json
import sys
import os
sys.path.append(os.getcwd())

def test_get_workflow():
    from lowCodeLLM import lowCodeLLM
    cases = json.load(open("./test/testcases/get_workflow_test_cases.json", "r"))
    llm = lowCodeLLM(0.5, 0)
    for c in cases:
        task_prompt = c["task_prompt"]
        result = llm.get_workflow(task_prompt)
        assert len(json.loads(result)) >= 1


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

import json
import sys
import os
import time
sys.path.append(os.getcwd())

def test_extend_workflow():
    from lowCodeLLM import lowCodeLLM
    cases = json.load(open("./test/testcases/execute_test_cases.json", "r"))
    llm = lowCodeLLM(0.5, 0)
    for c in cases:
        task_prompt = c["task_prompt"]
        confirmed_workflow = c["confirmed_workflow"]
        history = c["history"]
        curr_input = c["curr_input"]
        result = llm.execute(task_prompt, confirmed_workflow, history, curr_input)
        time.sleep(5)
        assert type(result) == str