Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recipe for each HAPI endpoint + refactor of DB schema #34

Merged
merged 92 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
aebca13
New neater schema, split into own tables
dividor Jun 1, 2024
ce42857
Checkout now works with new schema
dividor Jun 1, 2024
2b7a633
Removing all try/except statements, better to fix the root cause. Als…
dividor Jun 1, 2024
c32e812
Checkin now works with new table schema. Next up, automatic generatio…
dividor Jun 1, 2024
670255b
Updated docs
dividor Jun 1, 2024
de2ffe6
Automatically generate an openapi.json for recipe function
dividor Jun 1, 2024
5c34412
Added cksum so only commits changed recipes
dividor Jun 2, 2024
4a3a642
Added cksum so only commits changed recipes
dividor Jun 2, 2024
30e7059
Tided up input/output into a work folder
dividor Jun 2, 2024
4f329a1
Tided up input/output into a work folder
dividor Jun 2, 2024
552b289
I created a recipes CLI for easier management. In progress
dividor Jun 2, 2024
63c6804
Migrated to use jinja2 templates for easier maintenance
dividor Jun 2, 2024
937fe40
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
05e788b
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
59a7cd3
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
166bc37
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
1834354
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
d59d26d
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
94f0eff
Simplified and merged recipe addition so on creating a new recipe, it…
dividor Jun 2, 2024
37424b1
Added delete workflow to cli
dividor Jun 2, 2024
f514f00
Added session caching to cli
dividor Jun 2, 2024
61a0d21
CLI add recipe with vector updating
dividor Jun 2, 2024
1df26ba
CLI add recipe with vector updating
dividor Jun 2, 2024
245f0e8
CLI add recipe with vector updating
dividor Jun 2, 2024
08a3254
CLI add recipe with vector updating
dividor Jun 2, 2024
8cb0b59
CLI add recipe with vector updating
dividor Jun 2, 2024
95d2c89
Locks still not working, I think it's a transaction commit issue. Che…
dividor Jun 2, 2024
f8c510a
Bug fix in metadata template
dividor Jun 2, 2024
8e79ae7
Bug fix in metadata template
dividor Jun 2, 2024
167d7c8
Locks still not working, I think it's a transaction commit issue. Che…
dividor Jun 2, 2024
a5b0958
Locks still not working, I think it's a transaction commit issue. Che…
dividor Jun 2, 2024
659bc78
Aligning ids across tables, added constraints and foreign keys
dividor Jun 3, 2024
4cbbb22
Made code separator if __name__ == '__main__': so recipes.py can be e…
dividor Jun 3, 2024
6a0d124
Made code separator if __name__ == '__main__': so recipes.py can be e…
dividor Jun 3, 2024
ab713ab
Added recipe run to the cli, such that on running a recipe, it update…
dividor Jun 3, 2024
7a961dc
Created a helper cli function to convert sample results to memory to …
dividor Jun 3, 2024
edb2190
Created a helper cli function to convert sample results to memory to …
dividor Jun 3, 2024
f0ac569
Updated copilot prompt with latest table names
dividor Jun 3, 2024
291f1b5
Added geopandas GEODAL etc to recipes-manager
dividor Jun 3, 2024
2d246d9
A few tweaks about generated image locations. Needs more analysis and…
dividor Jun 3, 2024
2a1cc31
A few tweaks about generated image locations. Needs more analysis and…
dividor Jun 3, 2024
60ba285
Demo data with a few recipes and memories in new schema format, creat…
dividor Jun 3, 2024
c41910e
Split Demo SQL into different scripts, easier to manage.
dividor Jun 3, 2024
6491389
Get Debug on failed LLM calls
dividor Jun 3, 2024
3861b48
A basic README on the new CLI
dividor Jun 3, 2024
9c7312d
A few tweaks about generated image locations. Needs more analysis and…
dividor Jun 3, 2024
3df0dca
Added CASCADE to constraint so deletes of recipes and memories delete…
dividor Jun 3, 2024
7b5dcfe
Tidying up a few things
dividor Jun 3, 2024
09b189b
Added GPT-4o
dividor Jun 3, 2024
e3ab8bf
Bug fix on one insert
dividor Jun 3, 2024
9a7342d
Fix for ingestion, new endpoint
dividor Jun 3, 2024
485bfff
Removing HDX filter as they have changed API
dividor Jun 3, 2024
2f54c1e
Update ReadMe how to run cli
JanPeterDatakind Jun 3, 2024
3841dba
Fix to code prompt for generating new recipes
dividor Jun 3, 2024
03d8360
Merge branch 'feat/create_recipe_for_every_HAPI_endpoint' of github.c…
dividor Jun 3, 2024
975e441
Fix to code prompt for generating new recipes
dividor Jun 3, 2024
78a8ce5
Ensuring creation of work folder
dividor Jun 3, 2024
b6cb297
Ensuring creation of work folder
dividor Jun 3, 2024
3c8ca1d
Ensuring creation of work folder
dividor Jun 3, 2024
326422d
Ensuring creation of work folder
dividor Jun 3, 2024
4ceff79
Force cli to be run in recipes-management folder
dividor Jun 3, 2024
eff94a3
Added LLM edit
dividor Jun 3, 2024
19d232d
Added LLM edit
dividor Jun 3, 2024
af21e19
Added LLM edit
dividor Jun 3, 2024
89f0926
Added LLM edit
dividor Jun 3, 2024
36b82dd
Added LLM edit
dividor Jun 3, 2024
5bcad16
Added LLM edit
dividor Jun 3, 2024
d276cc5
Added LLM edit
dividor Jun 3, 2024
81d1aaa
Added LLM edit
dividor Jun 3, 2024
46a3168
Added LLM edit
dividor Jun 3, 2024
ba75643
Added LLM edit
dividor Jun 3, 2024
522b0b8
Added LLM edit
dividor Jun 3, 2024
473dd09
Added LLM edit
dividor Jun 3, 2024
fb0144b
Added LLM edit
dividor Jun 3, 2024
978c058
Added message to alert user recipe didn't output any information
dividor Jun 3, 2024
edffa1b
Added message to alert user recipe didn't output any information
dividor Jun 3, 2024
27c3931
Fix for GPT-4o
dividor Jun 3, 2024
4b9ec98
Fixed recipes to account for new HAPI data
dividor Jun 3, 2024
b11d533
Fixed recipes to account for new HAPI data
dividor Jun 3, 2024
93ecec3
Adjustment to actions for memorry new schema
dividor Jun 3, 2024
4af4be6
Don't know how this regressed, but reactivating imag
dividor Jun 3, 2024
d420f4b
Tidy up for code quality hooks
dividor Jun 4, 2024
0459115
skill.py exclusion, black and isort clashed due to typer
dividor Jun 4, 2024
c7076e7
Tidy up for code quality hooks
dividor Jun 4, 2024
2af83e9
Tidy up for code quality hooks
dividor Jun 4, 2024
d345ea0
Jan's demo recipes
dividor Jun 4, 2024
45a0843
Some improvements to LLM output handling
dividor Jun 4, 2024
def7daf
Implemented standard intent and entities taxonomy
dividor Jun 4, 2024
218a7a3
Implemented standard intent and entities taxonomy
dividor Jun 4, 2024
cbde756
Improved LLM editing for demo
dividor Jun 4, 2024
f9905c6
Regenerated recipes and memories using LLM CLI
dividor Jun 4, 2024
77f311a
Regenerated recipes and memories using LLM CLI
dividor Jun 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ recipes-management/checked_out/*
!recipes-management/checked_out/skills.py
recipes-management/files/
database.sqlite
.cli_config
recipes-management/work/

1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ repos:
rev: 24.4.2
hooks:
- id: black
exclude: 'skills.py'
language_version: python3.11
- repo: https://github.com/pycqa/flake8.git
rev: 7.0.0
Expand Down
51 changes: 30 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,41 +163,50 @@ As the robocorp actions might differ slightly, this can lead to differing requir

The management of recipes is part of the human in the loop approach of this repo. New recipes are created in status pending and only get marked as approved, once they have been verified by a recipe manager. Recipe managers can 'check out' recipes from the database into their local development environment such as VS Code to run, debug, and edit the recipes, before checking them back in. To make this process platform independent, recipes are checked out into a docker container, which can be used as the runtime environment to run the recipes via VSCode.

1. To check out recipes:
Recipes are managed using the recipes Command Line Interface (CLI), which allows you to check out recipes, run and refine, the commit them back to the recipes database for use in data recipes AI.

`cd recipes-management`
`docker exec haa-recipe-manager python recipe_sync.py --check_out <YOUR NAME>`
To run the cli, you will need to install some packages ...

`pip3 install typer`

Note: This will lock the recipes in the database so others cannot edit them.
Once this is done, and you have your docker environment running as described above, you start the recipes CLI with ...

`cd recipes-management`
`python cli.py`

2. The checked_out folder in the recipes-management directory now shows all the recipes that were checked out from the database including the recipe code as a .py file. Note that after this step, the recipes in the database are marked as locked with your name and the timestamp you checked them out. If someone else tries to check them out, they are notified accordingly and cannot proceed until you've unlocked the records (more on that below).
When you first log in, you will be asked for your name. This is used when checking in recipes. Once in, you will be presented with a menu like this ...

This step checks out three files:
```

- Recipe.py - Contains the recipe code (re-assembled from the corresponding sections in the metadata json file)
- metadata.json - Contains the content of the cmetadata column in the recipe database.
- record_info.json - Contains additional information about the record such as its custom_id, and output.
Welcome to the recipes management CLI, matt!

You can edit all files according to your needs. Please makes sure to not change the custom_id anywehere because it's needed for the check in process.
Here are the commands you can run:

'checkout': Check out recipes for you to work on
'list': List all recipes that are checked out
'run': Run a recipe, you will be prompted to choose which one
'add': Add a new recipe
'delete': Delete a recipe, you will be prompted to choose which one
'checkin': Check in recipes you have completed
'makemem': Create a memory using recipe sample output
'help': Show a list of commands
'quit': Exit this recipes CLI

3. Run the scripts and edit them as you deem fit. Please note: Do not delete the #Functions Code and #Calling Code comments as they're mandatory to reassemble the metadata json for the check in process.
4. Once you've checked and edited the recipes, run
Type one of the commands above to do some stuff.

`docker exec haa-recipe-manager python recipe_sync.py --check_in <YOUR NAME>`

To check the records back into the database and unlock them. All recipes that you've checked in in this fashion are automatically set to status 'approved' with your name as the approver and the timestamp of when you checked them back in.
>>
```

## Testing a Recipe
The first thing you will want to do is run 'checkout' to get all the recipe code from the database onto your computer so you can run them. Once you have them locally, you can edit them in tools like Visual Studio code.

You can run a specific recipe like this ...
To run recipes locally you can use the CLI 'run' command. This will run the recipe in the same environment, and will save the results like sample outputs, for you so they can be published back to the database.

`docker exec haa-recipe-manager python checked_out/retrieve_the_total_population_of_a_specified_country/recipe.py`
You can create new recipes by entering 'add', where you'll be prompted for an intent. This will call an LLM to generate a first pass at your recipe, using the data that's in the data recipes environment.

You can also exec into the container to do it ...
When ready, you can check in your new and edited recipes with 'checkin'.

1. `docker exec -it haa-recipe-manager /bin/bash`
2. `cd ./checked_out`, then `cd <RECIPE_DIR>`
3. `python recipe.py`
### Other approaches

You can also configure VS Code to connect to the recipe-manage container for running recipes ...

Expand Down
83 changes: 65 additions & 18 deletions actions/actions_plugins/recipe-server/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
)
from PIL import Image
from robocorp.actions import action
from sqlalchemy import create_engine, text

# Load environment variables from .env file
load_dotenv()
Expand Down Expand Up @@ -278,6 +279,54 @@ def get_recipe_memory(intent) -> str:
return memory_found, recipe_response


def connect_to_db(instance="recipe"):
"""
Connects to the specified database instance (RECIPE or DATA) DB and returns a connection object.

Args:
instance (str): The name of the database instance to connect to. Defaults to "RECIPE".

Returns:
sqlalchemy.engine.base.Engine: The connection object for the specified database instance.
"""

instance = instance.upper()

host = os.getenv(f"POSTGRES_{instance}_HOST")
port = os.getenv(f"POSTGRES_{instance}_PORT")
database = os.getenv(f"POSTGRES_{instance}_DB")
user = os.getenv(f"POSTGRES_{instance}_USER")
password = os.getenv(f"POSTGRES_{instance}_PASSWORD")
conn_str = f"postgresql://{user}:{password}@{host}:{port}/{database}"
# add an echo=True to see the SQL queries
conn = create_engine(conn_str)
return conn


def get_associated_data(metadata):

conn = connect_to_db("recipe")

with conn.connect() as connection:

if metadata["mem_type"] == "memory":
query = f"""
SELECT
result,
result_type
FROM
memory
WHERE
custom_id = '{metadata['custom_id']}'
"""
result = connection.execute(text(query))
result = result.fetchall()
metadata["result"] = result[0][0]
metadata["result_type"] = result[0][1]

return metadata


def check_memory(intent, mem_type, db, chat):
"""
Check the memory for a given intent.
Expand Down Expand Up @@ -306,10 +355,7 @@ def check_memory(intent, mem_type, db, chat):
score = m["score"]
content = m["content"]
metadata = m["metadata"]
if (
metadata["calling_code_run_status"] != "ERROR"
and metadata["mem_type"] == mem_type
):
if metadata["mem_type"] == mem_type:
print(f"\n Reranking candidate: Score: {score} ===> {content} \n")
# Here ask LLM to confirm our match
prompt = f"""
Expand All @@ -326,21 +372,17 @@ def check_memory(intent, mem_type, db, chat):
response = call_llm(prompt_map[mem_type], prompt, chat)
print(response)

if "user_intent_output_format" in response:
if (
response["user_intent_output_format"]
!= response["generic_db_output_format"]
):
response["answer"] = "no"
response["reason"] = "output formats do not match"

print("AI Judge of match: ", response)

if response["answer"].lower() == "yes":
print("We have a match!!!")
r["score"] = score
r["content"] = content
r["metadata"] = metadata

# Here we query the DB to get supporting data from other tables
metadata = get_associated_data(metadata)

return True, r

return False, r
Expand Down Expand Up @@ -374,10 +416,7 @@ def get_matching_candidates(intent, mem_type, db, cutoff=None):
content = d[0].page_content
metadata = d[0].metadata
print("\n", f"\n\nMatches: Score: {score} ===> {content}\n\n")
if (
metadata["calling_code_run_status"] != "ERROR"
and metadata["mem_type"] == mem_type
):
if metadata["mem_type"] == mem_type:
if d[1] < cutoff:
print("\n", " << MATCHED >>")
r["score"] = score
Expand Down Expand Up @@ -458,8 +497,12 @@ def get_memory(user_input, chat_history, generate_intent=True) -> str:
user_input = json.dumps(user_input)
memory_found, result = get_recipe_memory(user_input)
if memory_found is True:
response_text = result["metadata"]["response_text"]
response_image = result["metadata"]["response_image"]
if result["metadata"]["result_type"] == "image":
response_image = result["metadata"]["result"]
response_text = ""
else:
response_text = result["metadata"]["result"]
response_image = ""
recipe_id = result["metadata"]["custom_id"]
print("Recipe ID: ", recipe_id)
if response_image is not None and response_image != "":
Expand All @@ -474,3 +517,7 @@ def get_memory(user_input, chat_history, generate_intent=True) -> str:
else:
result = "No memory found"
return result


if __name__ == "__main__":
get_memory("What is the population of Mali?", [], False)
114 changes: 0 additions & 114 deletions actions/actions_plugins/recipe-server/db/1-schema.sql

This file was deleted.

42 changes: 0 additions & 42 deletions actions/actions_plugins/recipe-server/db/2-demo-data.sql

This file was deleted.

Loading
Loading