HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/CrewAI-Studio/app/pg_export_crew.py
import streamlit as st
from streamlit import session_state as ss
import zipfile
import os
import re
import json
import shutil
import db_utils
from utils import escape_quotes
from my_tools import TOOL_CLASSES
from crewai import Process
from my_crew import MyCrew
from my_agent import MyAgent
from my_task import MyTask
from datetime import datetime

class PageExportCrew:
    def __init__(self):
        self.name = "Import/export"

    def extract_placeholders(self, text):
        return re.findall(r'\{(.*?)\}', text)

    def get_placeholders_from_crew(self, crew):
        placeholders = set()
        for task in crew.tasks:
            placeholders.update(self.extract_placeholders(task.description))
            placeholders.update(self.extract_placeholders(task.expected_output))
        return list(placeholders)

    def generate_streamlit_app(self, crew, output_dir):
        agents = crew.agents
        tasks = crew.tasks

        # Check if any custom tools are used
        custom_tools_used = any(tool.name in ["CustomApiTool", "CustomFileWriteTool", "CustomCodeInterpreterTool"] 
                                for agent in agents for tool in agent.tools)

        def json_dumps_python(obj):
            if isinstance(obj, bool):
                return str(obj)
            return json.dumps(obj)

        def format_tool_instance(tool):
            tool_class = TOOL_CLASSES.get(tool.name)
            if tool_class:
                params = ', '.join([f'{key}={json_dumps_python(value)}' for key, value in tool.parameters.items() if value is not None])
                return f'{tool.name}({params})' if params else f'{tool.name}()'
            return None

        agent_definitions = ",\n        ".join([
            f"""
Agent(
    role={json_dumps_python(agent.role)},
    backstory={json_dumps_python(agent.backstory)},
    goal={json_dumps_python(agent.goal)},
    allow_delegation={json_dumps_python(agent.allow_delegation)},
    verbose={json_dumps_python(agent.verbose)},
    tools=[{', '.join([format_tool_instance(tool) for tool in agent.tools])}],
    llm=create_llm({json_dumps_python(agent.llm_provider_model)}, {json_dumps_python(agent.temperature)})
)
            """
            for agent in agents
        ])

        task_definitions = ",\n        ".join([
            f"""
Task(
    description={json_dumps_python(task.description)},
    expected_output={json_dumps_python(task.expected_output)},
    agent=next(agent for agent in agents if agent.role == {json_dumps_python(task.agent.role)}),
    async_execution={json_dumps_python(task.async_execution)}
)
            """
            for task in tasks
        ])

        placeholders = self.get_placeholders_from_crew(crew)
        placeholder_inputs = "\n    ".join([
            f'{placeholder} = st.text_input({json_dumps_python(placeholder.capitalize())})'
            for placeholder in placeholders
        ])
        placeholders_dict = ", ".join([f'{json_dumps_python(placeholder)}: {placeholder}' for placeholder in placeholders])

        manager_llm_definition = ""
        if crew.process == Process.hierarchical and crew.manager_llm:
            manager_llm_definition = f'manager_llm=create_llm({json_dumps_python(crew.manager_llm)})'
        elif crew.process == Process.hierarchical and crew.manager_agent:
            manager_llm_definition = f'manager_agent=next(agent for agent in agents if agent.role == {json_dumps_python(crew.manager_agent.role)})'
        
        app_content = f"""
import streamlit as st
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
from langchain_groq import ChatGroq
from langchain_anthropic import ChatAnthropic
from dotenv import load_dotenv
import os
from crewai_tools import *
{'''from custom_tools import CustomApiTool, CustomFileWriteTool, CustomCodeInterpreterTool''' if custom_tools_used else ''}

load_dotenv()

def create_lmstudio_llm(model, temperature):
    api_base = os.getenv('LMSTUDIO_API_BASE')
    os.environ["OPENAI_API_KEY"] = "lm-studio"
    os.environ["OPENAI_API_BASE"] = api_base
    if api_base:
        return ChatOpenAI(openai_api_key='lm-studio', openai_api_base=api_base, temperature=temperature)
    else:
        raise ValueError("LM Studio API base not set in .env file")

def create_openai_llm(model, temperature):
    safe_pop_env_var('OPENAI_API_KEY')
    safe_pop_env_var('OPENAI_API_BASE')
    load_dotenv(override=True)
    api_key = os.getenv('OPENAI_API_KEY')
    api_base = os.getenv('OPENAI_API_BASE', 'https://api.openai.com/v1/')
    if api_key:
        return ChatOpenAI(openai_api_key=api_key, openai_api_base=api_base, model_name=model, temperature=temperature)
    else:
        raise ValueError("OpenAI API key not set in .env file")

def create_groq_llm(model, temperature):
    api_key = os.getenv('GROQ_API_KEY')
    if api_key:
        return ChatGroq(groq_api_key=api_key, model_name=model, temperature=temperature)
    else:
        raise ValueError("Groq API key not set in .env file")

def create_anthropic_llm(model, temperature):
    api_key = os.getenv('ANTHROPIC_API_KEY')
    if api_key:
        return ChatAnthropic(anthropic_api_key=api_key, model_name=model, temperature=temperature)
    else:
        raise ValueError("Anthropic API key not set in .env file")

def safe_pop_env_var(key):
    try:
        os.environ.pop(key)
    except KeyError:
        pass
        
LLM_CONFIG = {{
    "OpenAI": {{
        "create_llm": create_openai_llm
    }},
    "Groq": {{
        "create_llm": create_groq_llm
    }},
    "LM Studio": {{
        "create_llm": create_lmstudio_llm
    }},
    "Anthropic": {{
        "create_llm": create_anthropic_llm
    }}
}}

def create_llm(provider_and_model, temperature=0.1):
    provider, model = provider_and_model.split(": ")
    create_llm_func = LLM_CONFIG.get(provider, {{}}).get("create_llm")
    if create_llm_func:
        return create_llm_func(model, temperature)
    else:
        raise ValueError(f"LLM provider {{provider}} is not recognized or not supported")

def load_agents():
    agents = [
        {agent_definitions}
    ]
    return agents

def load_tasks(agents):
    tasks = [
        {task_definitions}
    ]
    return tasks

def main():
    st.title({json_dumps_python(crew.name)})

    agents = load_agents()
    tasks = load_tasks(agents)
    crew = Crew(
        agents=agents, 
        tasks=tasks, 
        process={json_dumps_python(crew.process)}, 
        verbose={json_dumps_python(crew.verbose)}, 
        memory={json_dumps_python(crew.memory)}, 
        cache={json_dumps_python(crew.cache)}, 
        max_rpm={json_dumps_python(crew.max_rpm)},
        {manager_llm_definition}
    )

    {placeholder_inputs}

    placeholders = {{
        {placeholders_dict}
    }}

    if st.button("Run Crew"):
        with st.spinner("Running crew..."):
            try:
                result = crew.kickoff(inputs=placeholders)
                if isinstance(result, dict):
                    with st.expander("Final output", expanded=True):                
                        st.write(result.get('final_output', 'No final output available'))
                    with st.expander("Full output", expanded=False):
                        st.write(result)
                else:
                    st.write("Result:")
                    st.write(result)
            except Exception as e:
                st.error(f"An error occurred: {{str(e)}}")

if __name__ == '__main__':
    main()
"""
        with open(os.path.join(output_dir, 'app.py'), 'w') as f:
            f.write(app_content)

        # If custom tools are used, copy the custom_tools.py file
        if custom_tools_used:
            source_path = os.path.join(os.path.dirname(__file__), 'custom_tools.py')
            dest_path = os.path.join(output_dir, 'custom_tools.py')
            shutil.copy2(source_path, dest_path)

    def create_env_file(self, output_dir):
        env_content = """
# OPENAI_API_KEY="FILL-IN-YOUR-OPENAI-API-KEY"
# OPENAI_API_BASE="OPTIONAL-FILL-IN-YOUR-OPENAI-API-BASE"
# GROQ_API_KEY="FILL-IN-YOUR-GROQ-API-KEY"
# ANTHROPIC_API_KEY="FILL-IN-YOUR-ANTHROPIC-API-KEY"
# LMSTUDIO_API_BASE="http://localhost:1234/v1"
"""
        with open(os.path.join(output_dir, '.env'), 'w') as f:
            f.write(env_content)

    def create_shell_scripts(self, output_dir):
        install_sh_content = """
#!/bin/bash

# Create a virtual environment
python -m venv venv || { echo "Failed to create venv"; exit 1; }

# Activate the virtual environment
source venv/bin/activate || { echo "Failed to activate venv"; exit 1; }

# Install requirements
pip install -r requirements.txt || { echo "Failed to install requirements"; exit 1; }

echo "Installation completed successfully."
"""
        with open(os.path.join(output_dir, 'install.sh'), 'w') as f:
            f.write(install_sh_content)
            os.chmod(os.path.join(output_dir, 'install.sh'), 0o755)

        run_sh_content = """
#!/bin/bash

# Get the directory where the script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

# Activate the virtual environment
source "$SCRIPT_DIR/venv/bin/activate" || { echo "Failed to activate venv"; exit 1; }

cd "$SCRIPT_DIR"

streamlit run app.py --server.headless True
"""
        with open(os.path.join(output_dir, 'run.sh'), 'w') as f:
            f.write(run_sh_content)
            os.chmod(os.path.join(output_dir, 'run.sh'), 0o755)

        install_bat_content = """
@echo off

:: Create a virtual environment
python -m venv venv || (
    echo Failed to create venv
    exit /b 1
)

:: Activate the virtual environment
call venv\\Scripts\\activate || (
    echo Failed to activate venv
    exit /b 1
)

:: Install requirements
pip install -r requirements.txt || (
    echo Failed to install requirements
    exit /b 1
)

echo Installation completed successfully.
"""
        with open(os.path.join(output_dir, 'install.bat'), 'w') as f:
            f.write(install_bat_content)

        run_bat_content = """
@echo off

:: Activate the virtual environment
call venv\\Scripts\\activate || (
    echo Failed to activate venv
    exit /b 1
)

:: Run the Streamlit app
streamlit run app.py --server.headless true
"""
        with open(os.path.join(output_dir, 'run.bat'), 'w') as f:
            f.write(run_bat_content)

        # Copy the main project's requirements.txt
        source_requirements = os.path.join(os.path.dirname(__file__), '..', 'requirements.txt')
        dest_requirements = os.path.join(output_dir, 'requirements.txt')
        shutil.copy2(source_requirements, dest_requirements)

    def zip_directory(self, folder_path, output_path):
        with zipfile.ZipFile(output_path, 'w') as zip_file:
            for foldername, subfolders, filenames in os.walk(folder_path):
                for filename in filenames:
                    file_path = os.path.join(foldername, filename)
                    arcname = os.path.relpath(file_path, folder_path)
                    zip_file.write(file_path, arcname)

    def create_export(self, crew_name):
        output_dir = f"{crew_name}_app"
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        selected_crew = next((crew for crew in ss.crews if crew.name == crew_name), None)
        if selected_crew:
            self.generate_streamlit_app(selected_crew, output_dir)
            self.create_env_file(output_dir)
            self.create_shell_scripts(output_dir)

            zip_path = f"{crew_name}_app.zip"
            self.zip_directory(output_dir, zip_path)
            return zip_path

    def export_crew_to_json(self, crew):
        crew_data = {
            'id': crew.id,
            'name': crew.name,
            'process': crew.process,
            'verbose': crew.verbose,
            'memory': crew.memory,
            'cache': crew.cache,
            'max_rpm': crew.max_rpm,
            'manager_llm': crew.manager_llm,
            'manager_agent': crew.manager_agent.id if crew.manager_agent else None,
            'created_at': crew.created_at,
            'agents': [],
            'tasks': [],
            'tools': []
        }

        tool_ids = set()

        for agent in crew.agents:
            agent_data = {
                'id': agent.id,
                'role': agent.role,
                'backstory': agent.backstory,
                'goal': agent.goal,
                'allow_delegation': agent.allow_delegation,
                'verbose': agent.verbose,
                'cache': agent.cache,
                'llm_provider_model': agent.llm_provider_model,
                'temperature': agent.temperature,
                'max_iter': agent.max_iter,
                'tool_ids': [tool.tool_id for tool in agent.tools]
            }
            crew_data['agents'].append(agent_data)
            tool_ids.update(agent_data['tool_ids'])

        for task in crew.tasks:
            task_data = {
                'id': task.id,
                'description': task.description,
                'expected_output': task.expected_output,
                'async_execution': task.async_execution,
                'agent_id': task.agent.id if task.agent else None,
                'context_from_async_tasks_ids': task.context_from_async_tasks_ids,
                'created_at': task.created_at
            }
            crew_data['tasks'].append(task_data)

        for tool_id in tool_ids:
            tool = next((t for t in ss.tools if t.tool_id == tool_id), None)
            if tool:
                tool_data = {
                    'tool_id': tool.tool_id,
                    'name': tool.name,
                    'description': tool.description,
                    'parameters': tool.get_parameters()
                }
                crew_data['tools'].append(tool_data)

        return json.dumps(crew_data, indent=2)
    
    def import_crew_from_json(self, crew_data):
        # Create tools
        for tool_data in crew_data['tools']:
            tool_class = TOOL_CLASSES[tool_data['name']]
            tool = tool_class(tool_id=tool_data['tool_id'])
            tool.set_parameters(**tool_data['parameters'])
            if tool not in ss.tools:
                ss.tools.append(tool)
                db_utils.save_tool(tool)

        # Create agents
        agents = []
        for agent_data in crew_data['agents']:
            agent = MyAgent(
                id=agent_data['id'],
                role=agent_data['role'],
                backstory=agent_data['backstory'],
                goal=agent_data['goal'],
                allow_delegation=agent_data['allow_delegation'],
                verbose=agent_data['verbose'],
                cache=agent_data.get('cache', True),
                llm_provider_model=agent_data['llm_provider_model'],
                temperature=agent_data['temperature'],
                max_iter=agent_data['max_iter'],
                created_at=agent_data.get('created_at')
            )
            agent.tools = [next(tool for tool in ss.tools if tool.tool_id == tool_id) for tool_id in agent_data['tool_ids']]
            agents.append(agent)
            db_utils.save_agent(agent)

        # Create tasks
        tasks = []
        for task_data in crew_data['tasks']:
            task = MyTask(
                id=task_data['id'],
                description=task_data['description'],
                expected_output=task_data['expected_output'],
                async_execution=task_data['async_execution'],
                agent=next((agent for agent in agents if agent.id == task_data['agent_id']), None),
                context_from_async_tasks_ids=task_data['context_from_async_tasks_ids'],
                created_at=task_data['created_at']
            )
            tasks.append(task)
            db_utils.save_task(task)

        # Create crew
        crew = MyCrew(
            id=crew_data['id'],
            name=crew_data['name'],
            process=crew_data['process'],
            verbose=crew_data['verbose'],
            memory=crew_data['memory'],
            cache=crew_data['cache'],
            max_rpm=crew_data['max_rpm'],
            manager_llm=crew_data['manager_llm'],
            manager_agent=next((agent for agent in agents if agent.id == crew_data['manager_agent']), None),
            created_at=crew_data['created_at']
        )
        crew.agents = agents
        crew.tasks = tasks
        db_utils.save_crew(crew)

        if crew not in ss.crews:
            ss.crews.append(crew)

        return crew

    def draw(self):
        st.subheader(self.name)

        # Full JSON Export Button
        if st.button("Export everything to json"):
            current_datetime = datetime.now().strftime("%Y%m%d_%H%M%S")
            file_path = f"all_crews_{current_datetime}.json"
            db_utils.export_to_json(file_path)
            with open(file_path, "rb") as fp:
                st.download_button(
                    label="Download All Crews JSON",
                    data=fp,
                    file_name=file_path,
                    mime="application/json"
                )

        # JSON Import Button
        uploaded_file = st.file_uploader("Import JSON file", type="json")
        if uploaded_file is not None:
            json_data = json.load(uploaded_file)
            
            if isinstance(json_data, list):  # Full database export
                with open("uploaded_file.json", "w") as f:
                    json.dump(json_data, f)
                db_utils.import_from_json("uploaded_file.json")
                st.success("Full database JSON file imported successfully!")
            elif isinstance(json_data, dict) and 'id' in json_data:  # Single crew export
                imported_crew = self.import_crew_from_json(json_data)
                st.success(f"Crew '{imported_crew.name}' imported successfully!")
            else:
                st.error("Invalid JSON format. Please upload a valid crew or full database export file.")

        if 'crews' not in ss or len(ss.crews) == 0:
            st.write("No crews defined yet.")
        else:
            crew_names = [crew.name for crew in ss.crews]
            selected_crew_name = st.selectbox("Select crew to export", crew_names)
            
            if st.button("Export singlepage app"):
                zip_path = self.create_export(selected_crew_name)
                with open(zip_path, "rb") as fp:
                    st.download_button(
                        label="Download Exported App",
                        data=fp,
                        file_name=f"{selected_crew_name}_app.zip",
                        mime="application/zip"
                    )        
            if st.button("Export crew to JSON"):
                selected_crew = next((crew for crew in ss.crews if crew.name == selected_crew_name), None)
                if selected_crew:
                    crew_json = self.export_crew_to_json(selected_crew)
                    st.download_button(
                        label="Download Crew JSON",
                        data=crew_json,
                        file_name=f"{selected_crew_name}_export.json",
                        mime="application/json"
                    )