From ed1b44fd7b388c0d66155d3c6a0e06f26c3b1ff5 Mon Sep 17 00:00:00 2001 From: Vasilije <8619304+Vasilije1990@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:18:28 +0100 Subject: [PATCH] Add utils for graph visualization + classification nodes --- Demo_graph.ipynb | 135 ++++-------------- .../modules/cognify/graph/add_propositions.py | 118 +++++++++++---- 2 files changed, 115 insertions(+), 138 deletions(-) diff --git a/Demo_graph.ipynb b/Demo_graph.ipynb index d05e6b8fa..01f36b8ac 100644 --- a/Demo_graph.ipynb +++ b/Demo_graph.ipynb @@ -782,13 +782,11 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "id": "c94056bd-8d32-48e2-9982-e9af06da3333", "metadata": {}, "outputs": [], - "source": [ - "# from cognitive_architecture.modules.cognify.graph.create_semantic_graph import create_semantic_graph" - ] + "source": [] }, { "cell_type": "code", @@ -877,47 +875,21 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 83, "id": "4dab2ff0-0d12-4a00-a4e4-fb901e701bd3", "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'create_user_content_graph' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[50], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m B \u001b[38;5;241m=\u001b[39m \u001b[43mcreate_user_content_graph\u001b[49m(user_id, custom_user_properties, transformed_dict_2, existing_graph\u001b[38;5;241m=\u001b[39mG)\n", - "\u001b[0;31mNameError\u001b[0m: name 'create_user_content_graph' is not defined" - ] - } - ], + "outputs": [], "source": [ "# B = create_user_content_graph(user_id, custom_user_properties, transformed_dict_2, existing_graph=G)" ] }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "id": "627d42fd-d2ce-4ccd-a2a1-2f7ac2f463cf", "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'B' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[48], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mB\u001b[49m)\n", - "\u001b[0;31mNameError\u001b[0m: name 'B' is not defined" - ] - } - ], - "source": [ - "# print(B)" - ] + "outputs": [], + "source": [] }, { "cell_type": "code", @@ -1044,45 +1016,19 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": null, "id": "8d6a9eb5-387e-45a3-9dc9-5f8ac36fdd38", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'{\"layer\": \"Semantic Layer\"}': KnowledgeGraph(nodes=[Node(id=1, description='Britons have a significant affection for animals and treat pet-keeping as an integral part of life', category='people', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=2, description='Keeping pets is considered a serious and passionate activity in Britain, not merely a leisure activity', category='culturalPractice', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=3, description='Dogs are particularly treasured in Britain and are seen as outlets for emotions and social interaction', category='animal', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=4, description='British society is accommodating of dogs, with public spaces and services being dog-friendly', category='socialNorm', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=5, description='The COVID-19 pandemic caused a surge in pet ownership, particularly dogs, leading to increased numbers and issues like dog attacks', category='event', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=6, description='Pets, especially dogs, are increasingly being treated as commodities and status symbols, with a focus on aesthetic breeds', category='socialIssue', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=7, description='Fashionable dog breeds, such as French bulldogs and American XL bullies, are in high demand regardless of health issues they may face', category='animal', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=8, description='Pets are increasingly treated like substitute children or used to project personal identities', category='socialTrend', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=9, description='Spending on pets in the UK has doubled in the last decade, with a trend towards non-essential luxury items for pets', category='economicTrend', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=10, description='There is a discrepancy between what pets truly need and the human projection of desires onto them', category='animalWelfare', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=11, description='Modern lifestyles can conflict with the needs of pets, leading to behavioral issues and insufficient care', category='animalWelfare', color='blue', memory_type='semantic', created_at=None, summarized=None), Node(id=12, description='The relationship with pets should prioritize their wellbeing and recognize their distinct nature', category='ethicalPrinciple', color='blue', memory_type='semantic', created_at=None, summarized=None)], edges=[Edge(source=1, target=2, description='Britons are known for their serious approach to keeping pets', color='green', created_at=None, summarized=None), Edge(source=2, target=3, description='Dogs are a central part of the pet-keeping practice in Britain', color='green', created_at=None, summarized=None), Edge(source=3, target=4, description='Dogs are widely accepted in public spaces and services due to British social norms', color='green', created_at=None, summarized=None), Edge(source=5, target=6, description='The pandemic surge in pet ownership led to an increase in the commodification of pets', color='green', created_at=None, summarized=None), Edge(source=7, target=6, description='Designer dog breeds are part of the trend of pets being commodified', color='green', created_at=None, summarized=None), Edge(source=9, target=8, description='Increased spending on pet luxuries is related to treating pets as substitutes for children or personal identity projections', color='green', created_at=None, summarized=None), Edge(source=10, target=11, description='The conflict between pet needs and human desires is evident in modern pet care', color='green', created_at=None, summarized=None)])}" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "layer_1_graph[0]" - ] + "outputs": [], + "source": [] }, { "cell_type": "code", - "execution_count": 44, + "execution_count": null, "id": "7f1cde10-3d83-4800-9ef4-f8eaa39cf772", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "required_layers_two.dict()['label']['subclass'][0]" - ] + "outputs": [], + "source": [] }, { "cell_type": "code", @@ -1125,34 +1071,23 @@ }, { "cell_type": "code", - "execution_count": 264, + "execution_count": 85, "id": "d6d602c3-f543-4843-af8d-bfa13009f3e3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "DefaultContentPrediction(label=TextContent(type='TEXT', subclass=[]))" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# import uuid\n", - "\n", - "# def append_to_graph(layer_graphs, required_layers, G):\n", - "# layer_uuid = uuid.uuid4()\n", - " \n", - "# # Directly assign 'NEWS_STORIES' as category_name\n", - "# category_name = \"NEWS_STORIES\"\n", - " \n", - "# # Assuming 'required_layers' structure is as provided, extract 'News stories and blog posts' as the only subgroup\n", - "# # This assumes there's always at least one subclass and we're taking the first\n", - "# subgroup_name = 'News stories and blog posts'\n", - "\n", - "# for layer_decomposition in layer_graphs:\n", - "# print(layer_decomposition)\n", - "# layer_decomposition_uuid = uuid.uuid4()\n", - "\n", - "# # Assuming append_data_to_graph is defined elsewhere and appends data to G\n", - "# F = append_data_to_graph(G, category_name, subgroup_name, layer_decomposition, layer_uuid, layer_decomposition_uuid)\n", - " \n", - "# Print updated graph for verification\n", - "# print(\"Updated Nodes:\", F.nodes(data=True)) # Assuming F is a NetworkX Graph and you want to print node data\n", - "\n", - "# return F" + "required_layers_one" ] }, { @@ -1161,21 +1096,7 @@ "id": "66630223-3ba0-4384-95d2-df2995e15271", "metadata": {}, "outputs": [], - "source": [ - "# def append_to_graph(layer_graphs, required_layers, G):\n", - "# layer_uuid = uuid.uuid4()\n", - "# category_name = required_layers.dict()['name']\n", - "# subgroup_names = [subgroup['name'] for subgroup in required_layers.dict()['cognitive_subgroups']]\n", - "# for subgroup in subgroup_names:\n", - "\n", - "# for layer_decomposition in layer_graphs:\n", - "# layer_decomposition_uuid = uuid.uuid4()\n", - "# F = append_data_to_graph(G, category_name[0], subgroup, layer_decomposition, layer_uuid, layer_decomposition_uuid)\n", - " \n", - "# # Print updated graph for verification\n", - "# # print(\"Updated Nodes:\", F)\n", - "# return F\n" - ] + "source": [] }, { "cell_type": "code", diff --git a/cognitive_architecture/modules/cognify/graph/add_propositions.py b/cognitive_architecture/modules/cognify/graph/add_propositions.py index d64f347e5..ea7f3ab32 100644 --- a/cognitive_architecture/modules/cognify/graph/add_propositions.py +++ b/cognitive_architecture/modules/cognify/graph/add_propositions.py @@ -5,18 +5,20 @@ from enum import Enum, auto from typing import Type, Optional, Any from pydantic import BaseModel from cognitive_architecture.infrastructure.databases.graph.get_graph_client import get_graph_client -from cognitive_architecture.shared.data_models import GraphDBType, DefaultGraphModel, Document, DocumentType, Category, Relationship, UserProperties, UserLocation +from cognitive_architecture.modules.cognify.llm.content_to_propositions import generate_graph +from cognitive_architecture.shared.data_models import GraphDBType, DefaultGraphModel, Document, DocumentType, Category, \ + Relationship, UserProperties, UserLocation, KnowledgeGraph, TextSubclass, TextContent, DefaultContentPrediction -def add_propositions(G, category_name, subclass_content, layer_description, new_data, layer_uuid, +async def add_propositions(G, category_name, subclass_content, layer_description, new_data, layer_uuid, layer_decomposition_uuid): """ Add nodes and edges to the graph for the given LLM knowledge graph and the layer""" # Find the node ID for the subclass within the category - G.load_graph_from_file() - G = graph_client.graph + await G.load_graph_from_file() + subclass_node_id = None - for node, data in G.nodes(data=True): + for node, data in G.graph.nodes(data=True): if subclass_content in node: subclass_node_id = node @@ -33,7 +35,7 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_ for node in new_data.nodes: unique_node_id = uuid.uuid4() new_node_id = f"{node.description} - {str(layer_uuid)} - {str(layer_decomposition_uuid)} - {str(unique_node_id)}" - G.add_node(new_node_id, + await G.add_node(new_node_id, created_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), updated_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), description=node.description, @@ -42,9 +44,9 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_ layer_uuid=str(layer_uuid), layer_description=str(layer_description), layer_decomposition_uuid=str(layer_decomposition_uuid), - id=str(unique_node_id), + unique_id=str(unique_node_id), type='detail') - G.add_edge(subclass_node_id, new_node_id, relationship='detail') + await G.add_edge(subclass_node_id, new_node_id, relationship='detail') # Store the mapping from old node ID to new node ID node_id_mapping[node.id] = new_node_id @@ -56,7 +58,7 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_ target_node_id = node_id_mapping.get(edge.target) if source_node_id and target_node_id: - G.add_edge(source_node_id, target_node_id, description=edge.description, relationship='relation') + await G.add_edge(source_node_id, target_node_id, description=edge.description, relationship='relation') else: print(f"Could not find mapping for edge from {edge.source} to {edge.target}") @@ -68,30 +70,84 @@ def add_propositions(G, category_name, subclass_content, layer_description, new_ if __name__ == "__main__": import asyncio - # Assuming all necessary imports and GraphDBType, get_graph_client, Document, DocumentType, etc. are defined - - # Initialize the graph client - graph_client = get_graph_client(GraphDBType.NETWORKX) - G = asyncio.run(add_propositions(graph_client, 'category_name', 'subclass_content', 'layer_description', 'new_data', 'layer_uuid', - 'layer_decomposition_uuid')) - - - - - - - - - - - - - - -if __name__ == "__main__": - import asyncio # Assuming all necessary imports and GraphDBType, get_graph_client, Document, DocumentType, etc. are defined # Initialize the graph client graph_client = get_graph_client(GraphDBType.NETWORKX) + + from typing import List, Type + + + # Assuming generate_graph, KnowledgeGraph, and other necessary components are defined elsewhere + + async def generate_graphs_for_all_layers(text_input: str, layers: List[str], response_model: Type[BaseModel]): + tasks = [generate_graph(text_input, "generate_graph_prompt.txt", {'layer': layer}, response_model) for layer in + layers] + return await asyncio.gather(*tasks) + + + input_article_one= "The quick brown fox jumps over the lazy dog" + + + # Execute the async function and print results for each set of layers + async def async_graph_per_layer(text_input: str, cognitive_layers: List[str]): + graphs = await generate_graphs_for_all_layers(text_input, cognitive_layers, KnowledgeGraph) + # for layer, graph in zip(cognitive_layers, graphs): + # print(f"{layer}: {graph}") + return graphs + + cognitive_layers_one = ['Structural Layer', 'Semantic Layer', + 'Syntactic Layer', + 'Discourse Layer', + 'Pragmatic Layer', + 'Stylistic Layer', + 'Referential Layer', + 'Citation Layer', + 'Metadata Layer'] + required_layers_one = DefaultContentPrediction( + label=TextContent( + type='TEXT', + subclass=[TextSubclass.ARTICLES] + ) + ) + # Run the async function for each set of cognitive layers + level_1_graph = asyncio.run( async_graph_per_layer(input_article_one, cognitive_layers_one)) + import uuid + import json + + + async def append_to_graph(layer_graphs, required_layers, G): + # Generate a UUID for the overall layer + layer_uuid = uuid.uuid4() + + # Extract category name from required_layers data + category_name = required_layers.dict()['label']['type'] + + # Extract subgroup name from required_layers data + # Assuming there's always at least one subclass and we're taking the first + subgroup_name = required_layers.dict()['label']['subclass'][0].value # Access the value of the enum + + for layer_ind in layer_graphs: + + for layer_json, knowledge_graph in layer_ind.items(): + # Decode the JSON key to get the layer description + layer_description = json.loads(layer_json) + + # Generate a UUID for this particular layer decomposition + layer_decomposition_uuid = uuid.uuid4() + + # Assuming append_data_to_graph is defined elsewhere and appends data to G + # You would pass relevant information from knowledge_graph along with other details to this function + F = await add_propositions(G, category_name, subgroup_name, layer_description, knowledge_graph, + layer_uuid, layer_decomposition_uuid) + + # Print updated graph for verification (assuming F is the updated NetworkX Graph) + print("Updated Nodes:", F.graph.nodes(data=True)) + + return F + + G = asyncio.run(append_to_graph(level_1_graph, required_layers_one, graph_client)) + + +