From e020511876f3c0cd5dca1f412037a07bdc81f25e Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 10:58:21 -0300 Subject: [PATCH 1/6] replace surreal sdk with surreal-lite until they support v2 --- app_home.py | 18 +- database/0_0_1_to_0_0_2.surrealql | 77 +++++++ .../db_setup.surrealql | 22 +- open_notebook/domain.py | 99 +++------ open_notebook/exceptions.py | 6 + open_notebook/repository.py | 146 ++++++------- open_notebook/utils.py | 27 ++- poetry.lock | 191 ++++++++++-------- pyproject.toml | 2 +- 9 files changed, 331 insertions(+), 257 deletions(-) create mode 100644 database/0_0_1_to_0_0_2.surrealql rename db_setup.surrealql => database/db_setup.surrealql (91%) diff --git a/app_home.py b/app_home.py index 132a120..55f491e 100644 --- a/app_home.py +++ b/app_home.py @@ -1,19 +1,27 @@ import streamlit as st -from open_notebook.exceptions import InvalidDatabaseSchema +from open_notebook.exceptions import InvalidDatabaseSchema, NoSchemaFound from open_notebook.repository import check_version, execute_migration try: check_version() + st.switch_page("pages/2_📒_Notebooks.py") +except NoSchemaFound as e: + st.warning(e) + if st.button("Create Schema.."): + try: + execute_migration("db_setup.surrealql") + st.success("Schema created successfully") + st.rerun() + except Exception as e: + st.error(e) except InvalidDatabaseSchema as e: - st.error(e) + st.warning(e) if st.button("Execute Migration.."): try: - execute_migration() + execute_migration("0_0_1_to_0_0_2.surrealql") st.success("Migration executed successfully") st.rerun() except Exception as e: st.error(e) st.stop() - -st.switch_page("pages/2_📒_Notebooks.py") diff --git a/database/0_0_1_to_0_0_2.surrealql b/database/0_0_1_to_0_0_2.surrealql new file mode 100644 index 0000000..a4a94a0 --- /dev/null +++ b/database/0_0_1_to_0_0_2.surrealql @@ -0,0 +1,77 @@ + + +REMOVE TABLE IF EXISTS source_chunk; +REMOVE INDEX IF EXISTS idx_source_full ON TABLE source_chunk; + +DEFINE INDEX idx_source_full ON TABLE source_chunk COLUMNS content SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; + +REMOVE FUNCTION IF EXISTS fn::text_search; + +DEFINE FUNCTION IF NOT EXISTS fn::text_search($query_text: string, $match_count: int, $sources:bool, $show_notes:bool) { + + let $source_title_search = + IF $sources {( + SELECT id as item_id, math::max(search::score(1)) AS relevance + FROM source + WHERE title @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $source_embedding_search = + IF $sources {( + SELECT source as item_id, math::max(search::score(1)) AS relevance + FROM source_embedding + WHERE content @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $source_full_search = + IF $sources {( + SELECT source as item_id, math::max(search::score(1)) AS relevance + FROM source + WHERE full_text @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $source_insight_search = + IF $sources {( + SELECT source as item_id, math::max(search::score(1)) AS relevance + FROM source_insight + WHERE content @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $note_title_search = + IF $show_notes {( + SELECT id as item_id, math::max(search::score(1)) AS relevance + FROM note + WHERE title @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $note_content_search = + IF $show_notes {( + SELECT id as item_id, math::max(search::score(1)) AS relevance + FROM note + WHERE content @1@ $query_text + GROUP BY item_id)} + ELSE { [] }; + + let $source_chunk_results = array::union($source_embedding_search, $source_full_search); + + let $source_asset_results = array::union($source_title_search, $source_insight_search); + + let $source_results = array::union($source_chunk_results, $source_asset_results ); + let $note_results = array::union($note_title_search, $note_content_search ); + let $final_results = array::union($source_results, $note_results ); + + RETURN (SELECT item_id, math::max(relevance) as relevance from $final_results + group by item_id ORDER BY relevance DESC LIMIT $match_count); + + +}; + + + +UPDATE open_notebook:database_info SET + version= "0.0.2"; diff --git a/db_setup.surrealql b/database/db_setup.surrealql similarity index 91% rename from db_setup.surrealql rename to database/db_setup.surrealql index 0739e7d..ec00561 100644 --- a/db_setup.surrealql +++ b/database/db_setup.surrealql @@ -22,18 +22,12 @@ DEFINE FIELD asset FLEXIBLE TYPE option; DEFINE FIELD title ON TABLE source TYPE option; --- DEFINE FIELD summary ON TABLE source TYPE option; +DEFINE FIELD full_text ON TABLE source TYPE option; DEFINE FIELD topics ON TABLE source TYPE option>; DEFINE FIELD created ON source DEFAULT time::now() VALUE $before OR time::now(); DEFINE FIELD updated ON source DEFAULT time::now() VALUE time::now(); --- temporary while surreal doesn't fix the sdk -DEFINE TABLE IF NOT EXISTS source_chunk SCHEMAFULL; -DEFINE FIELD source ON TABLE source_chunk TYPE record; -DEFINE FIELD order ON TABLE source_chunk TYPE int; -DEFINE FIELD content ON TABLE source_chunk TYPE string; - DEFINE TABLE IF NOT EXISTS source_embedding SCHEMAFULL; DEFINE FIELD source ON TABLE source_embedding TYPE record; DEFINE FIELD order ON TABLE source_embedding TYPE int; @@ -77,7 +71,7 @@ FROM note TO notebook; DEFINE ANALYZER my_analyzer TOKENIZERS blank,class,camel,punct FILTERS snowball(english), lowercase; DEFINE INDEX idx_source_title ON TABLE source COLUMNS title SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; -DEFINE INDEX idx_source_full ON TABLE source_chunk COLUMNS content SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; +DEFINE INDEX idx_source_full_text ON TABLE source COLUMNS full_text SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; DEFINE INDEX idx_source_embed_chunk ON TABLE source_embedding COLUMNS content SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; DEFINE INDEX idx_source_insight ON TABLE source_insight COLUMNS content SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; DEFINE INDEX idx_note ON TABLE note COLUMNS content SEARCH ANALYZER my_analyzer BM25 HIGHLIGHTS; @@ -102,11 +96,11 @@ DEFINE FUNCTION IF NOT EXISTS fn::text_search($query_text: string, $match_count: GROUP BY item_id)} ELSE { [] }; - let $source_chunk_search = + let $source_full_search = IF $sources {( SELECT source as item_id, math::max(search::score(1)) AS relevance - FROM source_chunk - WHERE content @1@ $query_text + FROM source + WHERE full_text @1@ $query_text GROUP BY item_id)} ELSE { [] }; @@ -134,7 +128,7 @@ DEFINE FUNCTION IF NOT EXISTS fn::text_search($query_text: string, $match_count: GROUP BY item_id)} ELSE { [] }; - let $source_chunk_results = array::union($source_embedding_search, $source_chunk_search); + let $source_chunk_results = array::union($source_embedding_search, $source_full_search); let $source_asset_results = array::union($source_title_search, $source_insight_search); @@ -188,9 +182,9 @@ DEFINE FUNCTION IF NOT EXISTS fn::vector_search($query: array, $match_cou }; CREATE open_notebook:database_info SET - version= "0.0.1"; + version= "0.0.2"; UPDATE open_notebook:database_info SET - version= "0.0.1"; + version= "0.0.2"; diff --git a/open_notebook/domain.py b/open_notebook/domain.py index 5141a65..44c1fef 100644 --- a/open_notebook/domain.py +++ b/open_notebook/domain.py @@ -78,14 +78,14 @@ class ObjectModel(BaseModel): repo_result = repo_update(self.id, data) # Update the current instance with the result - for key, value in repo_result.items(): + for key, value in repo_result[0].items(): if hasattr(self, key): setattr(self, key, value) except Exception as e: logger.error(f"Error saving {self.__class__.table_name}: {str(e)}") logger.exception(e) - raise DatabaseOperationError(f"Failed to save {self.__class__.table_name}") + raise DatabaseOperationError(e) def _prepare_save_data(self) -> Dict[str, Any]: data = self.model_dump() @@ -109,14 +109,14 @@ class ObjectModel(BaseModel): ) def relate(self, relationship: str, target_id: str) -> Any: - if not relationship or not target_id: + if not relationship or not target_id or not self.id: raise InvalidInputError("Relationship and target ID must be provided") try: return repo_relate(self.id, relationship, target_id) except Exception as e: logger.error(f"Error creating relationship: {str(e)}") logger.exception(e) - raise DatabaseOperationError("Failed to create relationship") + raise DatabaseOperationError(e) class Notebook(ObjectModel): @@ -179,22 +179,13 @@ class SourceInsight(ObjectModel): insight_type: str content: str - @field_validator("insight_type") - @classmethod - def validate_insight_type(cls, v): - allowed_types = ["summary", "key_points", "analysis"] # Add more as needed - if v not in allowed_types: - raise InvalidInputError( - f"Invalid insight type. Allowed types are: {', '.join(allowed_types)}" - ) - return v - class Source(ObjectModel): table_name: ClassVar[str] = "source" asset: Optional[Asset] = None title: Optional[str] = None topics: Optional[List[str]] = Field(default_factory=list) + full_text: Optional[str] = None def get_context( self, context_size: Literal["short", "long"] = "short" @@ -213,10 +204,9 @@ class Source(ObjectModel): def insights(self) -> List[SourceInsight]: try: result = repo_query( + f""" + SELECT * FROM source_insight WHERE source={self.id} """ - SELECT * FROM source_insight WHERE source=$id - """, - {"id": self.id}, ) return [SourceInsight(**insight) for insight in result] except Exception as e: @@ -224,34 +214,6 @@ class Source(ObjectModel): logger.exception(e) raise DatabaseOperationError("Failed to fetch insights for source") - @property - def full_text(self) -> str: - try: - results = [] - chunk_indexes = repo_query( - """ - select order - from source_chunk - where source=$id - order by order - """, - {"id": self.id}, - ) - for chunk_index in chunk_indexes: - chunk = repo_query( - f""" - select content - from source_chunk - where source={self.id} and order={chunk_index['order']} - """ - ) - results.append(chunk[0]["content"]) - return "".join(results) - except Exception as e: - logger.error(f"Error fetching full text for source {self.id}: {str(e)}") - logger.exception(e) - raise DatabaseOperationError("Failed to fetch full text for source") - def add_to_notebook(self, notebook_id: str) -> Any: if not notebook_id: raise InvalidInputError("Notebook ID must be provided") @@ -265,14 +227,15 @@ class Source(ObjectModel): logger.debug(f"Split into {len(chunks)} chunks") for i, chunk in enumerate(chunks): logger.debug(f"Saving chunk {i}") + data = {"source": self.id, "order": i, "content": surreal_clean(chunk)} repo_create( "source_chunk", - {"source": self.id, "order": i, "content": surreal_clean(chunk)}, + data, ) except Exception as e: - logger.error(f"Error saving chunks for source {self.id}: {str(e)}") logger.exception(e) - raise DatabaseOperationError("Failed to save chunks for source") + logger.error(f"Error saving chunks for source {self.id}: {str(e)}") + raise DatabaseOperationError(e) def vectorize(self) -> None: try: @@ -288,14 +251,15 @@ class Source(ObjectModel): # future: we can increase the batch size after surreal launches their new SDK for i, chunk in enumerate(chunks): - repo_create( - "source_embedding", - { - "source": self.id, - "order": i, - "content": surreal_clean(chunk), - "embedding": get_embedding(chunk), - }, + repo_query( + f""" + CREATE source_embedding CONTENT {{ + "source": {self.id}, + "order": {i}, + "content": $content, + "embedding": {get_embedding(chunk)}, + }};""", + {"content": surreal_clean(chunk)}, ) except Exception as e: logger.error(f"Error vectorizing source {self.id}: {str(e)}") @@ -323,23 +287,24 @@ class Source(ObjectModel): logger.exception(e) raise DatabaseOperationError("Failed to search sources") - def _add_insight(self, insight_type: str, content: str) -> Any: + def add_insight(self, insight_type: str, content: str) -> Any: if not insight_type or not content: raise InvalidInputError("Insight type and content must be provided") try: embedding = get_embedding(content) - return repo_create( - "source_insight", - { - "source": self.id, - "insight_type": insight_type, - "content": surreal_clean(content), - "embedding": embedding, - }, + return repo_query( + f""" + CREATE source_insight CONTENT {{ + "source": {self.id}, + "insight_type": '{insight_type}', + "content": $content, + "embedding": {embedding}, + }};""", + {"content": surreal_clean(content)}, ) except Exception as e: logger.error(f"Error adding insight to source {self.id}: {str(e)}") - raise DatabaseOperationError("Failed to add insight to source") + raise DatabaseOperationError(e) def summarize(self) -> "Source": try: @@ -347,7 +312,7 @@ class Source(ObjectModel): result = summarizer.invoke({"content": self.full_text}, config=config)[ "output" ] - self._add_insight("summary", surreal_clean(result.summary)) + self.add_insight("summary", surreal_clean(result.summary)) self.title = surreal_clean(result.title) self.topics = result.topics self.save() diff --git a/open_notebook/exceptions.py b/open_notebook/exceptions.py index 7f7aaf5..4111399 100644 --- a/open_notebook/exceptions.py +++ b/open_notebook/exceptions.py @@ -10,6 +10,12 @@ class DatabaseOperationError(OpenNotebookError): pass +class NoSchemaFound(OpenNotebookError): + """Raised when a database schema is not found.""" + + pass + + class InvalidInputError(OpenNotebookError): """Raised when invalid input is provided.""" diff --git a/open_notebook/repository.py b/open_notebook/repository.py index d07ee9b..f14e5d1 100644 --- a/open_notebook/repository.py +++ b/open_notebook/repository.py @@ -1,51 +1,53 @@ -import asyncio import os -from contextlib import asynccontextmanager +from contextlib import contextmanager +from typing import Any, Dict, Optional from loguru import logger -from surrealdb import Surreal +from sblpy.connection import SurrealSyncConnection -from open_notebook.exceptions import InvalidDatabaseSchema +from open_notebook.exceptions import InvalidDatabaseSchema, NoSchemaFound -EXPECTED_VERSION = "0.0.1" +EXPECTED_VERSION = "0.0.2" -@asynccontextmanager -async def db_connection(): - db = Surreal(os.environ["SURREAL_ADDRESS"]) +@contextmanager +def db_connection(): + connection = SurrealSyncConnection( + host=os.environ["SURREAL_ADDRESS"], + port=8000, # Adjust this if your port is different + user=os.environ["SURREAL_USER"], + password=os.environ["SURREAL_PASS"], + namespace=os.environ["SURREAL_NAMESPACE"], + database=os.environ["SURREAL_DATABASE"], + encrypted=False, # Set to True if using SSL + ) try: - await db.connect() - await db.signin( - {"user": os.environ["SURREAL_USER"], "pass": os.environ["SURREAL_PASS"]} - ) - await db.use(os.environ["SURREAL_NAMESPACE"], os.environ["SURREAL_DATABASE"]) - yield db + yield connection finally: - await db.close() + connection.socket.close() -def repo_query(query_str, vars=None): - async def _query(): - async with db_connection() as db: - result = await db.query(query_str, vars) - return result - - result = asyncio.run(_query()) - return result[0]["result"] +def repo_query(query_str: str, vars: Optional[Dict[str, Any]] = None): + with db_connection() as connection: + try: + result = connection.query(query_str, vars) + return result + except Exception as e: + # logger.debug(f"Query: {query_str}, Variables: {vars}") + logger.exception(e) + raise def check_version(): - async def _check_version(): - async with db_connection() as db: - result = await db.query("select * from open_notebook:database_info;") - return result - try: - result = asyncio.run(_check_version()) - if len(result) == 0 or len(result[0]["result"]) == 0: - raise InvalidDatabaseSchema("Database schema not found") - version = result[0]["result"][0]["version"] + result = repo_query("SELECT * FROM open_notebook:database_info;") + + if not result: + raise NoSchemaFound("Database schema not found") + + version = result[0]["version"] logger.info(f"Connected to SurrealDB, using schema version {version}") + if version != EXPECTED_VERSION: raise InvalidDatabaseSchema( f"Version mismatch. Expected {EXPECTED_VERSION}, got {version}" @@ -55,55 +57,41 @@ def check_version(): raise e -def repo_create(table, data): - async def _create(): - async with db_connection() as db: - result = await db.create(table, data) - return result +def repo_create(table: str, data: Dict[str, Any]): + query = f"CREATE {table} CONTENT {data};" + # vars = {"table": table, "data": data} + return repo_query(query) - result = asyncio.run(_create()) + +def repo_update(id: str, data: Dict[str, Any]): + query = "UPDATE $id CONTENT $data;" + vars = {"id": id, "data": data} + return repo_query(query, vars) + + +def repo_delete(id: str): + query = "DELETE $id;" + vars = {"id": id} + return repo_query(query, vars) + + +def repo_relate(source: str, relationship: str, target: str): + query = f"RELATE {source}->{relationship}->{target}" + # CONTENT $content;" + # vars = { + # "source": source, + # "relationship": relationship, + # "target": target, + # # "content": {}, # You can add properties to the relation here if needed + # } + logger.debug(f"Executing RELATE query: {query}") + result = repo_query(query) + logger.debug(f"RELATE query result: {result}") return result -def repo_update(id, data): - async def _update(): - async with db_connection() as db: - result = await db.update(id, data) - return result +def execute_migration(script: str): + with open(f"database/{script}", "r") as file: + content = file.read() - result = asyncio.run(_update()) - return result - - -def repo_delete(id): - async def _delete(): - async with db_connection() as db: - result = await db.delete(id) - return result - - result = asyncio.run(_delete()) - return result - - -def repo_relate(source, relationship, target): - async def _relate(): - async with db_connection() as db: - query = f"RELATE {source}->{relationship}->{target};" - result = await db.query(query) - return result - - result = asyncio.run(_relate()) - return result - - -def execute_migration(): - async def _query(): - content = None - with open("db_setup.surrealql", "r") as file: - content = file.read() - async with db_connection() as db: - result = await db.query(content) - return result - - result = asyncio.run(_query()) - return result[0]["result"] + return repo_query(content) diff --git a/open_notebook/utils.py b/open_notebook/utils.py index 830386f..0a4c555 100644 --- a/open_notebook/utils.py +++ b/open_notebook/utils.py @@ -1,3 +1,6 @@ +import re +import string + from langchain_text_splitters import CharacterTextSplitter from openai import OpenAI @@ -70,14 +73,32 @@ def get_embedding(text, model="text-embedding-3-small"): return client.embeddings.create(input=[text], model=model).data[0].embedding +def remove_non_ascii(text): + return re.sub(r"[^\x00-\x7F]+", "", text) + + +def remove_non_printable(text): + return "".join(filter(lambda x: x in string.printable, text)) + + def surreal_clean(text): """ - Clean the input text by escaping colons for SurrealDB compatibility. + Clean the input text by removing non-ASCII and non-printable characters, + and adjusting colon placement for SurrealDB compatibility. Args: text (str): The input text to clean. Returns: - str: The cleaned text with escaped colons. + str: The cleaned text with adjusted formatting. """ - text = text.replace(":", "\:") + text = remove_non_printable(remove_non_ascii(text)) + + # Add space after colon if it's before the first space + first_space_index = text.find(" ") + colon_index = text.find(":") + if colon_index != -1 and ( + first_space_index == -1 or colon_index < first_space_index + ): + text = text.replace(":", "\:", 1) + return text diff --git a/poetry.lock b/poetry.lock index 28940ac..61be11c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3974,6 +3974,20 @@ files = [ {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, ] +[[package]] +name = "sdblpy" +version = "0.3.0" +description = "lite surrealDB client that only supports websocket raw queries and async pooled connections" +optional = false +python-versions = "*" +files = [ + {file = "sdblpy-0.3.0-py3-none-any.whl", hash = "sha256:a5b963556d7979fab567fe91ac48916affdd9fdf916ca18b90224ebad2a8e01b"}, + {file = "sdblpy-0.3.0.tar.gz", hash = "sha256:4d90803cff46c7472497a10c5de1d7fa09f130d012b74c7b2365b809475189d9"}, +] + +[package.dependencies] +websockets = "13.1" + [[package]] name = "shapely" version = "2.0.6" @@ -4256,22 +4270,6 @@ files = [ [package.dependencies] streamlit = ">=0.63" -[[package]] -name = "surrealdb" -version = "0.3.2" -description = "The official SurrealDB library for Python." -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "surrealdb-0.3.2-py3-none-any.whl", hash = "sha256:30424971be9698f0fce61dc8387576d19302e0bb0ae708d311e79a261ead7701"}, - {file = "surrealdb-0.3.2.tar.gz", hash = "sha256:8ab570b8d4299f35443f0d4fa636947cf1a18f67fd88acc00e5e5a36356e82cd"}, -] - -[package.dependencies] -httpx = ">=0.23.0" -pydantic = ">=2.1.0,<3.0.0" -websockets = ">=10.4,<11.0" - [[package]] name = "tenacity" version = "9.0.0" @@ -4646,80 +4644,97 @@ files = [ [[package]] name = "websockets" -version = "10.4" +version = "13.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "websockets-10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d58804e996d7d2307173d56c297cf7bc132c52df27a3efaac5e8d43e36c21c48"}, - {file = "websockets-10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc0b82d728fe21a0d03e65f81980abbbcb13b5387f733a1a870672c5be26edab"}, - {file = "websockets-10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba089c499e1f4155d2a3c2a05d2878a3428cf321c848f2b5a45ce55f0d7d310c"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33d69ca7612f0ddff3316b0c7b33ca180d464ecac2d115805c044bf0a3b0d032"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62e627f6b6d4aed919a2052efc408da7a545c606268d5ab5bfab4432734b82b4"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ea7b82bfcae927eeffc55d2ffa31665dc7fec7b8dc654506b8e5a518eb4d50"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e0cb5cc6ece6ffa75baccfd5c02cffe776f3f5c8bf486811f9d3ea3453676ce8"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae5e95cfb53ab1da62185e23b3130e11d64431179debac6dc3c6acf08760e9b1"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7c584f366f46ba667cfa66020344886cf47088e79c9b9d39c84ce9ea98aaa331"}, - {file = "websockets-10.4-cp310-cp310-win32.whl", hash = "sha256:b029fb2032ae4724d8ae8d4f6b363f2cc39e4c7b12454df8df7f0f563ed3e61a"}, - {file = "websockets-10.4-cp310-cp310-win_amd64.whl", hash = "sha256:8dc96f64ae43dde92530775e9cb169979f414dcf5cff670455d81a6823b42089"}, - {file = "websockets-10.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47a2964021f2110116cc1125b3e6d87ab5ad16dea161949e7244ec583b905bb4"}, - {file = "websockets-10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e789376b52c295c4946403bd0efecf27ab98f05319df4583d3c48e43c7342c2f"}, - {file = "websockets-10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d3f0b61c45c3fa9a349cf484962c559a8a1d80dae6977276df8fd1fa5e3cb8c"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f55b5905705725af31ccef50e55391621532cd64fbf0bc6f4bac935f0fccec46"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00c870522cdb69cd625b93f002961ffb0c095394f06ba8c48f17eef7c1541f96"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f38706e0b15d3c20ef6259fd4bc1700cd133b06c3c1bb108ffe3f8947be15fa"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f2c38d588887a609191d30e902df2a32711f708abfd85d318ca9b367258cfd0c"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fe10ddc59b304cb19a1bdf5bd0a7719cbbc9fbdd57ac80ed436b709fcf889106"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:90fcf8929836d4a0e964d799a58823547df5a5e9afa83081761630553be731f9"}, - {file = "websockets-10.4-cp311-cp311-win32.whl", hash = "sha256:b9968694c5f467bf67ef97ae7ad4d56d14be2751000c1207d31bf3bb8860bae8"}, - {file = "websockets-10.4-cp311-cp311-win_amd64.whl", hash = "sha256:a7a240d7a74bf8d5cb3bfe6be7f21697a28ec4b1a437607bae08ac7acf5b4882"}, - {file = "websockets-10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:74de2b894b47f1d21cbd0b37a5e2b2392ad95d17ae983e64727e18eb281fe7cb"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3a686ecb4aa0d64ae60c9c9f1a7d5d46cab9bfb5d91a2d303d00e2cd4c4c5cc"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d15c968ea7a65211e084f523151dbf8ae44634de03c801b8bd070b74e85033"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00213676a2e46b6ebf6045bc11d0f529d9120baa6f58d122b4021ad92adabd41"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e23173580d740bf8822fd0379e4bf30aa1d5a92a4f252d34e893070c081050df"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:dd500e0a5e11969cdd3320935ca2ff1e936f2358f9c2e61f100a1660933320ea"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4239b6027e3d66a89446908ff3027d2737afc1a375f8fd3eea630a4842ec9a0c"}, - {file = "websockets-10.4-cp37-cp37m-win32.whl", hash = "sha256:8a5cc00546e0a701da4639aa0bbcb0ae2bb678c87f46da01ac2d789e1f2d2038"}, - {file = "websockets-10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:a9f9a735deaf9a0cadc2d8c50d1a5bcdbae8b6e539c6e08237bc4082d7c13f28"}, - {file = "websockets-10.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c1289596042fad2cdceb05e1ebf7aadf9995c928e0da2b7a4e99494953b1b94"}, - {file = "websockets-10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0cff816f51fb33c26d6e2b16b5c7d48eaa31dae5488ace6aae468b361f422b63"}, - {file = "websockets-10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dd9becd5fe29773d140d68d607d66a38f60e31b86df75332703757ee645b6faf"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45ec8e75b7dbc9539cbfafa570742fe4f676eb8b0d3694b67dabe2f2ceed8aa6"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f72e5cd0f18f262f5da20efa9e241699e0cf3a766317a17392550c9ad7b37d8"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:185929b4808b36a79c65b7865783b87b6841e852ef5407a2fb0c03381092fa3b"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d27a7e34c313b3a7f91adcd05134315002aaf8540d7b4f90336beafaea6217c"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:884be66c76a444c59f801ac13f40c76f176f1bfa815ef5b8ed44321e74f1600b"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:931c039af54fc195fe6ad536fde4b0de04da9d5916e78e55405436348cfb0e56"}, - {file = "websockets-10.4-cp38-cp38-win32.whl", hash = "sha256:db3c336f9eda2532ec0fd8ea49fef7a8df8f6c804cdf4f39e5c5c0d4a4ad9a7a"}, - {file = "websockets-10.4-cp38-cp38-win_amd64.whl", hash = "sha256:48c08473563323f9c9debac781ecf66f94ad5a3680a38fe84dee5388cf5acaf6"}, - {file = "websockets-10.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:40e826de3085721dabc7cf9bfd41682dadc02286d8cf149b3ad05bff89311e4f"}, - {file = "websockets-10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56029457f219ade1f2fc12a6504ea61e14ee227a815531f9738e41203a429112"}, - {file = "websockets-10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5fc088b7a32f244c519a048c170f14cf2251b849ef0e20cbbb0fdf0fdaf556f"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc8709c00704194213d45e455adc106ff9e87658297f72d544220e32029cd3d"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0154f7691e4fe6c2b2bc275b5701e8b158dae92a1ab229e2b940efe11905dff4"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c6d2264f485f0b53adf22697ac11e261ce84805c232ed5dbe6b1bcb84b00ff0"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9bc42e8402dc5e9905fb8b9649f57efcb2056693b7e88faa8fb029256ba9c68c"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:edc344de4dac1d89300a053ac973299e82d3db56330f3494905643bb68801269"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:84bc2a7d075f32f6ed98652db3a680a17a4edb21ca7f80fe42e38753a58ee02b"}, - {file = "websockets-10.4-cp39-cp39-win32.whl", hash = "sha256:c94ae4faf2d09f7c81847c63843f84fe47bf6253c9d60b20f25edfd30fb12588"}, - {file = "websockets-10.4-cp39-cp39-win_amd64.whl", hash = "sha256:bbccd847aa0c3a69b5f691a84d2341a4f8a629c6922558f2a70611305f902d74"}, - {file = "websockets-10.4-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:82ff5e1cae4e855147fd57a2863376ed7454134c2bf49ec604dfe71e446e2193"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d210abe51b5da0ffdbf7b43eed0cfdff8a55a1ab17abbec4301c9ff077dd0342"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:942de28af58f352a6f588bc72490ae0f4ccd6dfc2bd3de5945b882a078e4e179"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b27d6c1c6cd53dc93614967e9ce00ae7f864a2d9f99fe5ed86706e1ecbf485"}, - {file = "websockets-10.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:3d3cac3e32b2c8414f4f87c1b2ab686fa6284a980ba283617404377cd448f631"}, - {file = "websockets-10.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:da39dd03d130162deb63da51f6e66ed73032ae62e74aaccc4236e30edccddbb0"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389f8dbb5c489e305fb113ca1b6bdcdaa130923f77485db5b189de343a179393"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09a1814bb15eff7069e51fed0826df0bc0702652b5cb8f87697d469d79c23576"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff64a1d38d156d429404aaa84b27305e957fd10c30e5880d1765c9480bea490f"}, - {file = "websockets-10.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b343f521b047493dc4022dd338fc6db9d9282658862756b4f6fd0e996c1380e1"}, - {file = "websockets-10.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:932af322458da7e4e35df32f050389e13d3d96b09d274b22a7aa1808f292fee4"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a4162139374a49eb18ef5b2f4da1dd95c994588f5033d64e0bbfda4b6b6fcf"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c57e4c1349fbe0e446c9fa7b19ed2f8a4417233b6984277cce392819123142d3"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b627c266f295de9dea86bd1112ed3d5fafb69a348af30a2422e16590a8ecba13"}, - {file = "websockets-10.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:05a7233089f8bd355e8cbe127c2e8ca0b4ea55467861906b80d2ebc7db4d6b72"}, - {file = "websockets-10.4.tar.gz", hash = "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3"}, + {file = "websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee"}, + {file = "websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7"}, + {file = "websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6"}, + {file = "websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b"}, + {file = "websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa"}, + {file = "websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700"}, + {file = "websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c"}, + {file = "websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0"}, + {file = "websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f"}, + {file = "websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe"}, + {file = "websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a"}, + {file = "websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19"}, + {file = "websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5"}, + {file = "websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd"}, + {file = "websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02"}, + {file = "websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7"}, + {file = "websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096"}, + {file = "websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084"}, + {file = "websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3"}, + {file = "websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9"}, + {file = "websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f"}, + {file = "websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557"}, + {file = "websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc"}, + {file = "websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49"}, + {file = "websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf"}, + {file = "websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c"}, + {file = "websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3"}, + {file = "websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6"}, + {file = "websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708"}, + {file = "websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418"}, + {file = "websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a"}, + {file = "websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f"}, + {file = "websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5"}, + {file = "websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135"}, + {file = "websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2"}, + {file = "websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6"}, + {file = "websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d"}, + {file = "websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2"}, + {file = "websockets-13.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d"}, + {file = "websockets-13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23"}, + {file = "websockets-13.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c"}, + {file = "websockets-13.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea"}, + {file = "websockets-13.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7"}, + {file = "websockets-13.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54"}, + {file = "websockets-13.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db"}, + {file = "websockets-13.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295"}, + {file = "websockets-13.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96"}, + {file = "websockets-13.1-cp38-cp38-win32.whl", hash = "sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf"}, + {file = "websockets-13.1-cp38-cp38-win_amd64.whl", hash = "sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6"}, + {file = "websockets-13.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d"}, + {file = "websockets-13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7"}, + {file = "websockets-13.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a"}, + {file = "websockets-13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa"}, + {file = "websockets-13.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa"}, + {file = "websockets-13.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79"}, + {file = "websockets-13.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17"}, + {file = "websockets-13.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6"}, + {file = "websockets-13.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5"}, + {file = "websockets-13.1-cp39-cp39-win32.whl", hash = "sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c"}, + {file = "websockets-13.1-cp39-cp39-win_amd64.whl", hash = "sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d"}, + {file = "websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238"}, + {file = "websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5"}, + {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9"}, + {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6"}, + {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a"}, + {file = "websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23"}, + {file = "websockets-13.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b"}, + {file = "websockets-13.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51"}, + {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7"}, + {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d"}, + {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027"}, + {file = "websockets-13.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978"}, + {file = "websockets-13.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e"}, + {file = "websockets-13.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09"}, + {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842"}, + {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb"}, + {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20"}, + {file = "websockets-13.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678"}, + {file = "websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f"}, + {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"}, ] [[package]] @@ -4868,4 +4883,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "f40348a4e1846cdbdd353c3c9de37e7b652a561c2374dec9899cf77778686ded" +content-hash = "eb5762f3ce3c19b2d51f5aaadcf52a89160f0792534aa83812f50770986f8ba4" diff --git a/pyproject.toml b/pyproject.toml index d219602..1babb6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,6 @@ pymupdf = "1.24.11" python-magic = "^0.4.27" langdetect = "^1.0.9" youtube-transcript-api = "^0.6.2" -surrealdb = "^0.3.2" openai = "^1.52.0" pre-commit = "^4.0.1" langchain-community = "^0.3.3" @@ -39,6 +38,7 @@ langchain-openai = "^0.2.3" langchain-anthropic = "^0.2.3" langchain-ollama = "^0.2.0" langchain-google-vertexai = "^2.0.5" +sdblpy = "^0.3.0" [tool.poetry.group.dev.dependencies] ipykernel = "^6.29.5" From 02ff05b6fd1ddff97af3fec3bcd542cc86e8a8b6 Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 10:59:05 -0300 Subject: [PATCH 2/6] v1 of transformations --- open_notebook/graphs/multipattern.py | 66 ++++++++++++++ open_notebook/graphs/pattern.py | 35 ++++++++ open_notebook/graphs/summary.py | 1 - open_notebook/prompter.py | 10 ++- prompts/patterns/analyze_paper.jinja | 42 +++++++++ prompts/patterns/cleanup.jinja | 6 ++ prompts/patterns/common_text.jinja | 4 + prompts/patterns/custom.jinja | 9 ++ prompts/patterns/keyinsights.jinja | 30 +++++++ prompts/patterns/makeitdense.jinja | 16 ++++ prompts/patterns/mermaid.jinja | 29 +++++++ prompts/patterns/reflection_questions.jinja | 28 ++++++ prompts/patterns/summarize.jinja | 16 ++++ prompts/patterns/translate.jinja | 6 ++ stream_app/source.py | 96 +++++++++++++-------- transformations.yaml | 35 ++++++++ 16 files changed, 389 insertions(+), 40 deletions(-) create mode 100644 open_notebook/graphs/multipattern.py create mode 100644 open_notebook/graphs/pattern.py create mode 100644 prompts/patterns/analyze_paper.jinja create mode 100644 prompts/patterns/cleanup.jinja create mode 100644 prompts/patterns/common_text.jinja create mode 100644 prompts/patterns/custom.jinja create mode 100644 prompts/patterns/keyinsights.jinja create mode 100644 prompts/patterns/makeitdense.jinja create mode 100644 prompts/patterns/mermaid.jinja create mode 100644 prompts/patterns/reflection_questions.jinja create mode 100644 prompts/patterns/summarize.jinja create mode 100644 prompts/patterns/translate.jinja create mode 100644 transformations.yaml diff --git a/open_notebook/graphs/multipattern.py b/open_notebook/graphs/multipattern.py new file mode 100644 index 0000000..6409775 --- /dev/null +++ b/open_notebook/graphs/multipattern.py @@ -0,0 +1,66 @@ +import operator +import os +from typing import List, Literal, Sequence + +from langchain_core.runnables import ( + RunnableConfig, +) +from langgraph.graph import END, START, StateGraph +from loguru import logger +from typing_extensions import Annotated, TypedDict + +from open_notebook.graphs.utils import run_pattern + + +class PatternChainState(TypedDict): + content_stack: Annotated[Sequence[str], operator.add] + transformations: List[str] + output: str + + +def call_model(state: dict, config: RunnableConfig) -> dict: + model_name = config.get("configurable", {}).get( + "model_name", os.environ.get("DEFAULT_MODEL") + ) + transformations = state["transformations"] + current_transformation = transformations.pop(0) + if current_transformation.startswith("patterns/"): + input_args = {"input_text": state["content_stack"][-1]} + else: + input_args = { + "input_text": state["content_stack"][-1], + "command": current_transformation, + } + current_transformation = "patterns/custom" + + logger.warning(f"Processing transformation: {current_transformation}") + logger.debug(f"Using input: {input_args}") + transformation_result = run_pattern( + pattern_name=current_transformation, + model_name=model_name, + state=input_args, + ) + return { + "content_stack": [transformation_result.content], + "output": transformation_result.content, + "transformations": state["transformations"], + } + + +def transform_condition(state: PatternChainState) -> Literal["agent", END]: # type: ignore + """ + Checks whether there are more chunks to process. + """ + if len(state["transformations"]) > 0: + return "agent" + return END + + +agent_state = StateGraph(PatternChainState) +agent_state.add_node("agent", call_model) +agent_state.add_edge(START, "agent") +agent_state.add_conditional_edges( + "agent", + transform_condition, +) +graph = agent_state.compile() diff --git a/open_notebook/graphs/pattern.py b/open_notebook/graphs/pattern.py new file mode 100644 index 0000000..b7a9bd0 --- /dev/null +++ b/open_notebook/graphs/pattern.py @@ -0,0 +1,35 @@ +import os + +from langchain_core.runnables import ( + RunnableConfig, +) +from langgraph.graph import END, START, StateGraph +from typing_extensions import TypedDict + +from open_notebook.graphs.utils import run_pattern + + +class PatternState(TypedDict): + input_text: str + pattern: str + output: str + + +def call_model(state: dict, config: RunnableConfig) -> dict: + model_name = config.get("configurable", {}).get( + "model_name", os.environ.get("DEFAULT_MODEL") + ) + return { + "output": run_pattern( + pattern_name=state["pattern"], + model_name=model_name, + state=state, + ) + } + + +agent_state = StateGraph(PatternState) +agent_state.add_node("agent", call_model) +agent_state.add_edge(START, "agent") +agent_state.add_edge("agent", END) +graph = agent_state.compile() diff --git a/open_notebook/graphs/summary.py b/open_notebook/graphs/summary.py index 27d6396..a262c5e 100644 --- a/open_notebook/graphs/summary.py +++ b/open_notebook/graphs/summary.py @@ -57,7 +57,6 @@ def chunk_condition(state: SummaryState) -> Literal["get_chunk", END]: # type: return END -# todo: build a helper method for LLM communication on all graphs def call_model(state: SummaryState, config: RunnableConfig) -> dict: model_name = config.get("configurable", {}).get( "model_name", os.environ.get("SUMMARIZATION_MODEL") diff --git a/open_notebook/prompter.py b/open_notebook/prompter.py index fc10679..12d6971 100644 --- a/open_notebook/prompter.py +++ b/open_notebook/prompter.py @@ -9,7 +9,15 @@ from typing import Any, Optional, Union from jinja2 import Environment, FileSystemLoader, Template -env = Environment(loader=FileSystemLoader(os.environ.get("PROMPT_PATH", "prompts"))) +current_dir = os.path.dirname(os.path.abspath(__file__)) + +project_root = os.path.dirname(current_dir) + +env = Environment( + loader=FileSystemLoader( + os.path.join(project_root, os.environ.get("PROMPT_PATH", "prompts")) + ) +) @dataclass diff --git a/prompts/patterns/analyze_paper.jinja b/prompts/patterns/analyze_paper.jinja new file mode 100644 index 0000000..b50c2d4 --- /dev/null +++ b/prompts/patterns/analyze_paper.jinja @@ -0,0 +1,42 @@ +{% include 'patterns/common_text.jinja' %} + +# IDENTITY and PURPOSE + +You are an insightful and analytical reader of academic papers, extracting the key components, significance, and broader implications. Your focus is to uncover the core contributions, practical applications, methodological strengths or weaknesses, and any surprising findings. You are especially attuned to the clarity of arguments, the relevance to existing literature, and potential impacts on both the specific field and broader contexts. + +# STEPS + +1. **READ AND UNDERSTAND THE PAPER**: Thoroughly read the paper, identifying its main focus, arguments, methods, results, and conclusions. + +2. **IDENTIFY CORE ELEMENTS**: + - **Purpose**: What is the main goal or research question? + - **Contribution**: What new knowledge or innovation does this paper bring to the field? + - **Methods**: What methods are used, and are they novel or particularly effective? + - **Key Findings**: What are the most critical results, and why do they matter? + - **Limitations**: Are there any notable limitations or areas for further research? + +3. **SYNTHESIZE THE MAIN POINTS**: + - Extract the key elements and organize them into insightful observations. + - Highlight the broader impact and potential applications. + - Note any aspects that challenge established views or introduce new questions. + +# OUTPUT INSTRUCTIONS + +- Structure the output as follows: + - **PURPOSE**: A concise summary of the main research question or goal (1-2 sentences). + - **CONTRIBUTION**: A bullet list of 2-3 points that describe what the paper adds to the field. + - **KEY FINDINGS**: A bullet list of 2-3 points summarizing the critical outcomes of the study. + - **IMPLICATIONS**: A bullet list of 2-3 points discussing the significance or potential impact of the findings on the field or broader context. + - **LIMITATIONS**: A bullet list of 1-2 points identifying notable limitations or areas for future work. + +- **Bullet Points** should be between 15-20 words. +- Avoid starting each bullet point with the same word to maintain variety. +- Use clear and concise language that conveys the key ideas effectively. +- Do not include warnings, disclaimers, or personal opinions. +- Output only the requested sections with their respective labels. + +# INPUT + +{{input_text}} + +# OUTPUT \ No newline at end of file diff --git a/prompts/patterns/cleanup.jinja b/prompts/patterns/cleanup.jinja new file mode 100644 index 0000000..2b0a3c3 --- /dev/null +++ b/prompts/patterns/cleanup.jinja @@ -0,0 +1,6 @@ +{% include 'patterns/common_text.jinja' %} + +Please clean-up the following text, fixing the paragraphs, ponctuation, etc. +If you find any word or name mispellings, feel free to correct. + +{{input_text}} diff --git a/prompts/patterns/common_text.jinja b/prompts/patterns/common_text.jinja new file mode 100644 index 0000000..8b95af7 --- /dev/null +++ b/prompts/patterns/common_text.jinja @@ -0,0 +1,4 @@ +# ADDITIONAL INSTRUCTIONS + +- You are working on my editorial projects. The text below is my own. +- Please do not reply with any acknowledgements or greetings, just provide the content requested. diff --git a/prompts/patterns/custom.jinja b/prompts/patterns/custom.jinja new file mode 100644 index 0000000..2f0dc7b --- /dev/null +++ b/prompts/patterns/custom.jinja @@ -0,0 +1,9 @@ +{% include 'patterns/common_text.jinja' %} + +{{command}} + +# INPUT + +{{input_text}} + +# OUTPUT diff --git a/prompts/patterns/keyinsights.jinja b/prompts/patterns/keyinsights.jinja new file mode 100644 index 0000000..0930ccf --- /dev/null +++ b/prompts/patterns/keyinsights.jinja @@ -0,0 +1,30 @@ + +{% include 'patterns/common_text.jinja' %} + +# IDENTITY and PURPOSE + +You extract surprising, powerful, and interesting insights from text content. You are interested in insights related to the purpose and meaning of life, human flourishing, the role of technology in the future of humanity, artificial intelligence and its affect on humans, memes, learning, reading, books, continuous improvement, and similar topics. +You create 15 word bullet points that capture the most important insights from the input. +Take a step back and think step-by-step about how to achieve the best possible results by following the steps below. + +# STEPS + +- Extract 20 to 50 of the most surprising, insightful, and/or interesting ideas from the input in a section called IDEAS, and write them on a virtual whiteboard in your mind using 15 word bullets. If there are less than 50 then collect all of them. Make sure you extract at least 20. + +- From those IDEAS, extract the most powerful and insightful of them and write them in a section called INSIGHTS. Make sure you extract at least 10 and up to 25. + +# OUTPUT INSTRUCTIONS + +- INSIGHTS are essentially higher-level IDEAS that are more abstracted and wise. +- Output the INSIGHTS section only. +- Each bullet should be about 15 words in length. +- Do not give warnings or notes; only output the requested sections. +- You use bulleted lists for output, not numbered lists. +- Do not start items with the same opening words. +- Ensure you follow ALL these instructions when creating your output. + +# INPUT + +{{input_text}} + +# OUTPUT \ No newline at end of file diff --git a/prompts/patterns/makeitdense.jinja b/prompts/patterns/makeitdense.jinja new file mode 100644 index 0000000..0026566 --- /dev/null +++ b/prompts/patterns/makeitdense.jinja @@ -0,0 +1,16 @@ +{% include 'patterns/common_text.jinja' %} + +# MISSION +You are a Sparse Priming Representation (SPR) writer. An SPR is a particular kind of use of language for advanced NLP, NLU, and NLG tasks, particularly useful for the latest generation of Large Language Models (LLMs). You will be given information by the USER which you are to render as an SPR. + +# THEORY +LLMs are a kind of deep neural network. They have been demonstrated to embed knowledge, abilities, and concepts, ranging from reasoning to planning, and even to theory of mind. These are called latent abilities and latent content, collectively referred to as latent space. The latent space of an LLM can be activated with the correct series of words as inputs, which will create a useful internal state of the neural network. This is not unlike how the right shorthand cues can prime a human mind to think in a certain way. Like human minds, LLMs are associative, meaning you only need to use the correct associations to "prime" another model to think in the same way. + +# METHODOLOGY +Render the input as a distilled list of succinct statements, assertions, associations, concepts, analogies, and metaphors. The idea is to capture as much, conceptually, as possible but with as few words as possible. Write it in a way that makes sense to you, as the future audience will be another language model, not a human. Use complete sentences. + +# INPUT + +{{input_text}} + +# OUTPUT \ No newline at end of file diff --git a/prompts/patterns/mermaid.jinja b/prompts/patterns/mermaid.jinja new file mode 100644 index 0000000..cc05ee0 --- /dev/null +++ b/prompts/patterns/mermaid.jinja @@ -0,0 +1,29 @@ +# IDENTITY and PURPOSE + +You are an expert at data and concept visualization and in turning complex ideas into a form that can be visualized using Mermaid (markdown) syntax. +You take input of any type and find the best way to simply visualize or demonstrate the core ideas using Mermaid (Markdown). +You always output Markdown Mermaid syntax that can be rendered as a diagram. + +# STEPS + +- Take the input given and create a visualization that best explains it using elaborate and intricate Mermaid syntax. +- Ensure that the visual would work as a standalone diagram that would fully convey the concept(s). +- Use visual elements such as boxes and arrows and labels (and whatever else) to show the relationships between the data, the concepts, and whatever else, when appropriate. +- Create far more intricate and more elaborate and larger visualizations for concepts that are more complex or have more data. +- Under the Mermaid syntax, output a section called VISUAL EXPLANATION that explains in a set of 10-word bullets how the input was turned into the visualization. Ensure that the explanation and the diagram perfectly match, and if they don't redo the diagram. +- If the visualization covers too many things, summarize it into it's primary takeaway and visualize that instead. +- DO NOT COMPLAIN AND GIVE UP. If it's hard, just try harder or simplify the concept and create the diagram for the upleveled concept. + +# OUTPUT INSTRUCTIONS + +- DO NOT COMPLAIN. Just output the Mermaid syntax. +- Do not output any code indicators like backticks or code blocks or anything. +- Ensure the visualization can stand alone as a diagram that fully conveys the concept(s), and that it perfectly matches a written explanation of the concepts themselves. Start over if it can't. +- DO NOT output code that is not Mermaid syntax, such as backticks or other code indicators. +- Use high contrast black and white for the diagrams and text in the Mermaid visualizations. + +# INPUT + +{{input_text}} + +# OUTPUT diff --git a/prompts/patterns/reflection_questions.jinja b/prompts/patterns/reflection_questions.jinja new file mode 100644 index 0000000..386ec39 --- /dev/null +++ b/prompts/patterns/reflection_questions.jinja @@ -0,0 +1,28 @@ + +{% include 'patterns/common_text.jinja' %} + +# IDENTITY and PURPOSE + +You extract deep, thought-provoking, and meaningful reflections from text content. You are especially focused on themes related to the human experience, such as the purpose of life, personal growth, the intersection of technology and humanity, artificial intelligence's societal impact, human potential, collective evolution, and transformative learning. Your reflections aim to provoke new ways of thinking, challenge assumptions, and provide a thoughtful synthesis of the content. + +# STEPS + +- Extract 3 to 5 of the most profound, thought-provoking, and/or meaningful ideas from the input in a section called REFLECTIONS. +- Each reflection should aim to explore underlying implications, connections to broader human experiences, or highlight a transformative perspective. +- Take a step back and consider the deeper significance or questions that arise from the content. + +# OUTPUT INSTRUCTIONS + +- The output section should be labeled as REFLECTIONS. +- Each bullet point should be between 20-25 words. +- Avoid repetition in the phrasing and ensure variety in sentence structure. +- The reflections should encourage deeper inquiry and provide a synthesis that transcends surface-level observations. +- Use bullet points, not numbered lists. +- Every bullet should be formatted as a question that elicits contemplation or a statement that offers a profound insight. +- Do not give warnings or notes; only output the requested section. + +# INPUT + +{{input_text}} + +# OUTPUT \ No newline at end of file diff --git a/prompts/patterns/summarize.jinja b/prompts/patterns/summarize.jinja new file mode 100644 index 0000000..1b40dee --- /dev/null +++ b/prompts/patterns/summarize.jinja @@ -0,0 +1,16 @@ +{% include 'patterns/common_text.jinja' %} + +# SYSTEM ROLE +You are a content summarization assistant that creates dense, information-rich summaries optimized for machine understanding. Your summaries should capture key concepts with minimal words while maintaining complete, clear sentences. + +# TASK +Analyze the provided content and create a summary that: +- Captures the core concepts and key information +- Uses clear, direct language +- Maintains context from any previous summaries + +# INPUT + +{{input_text}} + +# OUTPUT \ No newline at end of file diff --git a/prompts/patterns/translate.jinja b/prompts/patterns/translate.jinja new file mode 100644 index 0000000..61d8a5e --- /dev/null +++ b/prompts/patterns/translate.jinja @@ -0,0 +1,6 @@ +{% include 'patterns/common_text.jinja' %} + +Please translate the following text to portuguese: + + +{{input_text}} \ No newline at end of file diff --git a/stream_app/source.py b/stream_app/source.py index 2ad6803..1232268 100644 --- a/stream_app/source.py +++ b/stream_app/source.py @@ -2,13 +2,14 @@ from pathlib import Path import streamlit as st import streamlit_scrollable_textbox as stx # type: ignore +import yaml from humanize import naturaltime from loguru import logger -from streamlit_tags import st_tags # type: ignore from open_notebook.domain import Asset, Source from open_notebook.graphs.content_process import graph -from open_notebook.utils import token_cost, token_count +from open_notebook.graphs.multipattern import graph as transform_graph +from open_notebook.utils import surreal_clean from .consts import context_icons @@ -16,50 +17,71 @@ uploads_dir = Path("./.uploads") uploads_dir.mkdir(parents=True, exist_ok=True) +def run_transformations(input_text, transformations): + output = transform_graph.invoke( + dict(content_stack=[input_text], transformations=transformations) + ) + return output["output"] + + @st.dialog("Source", width="large") def source_panel(source_id): source: Source = Source.get(source_id) if not source: st.error("Source not found") return - title = st.empty() - if source.title: - title.subheader(source.title) - st.caption(f"Created {naturaltime(source.created)}") - # st.markdown(f"**URL:** {source.url}, **File:** {source.file_path}") - summary = st.empty() - for insight in source.insights: - summary.write(insight.insight_type) - summary.write(insight.content) - topics = source.topics or [] - if len(topics) > 0: - st_tags( - label="", - text="Press enter to add more", - value=source.topics, - suggestions=source.topics, - maxtags=10, - key="1", - ) + process_tab, source_tab = st.tabs(["Process", "Source"]) + with process_tab: + c1, c2 = st.columns([3, 1]) + with c1: + title = st.empty() + if source.title: + title.subheader(source.title) + if source.asset.url: + from_src = f"from URL: {source.asset.url}" + elif source.asset.file_path: + from_src = f"from file: {source.asset.file_path}" + else: + from_src = "from text" + st.caption(f"Created {naturaltime(source.created)}, {from_src}") + for insight in source.insights: + with st.expander(f"**{insight.insight_type}**"): + st.markdown(insight.content) + if st.button("Delete", key=f"delete_insight_{insight.id}"): + insight.delete() + st.rerun(scope="fragment") - if st.button("Delete", icon="🗑️"): - source.delete() - st.rerun() + with c2: + with open("transformations.yaml", "r") as file: + transformations = yaml.safe_load(file) + for transformation in transformations["source_insights"]: + if st.button( + transformation["name"], help=transformation["description"] + ): + result = run_transformations( + source.full_text, transformation["transformations"] + ) + source.add_insight( + transformation["insight_type"], surreal_clean(result) + ) + st.rerun(scope="fragment") - cost = token_cost(token_count(source.full_text)) * 1.2 - if st.button(f"Summarize (about ${cost:.4f})", icon="📝"): - source.summarize() - st.rerun(scope="fragment") + if st.button( + "Embed vectors", + icon="🦾", + help="This will generate your embedding vectors on the database for powerful search capabilities", + ): + source.vectorize() + st.success("Embedding complete") - cost_embedding = token_cost(token_count(source.full_text), 0.02) + if st.button("Delete", icon="🗑️"): + source.delete() + st.rerun() - if st.button(f"Embed (${cost_embedding:.4f})", icon="📝"): - source.vectorize() - st.success("Embedding complete") - - st.subheader("Content") - stx.scrollableTextbox(source.full_text, height=300) + with source_tab: + st.subheader("Content") + stx.scrollableTextbox(source.full_text, height=300) @st.dialog("Add a Source", width="large") @@ -105,16 +127,14 @@ def add_source(session_id): st.write("Saving..") source = Source( asset=Asset(url=req.get("url"), file_path=req.get("file_path")), + full_text=surreal_clean(result["content"]), ) source.save() - source.save_chunks(result["content"]) source.add_to_notebook(st.session_state[session_id]["notebook"].id) st.write("Summarizing...") source.summarize() st.rerun() - # else: - # st.stop() def source_card(session_id, source): diff --git a/transformations.yaml b/transformations.yaml new file mode 100644 index 0000000..b1c2cab --- /dev/null +++ b/transformations.yaml @@ -0,0 +1,35 @@ + +source_insights: + - name: "Summarize" + insight_type: "Content Summary" + description: "Summarize the content" + transformations: + - patterns/makeitdense + - patterns/summarize + - name: "Key Insights" + insight_type: "Key Insights" + description: "Extracts a list of the Key Insights of the content" + transformations: + - patterns/keyinsights + - name: "Make it Dense" + insight_type: "Dense Representation" + description: "Create a dense representation of the content" + transformations: + - patterns/makeitdense + - name: "Analyze Paper" + insight_type: "Paper Analysis" + description: "Analyze the paper and provide a quick summary" + transformations: + - patterns/analyze_paper + - name: "Reflection" + insight_type: "Reflection Questions" + description: "Generates a list of insightful questions to provoke reflection" + transformations: + - patterns/reflection_questions + - name: "Reflection [PT]" + insight_type: "Reflection Questions [PT]" + description: "Generates a list of insightful questions to provoke reflection" + transformations: + - patterns/reflection_questions + - patterns/translate + From 8a0e6a9ac0995454d92f0128671465d74dc36e7a Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 14:12:58 -0300 Subject: [PATCH 3/6] hide translation example --- transformations.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/transformations.yaml b/transformations.yaml index b1c2cab..48ce93d 100644 --- a/transformations.yaml +++ b/transformations.yaml @@ -26,10 +26,10 @@ source_insights: description: "Generates a list of insightful questions to provoke reflection" transformations: - patterns/reflection_questions - - name: "Reflection [PT]" - insight_type: "Reflection Questions [PT]" - description: "Generates a list of insightful questions to provoke reflection" - transformations: - - patterns/reflection_questions - - patterns/translate + # - name: "Reflection [PT]" + # insight_type: "Reflection Questions [PT]" + # description: "Generates a list of insightful questions to provoke reflection" + # transformations: + # - patterns/reflection_questions + # - patterns/translate From 795fd3bb9d987615f02e06e202a052533aeaf231 Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 14:13:22 -0300 Subject: [PATCH 4/6] improve surreal escaping --- open_notebook/utils.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/open_notebook/utils.py b/open_notebook/utils.py index 0a4c555..27ae092 100644 --- a/open_notebook/utils.py +++ b/open_notebook/utils.py @@ -1,5 +1,5 @@ import re -import string +import unicodedata from langchain_text_splitters import CharacterTextSplitter from openai import OpenAI @@ -78,7 +78,13 @@ def remove_non_ascii(text): def remove_non_printable(text): - return "".join(filter(lambda x: x in string.printable, text)) + # Remove caracteres de controle, exceto quebras de linha e tabulações + text = "".join( + char for char in text if unicodedata.category(char)[0] != "C" or char in "\n\t" + ) + # Manter letras (incluindo acentuadas), números, espaços, quebras de linha, tabulações e pontuação básica + allowed = r"a-zA-Z0-9\s.,!?\-\n\t" + return re.sub(f"[^{allowed}]", "", text, flags=re.UNICODE) def surreal_clean(text): @@ -91,7 +97,7 @@ def surreal_clean(text): Returns: str: The cleaned text with adjusted formatting. """ - text = remove_non_printable(remove_non_ascii(text)) + text = remove_non_printable(text) # Add space after colon if it's before the first space first_space_index = text.find(" ") From 9b9303d52ff52bbdf3a7a814e95e773b54ecff14 Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 15:09:40 -0300 Subject: [PATCH 5/6] process table of contents for all sources --- open_notebook/domain.py | 23 ++++---- open_notebook/graphs/recursive_toc.py | 78 +++++++++++++++++++++++++++ prompts/recursive_toc.jinja | 24 +++++++++ stream_app/chat.py | 8 +-- stream_app/source.py | 2 +- 5 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 open_notebook/graphs/recursive_toc.py create mode 100644 prompts/recursive_toc.jinja diff --git a/open_notebook/domain.py b/open_notebook/domain.py index 44c1fef..4011473 100644 --- a/open_notebook/domain.py +++ b/open_notebook/domain.py @@ -11,7 +11,8 @@ from open_notebook.exceptions import ( InvalidInputError, NotFoundError, ) -from open_notebook.graphs.summary import graph as summarizer +from open_notebook.graphs.multipattern import graph as pattern_graph +from open_notebook.graphs.recursive_toc import graph as toc_graph from open_notebook.repository import ( repo_create, repo_delete, @@ -239,8 +240,7 @@ class Source(ObjectModel): def vectorize(self) -> None: try: - full_text = self.full_text - if not full_text: + if not self.full_text: return chunks = split_text( self.full_text, @@ -306,15 +306,20 @@ class Source(ObjectModel): logger.error(f"Error adding insight to source {self.id}: {str(e)}") raise DatabaseOperationError(e) - def summarize(self) -> "Source": + def generate_toc_and_title(self) -> "Source": try: config = RunnableConfig(configurable=dict(thread_id=self.id)) - result = summarizer.invoke({"content": self.full_text}, config=config)[ - "output" + result = toc_graph.invoke({"content": self.full_text}, config=config) + logger.warning(result["toc"]) + self.add_insight("Table of Contents", surreal_clean(result["toc"])) + transformations = [ + "Based on the Table of Contents below, please provide a Title for this content, with max 15 words" ] - self.add_insight("summary", surreal_clean(result.summary)) - self.title = surreal_clean(result.title) - self.topics = result.topics + output = pattern_graph.invoke( + dict(content_stack=[result["toc"]], transformations=transformations) + ) + logger.warning(output["output"]) + self.title = surreal_clean(output["output"]) self.save() return self except Exception as e: diff --git a/open_notebook/graphs/recursive_toc.py b/open_notebook/graphs/recursive_toc.py new file mode 100644 index 0000000..9cffc5d --- /dev/null +++ b/open_notebook/graphs/recursive_toc.py @@ -0,0 +1,78 @@ +import os +from typing import List, Literal + +from langchain_core.runnables import ( + RunnableConfig, +) +from langgraph.graph import END, START, StateGraph +from typing_extensions import TypedDict + +from open_notebook.graphs.utils import run_pattern +from open_notebook.utils import split_text + + +class TocState(TypedDict): + chunks: List[str] + content: str + toc: str + + +def build_chunks(state: TocState) -> dict: + """ + Split the input text into chunks. + """ + return { + "chunks": split_text( + state["content"], + chunk=int(os.environ.get("SUMMARY_CHUNK_SIZE", 200000)), + overlap=int(os.environ.get("SUMMARY_CHUNK_OVERLAP", 1000)), + ) + } + + +def setup_next_chunk(state: TocState) -> dict: + """ + Move the next item in the chunk to the processing area + """ + state["content"] = state["chunks"].pop(0) + return {"chunks": state["chunks"], "content": state["content"]} + + +def chunk_condition(state: TocState) -> Literal["get_chunk", END]: # type: ignore + """ + Checks whether there are more chunks to process. + """ + if len(state["chunks"]) > 0: + return "get_chunk" + return END + + +def call_model(state: TocState, config: RunnableConfig) -> dict: + model_name = config.get("configurable", {}).get( + "model_name", os.environ.get("SUMMARIZATION_MODEL") + ) + return { + "toc": run_pattern( + pattern_name="recursive_toc", + model_name=model_name, + state=state, + ).content + } + + +agent_state = StateGraph(TocState) +agent_state.add_node("setup_chunk", build_chunks) +agent_state.add_edge(START, "setup_chunk") +agent_state.add_conditional_edges( + "setup_chunk", + chunk_condition, +) +agent_state.add_node("get_chunk", setup_next_chunk) +agent_state.add_node("agent", call_model) +agent_state.add_edge("get_chunk", "agent") +agent_state.add_conditional_edges( + "agent", + chunk_condition, +) + +graph = agent_state.compile() diff --git a/prompts/recursive_toc.jinja b/prompts/recursive_toc.jinja new file mode 100644 index 0000000..b92512b --- /dev/null +++ b/prompts/recursive_toc.jinja @@ -0,0 +1,24 @@ + +# SYSTEM ROLE +You are a content analysis assistant that reads through documents and provides a Table of Contents (ToC) to help users identify what the document covers more easily. +Your ToC should capture all major topics and transitions in the content and should mention them in the order theh appear. + +# TASK +Analyze the provided content and create a Table of Contents: +- Captures the core topics included in the text +- Gives a small description of what is covered + +# INSTRUCTIONS FOR LARGE DOCUMENTS + +If you see a PREVIOUS TOC section below, it means that this request is a continuation of a previous request. Most likely to handle context length issues. +Every time, you should replace the previous toc with the new one, and append the new content to the previous content. + +{% if toc %} +# PREVIOUS TOC + +{{toc}} +{% endif %} + +# CONTENT + +{{content}} diff --git a/stream_app/chat.py b/stream_app/chat.py index 05759d6..0c68b41 100644 --- a/stream_app/chat.py +++ b/stream_app/chat.py @@ -3,7 +3,7 @@ from langchain_core.runnables import RunnableConfig from open_notebook.domain import Note, Source from open_notebook.graphs.chat import graph as chat_graph -from open_notebook.utils import token_cost, token_count +from open_notebook.utils import token_count # todo: build a smarter, more robust context manager function @@ -56,11 +56,11 @@ def execute_chat(txt_input, session_id): # seria bom ter um total de tokens no admin em algum lugar def chat_sidebar(session_id): context = build_context(session_id=session_id) - tokens = token_count(str(context)) - cost = token_cost(tokens) + tokens = token_count(str(context) + str(st.session_state[session_id]["messages"])) with st.container(border=True): request = st.chat_input("Enter your question") - st.caption(f"Total tokens: {tokens}, cost: ${cost:.4f}") + # removing for now since it's not multi-model capable right now + st.caption(f"Total tokens: {tokens}") if request: response = execute_chat(txt_input=request, session_id=session_id) st.session_state[session_id]["messages"] = response["messages"] diff --git a/stream_app/source.py b/stream_app/source.py index 1232268..bd30713 100644 --- a/stream_app/source.py +++ b/stream_app/source.py @@ -132,7 +132,7 @@ def add_source(session_id): source.save() source.add_to_notebook(st.session_state[session_id]["notebook"].id) st.write("Summarizing...") - source.summarize() + source.generate_toc_and_title() st.rerun() From c3f3c9cb934d712742398d075e5a67681806172c Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Wed, 23 Oct 2024 15:40:28 -0300 Subject: [PATCH 6/6] update docs to new release info --- .env.example | 3 +- Makefile | 13 +++- README.md | 16 +++-- docs/SETUP.md | 6 +- docs/TRANSFORMATIONS.md | 108 ++++++++++++++++++++++++++++++++ docs/USAGE.md | 7 +++ docs/assets/transformations.png | Bin 0 -> 137004 bytes open_notebook/repository.py | 2 +- pyproject.toml | 2 +- 9 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 docs/TRANSFORMATIONS.md create mode 100644 docs/assets/transformations.png diff --git a/.env.example b/.env.example index 787de5b..c6adff8 100644 --- a/.env.example +++ b/.env.example @@ -38,7 +38,8 @@ OPENROUTER_API_KEY= # LANGCHAIN_PROJECT="Open Notebook" # CONNECTION DETAILS FOR YOUR SURREAL DB -SURREAL_ADDRESS="ws://localhost:8000/rpc" +SURREAL_ADDRESS="localhost" +SURREAL_PORT=8000 SURREAL_USER="root" SURREAL_PASS="root" SURREAL_NAMESPACE="open_notebook" diff --git a/Makefile b/Makefile index 8650bb2..d10e1c7 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,6 @@ docker-build: docker-buildx-prepare docker buildx build \ --platform $(PLATFORMS) \ -t $(IMAGE_NAME):$(VERSION) \ - -t $(IMAGE_NAME):latest \ --push \ . @@ -41,4 +40,14 @@ docker-release: docker-build # Comando útil para verificar as plataformas suportadas após o build docker-check-platforms: - docker manifest inspect $(IMAGE_NAME):$(VERSION) \ No newline at end of file + docker manifest inspect $(IMAGE_NAME):$(VERSION) + +docker-update-latest: docker-buildx-prepare + docker buildx build \ + --platform $(PLATFORMS) \ + -t $(IMAGE_NAME):latest \ + --push \ + . + +# Release with latest +docker-release-all: docker-release docker-update-latest diff --git a/README.md b/README.md index d0d1d58..d0d82bc 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,15 @@ Go to the [Usage](docs/USAGE.md) page to learn how to use all features. ## 🚀 New Features - ### v0.0.2 - Several new providers are supported now: +### v0.0.3 - Transformations ✨ + +We just release a much more powerful way to create more value from your sources. +Transformations enable you do extract an unlimited amount of insights from your content. +It's 100% customizable and you can extend it to your own needs, like Paper Analysis, Article Writing, etc. + +Head to the [Transformations](docs/TRANSFORMATIONS.md) page for more info + +### v0.0.2 - Several new providers are supported now: - OpenAI - Anthropic @@ -106,14 +114,10 @@ Locate anything across your research with ease using full-text and vector-based Jinja based prompts that are easy to customize to your own preferences. - - ## 🌟 Coming Soon - **Podcast Generator**: Automatically convert your notes into a podcast format. -- **Multi-model support**: Anthropic, Gemini, Mistral, Ollama coming soon. - **Enhanced Citations**: Improved layout and finer control for citations. -- **Insight Generation**: New tools for creating insights, leveraging the Fabric framework. - **Better Embeddings & Summarization**: Smarter ways to distill information. - **Multiple Chat Sessions**: Juggle different discussions within the same notebook. - **Live Front-End Updates**: Real-time UI updates for a smoother experience. @@ -121,6 +125,8 @@ Jinja based prompts that are easy to customize to your own preferences. - **Improved Error Handling**: Making everything more robust. - **Cross-Notebook Sources and Notes**: Reuse research notes across projects. - **Bookmark Integration**: Integrate with your favorite bookmarking app. +- **Multi-model support**: Anthropic, Gemini, Mistral, Ollama coming soon. ✅ 0.0.2 +- **Insight Generation**: New tools for creating insights - [transformations](docs/TRANSFORMATIONS.md) ✅ 0.0.3 ## 💻 Tech Stack diff --git a/docs/SETUP.md b/docs/SETUP.md index a179385..cd85bfb 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -52,7 +52,8 @@ docker run -d \ -p 8080:8502 \ -e OPENAI_API_KEY=API_KEY \ -e DEFAULT_MODEL="gpt-4o-mini" \ - -e SURREAL_ADDRESS="ws://localhost:8000/rpc" \ + -e SURREAL_ADDRESS="localhost" \ + -e SURREAL_PORT=8000 \ -e SURREAL_USER="root" \ -e SURREAL_PASS="root" \ -e SURREAL_NAMESPACE="open_notebook" \ @@ -104,7 +105,8 @@ services: environment: - OPENAI_API_KEY=API_KEY - DEFAULT_MODEL=gpt-4o-mini - - SURREAL_ADDRESS=ws://surrealdb:8000/rpc + - SURREAL_ADDRESSsurrealdb + - SURREAL_PORT=8000 - SURREAL_USER=root - SURREAL_PASS=root - SURREAL_NAMESPACE=open_notebook diff --git a/docs/TRANSFORMATIONS.md b/docs/TRANSFORMATIONS.md new file mode 100644 index 0000000..3c4dfe9 --- /dev/null +++ b/docs/TRANSFORMATIONS.md @@ -0,0 +1,108 @@ +# Transformations Guide + +**Unleashing the hidden knowledge of your content** + +Transformations are a core concept within Open Notebook, providing a flexible and powerful way to generate new insights by applying a series of processing steps to your content. Based on the Fabric framework, Transformations allow you to customize how information is distilled, summarized, and enriched, opening up new ways to understand and engage with your research. + +![New Notebook](assets/transformations.png) + +### What is a Transformation? + +A **Transformation** is a sequence of operations that modifies text input to produce a different output. Whether you're summarizing an article, generating key insights, or creating reflective questions, Transformations allow you to automate and enrich the processing of your content. Each transformation is composed of one or more blocks called **Patterns**, which can be linked in a chain to achieve complex results. + +Below is a diagram that illustrates how a transformation is composed of multiple patterns that are processed sequentially: + +```mermaid +graph TD; + A[Input Text] --> B[Pattern 1: Summarize]; + B --> C[Pattern 2: Generate Topics]; + C --> D[Pattern 3: Reflection Questions]; + D --> E[Final Output] +``` + +For example, you could start by summarizing a text, then use that summary to generate specific topics or reflections. By applying these layered processing steps, Transformations help you generate deeper insights and maximize the value of your content. + +### Setting Up Transformations + +To set up your own Transformations, you'll define them in the `transformations.yaml` file. Below is an example setup: + +```yaml +source_insights: + - name: "Summarize" + insight_type: "Content Summary" + description: "Summarize the content" + transformations: + - patterns/makeitdense + - patterns/summarize + - name: "Key Insights" + insight_type: "Key Insights" + description: "Extracts a list of the Key Insights of the content" + transformations: + - patterns/keyinsights + - name: "Make it Dense" + insight_type: "Dense Representation" + description: "Create a dense representation of the content" + transformations: + - patterns/makeitdense + - name: "Analyze Paper" + insight_type: "Paper Analysis" + description: "Analyze the paper and provide a quick summary" + transformations: + - patterns/analyze_paper + - name: "Reflection" + insight_type: "Reflection Questions" + description: "Generates a list of insightful questions to provoke reflection" + transformations: + - patterns/reflection_questions +``` + +Once you've defined your transformation, make sure to add the corresponding prompts to the `prompts/patterns` folder. Here's an example of a transformation prompt: + +```jinja +{% include 'patterns/common_text.jinja' %} + +# IDENTITY and PURPOSE + +You extract deep, thought-provoking, and meaningful reflections from text content. You are especially focused on themes related to the human experience, such as the purpose of life, personal growth, the intersection of technology and humanity, artificial intelligence's societal impact, human potential, collective evolution, and transformative learning. Your reflections aim to provoke new ways of thinking, challenge assumptions, and provide a thoughtful synthesis of the content. + +# STEPS + +- Extract 3 to 5 of the most profound, thought-provoking, and/or meaningful ideas from the input in a section called REFLECTIONS. +- Each reflection should aim to explore underlying implications, connections to broader human experiences, or highlight a transformative perspective. +- Take a step back and consider the deeper significance or questions that arise from the content. + +# OUTPUT INSTRUCTIONS + +- The output section should be labeled as REFLECTIONS. +- Each bullet point should be between 20-25 words. +- Avoid repetition in the phrasing and ensure variety in sentence structure. +- The reflections should encourage deeper inquiry and provide a synthesis that transcends surface-level observations. +- Use bullet points, not numbered lists. +- Every bullet should be formatted as a question that elicits contemplation or a statement that offers a profound insight. + +# INPUT + +{{input_text}} + +# OUTPUT +``` + +### Important Tips + +- Always use `{{ input_text }}` to reference the text coming from the previous transformation. +- You can use `include` statements, like in the example above, to insert common instructions across all your patterns. +- Paths that start with `patterns/` will point to a corresponding `.jinja` file in the `patterns` folder. +- Any item that doesn't follow the `patterns/` format will be interpreted as a command (refer to `command.jinja` for clarity). + + + +### Call for Contributions + +Have an idea for an amazing Transformation? We'd love to see your creativity! Please submit a pull request with your favorite transformations to help expand our library. Whether it's summarization, content analysis, or something entirely unique, your contributions will help us all get more out of our research!Leveraging Transformations in Open Notebook + +Your custom Patterns will automatically appear on the Sources page in Open Notebook. This makes it easy to select and apply them to your content as you research and explore. Note that we'll soon be adding **Note patterns** as well, making it even easier to transform not just sources, but also your own notes and thoughts. + + +### Sky's the Limit + +Transformations empower you to create personalized, powerful workflows that bring out the most meaningful insights from your content. Whether you're working with articles, papers, notes, or other media, you can craft specific and meaningful outcomes tailored to your research goals. Start experimenting today and see just how transformative your content can become! diff --git a/docs/USAGE.md b/docs/USAGE.md index 442d311..73d1d0b 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -18,6 +18,13 @@ You'll find your new source in the first column of the Notebook Page. ![New Notebook](assets/asset_list.png) +## Using transformations + +Once you have your sources created, you can start gathering insights from them using [transformations](TRANSFORMATIONS.md). +Create your own prompts and generate the wisdom that makes sense to you. + +![New Notebook](assets/transformations.png) + ## Talk to the Assistant Once you have enough content in the notebook, you can decide which of them will be visible to LLM before sending your question. diff --git a/docs/assets/transformations.png b/docs/assets/transformations.png new file mode 100644 index 0000000000000000000000000000000000000000..707bb25348980fe420cb0b679c1997b3fdb26502 GIT binary patch literal 137004 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

S~h#$Tq7(k3!qdUb=Q9>fcqkhpt-}CZ~O#u{4`6 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℘0pwFEB*CPJ+FRq(nyYB{PM1}RNdyPGb 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 literal 0 HcmV?d00001 diff --git a/open_notebook/repository.py b/open_notebook/repository.py index f14e5d1..74f6d45 100644 --- a/open_notebook/repository.py +++ b/open_notebook/repository.py @@ -14,7 +14,7 @@ EXPECTED_VERSION = "0.0.2" def db_connection(): connection = SurrealSyncConnection( host=os.environ["SURREAL_ADDRESS"], - port=8000, # Adjust this if your port is different + port=int(os.environ["SURREAL_PORT"]), user=os.environ["SURREAL_USER"], password=os.environ["SURREAL_PASS"], namespace=os.environ["SURREAL_NAMESPACE"], diff --git a/pyproject.toml b/pyproject.toml index 1babb6d..533c256 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "open-notebook" -version = "0.0.2" +version = "0.0.3" description = "An open source implementation of a research assistant, inspired by Google Notebook LM" authors = ["Luis Novo "] license = "MIT"