Skip to content

Commit

Permalink
Fix prompts and refactor into app and templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Funkmyster committed Aug 22, 2023
1 parent b027766 commit cbc376b
Show file tree
Hide file tree
Showing 21 changed files with 107 additions and 134 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
dist/*
*/__pycache__/*
**/__pycache__/*
.idea/*
Binary file removed .hypothesis/unicode_data/13.0.0/charmap.json.gz
Binary file not shown.
128 changes: 70 additions & 58 deletions langcontroller/cli.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""
A Generative AI Python Application Framework inspired by Django, Laravel, and Meltano
"""A Generative AI Python Application Framework inspired by Django, Laravel, and Meltano
Features
Features:
Architected for both Human and AI Devs
Scaffolds are designed to help your AI Code Assistant
Generated components render with CLI, FastAPI, and Dagster
TODO BasePrompt feature
TODO migrate commands to components
TODO migrate cli.py to manage.py
TODO Middleware
TODO Tests
Template Naming Conventions:
<domain>_<operation>_<data_type>
domain - manage|models|pipeline|prompt_templates|pyproject|repository
operation - append|create
data_type - asset|class|function|file|prompt|sensor
"""
import os

Expand Down Expand Up @@ -69,19 +69,19 @@ def __init__(self, help_panel_name: str):
self.help_panel_name = help_panel_name

def __call__(self, cls):
"""Convert methods in a class into a typer commands
"""Convert methods in a class into a typer repository
Setup Steps:
1. Decorate Class with Commandify
2. Decorate Classmethods with @staticmethod
1. Decorate class with Commandify
2. Decorate class methods with @staticmethod
Commandify Steps:
1. Find all classmethods that start with "do_"
2. Convert the classmethod name to a slug
3. Decorate the classmethod with typer.command
1. Find all class methods that start with "do_"
2. Convert the class method name to a slug
3. Decorate the class method with "app.command"
Args:
cls (class): The class to decorate classmethods into a typer commands
cls (class): The class to decorate class methods into a typer repository
"""
for attr_name, attr_value in vars(cls).items():
if callable(attr_value) and attr_name.startswith("do_"):
Expand Down Expand Up @@ -126,8 +126,11 @@ def do_project(project_name: str):

project = Renamer(slug=project_name)
os.mkdir(project.python_name())
os.mkdir(f"{project.python_name()}/prompt_templates")
f = open(f"{project.python_name()}/prompt_templates/__init__.py", "w")
os.mkdir(f"{project.python_name()}/app")
f = open(f"{project.python_name()}/app/__init__.py", "w")
f.close()
os.mkdir(f"{project.python_name()}/templates")
f = open(f"{project.python_name()}/templates/__init__.py", "w")
f.close()

script_path = os.path.realpath(__file__)
Expand All @@ -137,58 +140,65 @@ def do_project(project_name: str):
loader=FileSystemLoader(f"{script_dir}/templates"),
autoescape=select_autoescape(),
)
template = env.get_template("pyproject_file.toml.jinja2")
template = env.get_template("pyproject/create_pyproject_file.toml.j2")
file_contents = template.render(dict(
project_name=project.python_name()
))
with open(f"{project.python_name()}/pyproject.toml", "w") as f:
f.write(file_contents)

template = env.get_template("models_file.py.jinja2")
template = env.get_template("prompt_templates/create_prompt-base_file.j2.j2")
file_contents = template.render()
with open(f"{project.python_name()}/templates/base_prompt.j2", "w") as f:
f.write(file_contents)

template = env.get_template("models/create_models_file.py.j2")
file_contents = template.render(
project_name=project.human_name()
)
with open(f"{project.python_name()}/models.py", "w") as f:
with open(f"{project.python_name()}/app/models.py", "w") as f:
f.write(file_contents)

template = env.get_template("command_file.py.jinja2")
template = env.get_template("repository/create_repository_file.py.j2")
file_contents = template.render(
project_name=project.human_name()
)
with open(f"{project.python_name()}/commands.py", "w") as f:
with open(f"{project.python_name()}/app/repository.py", "w") as f:
f.write(file_contents)

template = env.get_template("cli_file.jinja2")
template = env.get_template("manage/create_manage_file.py.j2")
file_contents = template.render()
with open(f"{project.python_name()}/cli.py", "w") as f:
with open(f"{project.python_name()}/manage.py", "w") as f:
f.write(file_contents)

template = env.get_template("pipeline_file.py.jinja2")
template = env.get_template("pipeline/create_pipeline_file.py.j2")
file_contents = template.render(dict(
project_name=project.human_name()
))
with open(f"{project.python_name()}/pipeline.py", "w") as f:
with open(f"{project.python_name()}/app/pipeline.py", "w") as f:
f.write(file_contents)

@staticmethod
def do_feature_no_source(target_action: str, attribute_1: str, attribute_2: str, attribute_3: str):
def do_sensor(target_action: str, attribute_1: str, attribute_2: str, attribute_3: str):
"""Create a new LangController Feature from inside your LangController Project
Args:
target_action (str): The name of the out going target
target_action (str): The name of the outgoing target
attribute_1 (str): The name of the first attribute of the target action
attribute_2 (str): The name of the second attribute of the target action
attribute_3 (str): The name of the third attribute of the target action
Example:
langcontroller make-feature-no-input strategy mission vision values
poetry run python commands.py create_strategy "Tour Operator for the Moon"
langcontroller make-sensor strategy mission vision values
python manage.py create_strategy "Tour Operator for the Moon"
"""

if not all([
os.path.exists("commands.py"),
os.path.exists("pipeline.py"),
os.path.exists("prompt_templates"),
os.path.exists("app/models.py"),
os.path.exists("app/pipeline.py"),
os.path.exists("app/repository.py"),
os.path.exists("manage.py"),
os.path.exists("templates"),
]):
print("Please verify that you are in a LangController Project")
return
Expand All @@ -207,67 +217,69 @@ def do_feature_no_source(target_action: str, attribute_1: str, attribute_2: str,
)
prompt_name = f"{target_action.slug}"

template = env.get_template("prompt_command_no_source.jinja2")
template = env.get_template("prompt_templates/create_sensor_file.j2.j2")
my_prompt = template.render(dict(
target_action=target_action.human_name(),
))
with open(f"prompt_templates/{prompt_name}.jinja2", "w") as f:
with open(f"templates/{prompt_name}.j2", "w") as f:
f.write(my_prompt)

template = env.get_template("models_class.jinja2")
template = env.get_template("models/append_marvin_class.py.j2")
my_model = template.render(dict(
target_action_human_name=target_action.human_name(),
target_action_python_name=target_action.python_name(),
attribute_1_name=attribute_1.underscore_name(),
attribute_2_name=attribute_2.underscore_name(),
attribute_3_name=attribute_3.underscore_name(),
))
with open("models.py", "a") as f:
with open("app/models.py", "a") as f:
f.write("\n\n")
f.write(my_model)

template = env.get_template("command_function_no_source.jinja2")
template = env.get_template("repository/append_sensor_class.py.j2")
my_function = template.render(dict(
target_action_human_name=target_action.human_name(),
target_action_python_name=target_action.python_name(),
target_action_underscore_name=target_action.underscore_name(),
prompt_name=prompt_name,
controller_type="Marvin",
))
with open("commands.py", "a") as f:
with open("app/repository.py", "a") as f:
f.write("\n\n")
f.write(my_function)

template = env.get_template("pipeline_function_no_source.jinja2")
template = env.get_template("pipeline/append_sensor_function.py.j2")
my_asset = template.render(dict(
target_action_human_name=target_action.human_name(),
target_action_underscore_name=target_action.underscore_name(),
))
with open("pipeline.py", "a") as f:
with open("app/pipeline.py", "a") as f:
f.write("\n\n")
f.write(my_asset)

@staticmethod
def do_feature_with_source(source_action: str, target_action: str, attribute_1: str, attribute_2: str,
attribute_3: str):
def do_asset(source_action: str, target_action: str,
attribute_1: str, attribute_2: str, attribute_3: str):
"""Create a new LangController Feature from inside your LangController Project
Args:
source_action (str): The name of the in comming source
target_action (str): The name of the out going target
source_action (str): The name of the in coming source
target_action (str): The name of the outgoing target
attribute_1 (str): The name of the first attribute of the target action
attribute_2 (str): The name of the second attribute of the target action
attribute_3 (str): The name of the third attribute of the target action
Example:
langcontroller make-feature-with-source strategy scaled-agile-portfolio name description issues
poetry run python commands.py create_scaled_agile_portfolio --strategy "Tour Operator for the Moon"
langcontroller make-asset strategy scaled-agile-portfolio name description issues
python manage.py create_scaled_agile_portfolio "Award-winning Tour Operator for the Moon"
"""

if not all([
os.path.exists("commands.py"),
os.path.exists("pipeline.py"),
os.path.exists("prompt_templates"),
os.path.exists("app/models.py"),
os.path.exists("app/pipeline.py"),
os.path.exists("app/repository.py"),
os.path.exists("templates"),
os.path.exists("manage.py"),
]):
print("Please verify that you are in a LangController Project")
return
Expand All @@ -287,28 +299,28 @@ def do_feature_with_source(source_action: str, target_action: str, attribute_1:
)
prompt_name = f"{source_action.slug}-to-{target_action.slug}"

template = env.get_template("prompt_command_with_source.jinja2")
template = env.get_template("prompt_templates/create_asset_file.j2.j2")
my_prompt = template.render(dict(
source_action_underscore_name=source_action.underscore_name(),
source_action_human_name=source_action.human_name(),
target_action=target_action.human_name()
))
with open(f"prompt_templates/{prompt_name}.jinja2", "w") as f:
with open(f"templates/{prompt_name}.j2", "w") as f:
f.write(my_prompt)

template = env.get_template("models_class.jinja2")
template = env.get_template("models/append_marvin_class.py.j2")
my_model = template.render(dict(
target_action_human_name=target_action.human_name(),
target_action_python_name=target_action.python_name(),
attribute_1_name=attribute_1.underscore_name(),
attribute_2_name=attribute_2.underscore_name(),
attribute_3_name=attribute_3.underscore_name(),
))
with open("models.py", "a") as f:
with open("app/models.py", "a") as f:
f.write("\n\n")
f.write(my_model)

template = env.get_template("command_function_with_source.jinja2")
template = env.get_template("repository/append_asset_class.py.j2")
my_function = template.render(dict(
source_action_underscore_name=source_action.underscore_name(),
target_action_human_name=target_action.human_name(),
Expand All @@ -317,18 +329,18 @@ def do_feature_with_source(source_action: str, target_action: str, attribute_1:
prompt_name=prompt_name,
controller_type="Marvin",
))
with open("commands.py", "a") as f:
with open("app/repository.py", "a") as f:
f.write("\n\n")
f.write(my_function)

template = env.get_template("pipeline_function_with_source.jinja2")
template = env.get_template("pipeline/append_asset_function.py.j2")
my_asset = template.render(dict(
source_action_human_name=source_action.human_name(),
source_action_underscore_name=source_action.underscore_name(),
target_action_human_name=target_action.human_name(),
target_action_underscore_name=target_action.underscore_name(),
))
with open("pipeline.py", "a") as f:
with open("app/pipeline.py", "a") as f:
f.write("\n\n")
f.write(my_asset)

Expand Down
4 changes: 2 additions & 2 deletions langcontroller/controllers/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class GenericPromptTemplateMixin:
"""Mixin for prompting and applying middlewares to the prompt_template"""

env = Environment(
loader=FileSystemLoader("prompt_templates"),
loader=FileSystemLoader("templates"),
autoescape=select_autoescape(),
)

Expand All @@ -36,7 +36,7 @@ def get_rendered_prompt(self, prompt_template: str, **kwargs) -> str:
Returns:
str: The rendered prompt_template
"""
template = self.env.get_template(f"{prompt_template}.jinja2")
template = self.env.get_template(f"{prompt_template}.j2")
return template.render(**kwargs)

def apply_prompt_middleware(self, prompt: str) -> str:
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from commands import cli_app
from app.repository import cli_app

if __name__ == "__main__":
cli_app()
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""models.py
"""Pydantic Models

This module contains the important pydantic models of the {{ project_name }} project that
represent the structured output of the application.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""pipeline.py
"""Dagster Pipeline

This module contains the important assets of the {{ project_name }} project that
are used to build the Dagster Pipeline
Expand All @@ -8,5 +8,5 @@ from dagster import (
get_dagster_logger,
AssetExecutionContext,
)
from commands import *
from app.repository import *

1 change: 0 additions & 1 deletion langcontroller/templates/prompt_command_no_source.jinja2

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
{% raw %}{% extends "base_prompt.j2" %}

{% block prompt %}{% endraw %}
Create a {{ target_action }} given the following {{ source_action_human_name }}:
{% raw %}{{{% endraw %} {{ source_action_underscore_name }} {% raw %}}}{% endraw %}
{% raw %}{% endblock %} {% endraw %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
You are a Python Pydantic Model Creator.

Perform the follow to create a python pydantic model:
{% raw %}{% block prompt %}{% endblock %}{% endraw %}

Please ensure that your implementation is clear, accurate, and comprehensive.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% raw %}{% extends "base_prompt.j2" %}

{% block prompt %}{% endraw %}
Create an awesome {{ target_action }} for something awesome
{% raw %}{% endblock %}{% endraw %}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ readme = "README.md"
python = "^3.10"
jinja2 = "^3.1.2"
typer = {extras = ["all"], version = "^0.9.0"}
python-slugify = "^8.0.1"

[tool.poetry.group.marvin.dependencies]
marvin = "^1.3.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@api_app.post("/{{ target_action_underscore_name }}")
@api_app.post("{{ target_action_underscore_name }}")
@cli_app.command()
def create_{{ target_action_underscore_name }}({{ source_action_underscore_name }}: str) -> {{ target_action_python_name }}:
def create_{{ target_action_underscore_name }}(
{{ source_action_underscore_name }}: str) -> {{ target_action_python_name }}:
"""Creates a {{ target_action_human_name }}"""
print("Creating {{ target_action_human_name }}...")

Expand Down
Loading

0 comments on commit cbc376b

Please sign in to comment.