diff --git a/.github/workflows/coverage-jvcli.yaml b/.github/workflows/coverage-jvcli.yaml index 5ad4892..efa00f1 100644 --- a/.github/workflows/coverage-jvcli.yaml +++ b/.github/workflows/coverage-jvcli.yaml @@ -33,4 +33,4 @@ jobs: with: coverageFile: coverage.xml token: ${{ secrets.GITHUB_TOKEN }} - thresholdAll: 0.99 + thresholdAll: 0.98 diff --git a/jvcli/commands/create.py b/jvcli/commands/create.py index 2ea9ee6..450005b 100644 --- a/jvcli/commands/create.py +++ b/jvcli/commands/create.py @@ -150,103 +150,73 @@ def create_action( with open(lib_path, "w") as file: file.write(f"include:jac {name};\n") - # Create action-specific .jac file + # Create action-specific .jac file from template (new path) action_jac_path = os.path.join(action_dir, f"{name}.jac") + action_jac_template_path = os.path.join( + TEMPLATES_DIR, "2.1.0", "project", "actions", "action.tpl" + ) + if not os.path.exists(action_jac_template_path): + click.secho( + f"action.jac template for version {jivas_version} not found in {TEMPLATES_DIR}/project.", + fg="red", + ) + return + with open(action_jac_template_path, "r") as file: + action_jac_template = file.read() + node_class = { + "action": "Action", + "interact_action": "InteractAction", + "vector_store_action": "VectorStoreAction", + }[type] + action_jac_content = action_jac_template.replace("{{archetype}}", archetype) + action_jac_content = action_jac_content.replace("{{node_class}}", node_class) + action_jac_content = action_jac_content.replace("{{name}}", name) + action_jac_content = action_jac_content.replace("{{type}}", type) with open(action_jac_path, "w") as file: - node_class = { - "action": "Action", - "interact_action": "InteractAction", - "vector_store_action": "VectorStoreAction", - }[type] - - import_statement = f"import:jac from agent.action.{type} {{ {node_class} }}" - - abilities = """ - #* (Abilities - Uncomment and implement as needed) - can on_register { - # override to execute operations upon registration of action - } - - can post_register { - # override to execute any setup code when all actions are in place - } - - can on_enable { - # override to execute operations upon enabling of action - } - - can on_disable { - # override to execute operations upon disabling of action - } - - can on_deregister { - # override to execute operations upon deregistration of action - } - - can touch(visitor: interact_graph_walker) -> bool { - # override to authorize, redirect or deny the interact walker from running execute - } - - can execute(visitor: interact_graph_walker) -> dict { - # override to implement action execution - } - - can pulse() { - # override to implement pulse operation - } - *# - """ - node_content = f""" -# Define your custom action code here -{import_statement} - -node {archetype} :{node_class}: {{ - # Declare your has variables to be persisted here - # e.g has var_a : str = "string"; - -{abilities} -}} - """ - file.write(node_content.strip()) - - # Create action-specific .test.jac file - action_test_jac_path = os.path.join(action_dir, f"{name}.test.jac") - with open(action_test_jac_path, "w") as f: - f.write("with entry {}") + file.write(action_jac_content) # Create the 'app' folder and default 'app.py' app_dir = os.path.join(action_dir, "app") os.makedirs(app_dir, exist_ok=True) app_file_path = os.path.join(app_dir, "app.py") + app_template_path = os.path.join( + TEMPLATES_DIR, "2.1.0", "project", "app", "app.tpl" + ) + if not os.path.exists(app_template_path): + click.secho( + f"app.py template for version {jivas_version} not found in {TEMPLATES_DIR}/project.", + fg="red", + ) + return + with open(app_template_path, "r") as file: + app_code = file.read() + app_code = app_code.replace("{{title}}", title) with open(app_file_path, "w") as app_file: - app_code = """ -\"\"\" This module renders the streamlit app for the {title}. \"\"\" - -from jvcli.client.lib.widgets import app_controls, app_header, app_update_action - -from streamlit_router import StreamlitRouter - -def render(router: StreamlitRouter, agent_id: str, action_id: str, info: dict) -> None: - \"\"\"Render the Streamlit app for the {title}. - :param router: The StreamlitRouter instance - :param agent_id: The agent ID - :param action_id: The action ID - :param info: The action info dict - \"\"\" + app_file.write(app_code) - # Add app header controls - (model_key, action) = app_header(agent_id, action_id, info) + # Create action-specific .test.jac file + action_test_jac_path = os.path.join(action_dir, f"{name}.test.jac") + action_test_template_path = os.path.join( + TEMPLATES_DIR, "2.1.0", "project", "actions", "action.test.tpl" + ) + if not os.path.exists(action_test_template_path): + click.secho( + f"app.test.jac template for version {jivas_version} not found in {TEMPLATES_DIR}/project.", + fg="red", + ) + else: + action_jac_test_template = "with entry {\n}" - # Add app main controls - app_controls(agent_id, action_id) + with open(action_test_template_path, "r") as file: + action_jac_test_template = file.read() + action_jac_test_template = action_jac_test_template.replace( + "{{archetype}}", archetype + ) - # Add update button to apply changes - app_update_action(agent_id, action_id) - """ - app_code = app_code.replace("{title}", title) - app_file.write(app_code) + with open(action_test_jac_path, "w") as f: + f.write(action_jac_test_template) - create_docs(action_dir, title, version, "action", description) + create_docs(action_dir, title, version, "action", description) click.secho( f"Action '{name}' created successfully in {action_dir}!", fg="green", bold=True diff --git a/jvcli/commands/startproject.py b/jvcli/commands/startproject.py index e5ad54a..9eb1ae6 100644 --- a/jvcli/commands/startproject.py +++ b/jvcli/commands/startproject.py @@ -85,8 +85,9 @@ def startproject(project_name: str, version: str, no_env: bool) -> None: with open(target_file_path_example, "w") as example_file: example_file.write(contents) - with open(target_file_path, "w") as project_file: - project_file.write(contents) + if not target_file_path.endswith(".tpl"): + with open(target_file_path, "w") as project_file: + project_file.write(contents) click.secho( f"Successfully created Jivas project: {project_name} (Version: {version}){' (without .env file)' if no_env else ''}", diff --git a/jvcli/templates/2.1.0/project/actions/action.test.tpl b/jvcli/templates/2.1.0/project/actions/action.test.tpl new file mode 100644 index 0000000..e203162 --- /dev/null +++ b/jvcli/templates/2.1.0/project/actions/action.test.tpl @@ -0,0 +1,36 @@ +# Importing the JIVAS graph nodes +import from jivas.agent.core.agents { Agents } +import from jivas.agent.core.agent { Agent } +import from jivas.agent.action.action { Action } +import from jivas.agent.action.actions { Actions } +import from jivas.agent.memory.memory { Memory } + +# Import the walkers to execute the each functionality +# import from sample_walker_1 { sample_walker_1 } +# import from sample_walker_2 { sample_walker_2 } + + +# ----------------------------------------------------------------------- +# creating the graph here first +# ----------------------------------------------------------------------- +with entry { + agents = root ++> Agents(); + agent = agents[0] ++> Agent(); + memory = agent[0] ++> Memory(); + actions = agent[0] ++> Actions(); + action = actions[0] ++> Action(label='{{archetype}}'); + action[0].agent_id = agent[0].id; +} + + +# ----------------------------------------------------------------------- +# Implement the test cases here +# ----------------------------------------------------------------------- + +# test sample_test_case_1 { +# +# } + +# test sample_test_case_2 { +# +# } \ No newline at end of file diff --git a/jvcli/templates/2.1.0/project/actions/action.tpl b/jvcli/templates/2.1.0/project/actions/action.tpl new file mode 100644 index 0000000..aa11317 --- /dev/null +++ b/jvcli/templates/2.1.0/project/actions/action.tpl @@ -0,0 +1,40 @@ +import from agent.action.{{type}} { {{node_class}} } + +node {{archetype}} :{{node_class}}: { + # Declare your has variables to be persisted here + # e.g has var_a : str = "string"; + + #* (Abilities - Uncomment and implement as needed) + can on_register { + # override to execute operations upon registration of action + } + + can post_register { + # override to execute any setup code when all actions are in place + } + + can on_enable { + # override to execute operations upon enabling of action + } + + can on_disable { + # override to execute operations upon disabling of action + } + + can on_deregister { + # override to execute operations upon deregistration of action + } + + can touch(visitor: interact_graph_walker) -> bool { + # override to authorize, redirect or deny the interact walker from running execute + } + + can execute(visitor: interact_graph_walker) -> dict { + # override to implement action execution + } + + can pulse() { + # override to implement pulse operation + } + *# +} diff --git a/jvcli/templates/2.1.0/project/app/app.tpl b/jvcli/templates/2.1.0/project/app/app.tpl new file mode 100644 index 0000000..0c44e50 --- /dev/null +++ b/jvcli/templates/2.1.0/project/app/app.tpl @@ -0,0 +1,20 @@ +"""This module renders the streamlit app for the {{title}}.""" + +from streamlit_router import StreamlitRouter + +from jvcli.client.lib.widgets import app_controls, app_header, app_update_action + + +def render(router: StreamlitRouter, agent_id: str, action_id: str, info: dict) -> None: + """Render the Streamlit app for the {{title}}. + :param router: The StreamlitRouter instance + :param agent_id: The agent ID + :param action_id: The action ID + :param info: The action info dict + """ + # Add app header controls + (model_key, action) = app_header(agent_id, action_id, info) + # Add app main controls + app_controls(agent_id, action_id) + # Add update button to apply changes + app_update_action(agent_id, action_id) diff --git a/jvcli/templates/2.1.0/project/main.jac b/jvcli/templates/2.1.0/project/main.jac index b3c5b42..f1338bd 100644 --- a/jvcli/templates/2.1.0/project/main.jac +++ b/jvcli/templates/2.1.0/project/main.jac @@ -1,2 +1,2 @@ -import:jac globals; -include:jac jivas.agent.lib; \ No newline at end of file +import globals; +include jivas.agent.lib; \ No newline at end of file diff --git a/setup.py b/setup.py index 2283e9a..d09cd6e 100644 --- a/setup.py +++ b/setup.py @@ -54,6 +54,8 @@ def get_version() -> str: "pytest", "pytest-mock", "pytest-cov", + "pymongo", + "jac-cloud", ], }, entry_points={ diff --git a/tests/test_create.py b/tests/test_create.py index d23644f..19ba131 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -6,7 +6,11 @@ from pytest_mock import MockerFixture from jvcli import __supported__jivas__versions__ -from jvcli.commands.create import create_action, create_agent, create_namespace +from jvcli.commands.create import ( + create_action, + create_agent, + create_namespace, +) from jvcli.utils import TEMPLATES_DIR