Skip to content

Commit

Permalink
Merge pull request #429 from GooeyAI/functions_ux_cleanup
Browse files Browse the repository at this point in the history
functions: ux clean-up
  • Loading branch information
anish-work authored Aug 14, 2024
2 parents 8c748ed + 0a6ae3b commit c5f464a
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 41 deletions.
2 changes: 1 addition & 1 deletion daras_ai_v2/analysis_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def render_analysis_results_page(

gui.session_state.setdefault("selected_graphs", graphs)
selected_graphs = list_view_editor(
add_btn_label="Add a Graph",
add_btn_label="Add a Graph",
key="selected_graphs",
render_inputs=partial(render_inputs, results),
)
Expand Down
13 changes: 7 additions & 6 deletions daras_ai_v2/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class BasePage:

class RequestModel(BaseModel):
functions: list[RecipeFunction] | None = Field(
title="🧩 Functions",
title="🧩 Developer Tools and Functions",
)
variables: dict[str, typing.Any] = Field(
None,
Expand Down Expand Up @@ -1476,15 +1476,17 @@ def update_flag_for_run(self, run_id: str, uid: str, is_flagged: bool):

# Functions in every recipe feels like overkill for now, hide it in settings
functions_in_settings = True
show_settings = True

def _render_input_col(self):
self.render_form_v2()
placeholder = gui.div()

with gui.expander("⚙️ Settings"):
if self.functions_in_settings:
functions_input(self.request.user)
self.render_settings()
if self.show_settings:
with gui.expander("⚙️ Settings"):
self.render_settings()
if self.functions_in_settings:
functions_input(self.request.user)

with placeholder:
self.render_variables()
Expand All @@ -1499,7 +1501,6 @@ def _render_input_col(self):

def render_variables(self):
if not self.functions_in_settings:
gui.write("---")
functions_input(self.request.user)
variables_input(
template_keys=self.template_keys, allow_add=is_functions_enabled()
Expand Down
2 changes: 1 addition & 1 deletion daras_ai_v2/bot_integration_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def render_workflow_url_input(key: str, del_key: str | None, d: dict):
input_analysis_runs.append(dict(saved_run=sr, published_run=None))

list_view_editor(
add_btn_label="Add",
add_btn_label="Add",
key="analysis_urls",
render_inputs=render_workflow_url_input,
flatten_dict_key="url",
Expand Down
1 change: 1 addition & 0 deletions daras_ai_v2/icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
company = '<i class="fa-regular fa-buildings"></i>'
copy = '<i class="fa-solid fa-copy"></i>'
preview = '<i class="fa-solid fa-eye"></i>'
add = '<i class="fa-regular fa-add"></i>'

code = '<i class="fa-regular fa-code"></i>'
chat = '<i class="fa-regular fa-messages"></i>'
Expand Down
17 changes: 13 additions & 4 deletions daras_ai_v2/prompt_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,31 @@
from datetime import datetime
from types import SimpleNamespace

import gooey_gui as gui
import jinja2
import jinja2.meta
import jinja2.sandbox

import gooey_gui as gui
from daras_ai_v2 import icons


def variables_input(
*,
template_keys: typing.Iterable[str],
label: str = "###### ⌥ Variables",
description: str = "Variables let you pass custom parameters to your workflow. Access a variable in your instruction prompt with <a href='https://jinja.palletsprojects.com/en/3.1.x/templates/' target='_blank'>Jinja</a>, e.g. `{{ my_variable }}`\n ",
key: str = "variables",
allow_add: bool = False,
):
from daras_ai_v2.workflow_url_input import del_button

def render_title_desc():
gui.write(label)
gui.caption(
f"{description} <a href='/variables-help' target='_blank'>Learn more</a>.",
unsafe_allow_html=True,
)

# find all variables in the prompts
env = jinja2.sandbox.SandboxedEnvironment()
template_var_names = set()
Expand Down Expand Up @@ -56,7 +65,7 @@ def variables_input(
continue

if not title_shown:
gui.write(label)
render_title_desc()
title_shown = True

col1, col2 = gui.columns([11, 1], responsive=False)
Expand Down Expand Up @@ -93,7 +102,7 @@ def variables_input(

if allow_add:
if not title_shown:
gui.write(label)
render_title_desc()
gui.newline()
col1, col2, _ = gui.columns([6, 2, 4], responsive=False)
with col1:
Expand All @@ -105,7 +114,7 @@ def variables_input(
)
with col2:
gui.button(
'<i class="fa-regular fa-add"></i> Add',
f"{icons.add} Add",
key=var_add_key,
type="tertiary",
)
Expand Down
20 changes: 13 additions & 7 deletions daras_ai_v2/workflow_url_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def workflow_url_input(
del_key: str = None,
current_user: AppUser | None = None,
allow_none: bool = False,
include_root: bool = True
) -> tuple[typing.Type[BasePage], SavedRun, PublishedRun | None] | None:
init_workflow_selector(internal_state, key)

Expand All @@ -38,7 +39,9 @@ def workflow_url_input(
else:
internal_state["workflow"] = page_cls.workflow
with col1:
options = get_published_run_options(page_cls, current_user=current_user)
options = get_published_run_options(
page_cls, current_user=current_user, include_root=include_root
)
options.update(internal_state.get("--added_workflows", {}))
with gui.div(className="pt-1"):
url = gui.selectbox(
Expand Down Expand Up @@ -143,6 +146,7 @@ def url_to_runs(
def get_published_run_options(
page_cls: typing.Type[BasePage],
current_user: AppUser | None = None,
include_root: bool = True,
) -> dict[str, str]:
# approved examples
pr_query = Q(is_approved_example=True, visibility=PublishedRunVisibility.PUBLIC)
Expand All @@ -166,13 +170,15 @@ def get_published_run_options(
pr.updated_at, # newer first
),
)

options = {
# root recipe
page_cls.get_root_published_run().get_app_url(): "Default",
} | {
options_dict = {
pr.get_app_url(): get_title_breadcrumbs(page_cls, pr.saved_run, pr).h1_title
for pr in saved_runs_and_examples
}

return options
if include_root:
# include root recipe if requested
options_dict = {
page_cls.get_root_published_run().get_app_url(): "Default",
} | options_dict

return options_dict
18 changes: 18 additions & 0 deletions functions/migrations/0002_alter_calledfunction_trigger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.7 on 2024-08-12 12:00

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('functions', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='calledfunction',
name='trigger',
field=models.IntegerField(choices=[(1, 'Before'), (2, 'After')]),
),
]
4 changes: 2 additions & 2 deletions functions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class _TriggerData(typing.NamedTuple):


class FunctionTrigger(_TriggerData, GooeyEnum):
pre = _TriggerData(label="Pre", db_value=1)
post = _TriggerData(label="Post", db_value=2)
pre = _TriggerData(label="Before", db_value=1)
post = _TriggerData(label="After", db_value=2)


class RecipeFunction(BaseModel):
Expand Down
14 changes: 11 additions & 3 deletions functions/recipe_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def render_function_input(list_key: str, del_key: str, d: dict):
from daras_ai_v2.workflow_url_input import workflow_url_input
from recipes.Functions import FunctionsPage

col1, col2 = gui.columns([2, 10], responsive=False)
col1, col2 = gui.columns([3, 9], responsive=True)
with col1:
col1.node.props["className"] += " pt-1"
d["trigger"] = enum_selector(
Expand All @@ -133,20 +133,28 @@ def render_function_input(list_key: str, del_key: str, d: dict):
internal_state=d,
del_key=del_key,
current_user=current_user,
include_root=False,
)
col2.node.children[0].props["className"] += " col-12"

if gui.checkbox(
f"##### {field_title_desc(BasePage.RequestModel, key)}",
key=f"--enable-{key}",
value=key in gui.session_state,
):
gui.session_state.setdefault(key, [{}])
with gui.div(className="d-flex align-items-center"):
gui.write("###### Functions")
gui.caption(
"Functions give your workflow the ability run Javascript code (with webcalls!) allowing it execute logic, use common JS libraries or make external API calls before or after the workflow runs. <a href='/functions-help' target='_blank'>Learn more.</a>",
unsafe_allow_html=True,
)
list_view_editor(
add_btn_label="➕ Add Function",
add_btn_label="Add Function",
add_btn_type="tertiary",
key=key,
render_inputs=render_function_input,
)
gui.write("---")
else:
gui.session_state.pop(key, None)

Expand Down
4 changes: 2 additions & 2 deletions recipes/BulkEval.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def render_inputs(key: str, del_key: str, d: EvalPrompt):

gui.write("##### " + field_title_desc(self.RequestModel, "eval_prompts"))
list_view_editor(
add_btn_label="Add a Prompt",
add_btn_label="Add a Prompt",
key="eval_prompts",
render_inputs=render_inputs,
)
Expand All @@ -261,7 +261,7 @@ def render_agg_inputs(key: str, del_key: str, d: AggFunction):
gui.html("<br>")
gui.write("##### " + field_title_desc(self.RequestModel, "agg_functions"))
list_view_editor(
add_btn_label="Add an Aggregation",
add_btn_label="Add an Aggregation",
key="agg_functions",
render_inputs=render_agg_inputs,
)
Expand Down
12 changes: 8 additions & 4 deletions recipes/BulkRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import gooey_gui as gui
from bots.models import Workflow, SavedRun
from daras_ai.image_input import upload_file_from_bytes
from daras_ai_v2 import icons
from daras_ai_v2.base import BasePage
from daras_ai_v2.breadcrumbs import get_title_breadcrumbs
from daras_ai_v2.doc_search_settings_widgets import (
Expand Down Expand Up @@ -97,7 +98,7 @@ def preview_image(self, state: dict) -> str | None:
def render_form_v2(self):
gui.write(f"##### {field_title_desc(self.RequestModel, 'run_urls')}")
run_urls = list_view_editor(
add_btn_label="Add a Workflow",
add_btn_label="Add a Workflow",
key="run_urls",
render_inputs=self.render_run_url_inputs,
flatten_dict_key="url",
Expand Down Expand Up @@ -246,7 +247,7 @@ def render_form_v2(self):
gui.write("---")
gui.write(f"##### {field_title_desc(self.RequestModel, 'eval_urls')}")
list_view_editor(
add_btn_label="Add an Eval",
add_btn_label="Add an Eval",
key="eval_urls",
render_inputs=self.render_eval_url_inputs,
flatten_dict_key="url",
Expand Down Expand Up @@ -619,7 +620,8 @@ def read_df_any(f_url: str) -> "pd.DataFrame":

def list_view_editor(
*,
add_btn_label: str,
add_btn_label: str = None,
add_btn_type: str = "secondary",
key: str,
render_labels: typing.Callable = None,
render_inputs: typing.Callable[[str, str, dict], None],
Expand Down Expand Up @@ -658,5 +660,7 @@ def list_view_editor(
with label_placeholder:
render_labels()
gui.session_state[key] = new_lst
gui.button(add_btn_label, key=add_key)
if add_btn_label:
with gui.center():
gui.button(f"{icons.add} {add_btn_label}", key=add_key, type=add_btn_type)
return new_lst
10 changes: 6 additions & 4 deletions recipes/CompareLLM.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
import random
import typing

from pydantic import BaseModel, Field

import gooey_gui as gui
from pydantic import BaseModel

from bots.models import Workflow
from daras_ai_v2.base import BasePage
from daras_ai_v2.enum_selector_widget import enum_multiselect
from daras_ai_v2.language_model import (
run_language_model,
LargeLanguageModels,
SUPERSCRIPT,
ResponseFormatType,
)
from daras_ai_v2.language_model_settings_widgets import (
language_model_settings,
Expand Down Expand Up @@ -78,11 +77,14 @@ def render_form_v2(self):

enum_multiselect(
LargeLanguageModels,
label="#### 🤗 Compare Language Models",
label="#### 🧠 Language Models",
key="selected_models",
checkboxes=False,
)

gui.markdown("#### 💪 Capabilities")
# -- functions will render here in parent --

def validate_form_v2(self):
assert gui.session_state["input_prompt"], "Please enter a Prompt"
assert gui.session_state["selected_models"], "Please select at least one model"
Expand Down
10 changes: 8 additions & 2 deletions recipes/Functions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import typing

import gooey_gui as gui
import requests
from pydantic import BaseModel, Field

import gooey_gui as gui
from bots.models import Workflow
from daras_ai_v2 import settings
from daras_ai_v2.base import BasePage
Expand All @@ -21,6 +21,7 @@ class FunctionsPage(BasePage):
title = "Functions"
workflow = Workflow.FUNCTIONS
slug_versions = ["functions", "tools", "function", "fn", "functions"]
show_settings = False

class RequestModel(BaseModel):
code: str = Field(
Expand Down Expand Up @@ -83,7 +84,12 @@ def render_form_v2(self):
)

def render_variables(self):
variables_input(template_keys=["code"], allow_add=True)
variables_input(
template_keys=["code"],
allow_add=True,
description="Pass custom parameters to your function and access the parent workflow data. "
"Variables will be passed down as the first argument to your anonymous JS function.",
)

def render_output(self):
if error := gui.session_state.get("error"):
Expand Down
2 changes: 1 addition & 1 deletion recipes/Translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def related_workflows(self) -> list:
def render_form_v2(self):
gui.write("###### Source Texts")
list_view_editor(
add_btn_label="Add Text",
add_btn_label="Add Text",
key="texts",
render_inputs=render_text_input,
flatten_dict_key="text",
Expand Down
Loading

0 comments on commit c5f464a

Please sign in to comment.