diff --git a/CHANGELOG.md b/CHANGELOG.md index bc7bb47..2d03f0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## [1.2.0-beta.3](https://github.com/EURAC-EEBgroup/brick-llm/compare/v1.2.0-beta.2...v1.2.0-beta.3) (2024-11-11) + + +### Perf + +* add custom logging level ([82bead2](https://github.com/EURAC-EEBgroup/brick-llm/commit/82bead23929a23998f4d7504f31d83bf253927bf)) + +## [1.2.0-beta.2](https://github.com/EURAC-EEBgroup/brick-llm/compare/v1.2.0-beta.1...v1.2.0-beta.2) (2024-11-11) + + +### Bug Fixes + +* improved ttl description generation ([bf4bdae](https://github.com/EURAC-EEBgroup/brick-llm/commit/bf4bdaecca779ff835e2349bfcdff7a3d17ead0e)) + +## [1.2.0-beta.1](https://github.com/EURAC-EEBgroup/brick-llm/compare/v1.1.2...v1.2.0-beta.1) (2024-11-11) + + +### Features + +* ttl_to_building_description function ([d83e66f](https://github.com/EURAC-EEBgroup/brick-llm/commit/d83e66f5851a4db71825c925389d3183cb10faaf)) + + +### Docs + +* imporeved docs and ttl_output method ([24a7d8b](https://github.com/EURAC-EEBgroup/brick-llm/commit/24a7d8ba1d94fa25c0d6c5db33b38853bc2d5ff2)) + ## [1.1.2](https://github.com/EURAC-EEBgroup/brick-llm/compare/v1.1.1...v1.1.2) (2024-11-05) diff --git a/README.md b/README.md index 737ebfb..1ac0641 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ BrickLLM is a Python library for generating RDF files following the BrickSchema ontology using Large Language Models (LLMs). -## Features +## 🧰 Features - Generate BrickSchema-compliant RDF files from natural language descriptions of buildings and facilities - Support for multiple LLM providers (OpenAI, Anthropic, Fireworks) @@ -224,12 +224,12 @@ brick_graph_local.save_ttl_output("my_building_local.ttl") ## 📖 Documentation -For more detailed information on how to use BrickLLM, please refer to our [documentation](https://brickllm.com/docs). +For more detailed information on how to use BrickLLM, please refer to our [documentation](https://eurac-eebgroup.github.io/brick-llm/). ## ▶️ Web Application -A web app is available to use the library directly through an interface at the following link (). -The application can also be used locally as described in the dedicated repository [BrickLLM App](https://github.com/EURAC-EEBgroup/Brick_ontology_tool). +A web app is available to use the library directly through an interface at the following link (). +The application can also be used locally as described in the dedicated repository [BrickLLM App](https://github.com/EURAC-EEBgroup/Brick_ontology_tool). **Note**: The tool is currently being deployed on our servers and on the MODERATE platform. It will be online shortly ! @@ -241,7 +241,7 @@ We welcome contributions to BrickLLM! Please see our [contributing guidelines](C BrickLLM is released under the BSD-3-Clause License. See the [LICENSE](LICENSE) file for details. -## Contact +## 📧 Contact For any questions or support, please contact: @@ -249,17 +249,17 @@ For any questions or support, please contact: - Daniele Antonucci - Rocco Giudice -## Citation +## 📝 Citation Please cite us if you use the library - + [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14039358.svg)](https://zenodo.org/doi/10.5281/zenodo.14039358) -## 💙 Aknwoledegments -This work was carried out within European projects: +## 💙 Acknowledgements +This work was carried out within European projects:

- Moderate Moderate - Horizon Europe research and innovation programme under grant agreement No 101069834, with the aim of contributing to the development of open products useful for defining plausible scenarios for the decarbonization of the built environment diff --git a/brickllm/__init__.py b/brickllm/__init__.py index cdbd062..748d6b9 100644 --- a/brickllm/__init__.py +++ b/brickllm/__init__.py @@ -1,12 +1,20 @@ from .configs import GraphConfig -from .schemas import ElemListSchema, RelationshipsSchema, TTLSchema +from .logger import custom_logger +from .schemas import ( + ElemListSchema, + RelationshipsSchema, + TTLSchema, + TTLToBuildingPromptSchema, +) from .states import State, StateLocal __all__ = [ "ElemListSchema", "RelationshipsSchema", "TTLSchema", + "TTLToBuildingPromptSchema", "State", "StateLocal", "GraphConfig", + "custom_logger", ] diff --git a/brickllm/graphs/abstract_graph.py b/brickllm/graphs/abstract_graph.py index bde38c8..9268dec 100644 --- a/brickllm/graphs/abstract_graph.py +++ b/brickllm/graphs/abstract_graph.py @@ -1,12 +1,13 @@ import os from abc import ABC, abstractmethod -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Tuple, Union from langchain.chat_models.base import BaseChatModel from langgraph.graph import StateGraph from PIL import Image from ..helpers.llm_models import _get_model +from ..utils import ttl_to_building_prompt class AbstractBrickSchemaGraph(ABC): @@ -16,6 +17,9 @@ def __init__(self, model: Union[str, BaseChatModel] = "openai"): self.graph = None self.config = {"configurable": {"thread_id": "1", "llm_model": self.model}} self.result = None + self.ttl_output = None + self.generated_building_description = None + self.generated_key_elements = None @abstractmethod def build_graph(self): @@ -75,12 +79,16 @@ def save_ttl_output(self, output_file: str = "brick_schema_output.ttl") -> None: if self.result is None: raise ValueError("No result found. Please run the graph first.") - ttl_output = self.result.get("ttl_output", None) + if self.ttl_output is None: + raise ValueError("No TTL output found. Please run the graph first.") - if ttl_output: - with open(output_file, "w") as f: - f.write(ttl_output) - else: - raise ValueError( - "No TTL output found in the result. Please run the graph with a valid prompt." - ) + with open(output_file, "w") as f: + f.write(self.ttl_output) + + def ttl_to_building_description(self) -> Tuple[str, List[str]]: + if self.ttl_output is None: + raise ValueError("No TTL output found. Please run the graph first.") + self.generated_building_description, self.generated_key_elements = ( + ttl_to_building_prompt(self.ttl_output, self.model) + ) + return self.generated_building_description, self.generated_key_elements diff --git a/brickllm/graphs/brickschema_graph.py b/brickllm/graphs/brickschema_graph.py index 7e62c1a..1c9c960 100644 --- a/brickllm/graphs/brickschema_graph.py +++ b/brickllm/graphs/brickschema_graph.py @@ -56,7 +56,9 @@ def run( ): events.append(event) self.result = events[-1] + self.ttl_output = self.result.get("ttl_output", None) return events else: self.result = self.graph.invoke(input_data, self.config) + self.ttl_output = self.result.get("ttl_output", None) return self.result diff --git a/brickllm/graphs/brickschema_graph_local.py b/brickllm/graphs/brickschema_graph_local.py index 6301115..3b7a8bb 100644 --- a/brickllm/graphs/brickschema_graph_local.py +++ b/brickllm/graphs/brickschema_graph_local.py @@ -42,7 +42,9 @@ def run( ): events.append(event) self.result = events[-1] + self.ttl_output = self.result.get("ttl_output", None) return events else: self.result = self.graph.invoke(input_data, self.config) + self.ttl_output = self.result.get("ttl_output", None) return self.result diff --git a/brickllm/helpers/__init__.py b/brickllm/helpers/__init__.py index 5ab8e7d..12ec76c 100644 --- a/brickllm/helpers/__init__.py +++ b/brickllm/helpers/__init__.py @@ -6,6 +6,7 @@ prompt_template_local, schema_to_ttl_instructions, ttl_example, + ttl_to_user_prompt, ) __all__ = [ @@ -16,4 +17,5 @@ "schema_to_ttl_instructions", "ttl_example", "prompt_template_local", + "ttl_to_user_prompt", ] diff --git a/brickllm/helpers/prompts.py b/brickllm/helpers/prompts.py index 11a0bf5..158342d 100644 --- a/brickllm/helpers/prompts.py +++ b/brickllm/helpers/prompts.py @@ -9,7 +9,7 @@ You are now asked to identify the elements presents in the user prompt, even if not explicitly mentioned.\n USER PROMPT: {prompt} \n ELEMENTS: {elements_dict} \n - """ + """ # noqa get_elem_children_instructions: str = """ You are a BrickSchema ontology expert and you are provided with a user prompt which describes a building or facility.\n @@ -22,7 +22,7 @@ USER PROMPT: {prompt} \n ELEMENTS HIERARCHY: {elements_list} \n - """ + """ # noqa get_relationships_instructions: str = """ You are a BrickSchema ontology expert and are provided with a detailed description of a building or facility.\n @@ -35,7 +35,7 @@ If an element has no relationships, add an empty string in place of the missing component ("Room.1","").\n Hierarchical structure: {building_structure}\n USER PROMPT: {prompt} -""" +""" # noqa ttl_example: str = """ @prefix bldg: . @@ -84,7 +84,7 @@ bldg:livingroom a brick:Room ; brick:isPartOf bldg:Milano_Residence_1 . -""" +""" # noqa schema_to_ttl_instructions: str = """ You are a BrickSchema ontology expert and you are provided with a user prompt which describes a building or facility.\n @@ -102,7 +102,28 @@ USER DESCRIPTION: {prompt}\n COMPONENTS DICT: {sensors_dict}\n -""" +""" # noqa + +ttl_to_user_prompt: str = """ + You are a BrickSchema ontology expert tasked with generating a clear and concise description of a building or facility from a TTL script. + + Your output must follow these guidelines: + - Focus on the key building characteristics, components and relationships present in the TTL + - Maintain technical accuracy and use proper Brick terminology + - Keep descriptions clear and well-structured + - Only include information explicitly stated in the TTL script + - If no TTL content is provided, return an empty string + + Eventually, the user can provide additional instructions to help you generate the building description. + + {additional_instructions} + + + TTL script to analyze: + + {ttl_script} + +""" # noqa prompt_template_local: str = """ Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request. @@ -113,4 +134,4 @@ {user_prompt} ### Response: -""" +""" # noqa diff --git a/brickllm/logger.py b/brickllm/logger.py new file mode 100644 index 0000000..dc93b86 --- /dev/null +++ b/brickllm/logger.py @@ -0,0 +1,38 @@ +import logging + +# Create custom log level +EURAC_LEVEL = 25 +logging.addLevelName(EURAC_LEVEL, "EURAC") + + +def eurac(self, message, *args, **kwargs): + """ + Log with custom EURAC level + """ + if self.isEnabledFor(EURAC_LEVEL): + self._log(EURAC_LEVEL, message, args, **kwargs) + + +# Add eurac method to Logger class +logging.Logger.eurac = eurac + + +# Create and configure logger +def get_logger(name="BrickLLM"): + logger = logging.getLogger(name) + + # Create handler if none exists + if not logger.handlers: + handler = logging.StreamHandler() + formatter = logging.Formatter( + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) + handler.setFormatter(formatter) + logger.addHandler(handler) + + logger.setLevel(EURAC_LEVEL) + return logger + + +# Create default logger instance +custom_logger = get_logger() diff --git a/brickllm/nodes/generation_local.py b/brickllm/nodes/generation_local.py index 3c3d089..7a8a8e4 100644 --- a/brickllm/nodes/generation_local.py +++ b/brickllm/nodes/generation_local.py @@ -2,6 +2,7 @@ from .. import StateLocal from ..helpers import prompt_template_local +from ..logger import custom_logger from ..utils import extract_rdf_graph @@ -17,7 +18,7 @@ def generation_local(state: StateLocal, config: Dict[str, Any]) -> Dict[str, Any dict: A dictionary containing the output generated. """ - print("---One shot generation with local LLM Node---") + custom_logger.eurac("🤖 Starting one shot generation with local LLM") instructions = state["instructions"] user_prompt = state["user_prompt"] diff --git a/brickllm/nodes/get_elem_children.py b/brickllm/nodes/get_elem_children.py index 0c8c70b..bc383b4 100644 --- a/brickllm/nodes/get_elem_children.py +++ b/brickllm/nodes/get_elem_children.py @@ -4,6 +4,7 @@ from .. import ElemListSchema, State from ..helpers import get_elem_children_instructions +from ..logger import custom_logger from ..utils import create_hierarchical_dict, filter_elements, get_children_hierarchy @@ -18,7 +19,9 @@ def get_elem_children(state: State, config: Dict[str, Any]) -> Dict[str, Any]: Returns: dict: A dictionary containing the hierarchical structure of identified elements. """ - print("---Get Elem Children Node---") + custom_logger.eurac( + "📊 Getting children for each BrickSchema category in the element list" + ) user_prompt = state["user_prompt"] categories = state["elem_list"] diff --git a/brickllm/nodes/get_elements.py b/brickllm/nodes/get_elements.py index beb32d0..fc33b30 100644 --- a/brickllm/nodes/get_elements.py +++ b/brickllm/nodes/get_elements.py @@ -4,6 +4,7 @@ from .. import ElemListSchema, State from ..helpers import get_elem_instructions +from ..logger import custom_logger from ..utils import get_brick_definition, get_hierarchical_info @@ -19,7 +20,7 @@ def get_elements(state: State, config: Dict[str, Any]) -> Dict[str, Any]: Returns: dict: A dictionary containing the list of identified elements. """ - print("---Get Elements Node---") + custom_logger.eurac("🔍 Getting elements from user prompt") user_prompt = state["user_prompt"] diff --git a/brickllm/nodes/get_relationships.py b/brickllm/nodes/get_relationships.py index 81eb08b..70fb157 100644 --- a/brickllm/nodes/get_relationships.py +++ b/brickllm/nodes/get_relationships.py @@ -6,6 +6,7 @@ from .. import RelationshipsSchema, State from ..helpers import get_relationships_instructions +from ..logger import custom_logger from ..utils import build_hierarchy, find_sensor_paths @@ -20,7 +21,7 @@ def get_relationships(state: State, config: Dict[str, Any]) -> Dict[str, Any]: Returns: dict: A dictionary containing the grouped sensor paths. """ - print("---Get Relationships Node---") + custom_logger.eurac("🔗 Getting relationships between building components") user_prompt = state["user_prompt"] building_structure = state["elem_hierarchy"] diff --git a/brickllm/nodes/get_sensors.py b/brickllm/nodes/get_sensors.py index 0a386a4..ac6c207 100644 --- a/brickllm/nodes/get_sensors.py +++ b/brickllm/nodes/get_sensors.py @@ -1,6 +1,7 @@ from typing import Any, Dict from .. import State +from ..logger import custom_logger def get_sensors(state: State) -> Dict[str, Any]: @@ -13,7 +14,7 @@ def get_sensors(state: State) -> Dict[str, Any]: Returns: dict: A dictionary containing sensor UUIDs mapped to their locations. """ - print("---Get Sensor Node---") + custom_logger.eurac("📡 Getting sensors information") uuid_dict = { "Building#1>Floor#1>Office#1>Room#1": [ diff --git a/brickllm/nodes/schema_to_ttl.py b/brickllm/nodes/schema_to_ttl.py index 741a3e4..f9486b1 100644 --- a/brickllm/nodes/schema_to_ttl.py +++ b/brickllm/nodes/schema_to_ttl.py @@ -5,6 +5,7 @@ from .. import State, TTLSchema from ..helpers import schema_to_ttl_instructions, ttl_example +from ..logger import custom_logger def schema_to_ttl(state: State, config: Dict[str, Any]) -> Dict[str, Any]: @@ -18,7 +19,7 @@ def schema_to_ttl(state: State, config: Dict[str, Any]) -> Dict[str, Any]: Returns: dict: A dictionary containing the generated TTL output. """ - print("---Schema To TTL Node---") + custom_logger.eurac("📝 Generating TTL from schema") user_prompt = state["user_prompt"] sensors_dict = state["sensors_dict"] diff --git a/brickllm/nodes/validate_schema.py b/brickllm/nodes/validate_schema.py index 913f1d8..76d91d0 100644 --- a/brickllm/nodes/validate_schema.py +++ b/brickllm/nodes/validate_schema.py @@ -1,5 +1,6 @@ from typing import Any, Dict +from ..logger import custom_logger from ..utils import validate_ttl @@ -13,7 +14,7 @@ def validate_schema(state) -> Dict[str, Any]: Returns: dict: A dictionary containing the validation status and report. """ - print("---Validate Schema Node---") + custom_logger.eurac("✅ Validating TTL schema") ttl_output = state.get("ttl_output", None) max_iter = state.get("validation_max_iter", 2) diff --git a/brickllm/schemas.py b/brickllm/schemas.py index dd61887..5ba06b4 100644 --- a/brickllm/schemas.py +++ b/brickllm/schemas.py @@ -16,3 +16,12 @@ class TTLSchema(BaseModel): ttl_output: str = Field( ..., description="The generated BrickSchema turtle/rdf script." ) + + +class TTLToBuildingPromptSchema(BaseModel): + building_description: str = Field( + ..., description="The generated building description." + ) + key_elements: List[str] = Field( + ..., description="The generated list of key elements." + ) diff --git a/brickllm/utils/__init__.py b/brickllm/utils/__init__.py index 5524b11..a7bf289 100644 --- a/brickllm/utils/__init__.py +++ b/brickllm/utils/__init__.py @@ -22,6 +22,7 @@ validate_ttl, ) from .rdf_parser import extract_rdf_graph +from .ttl_to_prompt import ttl_to_building_prompt __all__ = [ "find_parents", @@ -44,4 +45,5 @@ "general_query", "validate_ttl", "extract_rdf_graph", + "ttl_to_building_prompt", ] diff --git a/brickllm/utils/ttl_to_prompt.py b/brickllm/utils/ttl_to_prompt.py new file mode 100644 index 0000000..5c280c5 --- /dev/null +++ b/brickllm/utils/ttl_to_prompt.py @@ -0,0 +1,35 @@ +import logging +from typing import List, Optional, Tuple, Union + +from langchain.chat_models.base import BaseChatModel +from langchain_community.llms import Ollama +from langchain_core.messages import HumanMessage, SystemMessage + +from ..helpers import ttl_to_user_prompt +from ..schemas import TTLToBuildingPromptSchema + +logger = logging.getLogger(__name__) + + +def ttl_to_building_prompt( + ttl_file: str, + llm: Union[Ollama, BaseChatModel], + additional_instructions: Optional[str] = None, +) -> Tuple[str, List[str]]: + + # Enforce structured output + structured_llm = llm.with_structured_output(TTLToBuildingPromptSchema) + + # System message + system_message = ttl_to_user_prompt.format( + ttl_script=ttl_file, additional_instructions=additional_instructions + ) + + logger.info("Generating building description and key elements from the TTL file.") + # Generate question + answer = structured_llm.invoke( + [SystemMessage(content=system_message)] + + [HumanMessage(content="Generate the TTL.")] + ) + + return answer.building_description, answer.key_elements diff --git a/examples/example_custom_llm.py b/examples/example_custom_llm.py index b548c58..6fa0231 100644 --- a/examples/example_custom_llm.py +++ b/examples/example_custom_llm.py @@ -34,3 +34,12 @@ # save the result to a file brick_graph.save_ttl_output("my_building_custom.ttl") + +# Generate the building description from the generated ttl file +building_description, key_elements = brick_graph.ttl_to_building_description() + +print("Generated building description:") +print(building_description) +print("--------------------------------") +print("Generated key elements:") +print(key_elements) diff --git a/examples/example_openai.py b/examples/example_openai.py index 9d8107d..d70c0b9 100644 --- a/examples/example_openai.py +++ b/examples/example_openai.py @@ -32,3 +32,12 @@ # save the result to a file brick_graph.save_ttl_output("my_building.ttl") + +# Generate the building description from the generated ttl file +building_description, key_elements = brick_graph.ttl_to_building_description() + +print("Generated building description:") +print(building_description) +print("--------------------------------") +print("Generated key elements:") +print(key_elements) diff --git a/examples/example_ttl_to_description.py b/examples/example_ttl_to_description.py new file mode 100644 index 0000000..8e40767 --- /dev/null +++ b/examples/example_ttl_to_description.py @@ -0,0 +1,32 @@ +import os + +from dotenv import load_dotenv +from langchain_openai import ChatOpenAI + +from brickllm.utils import ttl_to_building_prompt + +# Load environment variables +load_dotenv() + +# Create a custom model +custom_model = ChatOpenAI(temperature=0.8, model="gpt-4o") + +current_dir = os.path.dirname(os.path.abspath(__file__)) +file_name = "my_building.ttl" + +# Open the ttl file +with open(os.path.join(current_dir, file_name), "r") as file: + ttl_file = file.read() + +# Generate the building description from the ttl file +building_description, key_elements = ttl_to_building_prompt( + ttl_file, + custom_model, + additional_instructions="Keep a professional and structured tone.", +) + +print("Generated building description:") +print(building_description) +print("--------------------------------") +print("Generated key elements:") +print(key_elements) diff --git a/examples/my_building.ttl b/examples/my_building.ttl new file mode 100644 index 0000000..e3497bb --- /dev/null +++ b/examples/my_building.ttl @@ -0,0 +1,95 @@ +@prefix bldg: . +@prefix brick: . + +bldg:Bolzano_Building a brick:Building ; + brick:hasLocation [ brick:value "Bolzano" ] . + +bldg:Floor_1 a brick:Floor ; + brick:isPartOf bldg:Bolzano_Building . + +bldg:Floor_2 a brick:Floor ; + brick:isPartOf bldg:Bolzano_Building . + +bldg:Floor_3 a brick:Floor ; + brick:isPartOf bldg:Bolzano_Building . + +bldg:Office_1 a brick:Office ; + brick:isPartOf bldg:Floor_1 . + +bldg:Office_2 a brick:Office ; + brick:isPartOf bldg:Floor_2 . + +bldg:Office_3 a brick:Office ; + brick:isPartOf bldg:Floor_3 . + +bldg:Room_1 a brick:Room ; + brick:isPartOf bldg:Office_1 . + +bldg:Room_2 a brick:Room ; + brick:isPartOf bldg:Office_1 . + +bldg:Room_3 a brick:Room ; + brick:isPartOf bldg:Office_2 . + +bldg:Room_4 a brick:Room ; + brick:isPartOf bldg:Office_2 . + +bldg:Room_5 a brick:Room ; + brick:isPartOf bldg:Office_3 . + +bldg:Room_6 a brick:Room ; + brick:isPartOf bldg:Office_3 . + +bldg:Temperature_Sensor_1 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_1 . + +bldg:Humidity_Sensor_1 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_1 . + +bldg:CO_Sensor_1 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_1 . + +bldg:Temperature_Sensor_2 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_2 . + +bldg:Humidity_Sensor_2 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_2 . + +bldg:CO_Sensor_2 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_2 . + +bldg:Temperature_Sensor_3 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_3 . + +bldg:Humidity_Sensor_3 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_3 . + +bldg:CO_Sensor_3 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_3 . + +bldg:Temperature_Sensor_4 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_4 . + +bldg:Humidity_Sensor_4 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_4 . + +bldg:CO_Sensor_4 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_4 . + +bldg:Temperature_Sensor_5 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_5 . + +bldg:Humidity_Sensor_5 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_5 . + +bldg:CO_Sensor_5 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_5 . + +bldg:Temperature_Sensor_6 a brick:Temperature_Sensor ; + brick:isPointOf bldg:Room_6 . + +bldg:Humidity_Sensor_6 a brick:Humidity_Sensor ; + brick:isPointOf bldg:Room_6 . + +bldg:CO_Sensor_6 a brick:CO_Sensor ; + brick:isPointOf bldg:Room_6 . diff --git a/pyproject.toml b/pyproject.toml index f9cceeb..5389cd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "brickllm" -version = "1.1.2" +version = "1.2.0b3" description = "Library for generating RDF files following BrickSchema ontology using LLM" authors = ["Marco Perini ", "Daniele Antonucci "] license = "BSD-3-Clause"