Skip to content

Commit

Permalink
Merge pull request #202 from hoomano/kroussel/update_doc_workflow_cre…
Browse files Browse the repository at this point in the history
…ation

Kroussel/update doc workflow creation
  • Loading branch information
xbasset authored Jul 30, 2024
2 parents 77fad00 + e2793c1 commit 7535fde
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 85 deletions.
8 changes: 8 additions & 0 deletions backend/app/routes/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@
}
}
}
},
"review_chat_enabled":{
"type": "boolean",
"default": false
},
"user_validation_required":{
"type": "boolean",
"default": true
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion backend/app/routes/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ def put(self):
definition_for_system=step["definition_for_system"],
task_fk=task.task_pk,
rank=step_index + 1,
review_chat_enabled=step.get("review_chat_enabled", False)
review_chat_enabled=step.get("review_chat_enabled", False),
user_validation_required=step.get("user_validation_required", True),
)
db.session.add(db_step)
db.session.flush()
Expand Down
132 changes: 48 additions & 84 deletions docs/guides/workflows/new_workflow.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,64 @@
# Create a new workflow

## Technical definition
A workflow is a sequence of steps that the agent must execute one by one. Each step execution then requires a user validation before the agent can proceed to the next step.
Compared to the tasks, the workflows are more complex and constrainted, allowing the user to keep more control over the agent's actions.
A workflow is a sequence of steps that the agent must execute one by one. A step is code: anything can be done in this code including complex actions as API calls.

The result of each step execution is always available to the user that can consult it. On the steps requiring user validation, user can edit the step result and sometimes open a chat to give an instruction to relaunch the step.
Compared to the instruct tasks, the workflows are more complex and constrainted, allowing the user to keep more control over the agent's actions.

## How to create a new workflow?

STEP 1: Create the steps' code
In `backend>app>models>workflows` create a new folder named by your workflow. In this folder, create one file per step in your workflow.
In each of those files, implement the crresponding step code.
### STEP 1: Create the steps' code
In `mojodex_core>workflows` create a new folder named by your workflow. In this folder, create one file per step in your workflow.
In each of those files, implement the corresponding step code.
A workflow step is a class that implements the `WorkflowStep` class.

An implementation of `WorkflowStep` looks like this:
An implementation of `WorkflowStep` overrides the method `_execute()`. It looks like this:

```python
from models.workflows.step import WorkflowStep
from mojodex_core.entities.workflow_step import WorkflowStep

class MyWorkflowStep(WorkflowStep):

@property
def definition_for_system(self):
return "This is a definition of the step" # Definition of the step as used in prompts

@property
def input_keys(self):
return ['input_key1', 'input_key2'] # List of keys that must be present in the input parameter

@property
def output_keys(self):
return ['output_key1', 'output_key2'] # List of keys that will be present in the output parameter


def _execute(self, parameter: dict, learned_instructions: dict, initial_parameter: dict, history: List[dict], workflow_conversation: str):
def _execute(self, parameter: dict, learned_instructions: dict, initial_parameter: dict, past_validated_steps_results: List[dict], user_id: str, user_task_execution_pk: int, task_name_for_system: str, session_id:str):
try:
# parameter contains every input keys
return [{'output_key1': <output>, 'output_key2': <output>}] # output contains every output key
return [{'output_key1': <output>, 'output_key2': <output>}]
except Exception as e:
raise Exception(f"execute :: {e}")
```

STEP 2: Add your steps to the steps library
In `backend>app>models>workflows>steps_library.py`, add your steps to the `STEPS` dictionary. The key must be the name of the step and the value must be the class of the step. This is used to dynamically load the steps from their name in the database.
The result of the step execution must be a list of dictionaries. The next step of the workflow will be executed as many time as there are dictionaries in the list, each time with the corresponding dictionary as parameter.

STEP 3: Create the workflow
To create a new workflow, you can use the dedicated route PUT `/workflow`
### STEP 2: Add your steps to the steps library
In `mojodex_core>workflows>steps_library.py`, add your steps to the `STEPS` dictionary. The key must be the name of the step as later defined in DB and the value must be the class of the step. This is used to dynamically load the steps from their name in the database.

### STEP 3: Create the workflow
To create a new workflow, you can use the dedicated route PUT `/task`.

Replace `<BACKOFFICE_SECRET>` with your actual token and name, steps, icon and description with the actual workflow name, steps, icon and description.
> Careful: steps names must match the ones in the steps library.
> Careful: steps must be in the right order.
Then, run the following command in your terminal:

```shell
curl --location --request PUT 'http://localhost:5001/workflow' \
curl --location --request PUT 'http://localhost:5001/task' \
--header 'Authorization: <BACKOFFICE_SECRET>' \
--header 'Content-Type: application/json' \
--data-raw '{"datetime": "2024-02-14T17:49:26.545180",
"task_type": "workflow",
"predefined_actions": [],
"name_for_system": "<WORKFLOW_NAME_FOR_SYSTEM>",
"icon": "<EMOJI>",
"definition_for_system": "<WORKFLOW_DEFINITION_FOR_SYSTEM>",
"platforms": ["webapp", "mobile"], # List of platforms where the workflow is available
"output_type": "document",
"platforms": ["webapp"], # List of platforms where the workflow is available. Workflows are not yet implemented on mobile app.
"steps": [{
"name_for_system": "<STEP_NAME_FOR_SYSTEM>",
"definition_for_system": "<STEP_DEFINITION_FOR_SYSTEM>",
"rank": 1,
"review_chat_enabled": false, # Whether the chat is enabled at the end of the step or not.
"user_validation_required": true, # Whether the user validation is required or not at the end of this step
"step_displayed_data":[
{
"language_code": "<2-LETTERS LANGUAGE-CODE>",
Expand All @@ -71,80 +69,46 @@ curl --location --request PUT 'http://localhost:5001/workflow' \
]},
...
],
"workflow_displayed_data": [
"task_displayed_data": [
{
"language_code":"<2-LETTERS LANGUAGE-CODE>",
"name_for_user": <WORKFLOW_NAME_FOR_USER>",
"definition_for_user": <WORKFLOW_DEFINITION_FOR_USER>",
"json_inputs_spec": [
{"input_name_for_system": "<INPUT_NAME_FOR_SYSTEM>", "type": "text_area", "input_name_for_user":"<INPUT_NAME_FOR_USER>"},
"json_input": [
{"input_name": "<INPUT_NAME>",
"description_for_user": "<DESCRIPTION_FOR_USER>",
"description_for_system": "<DESCRIPTION_FOR_SYSTEM>",
"type": "text_area"},
...
]
},
...
]
],
"result_chat_enabled": false # Whether the chat is enabled at the end of the workflow on the produced text or not.
}'
```

STEP 4: Define workflow checkpoints
By default, every step is defined as a checkpoint. This means that at the end of each step_execution_run, if the user does not validate the result, the user will give an instruction and this same step_execution_run will be executed again.

Example on Qualify Lead workflow:
Step 1 is "Write the query you will use with SERP API to search Google"

- Step 1 - Run 1 - Execution 1:
parameter: {"company": "Hoomano"}
learned instructions: None
step result: "query: 'Hoomano industry'"
<USER DOES NOT VALIDATE>
user instruction: "This query is not specific enough, please add more keywords"

- Step 1 - Run 1 - Execution 2:
parameter: {"company": "Hoomano"}
learned instructions: "Make specific queries"
step result: "query: 'Hoomano company industry trends AI"
<USER VALIDATES>

On the contrary, if a step is not defined as a checkpoint, the user will give an instruction but the last checkpoint step last run will be executed again.
Let's keep Qualify Lead workflow example running:
Step 2 is "Check the SERP API results and select the 3 most relevant one"

- Step 2 - Run 1 - Execution 1:
parameter: {"query": "Hoomano company industry trends AI"}
learned instructions: None
step result: "result 1, result 2, ..."
<USER DOES NOT VALIDATE>
user instruction: "This is not relevant, please try again, look for any blog post the company wrote"

- Step 1 - Run 1 - Execution 3:
parameter: {"company": "Hoomano"}
learned instructions: "Make specific queries, look for any blog post the company wrote"
step result: "query: 'Hoomano company AI blog posts"
<USER VALIDATES>

- Step 2 - Run 2 - Execution 1:
parameter: {"query": "Hoomano company AI blog posts"}
learned instructions: "Make specific queries, look for any blog post the company wrote"
step result: "result 1, result 2, ..."
<USER VALIDATES>

STEP 5: Associate workflow to a user through a product.
Replace `<BACKOFFICE_SECRET>` with your actual token and `<user_id>` and `<workflow_pk>` with the actual user id and workflow primary key.
> **Note regarding "result_chat_enabled" parameter**:
Be careful that once on result page:
> - Assistant will no longer be able to re-launch past steps code - therefore relaunch api requests or other…
> - Text has been generated by a whole chain of steps. It could be too long for context-windows on a basic LLM chat call.
> As a consequence, depending on the workflow, it may be relevant to disable the chat on result to avoid user confusion (preventing them to ask to re-launch a query for example)

### STEP 4: Associate workflow to a user through a product.
Replace `<BACKOFFICE_SECRET>` with your actual token and `<user_id>` and `<task_pk>` with the actual user id and workflow primary key.
Then, run the following command in your terminal:


Default user `demo@example.com` is associated with default product `demo` with pk 1. Let's add the task to this product.
```
curl --location --request PUT 'http://localhost:5001/product_workflow_association' \
curl --location --request PUT 'http://localhost:5001/product_task_association' \
--header 'Authorization: backoffice_secret' \
--header 'Content-Type: application/json' \
--data-raw '{
"datetime": "'"$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")"'",
"product_pk": 1,
"workflow_pk": <workflow_pk retrieved from previous command>
"task_pk": <task_pk retrieved from previous command>
}'
```




```
6 changes: 6 additions & 0 deletions docs/openAPI/backend_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3618,6 +3618,12 @@ paths:
type: string
definition_for_system:
type: string
review_chat_enabled:
type: boolean
default: false
user_validation_required:
type: boolean
default: true
step_displayed_data:
type: array
items:
Expand Down

0 comments on commit 7535fde

Please sign in to comment.